Skip to content

Alexander-Ollman/basic-era-gemini

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

Gemini Live API Service

A Python-based containerized service that exposes an API for interacting with Google's Gemini Live API with tool use support.

Features

  • FastAPI-based REST and WebSocket endpoints for real-time streaming
  • Tool use support with manual tool declarations
  • WebSocket streaming for real-time responses
  • Docker containerization for easy deployment
  • Built-in tool management with registration and storage
  • Health checks and logging

Documentation

Project Structure

.
├── main.py                 # FastAPI application with endpoints
├── gemini_service.py       # Gemini Live API integration
├── tool_manager.py         # Tool declaration management
├── models.py              # Pydantic models for requests/responses
├── config.py              # Configuration management
├── live.py                # Original example from Gemini docs
├── requirements.txt       # Python dependencies
├── Dockerfile            # Container definition
├── docker-compose.yml    # Docker Compose configuration
├── .env.example          # Environment variables template
├── demo.html             # Interactive browser demo
├── gemini-client.js      # JavaScript SDK
├── gemini-client.d.ts    # TypeScript type definitions
├── API_FRONTEND.md       # Frontend API documentation
└── README.md             # This file

Prerequisites

  • Docker and Docker Compose (for containerized deployment)
  • Python 3.11+ (for local development)
  • Google API Key with Gemini API access

Getting Started

1. Get a Google API Key

Get your API key from Google AI Studio

2. Configure API Key

Option A: Dynamic Injection (Easiest)

Start the service first, then inject your key via API:

# Start service
docker-compose up -d

# Set key dynamically (no restart needed!)
curl -X POST http://localhost:8000/config/api-key \
  -H "Content-Type: application/json" \
  -d '{"api_key":"YOUR_KEY_HERE"}'

See QUICK_API_KEY_SETUP.md for details.

Option B: Environment File (Traditional)

Copy the example environment file and add your API key:

cp .env.example .env

Edit .env and add your API key:

GOOGLE_API_KEY=your_actual_api_key_here

3. Run with Docker Compose (Recommended)

# Build and start the service
docker-compose up --build

# Or run in detached mode
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the service
docker-compose down

The service will be available at http://localhost:8000

4. Run Locally (Development)

# Install dependencies
pip install -r requirements.txt

# Run the service
python main.py

# Or use uvicorn directly
uvicorn main:app --reload --host 0.0.0.0 --port 8000

API Endpoints

Health Check

GET /health

Check if the service is running:

curl http://localhost:8000/health

Manage Tools

Add Tools

POST /tools

Register tool declarations:

curl -X POST http://localhost:8000/tools \
  -H "Content-Type: application/json" \
  -d '[
    {
      "function_declarations": [
        {
          "name": "turn_on_the_lights",
          "description": "Turn on the lights in a room",
          "parameters": {
            "type": "object",
            "properties": {
              "room": {
                "type": "string",
                "description": "The room to turn lights on in"
              }
            },
            "required": ["room"]
          }
        }
      ]
    }
  ]'

Get Tools

GET /tools

Retrieve current tool declarations:

curl http://localhost:8000/tools

Delete Tools

DELETE /tools

Remove all tool declarations:

curl -X DELETE http://localhost:8000/tools

Chat Endpoints

WebSocket Streaming (Recommended)

Connect to the WebSocket endpoint for real-time streaming:

ws://localhost:8000/ws/chat

JavaScript Example:

const ws = new WebSocket('ws://localhost:8000/ws/chat');

