### Recommended Full Setup Configuration Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md This is a comprehensive configuration setup for the server, Gemini client, storage, and CORS. ```yaml server: host: "0.0.0.0" port: 8000 api_key: "your-key" gemini: clients: - id: "client-a" secure_1psid: "..." secure_1psidts: "..." proxy: null chat_mode: "normal" timeout: 600 max_chars_per_request: 1000000 storage: path: "data/lmdb" max_size: 268435456 retention_days: 14 cors: enabled: true allow_origins: ["*"] ``` -------------------------------- ### Configuration Example Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md An example of the configuration file structure. You must provide at least one credential pair for Gemini clients. ```yaml gemini: clients: - id: "client-a" secure_1psid: "YOUR_SECURE_1PSID_HERE" secure_1psidts: "YOUR_SECURE_1PSIDTS_HERE" proxy: null # Optional proxy URL (null/empty keeps direct connection) ``` -------------------------------- ### Clone Repository and Install Dependencies with uv Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Clone the Gemini-FastAPI repository and install its dependencies using uv. This is the recommended installation method. ```bash git clone https://github.com/Nativu5/Gemini-FastAPI.git cd Gemini-FastAPI uv sync ``` -------------------------------- ### Run Server with uv Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Start the Gemini-FastAPI server using uv. The server will be accessible at http://localhost:8000 by default. ```bash # Using uv uv run python run.py ``` -------------------------------- ### Clone Repository and Install Dependencies with pip Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Clone the Gemini-FastAPI repository and install its dependencies using pip. This is an alternative installation method. ```bash git clone https://github.com/Nativu5/Gemini-FastAPI.git cd Gemini-FastAPI pip install -e . ``` -------------------------------- ### POST /v1/responses Request Example Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/endpoints.md This example demonstrates how to make a POST request to the /v1/responses endpoint for advanced response generation, including tool usage for image generation. ```json { "model": "gemini-2.0-flash", "input": "Generate an image of a cat", "instructions": null, "stream": false, "temperature": 0.7, "top_p": 1.0, "max_output_tokens": null, "tool_choice": {"type": "image_generation"}, "tools": [{"type": "image_generation"}], "response_format": null } ``` -------------------------------- ### Environment Variable Syntax Example Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md Illustrates how to map environment variables to configuration paths. Nested keys are separated by double underscores (__). ```text CONFIG_{SECTION}__{KEY}__SUBKEY__SUBKEY=value ``` -------------------------------- ### Environment Variable to YAML Path Mapping Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md Provides examples of environment variables and their corresponding YAML configuration paths for different settings. ```text CONFIG_SERVER__HOST | server.host | string ``` ```text CONFIG_SERVER__PORT | server.port | integer ``` ```text CONFIG_GEMINI__TIMEOUT | gemini.timeout | integer ``` ```text CONFIG_GEMINI__AUTO_REFRESH | gemini.auto_refresh | boolean ``` ```text CONFIG_GEMINI__CLIENTS__0__ID | gemini.clients[0].id | string ``` ```text CONFIG_GEMINI__CLIENTS__0__PROXY | gemini.clients[0].proxy | string ``` ```text CONFIG_STORAGE__MAX_SIZE | storage.max_size | integer ``` ```text CONFIG_LOGGING__LEVEL | logging.level | string ``` -------------------------------- ### Run Server with Python Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Start the Gemini-FastAPI server directly using Python. The server will be accessible at http://localhost:8000 by default. ```bash # Using Python directly python run.py ``` -------------------------------- ### Basic Request Flow with GeminiClientPool Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Demonstrates the standard procedure for initializing the pool, acquiring a client, starting a chat session, and sending a message. ```python pool = GeminiClientPool() await pool.init() # For each request client = await pool.acquire() session = client.start_chat(model=model) response = await session.send_message("Hello") ``` -------------------------------- ### Gemini Protocol Tool Call Example Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md Demonstrates how tool calls are structured within the Gemini Protocol, including the tool name and parameters. ```text [ToolCalls] [Call:get_weather] [CallParameter:location] New York [/CallParameter] [/Call] [/ToolCalls] ``` -------------------------------- ### Start Docker Compose Services Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md This command starts the services defined in the docker-compose.yml file in detached mode. Ensure your .env file or environment variables are set for any placeholders like ${API_KEY}. ```bash docker compose up -d ``` -------------------------------- ### Gemini Protocol Message Example Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md Illustrates the PascalCase tag format for messages within the Gemini Protocol, including system, user, and assistant turns. ```text [System] You are helpful [/System] [User] What is 2+2? [/User] [Assistant] 2+2 equals 4. [/Assistant] ``` -------------------------------- ### get Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Retrieves a conversation from the store using its key. Returns the conversation object if found, otherwise returns None. ```APIDOC ## get ### Description Retrieves a conversation from the store using its key. Returns the conversation object if found, otherwise returns None. ### Method Signature `def get(key: str) -> ConversationInStore | None` ### Parameters #### Path Parameters - **key** (string) - Required - Storage key (hash or custom key) ### Returns `ConversationInStore | None` - Conversation if found, None otherwise ### Raises - `lmdb.Error` - Database read failed ### Example ```python conv = store.get("abc123def456...") if conv: print(f"Found conversation with {len(conv.messages)} messages") else: print("Conversation not found") ``` ``` -------------------------------- ### Conversation Reuse with Find Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Shows how to check for existing conversations using a model and a list of messages. If found, it reuses the metadata to start a chat session; otherwise, it starts a fresh session. This is useful for resuming conversations. ```python # User sends: "hello", "tell me more" messages = [ Message(role="user", content="hello"), Message(role="assistant", content="Hi!"), Message(role="user", content="tell me more") ] # Check if we've seen this conversation before if existing := store.find("gemini-2.0-flash", messages[:2]): # Reuse metadata to resume conversation session = client.start_chat( metadata=existing.metadata, model=model ) # Send only the new message response = await session.send_message("tell me more") else: # Start fresh session = client.start_chat(model=model) ``` -------------------------------- ### Health Monitoring Stats Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Provides an example of how to retrieve statistics from the store and log a warning if the number of entries exceeds a certain threshold, indicating potential performance issues. ```python stats = store.stats() if stats['ms_entries'] > 5000: logger.warning("High conversation count") ``` -------------------------------- ### ModelInconsistentError Handling Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/errors.md This example illustrates the conditions under which ModelInconsistentError from the Gemini API might occur, such as stale conversation metadata or server-side state changes. It also outlines the detection method and fallback strategy. ```python # Detection: Pattern matching in error message for "model is inconsistent with the conversation history" # Handling: Fallback to fresh chat with internal history replay ``` -------------------------------- ### Get Image Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md Retrieves a specific image file by its filename. ```APIDOC ## GET /images/{filename} ### Description Retrieves a specific image file by its filename. ### Method GET ### Endpoint /images/{filename} ### Parameters #### Path Parameters - **filename** (string) - Required - The name of the image file to retrieve. ### Auth Optional ``` -------------------------------- ### init Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Initializes the client and establishes a connection to the Gemini API, applying various configuration settings for timeouts, auto-closing, and cookie refreshing. ```APIDOC ## init ### Description Initializes the client and connects to Gemini API. Loads defaults from `g_config.gemini` if parameters are not provided. Calls the parent `GeminiClient.init()` with resolved parameters. ### Method `async init(timeout, watchdog_timeout, auto_close, close_delay, auto_refresh, refresh_interval, verbose) -> None` ### Parameters #### Path Parameters - **timeout** (float) - Optional - Connection timeout in seconds (defaults to config) - **watchdog_timeout** (float) - Optional - Watchdog timeout in seconds (defaults to config) - **auto_close** (bool) - Optional - Auto-close idle connections (defaults to False) - **close_delay** (float) - Optional - Delay in seconds before closing idle connections (defaults to config) - **auto_refresh** (bool) - Optional - Auto-refresh cookies (defaults to config) - **refresh_interval** (float) - Optional - Cookie refresh interval in seconds (defaults to config) - **verbose** (bool) - Optional - Verbose logging (defaults to config) ### Returns None ### Raises - Any exception if cookie validation fails, a network error occurs, or an authentication error happens. ### Example ```python client = GeminiClientWrapper("client-a", secure_1psid="...", secure_1psidts="...") await client.init(timeout=600, auto_refresh=True) ``` ``` -------------------------------- ### Get List of All Gemini Clients Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Retrieves a list of all GeminiClientWrapper instances managed by the pool, regardless of their current running status. ```python pool = GeminiClientPool() for client in pool.clients: print(f"Client {client.id}: {client.running()}") ``` -------------------------------- ### init() Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Asynchronously initializes all clients within the pool, establishing connections to the Gemini API. It raises a RuntimeError if no clients are successfully initialized after attempting to connect. ```APIDOC ## async init() ### Description Asynchronously initializes all Gemini clients managed by the pool, attempting to connect them to the Gemini API. This method is crucial for preparing the clients for use and is often called automatically during application startup. ### Parameters None ### Returns None ### Raises - `RuntimeError`: If no clients could be successfully initialized after the process. ### Behavior 1. Iterates through all configured clients. 2. Calls `GeminiClientWrapper.init()` for each client. 3. Logs any exceptions encountered during individual client initialization but continues with others. 4. Raises a `RuntimeError` if, after attempting initialization, zero clients are operational. 5. Typically invoked automatically by the FastAPI application's lifespan events on startup. ### Example ```python pool = GeminiClientPool() await pool.init() ``` ``` -------------------------------- ### Minimum Required Configuration Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md This is the minimum configuration required to run the Gemini client. ```yaml gemini: clients: - id: "client-a" secure_1psid: "..." secure_1psidts: "..." ``` -------------------------------- ### Get Status of All Gemini Clients Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Returns a dictionary indicating the running status of each Gemini client in the pool. This is useful for health checks. ```python pool = GeminiClientPool() status = pool.status() # Returns: {"client-a": True, "client-b": False} if all(status.values()): print("All clients healthy") else: print("Some clients down") ``` -------------------------------- ### Initialize GeminiClientWrapper and Connect Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Initialize the client and establish a connection to the Gemini API. This method accepts various optional parameters to configure connection timeouts, auto-closing behavior, and cookie refresh settings. Defaults are loaded from configuration if not provided. ```python client = GeminiClientWrapper("client-a", secure_1psid="...", secure_1psidts="...") await client.init(timeout=600, auto_refresh=True) ``` -------------------------------- ### File Structure Overview Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/api-reference.md This snippet shows the directory structure of the Gemini FastAPI project, highlighting key documentation and source files. ```tree output/ ├── README.md # Main project overview ├── endpoints.md # HTTP API endpoint specifications ├── types.md # Type and model definitions ├── configuration.md # Configuration options ├── errors.md # Error catalog └── api-reference/ ├── pool.md # GeminiClientPool ├── client.md # GeminiClientWrapper ├── lmdb.md # LMDBConversationStore └── middleware.md # Middleware and utilities ``` -------------------------------- ### Configure Gemini Clients with Proxies Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md This YAML configuration shows how to set up individual Gemini clients with specific proxy settings. Use this to manage rate limits or network restrictions per client. Setting proxy to null indicates a direct connection. ```yaml gemini: clients: - id: "client-proxy-1" proxy: "socks5://proxy1.example.com:1080" - id: "client-proxy-2" proxy: "http://proxy2.example.com:3128" - id: "client-direct" proxy: null # Direct connection ``` -------------------------------- ### Project Directory Structure Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/README.md Overview of the application's directory structure, outlining the location of core services, server routes, utilities, and models. ```tree app/ ├── main.py # FastAPI app initialization and lifespan ├── models/ # Pydantic data models ├── server/ # HTTP route handlers │ ├── chat.py # Chat completion and responses endpoints │ ├── health.py # Health check endpoint │ ├── images.py # Image serving endpoint │ └── middleware.py # CORS, exception handling, auth ├── services/ # Core business logic │ ├── client.py # GeminiClientWrapper │ ├── pool.py # GeminiClientPool (connection pooling) │ └── lmdb.py # LMDBConversationStore (persistence) └── utils/ # Configuration and helpers ├── config.py # Configuration loading ├── helper.py # Text processing utilities ├── logging.py # Logging setup └── singleton.py # Singleton metaclass ``` -------------------------------- ### GET /images/{filename} Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/endpoints.md Serves generated images with token-based access control. Access is secured using HMAC-SHA256 tokens when an API key is configured. ```APIDOC ## GET /images/{filename} ### Description Serve generated images with token-based access control. ### Method GET ### Endpoint /images/{filename} ### Parameters #### Query Parameters - **token** (string) - Required: ✗ - HMAC-SHA256 token (required if API key is set) ### Response - 200 OK: Image file with appropriate Content-Type (image/png, image/jpeg, etc.) - 403 Forbidden: Invalid or missing token (if API key is set) - 404 Not Found: Image file not found **Notes**: - Images are stored in the directory specified by `storage.images_path` config (default: data/images) - Token generation: `hmac_sha256(api_key, filename)` - Images are automatically cleaned up after `storage.retention_days` (default: 14 days) - If no API key is configured, token validation is skipped ``` -------------------------------- ### Instantiate GeminiClientPool (Singleton) Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Demonstrates that instantiating GeminiClientPool always returns the same singleton instance. ```python from app.services import GeminiClientPool pool = GeminiClientPool() # Returns singleton instance pool = GeminiClientPool() # Same instance returned ``` -------------------------------- ### GET /health Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/endpoints.md Provides a health check for Gemini clients and the LMDB conversation store. It returns the operational status of all connected clients and the storage system. ```APIDOC ## GET /health ### Description Health check endpoint returning status of Gemini clients and LMDB conversation store. ### Method GET ### Endpoint /health ### Parameters #### Query Parameters None ### Response #### Success Response (200 OK) - **ok** (boolean) - true if all clients running and storage healthy - **storage** (object) - LMDB statistics (entry count, page info) or null if unavailable - **clients** (object) - Map of client_id → running status - **error** (string) - Error message if ok=false #### Response Example ```json { "ok": true, "storage": { "ms_entries": 1500, "ms_leaf_pages": 42, "ms_overflow_pages": 0, "ms_page_size": 4096, "ms_psize": 4096 }, "clients": { "client-a": true, "client-b": false } } ``` **Error Responses**: - 500 Internal Server Error: Storage unavailable or critical error **Notes**: - Returns 200 even if some clients are down (check `ok` field and `clients` map) - Storage statistics include LMDB page and entry counts ``` -------------------------------- ### Initialize LMDBConversationStore with Defaults Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Initializes the LMDBConversationStore using default values from the application configuration. This is the simplest way to create a store instance. ```python from app.services import LMDBConversationStore # Uses configuration defaults store = LMDBConversationStore() ``` -------------------------------- ### Acquiring a Specific Client Instance Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Shows how to acquire a client by its specific ID, useful for reusing existing conversation contexts or maintaining state with a particular client. ```python # Always use specific client (for conversation reuse) client = await pool.acquire("client-a") session = client.start_chat(model=model, metadata=metadata) ``` -------------------------------- ### Run Gemini-FastAPI with Docker Options Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md This command runs the Gemini-FastAPI Docker container with specified port mappings, volume mounts for data and cache, and environment variables for API key and Gemini client configuration. It's useful for quick testing or single-container deployments. ```bash docker run -p 8000:8000 \ -v $(pwd)/data:/app/data \ -v $(pwd)/cache:/app/cache \ -e CONFIG_SERVER__API_KEY="your-api-key-here" \ -e CONFIG_GEMINI__CLIENTS__0__ID="client-a" \ -e CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID="your-secure-1psid" \ -e CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS="your-secure-1psidts" \ -e GEMINI_COOKIE_PATH="/app/cache" \ ghcr.io/nativu5/gemini-fastapi ``` -------------------------------- ### Check if GeminiClientWrapper is Running Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Determine if the client is currently connected and active with the Gemini API. This is useful for ensuring the client is ready before starting a chat session or performing other operations. ```python if client.running(): session = client.start_chat(model=model) else: logger.error("Client not running") ``` -------------------------------- ### Run Gemini FastAPI with Environment Variables Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md This command demonstrates how to run the Gemini FastAPI Docker container, setting various configuration options via environment variables. Ensure you replace placeholder values like 'your-api-key' with your actual credentials. ```bash docker run \ -p 8000:8000 \ -e CONFIG_SERVER__HOST="0.0.0.0" \ -e CONFIG_SERVER__PORT="8000" \ -e CONFIG_SERVER__API_KEY="your-api-key" \ -e CONFIG_GEMINI__CLIENTS__0__ID="client-a" \ -e CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID="your-1psid" \ -e CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS="your-1psidts" \ -e CONFIG_GEMINI__CHAT_MODE="normal" \ -e CONFIG_STORAGE__RETENTION_DAYS="7" \ -v $(pwd)/data:/app/data \ -v $(pwd)/cache:/app/cache \ ghcr.io/nativu5/gemini-fastapi ``` -------------------------------- ### Get LMDB Database Statistics Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Retrieves statistics about the LMDB database, including entry counts, page usage, and page size. The returned dictionary contains various metrics. ```python def stats(self) -> dict[str, Any]: pass ``` ```json { "ms_entries": 1500, // Total entries "ms_leaf_pages": 42, // Leaf pages used "ms_overflow_pages": 0, // Overflow pages "ms_page_size": 4096, // Page size "ms_psize": 4096 // Physical page size } ``` ```python stats = store.stats() print(f"Store has {stats['ms_entries']} entries") print(f"Database uses {stats['ms_leaf_pages']} pages") ``` -------------------------------- ### Override Server and Gemini Client Configuration via Environment Variables Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Use environment variables with the CONFIG_ prefix to override server and Gemini client settings. Double underscores represent nested keys. This is useful for Docker and production environments. ```bash export CONFIG_SERVER__API_KEY="your-secure-api-key" export CONFIG_GEMINI__CLIENTS__0__ID="client-a" export CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID="your-secure-1psid" export CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS="your-secure-1psidts" export CONFIG_GEMINI__CLIENTS__0__PROXY="socks5://127.0.0.1:1080" export CONFIG_STORAGE__MAX_SIZE=268435456 # 256 MB ``` -------------------------------- ### Define Tool and ToolChoiceFunction Models Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/types.md Defines Pydantic models for Tool and ToolChoiceFunction, used to specify available tools and guide the model's tool selection. Includes function name, description, and parameter schema. ```python class ToolFunctionDefinition(BaseModel): name: str description: str | None = None parameters: dict[str, Any] | None = None class Tool(BaseModel): type: Literal["function"] function: ToolFunctionDefinition class ToolChoiceFunctionDetail(BaseModel): name: str class ToolChoiceFunction(BaseModel): type: Literal["function"] function: ToolChoiceFunctionDetail ``` -------------------------------- ### Initialize LMDBConversationStore with Custom Parameters Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Initializes the LMDBConversationStore with custom parameters for database path, maximum size, and retention days. This allows for fine-grained control over storage settings. ```python from app.services import LMDBConversationStore # Custom paths store = LMDBConversationStore( db_path="/var/lib/gemini/conversations", max_db_size=1024**3, # 1 GB retention_days=30 ) ``` -------------------------------- ### Health Check Endpoint Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/endpoints.md Use the GET /health endpoint to check the status of Gemini clients and the LMDB conversation store. It returns a 200 OK status even if some clients are down, requiring checks of the 'ok' field and 'clients' map. ```http GET /health ``` ```json { "ok": true, "storage": { "ms_entries": 1500, "ms_leaf_pages": 42, "ms_overflow_pages": 0, "ms_page_size": 4096, "ms_psize": 4096 }, "clients": { "client-a": true, "client-b": false } } ``` -------------------------------- ### Gemini Client Configuration (Environment Variables) Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Set Gemini client configurations using environment variables, following a specific naming convention for nested properties. ```bash CONFIG_GEMINI__CLIENTS__0__ID="client-a" CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID="..." CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS="..." CONFIG_GEMINI__CLIENTS__0__PROXY="null" ``` -------------------------------- ### Extract Output from Gemini API Response Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Extracts and normalizes text from a Gemini API ModelOutput response. Optionally includes thinking or reasoning steps enclosed in tags. Use this to get clean text output from the model. ```python # Assuming ModelOutput and session are defined elsewhere # class ModelOutput: # def __init__(self, text: str, thoughts: str = None): # self.text = text # self.thoughts = thoughts # class MockSession: # async def send_message(self, prompt: str) -> ModelOutput: # # Mock response # return ModelOutput(text="2+2 equals 4.", thoughts="User asked for a simple calculation.") # Mock objects for demonstration class ModelOutput: def __init__(self, text: str, thoughts: str = None): self.text = text self.thoughts = thoughts class MockSession: async def send_message(self, prompt: str) -> ModelOutput: return ModelOutput(text="2+2 equals 4.", thoughts="User asked for a simple calculation.") class GeminiClientWrapper: @staticmethod def extract_output(response: ModelOutput, include_thoughts: bool = True) -> str: output = "" if include_thoughts and response.thoughts: output += f"{response.thoughts}\n" output += response.text return output async def main(): session = MockSession() response = await session.send_message("What is 2+2?") text = GeminiClientWrapper.extract_output(response, include_thoughts=False) print(text) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` -------------------------------- ### Instantiate and Access Client ID Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Demonstrates how to create an instance of GeminiClientWrapper and access its unique identifier. ```python client = GeminiClientWrapper("client-a", ...) print(client.id) # "client-a" ``` -------------------------------- ### Serve Generated Images Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/endpoints.md Access generated images via the GET /images/{filename} endpoint. Token-based access control is enforced if an API key is configured, using HMAC-SHA256 for token generation. Images are automatically cleaned up based on storage retention settings. ```http GET /images/img_abc123def456.png?token= ``` -------------------------------- ### Instantiate GeminiClientWrapper Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Create an instance of GeminiClientWrapper, providing a unique client ID and optional authentication/proxy parameters. The client does not connect to the Gemini API until its init() method is called. ```python from app.services import GeminiClientWrapper client = GeminiClientWrapper( client_id="client-a", secure_1psid="...", secure_1psidts="...", proxy=None ) ``` -------------------------------- ### Gemini Client Configuration (YAML) Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Configure Gemini clients using a YAML structure, specifying client IDs, secure tokens, and optional proxy settings. ```yaml gemini: clients: - id: "client-a" secure_1psid: "..." secure_1psidts: "..." proxy: null - id: "client-b" secure_1psid: "..." secure_1psidts: "..." proxy: "socks5://..." ``` -------------------------------- ### GeminiClientWrapper Constructor Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Initializes the GeminiClientWrapper. It takes a client_id and optional keyword arguments that are passed to the parent GeminiClient. ```APIDOC ## GeminiClientWrapper Constructor ### Description Initializes the GeminiClientWrapper with a unique client identifier and passes additional arguments to the parent GeminiClient. ### Parameters #### Path Parameters - **client_id** (string) - Required - Unique identifier for this client instance - **kwargs** (dict) - Optional - Passed to parent GeminiClient (secure_1psid, secure_1psidts, proxy, etc.) ### Example ```python from app.services import GeminiClientWrapper client = GeminiClientWrapper( client_id="client-a", secure_1psid="...", secure_1psidts="...", proxy=None ) ``` ``` -------------------------------- ### Round-Robin Client Acquisition with Fallback Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Explains how the pool automatically selects the next healthy client using a round-robin strategy and handles cases where all clients might be unavailable. ```python # Automatically picks next healthy client try: client = await pool.acquire() # May restart if down response = await send_request(client) except RuntimeError: logger.error("All clients unavailable") ``` -------------------------------- ### Project File Organization Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/INDEX.md Lists the main files and their purposes within the Gemini Protocol project. ```text /workspace/home/output/ ├── INDEX.md # This file ├── README.md # Project overview ├── endpoints.md # HTTP API specification ├── types.md # Type definitions ├── configuration.md # Setup and config ├── errors.md # Error catalog ├── api-reference.md # API overview ├── pool.md # GeminiClientPool ├── client.md # GeminiClientWrapper └── lmdb.md # LMDBConversationStore ``` -------------------------------- ### Process Message with Tool Calls Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Demonstrates how to process a message containing tool calls, extracting function names and arguments. The output format includes tags for tool calls. ```python from app.models import Message, ToolCall, FunctionCall msg = Message( role="assistant", tool_calls=[ ToolCall( id="call_123", type="function", function=FunctionCall( name="get_weather", arguments='{"location": "NYC"}' ) ) ] ) text, files = await GeminiClientWrapper.process_message(msg) # text includes [ToolCalls][Call:get_weather]...[/Call][/ToolCalls] ``` -------------------------------- ### running Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Checks if the client is currently running and connected to the Gemini API. ```APIDOC ## running ### Description Checks if the client is running (connected to Gemini API). ### Method `def running() -> bool` ### Parameters None ### Returns `bool` — true if connected and active, false otherwise ### Example ```python if client.running(): session = client.start_chat(model=model) else: logger.error("Client not running") ``` ``` -------------------------------- ### Set Environment Variables for Multiple Gemini Clients Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md Configure multiple Gemini clients by exporting environment variables for each client's ID, session cookies, and proxy settings. This method is an alternative to YAML configuration. ```bash export CONFIG_GEMINI__CLIENTS__0__ID="client-a" export CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID="psid_a" export CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS="psidts_a" export CONFIG_GEMINI__CLIENTS__1__ID="client-b" export CONFIG_GEMINI__CLIENTS__1__SECURE_1PSID="psid_b" export CONFIG_GEMINI__CLIENTS__1__SECURE_1PSIDTS="psidts_b" ``` -------------------------------- ### GeminiClientPool Constructor Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Initializes the GeminiClientPool. Configuration is loaded from g_config.gemini.clients. It raises a ValueError if no Gemini clients are configured. This method is part of a singleton pattern, always returning the same instance. ```APIDOC ## GeminiClientPool() ### Description Initializes the GeminiClientPool, loading client configurations from `g_config.gemini.clients`. It ensures only one instance of the pool exists throughout the application. ### Parameters None ### Raises - `ValueError`: If no Gemini clients are configured. ### Example ```python from app.services import GeminiClientPool pool = GeminiClientPool() ``` ``` -------------------------------- ### Acquiring a Client from the Pool Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Acquire a client from the pool. If the current client becomes unavailable, the pool will automatically rotate to the next available client. The pool will detect and utilize a restarted client. ```python client = await pool.acquire() # Gets client-a # client-a crashes... client = await pool.acquire() # Rotates to client-b # Later, if client-a is restarted externally: client = await pool.acquire() # Will detect and use client-a again ``` -------------------------------- ### Configure Custom Gemini Models via Environment Variable Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md Set custom Gemini model configurations, including model names and headers, using a JSON string assigned to the `CONFIG_GEMINI__MODELS` environment variable. This allows for dynamic model configuration. ```bash export CONFIG_GEMINI__MODELS='[{"model_name":"gemini-3.0-pro","model_header":{"x-goog-ext-525001261-jspb":"[1,null,...]"}}]' ``` -------------------------------- ### Initialize GeminiClientPool Clients Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Initializes all configured Gemini clients in the pool, connecting them to the Gemini API. This method is typically called automatically during application startup. ```python pool = GeminiClientPool() await pool.init() # All clients now connected ``` -------------------------------- ### _ensure_client_ready() Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md An internal method that verifies if a given Gemini client is running. If the client is not running, it attempts to restart it in a thread-safe manner using per-client asyncio locks. It returns true if the client is running after the check, false otherwise. ```APIDOC ## async _ensure_client_ready(client: GeminiClientWrapper) -> bool ### Description This is an internal helper method designed to check the operational status of a `GeminiClientWrapper` instance. If the client is detected as not running, this method attempts to restart it. It ensures thread safety during restart attempts by utilizing per-client asyncio locks. ### Parameters #### Path Parameters - **client** (GeminiClientWrapper) - Required - The client instance to check and potentially restart. ### Returns - `bool` — Returns `true` if the client is confirmed to be running after the check (and potential restart), and `false` if the restart attempt fails. ### Behavior 1. Checks if the provided `client` is currently running using `client.running()`. 2. If the client is not running, it acquires a specific asyncio lock associated with that client to prevent concurrent restart attempts. 3. It then attempts to re-initialize the client by calling `client.init()`. 4. Logs whether the restart was successful or if it failed. 5. Returns `true` only if the client is confirmed to be in a running state after these steps. ### Thread Safety Employs per-client asyncio locks to guarantee that restart operations for individual clients do not interfere with each other, preventing race conditions. ### Example ```python # This method is intended for internal use within GeminiClientPool # Example of how it might be called internally: # await self._ensure_client_ready(some_client_instance) ``` ``` -------------------------------- ### Gemini Protocol Tool Calls Structure Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Illustrates the structured format for tool calls, including call parameters and their values. ```plaintext [ToolCalls] [Call:function_name] [CallParameter:param1] ```json value ``` [/CallParameter] [/Call] [/ToolCalls] ``` -------------------------------- ### Configure Gemini Chat Mode and Context Handling in YAML Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md Set the chat mode and context handling strategies in the YAML configuration file. 'temporary' chat mode has an effective input limit of 90% of max_chars_per_request. ```yaml gemini: chat_mode: "normal" # "normal" (reuse metadata) or "temporary" (Google temporary chat, not saved to account) max_chars_per_request: 1000000 oversized_context_strategy: "compaction" # "compaction" or "file" ``` -------------------------------- ### Docker Compose Configuration for Gemini-FastAPI Source: https://github.com/nativu5/gemini-fastapi/blob/main/README.md This docker-compose.yml file defines the Gemini-FastAPI service, including image, ports, volume mounts for data and cache, environment variables, and restart policy. It's recommended for managing multi-container applications or for more complex configurations. ```yaml services: gemini-fastapi: image: ghcr.io/nativu5/gemini-fastapi:latest ports: - "8000:8000" volumes: # - ./config:/app/config # Uncomment to use a custom config file # - ./certs:/app/certs # Uncomment to enable HTTPS with your certs - ./data:/app/data - ./cache:/app/cache environment: - CONFIG_SERVER__HOST=0.0.0.0 - CONFIG_SERVER__PORT=8000 - CONFIG_SERVER__API_KEY=${API_KEY} - CONFIG_GEMINI__CLIENTS__0__ID=client-a - CONFIG_GEMINI__CLIENTS__0__SECURE_1PSID=${SECURE_1PSID} - CONFIG_GEMINI__CLIENTS__0__SECURE_1PSIDTS=${SECURE_1PSIDTS} - GEMINI_COOKIE_PATH=/app/cache # must match the cache volume mount above restart: on-failure:3 # Avoid retrying too many times ``` -------------------------------- ### acquire() Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/pool.md Asynchronously acquires a healthy Gemini client. It can return a specific client by its ID or select one using a round-robin strategy if no ID is provided. It attempts to restart a client if it's not running. ```APIDOC ## async acquire(client_id: str | None = None) -> GeminiClientWrapper ### Description Acquires a healthy Gemini client instance from the pool. If a `client_id` is specified, it attempts to return that particular client. Otherwise, it selects the next available client using a round-robin approach. The method includes logic to restart a client if it's found to be not running. ### Parameters #### Path Parameters - **client_id** (string) - Optional - The specific ID of the client to acquire. If `None`, the pool uses round-robin selection. ### Returns - `GeminiClientWrapper` — A reference to a running Gemini client. ### Raises - `RuntimeError`: If no clients are configured in the pool or if all available clients are currently unavailable. - `ValueError`: If a `client_id` is provided but does not correspond to any configured client. ### Behavior - **Specific Client Acquisition**: If `client_id` is given, the pool attempts to return that client. If it's unavailable, an error is raised. - **Round-Robin Selection**: If `client_id` is `None`, the pool iterates through its clients in a round-robin fashion until a healthy one is found. - **Client Restart Attempt**: If a client is found to be not running, the pool attempts a single restart using `_ensure_client_ready()` before returning it. - **All Clients Fail**: If all clients in the pool fail to be acquired or restarted, a `RuntimeError` is raised. ### Example ```python pool = GeminiClientPool() await pool.init() # Get the next available client using round-robin client = await pool.acquire() # Get a specific client by its ID client = await pool.acquire("client-a") ``` ``` -------------------------------- ### Store and Retrieve Conversation Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/lmdb.md Demonstrates how to store a new conversation object and retrieve it later using its generated key. Ensure the ConversationInStore object is properly initialized. ```python # Store conv = ConversationInStore( model="gemini-2.0-flash", client_id="client-a", metadata=[...], messages=[...] ) key = store.store(conv) # Retrieve later conv = store.get(key) ``` -------------------------------- ### ResponseReasoning Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/types.md Details the reasoning process, including summary and content parts. ```APIDOC ## ResponseReasoning ### Description Provides details about the reasoning process, including an ID, status, optional summary, and content. ### Fields - **id** (string) - Required - Reasoning ID - **type** (string) - Required - Must always be "reasoning" - **status** (string | None) - Optional - Status of the reasoning (options: "in_progress", "completed", "incomplete") - **summary** (array[ResponseSummaryPart] | None) - Optional - Summary parts of the reasoning - **content** (array[ResponseReasoningContentPart] | None) - Optional - Reasoning content parts ``` -------------------------------- ### Gemini-FastAPI Configuration Structure Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/configuration.md This YAML structure defines the default configuration for the Gemini-FastAPI server, including server, CORS, Gemini, storage, and logging settings. Environment variables can override these values. ```yaml server: host: "0.0.0.0" port: 8000 api_key: null https: enabled: false key_file: "certs/privkey.pem" cert_file: "certs/fullchain.pem" cors: enabled: true allow_origins: - "*" allow_credentials: true allow_methods: - "*" allow_headers: - "*" gemini: clients: - id: "client-a" secure_1psid: "YOUR_SECURE_1PSID" secure_1psidts: "YOUR_SECURE_1PSIDTS" proxy: null models: [] model_strategy: "append" timeout: 600 watchdog_timeout: 300 auto_refresh: true refresh_interval: 600 verbose: false max_chars_per_request: 1000000 oversized_context_strategy: "compaction" chat_mode: "normal" storage: path: "data/lmdb" images_path: "data/images" max_size: 268435456 retention_days: 14 logging: level: "DEBUG" ``` -------------------------------- ### Extract Output from Response Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Shows how to extract the output from a session response, with options to include or exclude reasoning (thoughts). ```python response = await session.send_message("Hello") # With reasoning full_text = GeminiClientWrapper.extract_output(response, include_thoughts=True) # Text only text = GeminiClientWrapper.extract_output(response, include_thoughts=False) ``` -------------------------------- ### Process Single Message with Image Source: https://github.com/nativu5/gemini-fastapi/blob/main/_autodocs/client.md Shows how to process a single message that includes text and an image URL. The temporary directory is used to store downloaded images. ```python from app.models import Message, ContentItem from pathlib import Path msg = Message( role="user", content=[ ContentItem(type="text", text="Describe this image:"), ContentItem( type="image_url", image_url={"url": "https://example.com/image.jpg"} ) ] ) text, files = await GeminiClientWrapper.process_message(msg, tempdir=Path("/tmp")) # text includes [User] tags and image reference # files contains path to downloaded image ```