Skip to content
Go back

Gemini 3.0 API Tutorial: Complete Developer Guide

Gemini 3.0 API Tutorial: Complete Developer Guide

Gemini 3.0 API

This comprehensive tutorial will take you from API basics to advanced implementation patterns with Googleโ€™s Gemini 3.0. Whether youโ€™re building a simple chatbot or a complex AI-powered application, this guide has everything you need.

๐Ÿš€ API Overview

The Gemini 3.0 API provides powerful AI capabilities through a simple REST interface:

๐Ÿ“‹ Prerequisites

๐Ÿ”‘ Authentication Setup

import google.generativeai as genai
import os

# Set your API key
genai.configure(api_key="your_api_key_here")

OAuth 2.0 Method (For Production)

from google.oauth2 import service_account
import google.generativeai as genai

# Load service account credentials
credentials = service_account.Credentials.from_service_account_file(
    'path/to/your/credentials.json',
    scopes=['https://www.googleapis.com/auth/cloud-platform']
)

genai.configure(credentials=credentials)

๐Ÿ› ๏ธ Basic API Usage

Simple Text Generation

import google.generativeai as genai

# Configure API
genai.configure(api_key="your_api_key_here")

# Initialize model
model = genai.GenerativeModel('gemini-3.0-flash')

# Generate content
response = model.generate_content("Write a haiku about artificial intelligence")
print(response.text)

With Parameters

# Configure generation parameters
generation_config = {
    "temperature": 0.7,
    "top_p": 0.8,
    "top_k": 40,
    "max_output_tokens": 1024,
}

response = model.generate_content(
    "Explain quantum computing in simple terms",
    generation_config=generation_config
)
print(response.text)

๐Ÿ–ผ๏ธ Multimodal Input

Text + Image

import PIL.Image

# Load an image
image = PIL.Image.open('path/to/your/image.jpg')

# Generate content with image
response = model.generate_content([
    "What's happening in this image? Describe the scene in detail.",
    image
])
print(response.text)

Multiple Images

# Load multiple images
image1 = PIL.Image.open('image1.jpg')
image2 = PIL.Image.open('image2.jpg')

# Compare images
response = model.generate_content([
    "Compare these two images. What are the similarities and differences?",
    image1,
    image2
])
print(response.text)

๐Ÿ”„ Streaming Responses

Basic Streaming

# Stream response in real-time
response = model.generate_content(
    "Write a short story about a time-traveling detective",
    stream=True
)

for chunk in response:
    print(chunk.text, end='')

Advanced Streaming with Callbacks

def on_chunk_received(chunk):
    print(f"Received chunk: {chunk.text}")

def on_complete(response):
    print(f"Complete response: {response.text}")

# Stream with callbacks
response = model.generate_content(
    "Explain the theory of relativity",
    stream=True,
    on_chunk=on_chunk_received,
    on_complete=on_complete
)

๐ŸŽฏ Function Calling

Define Functions

import json

# Define available functions
functions = [
    {
        "name": "get_weather",
        "description": "Get current weather for a location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City name"
                }
            },
            "required": ["location"]
        }
    },
    {
        "name": "send_email",
        "description": "Send an email to a recipient",
        "parameters": {
            "type": "object",
            "properties": {
                "to": {"type": "string"},
                "subject": {"type": "string"},
                "body": {"type": "string"}
            },
            "required": ["to", "subject", "body"]
        }
    }
]

# Configure model with functions
model = genai.GenerativeModel(
    'gemini-3.0-flash',
    tools=[{"function_declarations": functions}]
)

Handle Function Calls

def handle_function_call(function_name, arguments):
    if function_name == "get_weather":
        location = arguments.get("location")
        # Simulate weather API call
        return {"temperature": "22ยฐC", "condition": "Sunny"}
    
    elif function_name == "send_email":
        to = arguments.get("to")
        subject = arguments.get("subject")
        body = arguments.get("body")
        # Simulate email sending
        return {"status": "sent", "message_id": "12345"}
    
    return {"error": "Unknown function"}

# Generate content with function calling
response = model.generate_content(
    "What's the weather like in Tokyo? Also, send me an email about it."
)

# Check if function calls were made
if response.candidates[0].content.parts[0].function_call:
    function_call = response.candidates[0].content.parts[0].function_call
    result = handle_function_call(
        function_call.name,
        json.loads(function_call.args)
    )
    print(f"Function result: {result}")

๐Ÿ”’ Safety and Content Filtering

Configure Safety Settings

