DS DevShelfHub Projects · AI tools
Cheatsheets / Gemini API
Cheatsheet · AI frameworks

Gemini API Cheatsheet: google-genai SDK Reference

By DevShelfHub

google-genai SDK, generate_content, structured output, function calling, streaming, multimodal, files, embeddings, grounding — the Gemini surface day-to-day.

114 items 8 min GenAI Multimodal Grounding

Start hereQuick start · 6 you’ll reach for daily

Simple callclient.models.generate_content(model, contents)
Multi-turn chatchat = client.chats.create(model)
Structured outputresponse_schema=Schema (Pydantic)
Tool callingtools=[my_function]
Stream tokensgenerate_content_stream(…)
Visioncontents=[image, "describe"]

Target versions · paceVersions

Targets: google-genai ≥ 1.0 @google/genai ≥ 0.10 API: Gemini 2.x python ≥ 3.9

Use the new google-genai SDK (from google import genai) for Gemini 2.x and beyond. The older google-generativeai package (import google.generativeai as genai) is Legacy — new features (Live API, batch, Files v2) only ship on google-genai. The same SDK calls AI Studio (GEMINI_API_KEY) and Vertex AI (ADC + project/location) — switched by env var.

Install · envSetup

bash
# Python SDK — the modern one (Gemini 2.x era)
pip install google-genai     # ≥ 1.0

# Node / TS SDK
npm install @google/genai

# env — picked up automatically by Client()
export GEMINI_API_KEY=AIza...
# or, equivalently, for AI Studio keys:
export GOOGLE_API_KEY=AIza...

# Vertex AI mode uses ADC instead of an API key:
export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT=my-project
export GOOGLE_CLOUD_LOCATION=us-central1

Where things liveCommon imports

Two top-level imports cover the surface: the genai package for clients and the types module for config + content objects.

from google import genaiTop-level package.
from google.genai import typesConfig classes, Content / Part / Tool wrappers.
client = genai.Client()Reads GEMINI_API_KEY (or Vertex env).
client = genai.Client(api_key="…", vertexai=True, project=…, location=…)Override env explicitly.
client.aio.models.generate_content(…)Async variant. Use in FastAPI / asyncio.
from google.genai.errors import APIError, ClientError, ServerErrorException base classes.
from pydantic import BaseModelSchemas for response_schema.
import google.generativeai as genaiLegacy Old SDK. Avoid in new code.

Pick the right oneModels

Current generation

gemini-2.5-proFlagship reasoning. Best at code, math, long context.
gemini-2.5-flashStrong default. Fast, multimodal, cheap, 1M-token context.
gemini-2.5-flash-liteCheapest 2.5. Classify / extract / route.
gemini-2.0-flash, gemini-2.0-flash-litePrevious gen. Still widely deployed.
gemini-live-2.5-flash-previewLive API — bidirectional audio/video streaming.

Embeddings, images, TTS

gemini-embedding-001Default text embedding. Up to 3072 dims.
imagen-4.0-generate-preview, imagen-4.0-fast-generateImage generation.
veo-3.0-generate-previewVideo generation. Async via long-running operations.
gemini-2.5-flash-preview-ttsText-to-speech.
gemini-1.5-pro, gemini-1.0-proLegacy Outdated. Migrate to 2.5.
List live IDs with client.models.list(). Pin the exact ID in production — Google rotates -latest aliases without notice and previews graduate to stable under new names.

The single endpointgenerate_content

Basic call

client.models.generate_content(model, contents)The everyday call. Contents = string, Part, or list of either.
resp.textConcatenated text across all parts. The shortcut.
resp.parsedPydantic instance when response_schema was set.
resp.candidates[0].content.partsFull content tree (text, function_call, inline_data…).
resp.usage_metadataToken counts: prompt, candidates, cached, total.
resp.prompt_feedbackSet when the prompt itself was blocked.

Contents — accepted shapes

