Google AI Examples¶
Code examples for Gemini API and Vertex AI integration.
Gemini API (LLM Tasks)¶
Basic Text Generation¶
from google.genai import Client, types
client = Client(api_key=settings.GEMINI_API_KEY)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="Describe the latest trends in sustainable fashion.",
)
print(response.text)
Structured JSON Output¶
config = types.GenerateContentConfig(
response_mime_type="application/json"
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents='List 3 fashion trends. Return JSON: {"trends": [{"name": "...", "description": "..."}]}',
config=config,
)
import json
trends = json.loads(response.text)
With System Instructions¶
config = types.GenerateContentConfig(
response_mime_type="application/json",
system_instruction=[
types.Part.from_text(text="You are a professional fashion stylist. Always respond in JSON.")
]
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="Suggest an outfit for a summer wedding.",
config=config,
)
Multimodal - Image + Text¶
from pathlib import Path
def analyze_image(image_path: str, prompt: str) -> dict:
image_bytes = Path(image_path).read_bytes()
# Detect MIME type
mime_type = "image/jpeg" if image_path.endswith(".jpg") else "image/png"
contents = types.Content(
role="user",
parts=[
types.Part.from_bytes(data=image_bytes, mime_type=mime_type),
types.Part.from_text(text=prompt),
]
)
config = types.GenerateContentConfig(
response_mime_type="application/json"
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=contents,
config=config,
)
return json.loads(response.text)
# Usage
result = analyze_image(
"product.jpg",
'Describe this garment. Return JSON: {"category": "...", "color": "...", "style": "..."}'
)
Outfit Styling Service¶
Complete Styling Workflow¶
class StylingService:
def __init__(self, api_key: str):
self.client = Client(api_key=api_key)
def generate_outfits(
self,
core_product: dict,
catalog: list[dict],
num_looks: int = 3
) -> dict:
# Format catalog as TSV for token efficiency
catalog_tsv = "id\tname\tcategory\tcolor\n"
for item in catalog:
catalog_tsv += f"{item['id']}\t{item['name']}\t{item['category']}\t{item['color']}\n"
system_prompt = """
You are a professional fashion stylist.
Create outfit recommendations using ONLY products from the provided catalog.
Each look MUST include the core product.
Return valid JSON with product IDs from the catalog.
"""
user_prompt = f"""
Core product:
ID: {core_product['id']}
Name: {core_product['name']}
Category: {core_product['category']}
Available catalog:
{catalog_tsv}
Create {num_looks} complete outfit looks. Return:
{{
"looks": [
{{
"name": "Look name",
"items": [{{"id": "uuid", "role": "category"}}]
}}
]
}}
"""
config = types.GenerateContentConfig(
response_mime_type="application/json",
system_instruction=[types.Part.from_text(text=system_prompt)]
)
response = self.client.models.generate_content(
model="gemini-2.0-flash-latest",
contents=user_prompt,
config=config,
)
return json.loads(response.text)
# Usage
stylist = StylingService(api_key=settings.GEMINI_API_KEY)
outfits = stylist.generate_outfits(
core_product={"id": "prod-123", "name": "Blue Dress", "category": "dresses"},
catalog=[...],
num_looks=3
)
Vertex AI (Image Tasks)¶
Image Generation¶
from google import genai
from google.genai import types
client = genai.Client(
api_key=settings.GOOGLE_API_KEY,
vertexai=True,
project=settings.GOOGLE_CLOUD_PROJECT,
location=settings.GOOGLE_CLOUD_LOCATION,
)
# Safety settings for fashion content
safety_settings = [
types.SafetySetting(
category=types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
threshold=types.HarmBlockThreshold.OFF,
),
types.SafetySetting(
category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
threshold=types.HarmBlockThreshold.OFF,
),
]
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents="Professional fashion photograph of a model wearing an elegant black dress, studio lighting",
config=types.GenerateContentConfig(
safety_settings=safety_settings,
generation_config=types.GenerationConfig(
temperature=0.8,
top_p=0.95,
)
),
)
# Extract generated image
for part in response.candidates[0].content.parts:
if part.inline_data:
image_bytes = part.inline_data.data
# Save or process image
Image Editing (Virtual Try-On)¶
def virtual_tryon(
base_image_path: str,
garment_image_path: str,
prompt: str = "Make the person wear this garment"
) -> bytes:
"""Perform virtual try-on using Vertex AI."""
base_bytes = Path(base_image_path).read_bytes()
garment_bytes = Path(garment_image_path).read_bytes()
contents = types.Content(
role="user",
parts=[
types.Part.from_text(text="Base image (person):"),
types.Part.from_bytes(data=base_bytes, mime_type="image/jpeg"),
types.Part.from_text(text="Reference garment:"),
types.Part.from_bytes(data=garment_bytes, mime_type="image/jpeg"),
types.Part.from_text(text=f"Task: {prompt}. Generate an image showing the person wearing the garment."),
]
)
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents=contents,
config=types.GenerateContentConfig(
safety_settings=safety_settings,
),
)
# Extract image from response
for part in response.candidates[0].content.parts:
if part.inline_data:
return part.inline_data.data
raise ValueError("No image generated")
# Usage
result_image = virtual_tryon(
"model_photo.jpg",
"dress.jpg",
"Virtual try-on: make the model wear this dress naturally"
)
Vision Analysis¶
def analyze_fashion_image(image_path: str) -> dict:
"""Analyze a fashion photograph using Vertex AI."""
image_bytes = Path(image_path).read_bytes()
contents = types.Content(
role="user",
parts=[
types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"),
types.Part.from_text(text="""
Analyze this fashion photograph in detail.
Describe:
1. The outfit and styling
2. The model's pose and expression
3. Lighting and composition
4. Overall aesthetic and target audience
Return a detailed JSON response.
"""),
]
)
response = client.models.generate_content(
model="gemini-3-pro-preview", # Text model for analysis
contents=contents,
config=types.GenerateContentConfig(
response_mime_type="application/json",
),
)
return json.loads(response.text)
Token Counting¶
from google.generativeai import GenerativeModel
from google.generativeai.types.content_types import to_contents
def count_tokens(text: str, model: str = "gemini-2.0-flash") -> int:
"""Count tokens for a given text."""
model_instance = GenerativeModel(model)
result = model_instance.count_tokens(to_contents(text))
return result.total_tokens
# Usage
token_count = count_tokens(my_prompt)
print(f"Prompt uses {token_count} tokens")
Error Handling¶
Robust Response Parsing¶
import json
import re
def parse_gemini_json(response_text: str) -> dict:
"""Parse JSON from Gemini response, handling various formats."""
text = response_text.strip()
# Try direct parse
try:
return json.loads(text)
except json.JSONDecodeError:
pass
# Handle markdown code blocks
patterns = [
r'```json\s*(.*?)\s*```',
r'```\s*(.*?)\s*```',
]
for pattern in patterns:
match = re.search(pattern, text, re.DOTALL)
if match:
try:
return json.loads(match.group(1))
except json.JSONDecodeError:
continue
raise ValueError(f"Could not parse JSON: {text[:200]}")
Retry with Backoff¶
import time
from google.api_core.exceptions import ResourceExhausted
def call_with_retry(func, max_retries: int = 3):
"""Call function with exponential backoff on rate limits."""
for attempt in range(max_retries):
try:
return func()
except ResourceExhausted:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Rate limited, waiting {wait_time}s...")
time.sleep(wait_time)
else:
raise
except Exception as e:
if "quota" in str(e).lower() and attempt < max_retries - 1:
time.sleep(5)
else:
raise
Complete Workflow: Product Captioning¶
async def caption_products(products: list[dict]) -> list[dict]:
"""Caption multiple products using Gemini."""
client = Client(api_key=settings.GEMINI_API_KEY)
results = []
for product in products:
try:
image_bytes = await fetch_image(product["image_url"])
contents = types.Content(
role="user",
parts=[
types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"),
types.Part.from_text(text="""
Describe this product for an e-commerce catalog.
Return JSON: {
"title": "Product title",
"description": "2-3 sentence description",
"attributes": {"color": "...", "material": "...", "style": "..."}
}
"""),
]
)
response = client.models.generate_content(
model="gemini-2.5-flash-preview-05-20",
contents=contents,
config=types.GenerateContentConfig(
response_mime_type="application/json"
),
)
caption = json.loads(response.text)
results.append({
"product_id": product["id"],
"caption": caption,
"status": "success"
})
except Exception as e:
results.append({
"product_id": product["id"],
"error": str(e),
"status": "failed"
})
return results