# Define safety settings
safety_settings = [
    {
        "category": "HARM_CATEGORY_HARASSMENT",
        "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
    {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
    {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
    {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    }
]

# Use safety settings
response = model.generate_content(
    "Your prompt here",
    safety_settings=safety_settings
)

Check Safety Ratings

# Check safety ratings
response = model.generate_content("Your potentially sensitive prompt")

# Check if content was blocked
if response.candidates[0].finish_reason == "SAFETY":
    print("Content was blocked due to safety concerns")
    print(f"Safety ratings: {response.candidates[0].safety_ratings}")
else:
    print(response.text)

๐Ÿ“Š Error Handling and Retries

Comprehensive Error Handling

import time
import random
from typing import Optional

class GeminiAPIError(Exception):
    pass

def make_api_call_with_retry(
    model, 
    prompt, 
    max_retries=3, 
    base_delay=1
) -> Optional[str]:
    """
    Make API call with exponential backoff retry logic
    """
    for attempt in range(max_retries):
        try:
            response = model.generate_content(prompt)
            return response.text
            
        except Exception as e:
            error_msg = str(e).lower()
            
            # Handle different error types
            if "quota" in error_msg or "rate limit" in error_msg:
                # Rate limit - wait longer
                delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
                print(f"Rate limit hit. Waiting {delay:.2f} seconds...")
                time.sleep(delay)
                
            elif "safety" in error_msg:
                # Safety violation - don't retry
                raise GeminiAPIError(f"Content blocked by safety filters: {e}")
                
            elif "invalid" in error_msg:
                # Invalid request - don't retry
                raise GeminiAPIError(f"Invalid request: {e}")
                
            else:
                # Other errors - retry with backoff
                if attempt < max_retries - 1:
                    delay = base_delay * (2 ** attempt)
                    print(f"Error occurred. Retrying in {delay} seconds...")
                    time.sleep(delay)
                else:
                    raise GeminiAPIError(f"Max retries exceeded: {e}")
    
    return None

# Usage
try:
    result = make_api_call_with_retry(
        model, 
        "Write a creative story about AI"
    )
    print(result)
except GeminiAPIError as e:
    print(f"API Error: {e}")

๐Ÿš€ Advanced Patterns

Conversation Management

class ConversationManager:
    def __init__(self, model):
        self.model = model
        self.history = []
    
    def add_message(self, role, content):
        self.history.append({"role": role, "content": content})
    
    def generate_response(self, user_message):
        # Add user message to history
        self.add_message("user", user_message)
        
        # Generate response
        response = self.model.generate_content(
            self._format_conversation()
        )
        
        # Add assistant response to history
        self.add_message("assistant", response.text)
        
        return response.text
    
    def _format_conversation(self):
        formatted = []
        for msg in self.history:
            formatted.append(f"{msg['role']}: {msg['content']}")
        return "\n".join(formatted)

# Usage
chat = ConversationManager(model)
response = chat.generate_response("Hello, how are you?")
print(response)

Batch Processing

import asyncio
from concurrent.futures import ThreadPoolExecutor

async def process_batch(prompts, max_workers=5):
    """
    Process multiple prompts concurrently
    """
    def process_single(prompt):
        try:
            response = model.generate_content(prompt)
            return {"success": True, "result": response.text}
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        tasks = [executor.submit(process_single, prompt) for prompt in prompts]
        results = [task.result() for task in tasks]
    
    return results

# Usage
prompts = [
    "Write a haiku about spring",
    "Explain machine learning",
    "Create a recipe for chocolate cake"
]

results = await process_batch(prompts)
for i, result in enumerate(results):
    if result["success"]:
        print(f"Prompt {i+1}: {result['result']}")
    else:
        print(f"Prompt {i+1} failed: {result['error']}")

๐Ÿ“ˆ Performance Optimization

Caching Responses

import hashlib
import json
from functools import lru_cache

class CachedGeminiAPI:
    def __init__(self, model):
        self.model = model
        self.cache = {}
    
    def _get_cache_key(self, prompt, config):
        content = f"{prompt}_{json.dumps(config, sort_keys=True)}"
        return hashlib.md5(content.encode()).hexdigest()
    
    def generate_content(self, prompt, generation_config=None):
        cache_key = self._get_cache_key(prompt, generation_config or {})
        
        if cache_key in self.cache:
            print("Cache hit!")
            return self.cache[cache_key]
        
        response = self.model.generate_content(
            prompt, 
            generation_config=generation_config
        )
        
        self.cache[cache_key] = response
        return response

# Usage
cached_model = CachedGeminiAPI(model)
response = cached_model.generate_content("Explain quantum physics")

Response Compression

import gzip
import base64

def compress_response(text):
    """Compress response text for storage"""
    compressed = gzip.compress(text.encode())
    return base64.b64encode(compressed).decode()

def decompress_response(compressed_text):
    """Decompress stored response"""
    compressed = base64.b64decode(compressed_text.encode())
    return gzip.decompress(compressed).decode()

๐Ÿ”ง Testing and Debugging

API Testing Suite

import unittest
from unittest.mock import patch, MagicMock

class TestGeminiAPI(unittest.TestCase):
    def setUp(self):
        self.model = genai.GenerativeModel('gemini-3.0-flash')
    
    def test_basic_generation(self):
        with patch.object(self.model, 'generate_content') as mock_generate:
            mock_generate.return_value.text = "Test response"
            
            response = self.model.generate_content("Test prompt")
            self.assertEqual(response.text, "Test response")
    
    def test_safety_filtering(self):
        with patch.object(self.model, 'generate_content') as mock_generate:
            mock_response = MagicMock()
            mock_response.candidates[0].finish_reason = "SAFETY"
            mock_generate.return_value = mock_response
            
            response = self.model.generate_content("Sensitive prompt")
            self.assertEqual(response.candidates[0].finish_reason, "SAFETY")

if __name__ == '__main__':
    unittest.main()

๐Ÿ“š Best Practices

1. Prompt Engineering

def create_effective_prompt(task, context, format_requirements=None):
    """
    Create well-structured prompts for better results
    """
    prompt = f"""
    Task: {task}
    Context: {context}
    
    {f"Format Requirements: {format_requirements}" if format_requirements else ""}
    
    Please provide a response that:
    1. Directly addresses the task
    2. Uses the provided context appropriately
    3. Follows the specified format
    4. Is clear and actionable
    """
    return prompt.strip()

# Usage
prompt = create_effective_prompt(
    task="Write a product description",
    context="AI-powered writing assistant for content creators",
    format_requirements="2-3 sentences, marketing tone"
)

2. Response Validation

def validate_response(response, expected_length=None, required_keywords=None):
    """
    Validate API responses for quality and completeness
    """
    if not response.text:
        return False, "Empty response"
    
    if expected_length and len(response.text) < expected_length:
        return False, f"Response too short: {len(response.text)} chars"
    
    if required_keywords:
        missing_keywords = [
            kw for kw in required_keywords 
            if kw.lower() not in response.text.lower()
        ]
        if missing_keywords:
            return False, f"Missing keywords: {missing_keywords}"
    
    return True, "Response valid"

# Usage
is_valid, message = validate_response(
    response,
    expected_length=100,
    required_keywords=["AI", "technology", "future"]
)

๐Ÿ”— Integration Examples

Flask Web Application

from flask import Flask, request, jsonify
import google.generativeai as genai

app = Flask(__name__)
genai.configure(api_key="your_api_key_here")
model = genai.GenerativeModel('gemini-3.0-flash')

@app.route('/generate', methods=['POST'])
def generate_content():
    try:
        data = request.get_json()
        prompt = data.get('prompt')
        
        if not prompt:
            return jsonify({'error': 'Prompt required'}), 400
        
        response = model.generate_content(prompt)
        
        return jsonify({
            'success': True,
            'text': response.text,
            'usage': {
                'prompt_tokens': len(prompt.split()),
                'completion_tokens': len(response.text.split())
            }
        })
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)

FastAPI Application

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import google.generativeai as genai

app = FastAPI()
genai.configure(api_key="your_api_key_here")
model = genai.GenerativeModel('gemini-3.0-flash')

class GenerateRequest(BaseModel):
    prompt: str
    temperature: float = 0.7
    max_tokens: int = 1024

@app.post("/generate")
async def generate_content(request: GenerateRequest):
    try:
        config = {
            "temperature": request.temperature,
            "max_output_tokens": request.max_tokens
        }
        
        response = model.generate_content(
            request.prompt,
            generation_config=config
        )
        
        return {
            "text": response.text,
            "config": config
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

๐Ÿ“– Additional Resources

โ“ Troubleshooting

Common Issues and Solutions

1. API Key Issues

# Verify API key is set correctly
import google.generativeai as genai
try:
    genai.configure(api_key="your_key")
    models = genai.list_models()
    print("API key working correctly")
except Exception as e:
    print(f"API key issue: {e}")

2. Rate Limiting

# Implement proper rate limiting
import time
from collections import deque

class RateLimiter:
    def __init__(self, max_requests=60, time_window=60):
        self.max_requests = max_requests
        self.time_window = time_window
        self.requests = deque()
    
    def can_make_request(self):
        now = time.time()
        # Remove old requests
        while self.requests and self.requests[0] <= now - self.time_window:
            self.requests.popleft()
        
        return len(self.requests) < self.max_requests
    
    def record_request(self):
        self.requests.append(time.time())

3. Memory Management

# Clear conversation history periodically
class MemoryEfficientChat:
    def __init__(self, model, max_history=10):
        self.model = model
        self.max_history = max_history
        self.history = []
    
    def add_message(self, role, content):
        self.history.append({"role": role, "content": content})
        
        # Keep only recent history
        if len(self.history) > self.max_history:
            self.history = self.history[-self.max_history:]

Master the Gemini 3.0 API with these advanced techniques. Explore more tutorials and join our community for support and collaboration.

Ready to build something amazing? Check out our use cases for inspiration!


Share this post on:

Previous Post
Gemini 3.0 for Developers: Code Generation, Debugging, and More
Next Post
Getting Started with Gemini 3.0: Complete Setup Guide