contents="hi"String shorthand. One user turn, one text part.
contents=["hi", image_part]List = one user turn with multiple parts.
contents=[Content(role="user", parts=[…]), Content(role="model", …)]Multi-turn. Roles are user / model (not assistant).
types.Part.from_text(text="…")Explicit text part.
types.Part.from_bytes(data=..., mime_type="image/png")Inline image / audio / video bytes.
types.Part.from_uri(file_uri="https://…", mime_type="…")File served from GCS or a public URL.

GenerateContentConfig

config=types.GenerateContentConfig(…)Wrapper for everything below. Pass via config=.
system_instruction="You are a tutor."System prompt slot. Distinct from contents.
temperature=0.0…2.00 for extraction / code. Range is 0–2.
top_p, top_kSampling controls. Tune one at a time.
max_output_tokens=1024Cap on the model’s reply. Not required.
candidate_count=1Number of candidates. Most models only support 1.
stop_sequences=["END"]List of strings to halt on.
safety_settings=[{"category":…,"threshold":…}]Per-category content filters.
thinking_config=types.ThinkingConfig(thinking_budget=2048)2.5 reasoning budget. 0 disables, -1 = dynamic.

Multi-turn helperChats

Tracks history client-side and resends it each turn. Same model, same config — just a wrapper that keeps state.

chat = client.chats.create(model="gemini-2.5-flash", config=…)Open a chat session.
chat.send_message("hi")One turn → GenerateContentResponse.
chat.send_message_stream("hi")Same, streaming.
chat.get_history()List of Content objects, in order.
client.chats.create(model, history=[…])Resume from saved history.
client.aio.chats.create(…)Async variant.

JSON that parsesStructured output

response_mime_type="application/json"Required for JSON output. Without it you get freeform text.
response_schema=Pydantic_ModelPreferred Pydantic class → strict schema. resp.parsed returns the instance.
response_schema=list[Pydantic_Model]Top-level array of objects.
response_schema={"type":"OBJECT","properties":{…}}Raw schema dict. Use when you can’t use Pydantic.
response_mime_type="text/x.enum"Enum mode — pair with response_schema=MyEnum.
resp.parsedPydantic instance. None if no schema was set.

Worked example

python
from google import genai
from google.genai import types
from pydantic import BaseModel

client = genai.Client()

class Invoice(BaseModel):
    vendor: str
    total: float
    line_items: list[str]

resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Extract from: ACME, $129.50, 2x widget, 1x cable",
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=Invoice,
    ),
)

invoice: Invoice = resp.parsed  # typed, validated
print(invoice.vendor, invoice.total)

Tool useFunction calling

tools=[my_function]Preferred Pass plain functions; schema inferred from hints + docstring.
tools=[types.Tool(function_declarations=[…])]Explicit declaration when you need full control of the schema.
automatic_function_calling=AutomaticFunctionCallingConfig(disable=False)Default: SDK runs the function and returns the final answer.
AutomaticFunctionCallingConfig(disable=True)Manual mode. Inspect resp.function_calls yourself.
tool_config=ToolConfig(function_calling_config=FunctionCallingConfig(mode="ANY"))Force the model to call some tool. Modes: AUTO / ANY / NONE.
FunctionCallingConfig(mode="ANY", allowed_function_names=["…"])Restrict which tools may be called.
resp.function_callsList of pending calls in manual mode.

Built-in tools

types.Tool(google_search=types.GoogleSearch())Grounding by Google Search. Adds citations to the response.
types.Tool(code_execution=types.ToolCodeExecution())Run Python in a sandbox.
types.Tool(url_context=types.UrlContext())Let the model fetch and read URLs you cite.

Worked example

python
from google import genai
from google.genai import types

client = genai.Client()

# Plain Python function — schema inferred from type hints + docstring
def get_weather(city: str) -> dict:
    """Current weather for a city."""
    return {"temp_c": 31, "city": city}

# Automatic function calling: SDK executes the call and feeds the result back
resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Weather in Mumbai?",
    config=types.GenerateContentConfig(
        tools=[get_weather],
    ),
)
print(resp.text)

