Complete Guide: Using Gemini 3.6 Flash via Unorouter API
A comprehensive tutorial with runnable Python code for integrating Google's free Gemini 3.6 Flash model through the Unorouter API.
Introduction
Gemini 3.6 Flash is Google's latest fast and efficient AI model, available for free through Unorouter's unified API gateway. This tutorial provides step-by-step instructions and complete Python code examples for text generation, chat completion, and streaming responses.
Prerequisites
- Python 3.8 or higher
-
requestslibrary:pip install requests - Unorouter account (free at unorouter.com)
- API key from your Unorouter dashboard
Quick Start: Basic Text Generation
import requests import os from typing import Optional # Configuration UNOROUTER_BASE_URL = "https://api.unorouter.com/v1" MODEL = "google/gemini-3.6-flash:free" class GeminiClient: """Client for interacting with Gemini 3.6 Flash via Unorouter.""" def __init__(self, api_key: Optional[str] = None): self.api_key = api_key or os.getenv("UNOROUTER_API_KEY") if not self.api_key: raise ValueError("API key required. Set UNOROUTER_API_KEY environment variable.") self.headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } self.url = f"{UNOROUTER_BASE_URL}/chat/completions" def generate(self, prompt: str, temperature: float = 0.7, max_tokens: int = 1000, system_prompt: Optional[str] = None) -> str: """Generate text completion.""" messages = [] if system_prompt: messages.append({"role": "system", "content": system_prompt}) messages.append({"role": "user", "content": prompt}) data = { "model": MODEL, "messages": messages, "temperature": temperature, "max_tokens": max_tokens } response = requests.post(self.url, headers=self.headers, json=data, timeout=30) response.raise_for_status() return response.json()["choices"][0]["message"]["content"] # Usage Example if __name__ == "__main__": client = GeminiClient() # Simple text generation prompt = "Write a Python function to calculate fibonacci numbers" result = client.generate(prompt) print(f"Prompt: {prompt}") print(f"Response:\n{result}") Advanced Features
Streaming Responses for Real-Time Output
import json def stream_generate(self, prompt: str, system_prompt: Optional[str] = None): """Stream text generation for real-time display.""" messages = [] if system_prompt: messages.append({"role": "system", "content": system_prompt}) messages.append({"role": "user", "content": prompt}) data = { "model": MODEL, "messages": messages, "temperature": 0.7, "max_tokens": 1000, "stream": True } response = requests.post( self.url, headers=self.headers, json=data, timeout=30, stream=True ) response.raise_for_status() for line in response.iter_lines(): if line: line = line.decode('utf-8') if line.startswith('data: '): line = line[6:] if line.strip() == '[DONE]': break try: chunk = json.loads(line) content = chunk["choices"][0]["delta"].get("content", "") if content: print(content, end="", flush=True) except: pass print() # Add to class GeminiClient.stream = stream_generate # Usage client.stream("Write a short story about a robot learning to paint") Multi-Turn Conversations
class ChatSession: """Maintains conversation context across multiple turns.""" def __init__(self, client: GeminiClient, system_prompt: Optional[str] = None): self.client = client self.messages = [] if system_prompt: self.messages.append({"role": "system", "content": system_prompt}) def send(self, user_message: str) -> str: self.messages.append({"role": "user", "content": user_message}) data = { "model": MODEL, "messages": self.messages, "temperature": 0.7, "max_tokens": 1000 } response = requests.post(self.client.url, headers=self.client.headers, json=data, timeout=30) response.raise_for_status() reply = response.json()["choices"][0]["message"]["content"] self.messages.append({"role": "assistant", "content": reply}) return reply def get_history(self) -> list: return self.messages # Usage client = GeminiClient() chat = ChatSession(client, "You are a helpful Python tutor.") print(chat.send("How do I read a JSON file in Python?")) print(chat.send("Can you show me with error handling?")) print(chat.send("What about writing JSON files?")) Error Handling & Rate Limiting
import time from functools import wraps def retry_on_rate_limit(max_retries: int = 3, base_delay: float = 2.0): """Decorator for handling rate limits with exponential backoff.""" def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except requests.exceptions.HTTPError as e: if e.response.status_code in (429, 503): delay = base_delay ** attempt print(f"Rate limited. Waiting {delay}s... (attempt {attempt + 1}/{max_retries})") time.sleep(delay) else: raise raise Exception(f"Max retries ({max_retries}) exceeded") return wrapper return decorator # Apply to generate method @retry_on_rate_limit(max_retries=3) def robust_generate(self, prompt: str, **kwargs) -> str: return self.generate(prompt, **kwargs) GeminiClient.robust_generate = robust_generate Complete Working Example
Save this as gemini_demo.py and run it:
#!/usr/bin/env python3 """ Complete Gemini 3.6 Flash Demo via Unorouter Run: python gemini_demo.py """ import os import requests import json import time from typing import Optional # ============== CONFIGURATION ============== UNOROUTER_BASE_URL = "https://api.unorouter.com/v1" MODEL = "google/gemini-3.6-flash:free" API_KEY = os.getenv("UNOROUTER_API_KEY") if not API_KEY: print("ERROR: Please set UNOROUTER_API_KEY environment variable") print("Get your free key at: https://unorouter.com") exit(1) # ============== CLIENT CLASS ============== class GeminiClient: def __init__(self, api_key: str): self.api_key = api_key self.headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } self.url = f"{UNOROUTER_BASE_URL}/chat/completions" def generate(self, prompt: str, temperature: float = 0.7, max_tokens: int = 1000) -> str: data = { "model": MODEL, "messages": [{"role": "user", "content": prompt}], "temperature": temperature, "max_tokens": max_tokens } response = requests.post(self.url, headers=self.headers, json=data, timeout=30) response.raise_for_status() return response.json()["choices"][0]["message"]["content"] def stream(self, prompt: str): data = { "model": MODEL, "messages": [{"role": "user", "content": prompt}], "temperature": 0.7, "max_tokens": 1000, "stream": True } response = requests.post(self.url, headers=self.headers, json=data, timeout=30, stream=True) response.raise_for_status() for line in response.iter_lines(): if line: line = line.decode('utf-8') if line.startswith('data: '): line = line[6:] if line.strip() == '[DONE]': break try: chunk = json.loads(line) content = chunk["choices"][0]["delta"].get("content", "") if content: print(content, end="", flush=True) except: pass print() # ============== DEMO FUNCTIONS ============== def demo_basic_generation(client: GeminiClient): print("=" * 60) print("DEMO 1: Basic Text Generation") print("=" * 60) prompt = "Explain decorators in Python in 3 sentences" print(f"Prompt: {prompt}\n") result = client.generate(prompt) print(f"Response:\n{result}\n") def demo_streaming(client: GeminiClient): print("=" * 60) print("DEMO 2: Streaming Response") print("=" * 60) prompt = "Write a haiku about coding" print(f"Prompt: {prompt}\nResponse: ") client.stream(prompt) print() def demo_code_generation(client: GeminiClient): print("=" * 60) print("DEMO 3: Code Generation") print("=" * 60) prompt = """Write a complete Python class for a simple REST API client with: - GET, POST, PUT, DELETE methods - Automatic JSON handling - Error handling with retries - Type hints""" print(f"Prompt: {prompt}\n") result = client.generate(prompt, temperature=0.5, max_tokens=1500) print(f"Response:\n{result}\n") def demo_creative_writing(client: GeminiClient): print("=" * 60) print("DEMO 4: Creative Writing") print("=" * 60) prompt = "Write a micro-fiction story (100 words) about an AI that discovers it can dream" print(f"Prompt: {prompt}\n") result = client.generate(prompt, temperature=0.9, max_tokens=500) print(f"Response:\n{result}\n") # ============== MAIN ============== if __name__ == "__main__": print("Gemini 3.6 Flash via Unorouter - Complete Demo") print("=" * 60) client = GeminiClient(API_KEY) demo_basic_generation(client) demo_streaming(client) demo_code_generation(client) demo_creative_writing(client) print("=" * 60) print("All demos completed successfully!") print("=" * 60) Best Practices
- Secure API Keys: Use environment variables, never hardcode
- Handle Rate Limits: Implement exponential backoff (shown above)
- Set Timeouts: Prevent hanging requests (30s recommended)
- Use Appropriate Temperatures:
- 0.3-0.5 for code/factual tasks
- 0.7-0.9 for creative writing
- Monitor Token Usage: Free tier has limits
- Cache Responses: During development to save API calls