Skip to main content

A Python client for managing multiple free OpenRouter API keys with automatic rotation

Project description

OpenRouter Free Client

A Python library for managing multiple free OpenRouter API keys with automatic rotation and seamless integration with LlamaIndex and LangChain.

Features

  • Automatic Key Rotation: Automatically switches between multiple API keys when rate limits are reached
  • Smart Rate Limit Handling: Detects daily limits and seamlessly rotates to the next available key
  • Framework Integration: Native support for LlamaIndex and LangChain
  • Comprehensive Logging: Tracks key usage with masked key display for security
  • Async Support: Full async/await support for high-performance applications
  • Error Handling: Robust error handling with custom exceptions
  • Pre-configured Models: Includes configurations for popular free models

Supported Models

The library includes pre-configured free models from OpenRouter:

Model Key Full Model Name Context Length Max Output
gpt-oss-20b openai/gpt-oss-20b:free 137,072 137,072
deepseek-chat-v3.1 deepseek/deepseek-chat-v3.1:free 163,800 163,800
deepseek-r1t2-chimera tngtech/deepseek-r1t2-chimera:free 163,840 163,840

Installation

Basic Installation

pip install openrouter-free

With LlamaIndex Support

pip install openrouter-free[llama-index]

With LangChain Support

pip install openrouter-free[langchain]

Full Installation (All Integrations)

pip install openrouter-free[all]

Quick Start

Basic Usage

import asyncio
from openrouter_free import FreeOpenRouterClient, MODELS

# Initialize client with multiple API keys
client = FreeOpenRouterClient(
    model=MODELS["gpt-oss-20b"],
    api_keys=[
        "sk-or-v1-key1...",
        "sk-or-v1-key2...",
        "sk-or-v1-key3...",
    ]
)

# Async usage
async def main():
    response = await client.chat_completion(
        messages=[
            {"role": "user", "content": "Hello, how are you?"}
        ]
    )
    print(response.choices[0].message.content)

# Run async function
asyncio.run(main())

Using Predefined Models

from openrouter_free import FreeOpenRouterClient, MODELS

# Use predefined model configuration
client = FreeOpenRouterClient(
    model=MODELS["gpt-oss-20b"],
    api_keys=["key1", "key2", "key3"]
)

Stream Responses

async def stream_example():
    async for chunk in client.stream_chat_completion(
        messages=[{"role": "user", "content": "Tell me a story"}]
    ):
        if chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="")

LlamaIndex Integration

from openrouter_free import LlamaORFAdapter, MODELS

# Create LlamaIndex-compatible LLM
llm = LlamaORFAdapter(
    model=MODELS["gpt-oss-20b"],
    api_keys=["key1", "key2", "key3"],
    temperature=0.7,
    max_tokens=2000
)

# Use with LlamaIndex
response = llm.chat([
    ChatMessage(role=MessageRole.USER, content="What is machine learning?")
])
print(response.message.content)

# Stream responses
for chunk in llm.stream_chat([
    ChatMessage(role=MessageRole.USER, content="Explain quantum computing")
]):
    print(chunk.delta, end="")

LangChain Integration

from openrouter_free import LangChainORFAdapter, MODELS
from langchain_core.messages import HumanMessage

# Create LangChain-compatible chat model
chat = LangChainORFAdapter(
    model=MODELS["gpt-oss-20b"],
    api_keys=["key1", "key2", "key3"],
    temperature=0.7
)

# Use with LangChain
messages = [HumanMessage(content="What is the capital of France?")]
response = chat.invoke(messages)
print(response.content)

# Stream responses
for chunk in chat.stream(messages):
    print(chunk.content, end="")

Advanced Features

Key Management

# Add new key at runtime
client.add_key("sk-or-v1-newkey...")

# Remove a key
client.remove_key("sk-or-v1-oldkey...")

# Check available keys
print(f"Available keys: {client.available_keys_count}/{client.total_keys_count}")

# Reset all keys (mark as non-exhausted)
client.reset_keys()

Custom Model Configuration

from openrouter_free import ModelInfo, FreeOpenRouterClient

# Create custom model configuration
custom_model = ModelInfo(
    name="meta-llama/llama-3.2-90b-text-preview",
    context_length=131072,
    max_output_tokens=8192
)

client = FreeOpenRouterClient(
    model=custom_model,
    api_keys=["key1", "key2"]
)

Error Handling

from openrouter_free import AllKeysExhausted, InvalidKeyError, RateLimitError

try:
    response = await client.chat_completion(messages=[...])
except AllKeysExhausted:
    print("All API keys have reached their daily limits")
except InvalidKeyError:
    print("Invalid API key detected")
except RateLimitError:
    print("Rate limit exceeded")

Logging Configuration

from loguru import logger

# Loguru provides automatic configuration
# To enable debug level:
logger.enable("openrouter_free")
logger.add("debug.log", level="DEBUG")

API Key Format

OpenRouter API keys should follow the format: sk-or-v1-...

You can get free API keys by:

  1. Creating an account on OpenRouter
  2. Adding credits or using free tier models
  3. Generating API keys from your account settings

Best Practices

  1. Multiple Keys: Use at least 3-5 API keys for better reliability
  2. Error Handling: Always implement proper error handling for production use
  3. Logging: Enable logging to monitor key usage and rotation
  4. Async Operations: Use async methods for better performance in production
  5. Key Security: Never hardcode API keys; use environment variables

Example: Complete Application

import asyncio
import os
from openrouter_free import FreeOpenRouterClient, MODELS, AllKeysExhausted
from loguru import logger

# Setup is automatic with loguru

async def main():
    # Load keys from environment
    keys = [
        os.getenv("OPENROUTER_KEY_1"),
        os.getenv("OPENROUTER_KEY_2"),
        os.getenv("OPENROUTER_KEY_3"),
    ]
    
    # Initialize client
    client = FreeOpenRouterClient(
        model=MODELS["gpt-oss-20b"],
        api_keys=[k for k in keys if k],  # Filter out None values
        max_retries=3
    )
    
    try:
        # Simple chat
        response = await client.chat_completion(
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": "What is Python?"}
            ],
            temperature=0.7,
            max_tokens=500
        )
        print(response.choices[0].message.content)
        
        # Check remaining keys
        print(f"Keys available: {client.available_keys_count}/{client.total_keys_count}")
        
    except AllKeysExhausted:
        print("All API keys exhausted. Please try again tomorrow.")

if __name__ == "__main__":
    asyncio.run(main())

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues and questions, please use the GitHub Issues page.

Disclaimer

This library is not officially affiliated with OpenRouter. It's an independent project designed to help manage multiple free-tier API keys efficiently.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openrouter_free-0.1.4.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openrouter_free-0.1.4-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file openrouter_free-0.1.4.tar.gz.

File metadata

  • Download URL: openrouter_free-0.1.4.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for openrouter_free-0.1.4.tar.gz
Algorithm Hash digest
SHA256 167d4c912d26792348f48b1df1001c76cccb1ec9e948ea91b0913907b74c1b08
MD5 56cf5557c51986d3845621e85cb3144d
BLAKE2b-256 4ca3e1dde338dd9b4c2140db3584bf71ebaaed8cd9e2dd695a6863682d80d56e

See more details on using hashes here.

File details

Details for the file openrouter_free-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for openrouter_free-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 3254f5576cf8c6c5af17fb9ce9c2df6dba265f2272501061ddc7abf54a07eba7
MD5 cb69018ac3b96b7c0df4a77eb5495686
BLAKE2b-256 058d4598a10b80a8ffa0d6524aa0a90696603721c570a12d307a8f663a3a6f98

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page