# Manual mode — disable auto-execution and inspect the call
resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Weather in Mumbai?",
    config=types.GenerateContentConfig(
        tools=[get_weather],
        automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True),
    ),
)
for call in resp.function_calls:
    print(call.name, call.args)

Token-by-tokenStreaming

client.models.generate_content_stream(…)Streaming variant. Same args, returns an iterator.
for chunk in stream: chunk.textEach chunk is a partial GenerateContentResponse.
chunk.candidates[0].content.partsStreamed parts — including function calls.
final_chunk.usage_metadataUsage lands on the final chunk. Save the last one.
await aio.models.generate_content_stream(…)Async streaming. Iterate with async for.
chat.send_message_stream(…)Streaming for multi-turn chats.

Worked example

python
from google import genai

client = genai.Client()

# Streaming variant — same call, _stream suffix, chunk iterator
stream = client.models.generate_content_stream(
    model="gemini-2.5-flash",
    contents="Write a haiku about Mumbai monsoons.",
)

for chunk in stream:
    if chunk.text:
        print(chunk.text, end="", flush=True)

# Final usage is on the last chunk's usage_metadata
print(f"\n[done · {chunk.usage_metadata.total_token_count} tokens]")

Beyond textMultimodal & Files

Inline media

types.Part.from_bytes(data=b, mime_type="image/jpeg")Send up to ~20MB inline. Past that, use Files.
contents=[img_part, "What's in this image?"]Vision call. Just mix parts.
mime_type in {"image/*", "audio/*", "video/*", "application/pdf"}All natively understood.

Files API (for large uploads)

file = client.files.upload(file="long_video.mp4")Upload once, reference many times. Files live ~48h.
contents=[file, "Summarize"]Pass the File object directly.
client.files.get(name=file.name)Check processing state (ACTIVE vs PROCESSING).
client.files.list()All current uploads in your project.
client.files.delete(name=…)Free quota explicitly. Auto-expires anyway.
Wait for file.state == "ACTIVE" before referencing video / audio. Large uploads kick off async processing; reference too early and you get a 400.

Vectors · reuse prefixesEmbeddings & context caching

Embeddings

client.models.embed_content(model="gemini-embedding-001", contents="…")Single text → one vector.
client.models.embed_content(…, contents=["a","b","c"])Batched.
resp.embeddings[i].valueslist[float] per input.
config=EmbedContentConfig(output_dimensionality=768)Truncate dims (256 / 768 / 1536 / 3072).
task_type="RETRIEVAL_QUERY" | "RETRIEVAL_DOCUMENT" | …Hint the model. Different vectors for queries vs docs.

Context caching

cache = client.caches.create(model="…", config=CreateCachedContentConfig(contents=[…], ttl="3600s"))Persist a long prefix server-side.
generate_content(…, config=GenerateContentConfig(cached_content=cache.name))Reuse the prefix. Cached tokens billed at ~25% of normal.
client.caches.update(name=…, config=UpdateCachedContentConfig(ttl="7200s"))Extend the TTL.
client.caches.delete(name=…)Release the cache early.
Min cache: 4096 tokens (flash) / 32768 tokens (pro)Below that, caching is a no-op.

50% off · 24h SLABatch API

client.batches.create(model="…", src=batch_file_or_jsonl)Submit a batch. Inline list or JSONL upload.
client.batches.get(name=…)Poll for state (JOB_STATE_SUCCEEDED…).
client.batches.list()Recent batches.
client.batches.cancel(name=…)Stop an in-flight batch.
client.files.download(file=batch.dest.file_name)Pull the JSONL results.

Production hygieneErrors & retries

genai.Client(http_options=HttpOptions(timeout=30_000))Per-client timeout. Milliseconds.
ClientError (4xx)Bad input, auth, schema mismatch. Don’t retry.
ServerError (5xx)Transient. Safe to retry with backoff.
resp.prompt_feedback.block_reasonSet when the prompt was filtered. Check before reading resp.text.
candidate.finish_reason in {"STOP","MAX_TOKENS","SAFETY",…}Why generation stopped. Anything but STOP/MAX_TOKENS deserves a look.
candidate.safety_ratingsPer-category scores when SAFETY is the finish reason.
request_options={"retry":…}Legacy SDK Not on google-genai. Wrap calls yourself.