ws.onopen = () => {
  // Send a message
  ws.send(JSON.stringify({
    message: "Turn on the lights in the living room",
    tools: [  // Optional: specify tools for this session
      {
        "function_declarations": [
          {
            "name": "turn_on_the_lights",
            "description": "Turn on the lights"
          }
        ]
      }
    ]
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  if (data.type === 'text') {
    console.log('Text:', data.text);
  } else if (data.type === 'tool_call') {
    console.log('Tool calls:', data.tool_calls);
  } else if (data.type === 'error') {
    console.error('Error:', data.error);
  } else if (data.type === 'done') {
    console.log('Response complete');
  }
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

Python Example:

import asyncio
import websockets
import json

async def chat():
    uri = "ws://localhost:8000/ws/chat"
    async with websockets.connect(uri) as websocket:
        # Send message
        await websocket.send(json.dumps({
            "message": "Turn on the lights in the bedroom"
        }))

        # Receive responses
        while True:
            response = await websocket.recv()
            data = json.loads(response)

            if data.get('type') == 'done':
                break
            elif data.get('type') == 'text':
                print(f"Text: {data['text']}")
            elif data.get('type') == 'tool_call':
                print(f"Tool calls: {data['tool_calls']}")
            elif data.get('type') == 'error':
                print(f"Error: {data['error']}")

asyncio.run(chat())

REST Chat Endpoint

POST /chat

Non-streaming endpoint that returns the complete response:

curl -X POST http://localhost:8000/chat \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Turn on the lights in the kitchen",
    "tools": [
      {
        "function_declarations": [
          {
            "name": "turn_on_the_lights",
            "description": "Turn on the lights"
          }
        ]
      }
    ]
  }'

Tool Declaration Format

Tools follow the Gemini API function calling format:

[
  {
    "function_declarations": [
      {
        "name": "function_name",
        "description": "What the function does",
        "parameters": {
          "type": "object",
          "properties": {
            "param1": {
              "type": "string",
              "description": "Parameter description"
            }
          },
          "required": ["param1"]
        }
      }
    ]
  }
]

Simple Tools (No Parameters)

For tools without parameters:

[
  {
    "function_declarations": [
      {
        "name": "turn_on_the_lights"
      }
    ]
  }
]

Development

Running Tests

# Install dev dependencies
pip install pytest pytest-asyncio httpx

# Run tests (you'll need to create tests)
pytest

Project Structure

  • main.py: FastAPI application with all endpoints
  • gemini_service.py: Handles Gemini Live API connections and streaming
  • tool_manager.py: Tool registration and management utilities
  • models.py: Pydantic models for request/response validation
  • config.py: Configuration loaded from environment variables

Adding Custom Tool Handlers

You can implement custom tool handlers by modifying gemini_service.py:

async def my_tool_handler(tool_name: str, tool_args: dict):
    if tool_name == "turn_on_the_lights":
        # Your custom logic here
        return {"result": "Lights turned on", "status": "success"}
    return {"result": "ok"}

Docker

Build Image

docker build -t gemini-live-api .

Run Container

docker run -d \
  -p 8000:8000 \
  -e GOOGLE_API_KEY=your_api_key \
  --name gemini-live-api \
  gemini-live-api

Docker Compose

The docker-compose.yml includes:

  • Automatic restarts
  • Health checks
  • Volume mounting for development
  • Environment variable configuration
  • Logging configuration

Environment Variables

Variable Description Default
GOOGLE_API_KEY Google API key (required) None
GEMINI_MODEL Model to use gemini-live-2.5-flash-preview
RESPONSE_MODALITIES Response types ["TEXT"]
HOST Server host 0.0.0.0
PORT Server port 8000

Troubleshooting

API Key Issues

If you get authentication errors:

  1. Verify your API key is correct in .env
  2. Check that your API key has Gemini API access enabled
  3. Ensure the .env file is being loaded (check logs)

Connection Issues

If WebSocket connections fail:

  1. Check that port 8000 is not blocked by firewall
  2. Verify the service is running: curl http://localhost:8000/health
  3. Check logs: docker-compose logs -f

Tool Calls Not Working

If tools aren't being called:

  1. Verify tool declarations are registered: curl http://localhost:8000/tools
  2. Check that tool descriptions are clear and relevant to your prompt
  3. Review logs for any errors during tool execution

Example Use Cases

Smart Home Control

{
  "function_declarations": [
    {
      "name": "control_device",
      "description": "Control smart home devices",
      "parameters": {
        "type": "object",
        "properties": {
          "device": {"type": "string"},
          "action": {"type": "string"},
          "value": {"type": "number"}
        }
      }
    }
  ]
}

Data Retrieval

{
  "function_declarations": [
    {
      "name": "get_weather",
      "description": "Get current weather",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {"type": "string"}
        }
      }
    }
  ]
}

License

This project is provided as-is for educational and development purposes.

Contributing

Feel free to submit issues and enhancement requests!

Resources

basic-era-gemini

basic-era-gemini

About

An API endpoint for Gemini 2.5 Flash Live with tool use in a Docker container

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors