Skip to main content

Make API requests using free-tier quota across multiple keys automatically

Project description

free_calls

Make API requests using free-tier quota across multiple keys automatically.

free_calls automatically rotates through multiple API keys when quotas are exhausted, allowing you to maximize your free-tier usage across services.

Installation

pip install free_calls

Or install from source:

git clone https://github.com/MuOssama/free_calls.git
cd free_calls
pip install -e .

Quick Start

1. Set up environment variables

# Single key
export OPENAI_API_KEY="sk-key1"

# Multiple keys (comma-separated)
export OPENAI_API_KEY="sk-key1,sk-key2,sk-key3"

2. Use in your code

from free_calls import FreeCallsManager

# Initialize manager
manager = FreeCallsManager(env_prefix="OPENAI_API_KEY")

# Define your API function (key must be first parameter)
def call_openai_api(api_key, prompt):
    import openai
    openai.api_key = api_key
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    return response

# Call with automatic rotation
try:
    result = manager.call_with_rotation(
        call_openai_api,
        "Hello, world!",
        quota_error_types=(openai.error.RateLimitError,)
    )
    print(result)
except Exception as e:
    print(f"All keys exhausted: {e}")

Features

Automatic key rotation - Seamlessly switch to next key when quota is exhausted
Runtime status tracking - See which keys are working and which have failed
Multiple API support - Works with any API service
Configurable error types - Define which exceptions trigger rotation
Simple integration - Minimal code changes required

How it Works

  1. Loads all API keys from environment variable
  2. Tries first available key
  3. If quota error occurs, marks key as failed and tries next key
  4. Failed keys are moved to the end of the list
  5. If all keys fail, raises NoValidAPIKeyError

API Reference

FreeCallsManager(env_prefix, separator=",")

Initialize the manager with API keys from environment.

Parameters:

  • env_prefix (str): Environment variable name containing API keys
  • separator (str): Character separating multiple keys (default: ",")

call_with_rotation(api_function, *args, quota_error_types=None, **kwargs)

Call an API function with automatic key rotation on quota errors.

Parameters:

  • api_function (Callable): Function to call (must accept API key as first parameter)
  • quota_error_types (tuple): Exception types indicating quota exhaustion
  • *args, **kwargs: Additional arguments passed to the API function

Returns: Result from the API function

get_ordered_keys()

Get runtime list of all API keys ordered by status.

Returns: List of dicts with:

  • key (str): Masked API key (e.g., "sk-1...xyz4")
  • status (str): Either "active" or "failed"

Example:

keys = manager.get_ordered_keys()
for item in keys:
    print(f"{item['key']}: {item['status']}")

# Output:
# sk-2...def5: active   <- working keys first
# sk-3...ghi6: active
# sk-1...abc4: failed   <- failed keys last

reset()

Reset all failed keys to try them again.

get_current_key()

Get the current active API key (returns None if all failed).

Examples

OpenAI API

from free_calls import FreeCallsManager
import openai

manager = FreeCallsManager("OPENAI_API_KEY")

def chat_completion(api_key, prompt):
    openai.api_key = api_key
    return openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )

result = manager.call_with_rotation(
    chat_completion,
    "What is Python?",
    quota_error_types=(openai.error.RateLimitError,)
)

Anthropic Claude API

from free_calls import FreeCallsManager
import anthropic

manager = FreeCallsManager("ANTHROPIC_API_KEY")

def claude_message(api_key, prompt):
    client = anthropic.Anthropic(api_key=api_key)
    return client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )

result = manager.call_with_rotation(
    claude_message,
    "Hello!",
    quota_error_types=(anthropic.RateLimitError,)
)

Custom API

from free_calls import FreeCallsManager
import requests

manager = FreeCallsManager("MY_API_KEY")

def my_api_call(api_key, endpoint, data):
    response = requests.post(
        endpoint,
        headers={"Authorization": f"Bearer {api_key}"},
        json=data
    )
    if response.status_code == 429:  # Rate limit
        raise Exception("Rate limited")
    return response.json()

result = manager.call_with_rotation(
    my_api_call,
    "https://api.example.com/endpoint",
    {"query": "test"},
    quota_error_types=(Exception,)
)

License

MIT License - see LICENSE file for details

Author

Mustapha Ossama - MuOssama

Contributing

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

Support

If you encounter any issues or have questions, please file an issue on the GitHub issue tracker.

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

free_api_calls-0.1.0.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

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

free_api_calls-0.1.0-py3-none-any.whl (4.2 kB view details)

Uploaded Python 3

File details

Details for the file free_api_calls-0.1.0.tar.gz.

File metadata

  • Download URL: free_api_calls-0.1.0.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for free_api_calls-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b056208f8d9655277e5a1c04454d6628bedb276c7359581d9ffe399bfa260ce2
MD5 754e674d4c1513f7967d75d8d4135bf4
BLAKE2b-256 e2653f25b0b755b95e34c17b41cfe77a844ac69d7c04741ea0e4320c3a09738d

See more details on using hashes here.

File details

Details for the file free_api_calls-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: free_api_calls-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for free_api_calls-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2dff3e35eac835b0159f6586e7771c9798392e5eab2f25608fe0b1920dde09e3
MD5 a4a90515604e53088d9535e4078dfcc1
BLAKE2b-256 d2f4b27764489ffa44ac9301e603fb97d7b099aa5c35e2a9c95818d2e8049ebf

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