Grounded chat · ~25 linesEnd-to-end · Grounded chat

Multi-turn chat with Google Search grounding, system prompt, and citation extraction. No vector DB — the search tool does the retrieval.

python
from google import genai
from google.genai import types

client = genai.Client()

# Multi-turn chat with grounding via Google Search
chat = client.chats.create(
    model="gemini-2.5-flash",
    config=types.GenerateContentConfig(
        system_instruction="You are a concise travel assistant.",
        tools=[types.Tool(google_search=types.GoogleSearch())],
        temperature=0.3,
    ),
)

for question in [
    "What's the weather like in Mumbai in July?",
    "And how does that compare to Goa?",
]:
    resp = chat.send_message(question)
    print(f"Q: {question}\nA: {resp.text}\n")

# Citations from grounded search live in candidate metadata
candidate = resp.candidates[0]
if candidate.grounding_metadata:
    for chunk in candidate.grounding_metadata.grounding_chunks:
        print(f"  - {chunk.web.title}: {chunk.web.uri}")

Best practiceGood to know

Use google-genai, not google-generativeai. The old SDK only covers Gemini 1.5; new APIs (Live, batch, caches v2) land on the new SDK first. Same imports differ — pay attention to docs versions.
Set response_mime_type AND response_schema together. Schema alone gives you freeform text that tends to match the schema. The MIME type is what forces strict JSON output.
Use Flash for everything except hard reasoning. Gemini 2.5 Flash has the same 1M-token context as Pro and handles 95% of workloads at a fraction of the cost.

Common trapsWatch out for

Roles are user / model. Not assistant. Copy-paste an OpenAI-style messages array and Gemini rejects it.
Safety filters can return an empty response. If resp.text is empty, check resp.prompt_feedback.block_reason and candidate.finish_reason — SAFETY is silent unless you look.
Context cache minimums are large. Flash needs 4k tokens, Pro needs 32k. Cache anything smaller and the create call errors. For shorter prefixes, just resend.

Go deeperSee also

Gemini API FAQ

What is the Gemini API?

The Gemini API gives developers programmatic access to Google's Gemini family of multimodal LLMs. You can generate text, analyze images and video, call tools, stream responses, and build multi-turn chat sessions. It is accessible via AI Studio (API key) or Vertex AI (Google Cloud credentials).

What is the difference between google-genai and google-generativeai?

google-genai (from google import genai) is the current SDK targeting Gemini 2.x and all new features including the Live API, Files v2, and batch inference. google-generativeai (import google.generativeai as genai) is the legacy SDK for Gemini 1.x — it still works but new features will not be added to it. New projects should use google-genai.

How do I use function calling with the Gemini API?

Define your function with a standard Python signature and pass it in the tools parameter: client.models.generate_content(model, contents, config=GenerateContentConfig(tools=[my_func])). The model will emit a function call part when it wants to invoke the tool; you execute it and return the result as a function response in the next turn.

Does the Gemini API support streaming?

Yes. Call generate_content_stream instead of generate_content to receive an iterator of response chunks as they are generated. Each chunk has a text property. This is useful for showing progressively generated output in a UI without waiting for the full response.

Can the Gemini API process images and video?

Yes. Pass a PIL image, raw bytes, or a Google Cloud Storage URI in the contents list alongside the text prompt to analyze images. For video, upload the file via the Files API first (client.files.upload), then reference the returned file URI in your contents. Supported formats include JPEG, PNG, MP4, and MOV.

Is the Gemini API free to use?

There is a free tier with rate limits (requests per minute and per day) accessible through AI Studio with a GEMINI_API_KEY. Production workloads or higher-volume usage are billed per token. Vertex AI access uses Google Cloud pricing with committed-use discounts available.