A lightweight Python library for Google Gemini API key rotation and model fallback.
Project description
Gemini Rotate
A lightweight Async Python library for Google Gemini API key rotation, valid model selection, and automatic fallback to "Lite" models on server errors.
🚀 Features
- ✅ Automatic Key Rotation: Seamlessly rotates through a list of API keys when quota is exhausted (
429), permission denied (403), or any other API error occurs. - 🔄 Smart Model Fallback: Automatically downgrades specific models (e.g.,
gemini-2.0-flash->gemini-2.0-flash-lite) if server errors (5xx) persist. - ⚡ Async First: Built on top of the
google-genaiasync client for high-performance non-blocking applications. - 🛡️ Robust Error Handling: Implements exponential backoff before rotating keys or switching models.
- 📝 Concise Logging: Logs only essential success/failure information (e.g.,
400 INVALID_ARGUMENT) to keep your console clean.
📦 Installation
pip install gemini-rotate
⚡ Quick Start
-
Configure Environment: Create a
.envfile.GEMINI_API_KEY_1="AIzaSy..." GEMINI_API_KEY_2="AI3yhj..." GEMINI_API_KEY_3="AIdf56..."
-
Run Code:
import asyncio from gemini_rotate import GeminiRotationClient async def main(): client = GeminiRotationClient() response = await client.generate_content("Hello, Gemini!") print(response.text) asyncio.run(main())
📖 Usage Guide
Initialization
The client automatically loads API keys from your environment variables (GEMINI_API_KEY_1, GEMINI_API_KEY_2, etc.).
client = GeminiRotationClient()
Generating Content
The generate_content method wraps the standard google-genai call but adds rotation and fallback logic.
1. Basic Text Generation
import asyncio
from gemini_rotate import GeminiRotationClient
from dotenv import load_dotenv
load_dotenv()
async def generate_text():
client = GeminiRotationClient()
try:
response = await client.generate_content(
contents="Explain quantum computing in 50 words."
)
print(f"Generated text: {response.text}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(generate_text())
2. Advanced: Tool Calling & Structured Output
You can pass tools and response_schema (or response_mime_type) via the config parameter.
import asyncio
from google import genai
from gemini_rotate import GeminiRotationClient
from pydantic import BaseModel
from dotenv import load_dotenv
load_dotenv()
# Define a schema for structured output
class Recipe(BaseModel):
title: str
ingredients: list[str]
instructions: list[str]
async def generate_recipe():
client = GeminiRotationClient()
try:
response = await client.generate_content(
contents="Give me a recipe for chocolate cake.",
config={
"response_mime_type": "application/json",
"response_schema": Recipe,
}
)
# Parse result directly into Pydantic model
recipe = response.parsed
print(f"Title: {recipe.title}")
print(f"Ingredients: {recipe.ingredients}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(generate_recipe())
Parameters
| Parameter | Type | Description |
|---|---|---|
contents |
str | list |
The prompt or content to send. |
model |
str |
(Optional) The specific model to use. Defaults to first in priority list. |
config |
dict |
(Optional) Generation config (temperature, tools, schema) passed to google.genai. |
⚙️ Configuration
1. API Keys (Required)
Define your keys in .env or environment variables using the pattern GEMINI_API_KEY_n.
GEMINI_API_KEY_1="key_one..."
GEMINI_API_KEY_2="key_two..."
GEMINI_API_KEY_3="key_three..."
(Note: A single GEMINI_API_KEY is also supported, but using the numbered pattern allows for rotation.)
2. Model Priority (Optional)
You can customize the order in which models are attempted by setting GEMINI_MODELS in .env. The library processes models in Primary -> Secondary pairs.
Default Behavior (if not set):
gemini-flash-latest->gemini-flash-lite-latestgemini-3-flash-preview->gemini-2.5-flashgemini-2.5-flash-lite->gemini-2.0-flashgemini-2.0-flash-lite-> (None)
Custom Configuration:
GEMINI_MODELS='["gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-2.0-flash"]'
🔍 How it Works
graph TD
Start[Start Request] --> LoopPairs{Loop Model Pairs}
LoopPairs -->|Primary, Secondary| LoopClients{Loop API Clients}
LoopClients -->|Next Client| AttemptPrimary[Attempt Primary Model]
AttemptPrimary -->|Success| ReturnResponse[Return Response]
AttemptPrimary -->|Failure| CheckSecondary{Has Secondary Model?}
CheckSecondary -->|Yes| AttemptSecondary[Attempt Secondary Model]
CheckSecondary -->|No| NextClient[Next Client]
AttemptSecondary -->|Success| ReturnResponse
AttemptSecondary -->|Failure| NextClient
NextClient -->|Clients Exhausted| NextPair[Next Pair]
NextPair -->|Pairs Exhausted| RaiseError[Raise AllClientsFailed]
style Start fill:#f9f,stroke:#333,stroke-width:2px
style ReturnResponse fill:#9f9,stroke:#333,stroke-width:2px
style RaiseError fill:#f99,stroke:#333,stroke-width:2px
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gemini_rotate-0.1.2.tar.gz.
File metadata
- Download URL: gemini_rotate-0.1.2.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b68253c4d8a32712f85b1fc49ff98266532067c0f16d35714f034f628039c37c
|
|
| MD5 |
54aea17a8c67551b8ea08f54c393511e
|
|
| BLAKE2b-256 |
c79010920f29a5b115d10dfed9534d049f060df76267b2e04cde13db1292ccc9
|
Provenance
The following attestation bundles were made for gemini_rotate-0.1.2.tar.gz:
Publisher:
pypi-publish.yml on jayeeed/gemini-rotate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gemini_rotate-0.1.2.tar.gz -
Subject digest:
b68253c4d8a32712f85b1fc49ff98266532067c0f16d35714f034f628039c37c - Sigstore transparency entry: 927056866
- Sigstore integration time:
-
Permalink:
jayeeed/gemini-rotate@bfbe675570c097c9573eab36a43fbd13e1ce0398 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jayeeed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@bfbe675570c097c9573eab36a43fbd13e1ce0398 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gemini_rotate-0.1.2-py3-none-any.whl.
File metadata
- Download URL: gemini_rotate-0.1.2-py3-none-any.whl
- Upload date:
- Size: 6.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fda7f77c310f73bc4ffe70298e75f8b973b71d3d78d321b7ba3295fde73c6cf0
|
|
| MD5 |
5aa671c67e2cb1db298b880b4e2546ca
|
|
| BLAKE2b-256 |
bdabffadefca3dd39b371afe4f54502f606e91f5844ac0b5b4aef24908e8326c
|
Provenance
The following attestation bundles were made for gemini_rotate-0.1.2-py3-none-any.whl:
Publisher:
pypi-publish.yml on jayeeed/gemini-rotate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gemini_rotate-0.1.2-py3-none-any.whl -
Subject digest:
fda7f77c310f73bc4ffe70298e75f8b973b71d3d78d321b7ba3295fde73c6cf0 - Sigstore transparency entry: 927056867
- Sigstore integration time:
-
Permalink:
jayeeed/gemini-rotate@bfbe675570c097c9573eab36a43fbd13e1ce0398 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jayeeed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@bfbe675570c097c9573eab36a43fbd13e1ce0398 -
Trigger Event:
push
-
Statement type: