◉ANTIGRAVITY LABJP
Articles/Antigravity Basics
◉ Antigravity Basics/2026-04-17Beginner

google-genai SDK with Antigravity: Python Quickstart Practical Guide

Use the google-genai SDK to call Antigravity from Python. Install, authenticate, generate text, use multimodal inputs, stream responses, and handle errors—all with code.

Antigravity376Python17google-genai5SDK5quickstartAPI6

There are a few ways to call Antigravity from Python, but the google-genai SDK is the current recommended approach. It replaced the older google-generativeai package with better type safety and a cleaner interface.

This guide gets you to a working setup as quickly as possible.

Installation and Setup

pip install google-genai

Authentication

from google import genai
import os
 
# Use environment variables (recommended)
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])

Get your API key from Google AI Studio.

Basic Text Generation

from google import genai
 
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
 
response = client.models.generate_content(
    model="gemma-4-antigravity",
    contents="Explain Python decorators in one paragraph."
)
print(response.text)

With System Instructions

from google.genai import types
 
response = client.models.generate_content(
    model="gemma-4-antigravity",
    config=types.GenerateContentConfig(
        system_instruction="You are a Python expert. Keep explanations concise and practical.",
        temperature=0.7,
        max_output_tokens=1024
    ),
    contents="What is asyncio and when should I use it?"
)
print(response.text)

Multi-Turn Chat

from google import genai
from google.genai import types
 
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
 
chat = client.chats.create(
    model="gemma-4-antigravity",
    config=types.GenerateContentConfig(
        system_instruction="You are a code review expert.",
        temperature=0.3
    )
)
 
messages = [
    "Review this function:\ndef calc(x, y):\n    return x + y",
    "How would you add type hints?",
    "Can you write a test for it too?"
]
 
for msg in messages:
    response = chat.send_message(msg)
    print(f"User: {msg[:50]}")
    print(f"AI: {response.text[:200]}\n")

Streaming

Stream responses in real time instead of waiting for the full output.

# Streaming text generation
for chunk in client.models.generate_content_stream(
    model="gemma-4-antigravity",
    contents="Explain Python dataclasses in detail"
):
    print(chunk.text, end="", flush=True)
print()
 
# Streaming chat
chat = client.chats.create(model="gemma-4-antigravity")
for chunk in chat.send_message_stream("Describe the Factory design pattern"):
    print(chunk.text, end="", flush=True)
print()

Multimodal (Image + Text)

import PIL.Image
from google import genai
 
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
 
# Single image
image = PIL.Image.open("screenshot.png")
response = client.models.generate_content(
    model="gemma-4-antigravity",
    contents=[image, "What UI issues do you see in this screenshot?"]
)
print(response.text)
 
# Compare two images
before = PIL.Image.open("before.png")
after = PIL.Image.open("after.png")
response = client.models.generate_content(
    model="gemma-4-antigravity",
    contents=["Compare these two designs:", "Before:", before, "After:", after]
)
print(response.text)

Structured Output (JSON)

import json
from google.genai import types
 
response = client.models.generate_content(
    model="gemma-4-antigravity",
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema={
            "type": "object",
            "properties": {
                "title": {"type": "string"},
                "summary": {"type": "string"},
                "tags": {"type": "array", "items": {"type": "string"}},
                "difficulty": {
                    "type": "string",
                    "enum": ["beginner", "intermediate", "advanced"]
                }
            },
            "required": ["title", "summary", "tags", "difficulty"]
        }
    ),
    contents="Generate article metadata for a post about Python decorators"
)
 
metadata = json.loads(response.text)
print(f"Title: {metadata['title']}")
print(f"Tags: {', '.join(metadata['tags'])}")
print(f"Difficulty: {metadata['difficulty']}")

Async Parallel Requests

import asyncio
from google import genai
 
async def parallel_requests(prompts: list[str]) -> list[str]:
    client = genai.AsyncClient(api_key=os.environ["GOOGLE_API_KEY"])
    
    async def _request(prompt: str) -> str:
        response = await client.aio.models.generate_content(
            model="gemma-4-antigravity",
            contents=prompt
        )
        return response.text
    
    return await asyncio.gather(*[_request(p) for p in prompts])
 
async def main():
    prompts = [
        "What are list comprehensions?",
        "What is a generator?",
        "How do decorators work?"
    ]
    results = await parallel_requests(prompts)
    for p, r in zip(prompts, results):
        print(f"Q: {p}\nA: {r[:100]}...\n")
 
asyncio.run(main())

Error Handling

from google import genai
from google.api_core import exceptions as google_exceptions
import time
 
def safe_generate(client, model: str, contents, max_retries: int = 3) -> str:
    for attempt in range(max_retries):
        try:
            response = client.models.generate_content(model=model, contents=contents)
            return response.text
        
        except google_exceptions.ResourceExhausted:
            wait = 2 ** attempt
            print(f"Rate limited. Waiting {wait}s...")
            time.sleep(wait)
        
        except google_exceptions.InvalidArgument as e:
            print(f"Invalid input: {e}")
            raise  # Don't retry invalid input
        
        except google_exceptions.ServiceUnavailable:
            if attempt < max_retries - 1:
                time.sleep(5)
            else:
                raise
    
    raise RuntimeError(f"Failed after {max_retries} attempts")

Token Counting

# Check token count before sending
token_count = client.models.count_tokens(
    model="gemma-4-antigravity",
    contents="Your long prompt text here..."
)
print(f"Input tokens: {token_count.total_tokens}")
 
# Check usage after a request
response = client.models.generate_content(
    model="gemma-4-antigravity",
    contents="Hello"
)
if response.usage_metadata:
    print(f"Input: {response.usage_metadata.prompt_token_count} tokens")
    print(f"Output: {response.usage_metadata.candidates_token_count} tokens")

Three Steps to Get Started

  1. pip install google-genai
  2. Get an API key from Google AI Studio, set it as GOOGLE_API_KEY environment variable
  3. Call client.models.generate_content(model="gemma-4-antigravity", contents="...")

The google-genai SDK has better type support and a cleaner interface than the previous google-generativeai package. For any new project, this is the SDK to use.

Full API reference is available in the Google AI documentation.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◉ Antigravity2026-07-31
The Flaky Hook Started Failing Every Time — Migrating to Declarative Sessions in the Antigravity SDK
Registering hooks after session init is gone, replaced by declaration at session creation. Here is what happened when I moved four agent definitions across, plus the harness I used to measure ordering non-determinism over 2,000 runs.
◉ Antigravity2026-09-13
When You Cannot Decide Between Rules and Skills: Rethinking Where Instructions Live
Rules and Skills load at different moments in Antigravity. Rules go in full on every turn; Skills lead with a heading and load the rest on demand. After the same note drifted apart in two places on a client site, here are the questions I use to place an instruction, plus a small script to measure what you carry each turn.
◉ Antigravity2026-09-02
Why Filename Search Misses Every Error String in Your Repo
Antigravity 2.12 improved partial filename search. Measuring name lookups against full-text search across a 2,088-file repository, the reading cost differed by 67x and error strings hit filenames only 4.5% of the time. Here is where the line actually falls.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links