### Install Dependencies and Set API Keys
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Installs project dependencies and sets required environment variables for API keys. Ensure all necessary keys are exported before running the script.
```bash
pip install -r src/requirements.txt
export GROQ_API_KEY="gsk_..."
export CLOUDFLARE_ACCOUNT_ID="abc123"
export CLOUDFLARE_API_KEY="cfkey..."
export HYPERBOLIC_API_KEY="hk-..."
export GCP_PROJECT_ID="my-project"
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/adc.json"
export LAMBDA_API_KEY="lk-..."
export SCALEWAY_API_KEY="sk-..."
export COHERE_API_KEY="co-..."
```
--------------------------------
### GitHub Actions Workflow for Daily README Update
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
A GitHub Actions workflow that automatically updates the README.md file daily. It checks out the code, sets up Python, installs dependencies, authenticates to GCP, runs the generation script with injected secrets, and opens a pull request.
```yaml
# .github/workflows/update-readme.yml (key excerpt)
on:
schedule:
- cron: "0 0 * * *" # runs every day at midnight UTC
workflow_dispatch: # also triggerable manually from the Actions UI
jobs:
update-readme:
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install -r src/requirements.txt
- uses: google-github-actions/auth@v3 # Workload Identity — no long-lived key
with:
workload_identity_provider: "projects/.../providers/cheahjs-org"
project_id: ${{ secrets.GCP_PROJECT }}
- run: python -u src/pull_available_models.py
env:
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }}
HYPERBOLIC_API_KEY: ${{ secrets.HYPERBOLIC_API_KEY }}
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
LAMBDA_API_KEY: ${{ secrets.LAMBDA_API_KEY }}
SCALEWAY_API_KEY: ${{ secrets.SCALEWAY_API_KEY }}
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
- uses: peter-evans/create-pull-request@v8
with:
title: "Update README with latest models"
branch: update-readme
base: main
```
--------------------------------
### Run README Generation Script
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Executes the main script to generate the README.md file. Can be run sequentially or in parallel for faster execution. Logs any missing model IDs from MODEL_TO_NAME_MAPPING.
```bash
# Run sequentially (default)
python src/pull_available_models.py
# Run provider fetches in parallel (faster)
FETCH_CONCURRENTLY=true python src/pull_available_models.py
```
--------------------------------
### Fetch Google AI Studio Quotas
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Fetches free-tier token and request quotas for Gemini/Gemma models using the google-cloud-quotas SDK. Requires Application Default Credentials (ADC) or GOOGLE_APPLICATION_CREDENTIALS.
```python
import os
from pull_available_models import fetch_gemini_limits, create_logger
# Requires Application Default Credentials (ADC) or GOOGLE_APPLICATION_CREDENTIALS
os.environ["GCP_PROJECT_ID"] = "my-gcp-project"
logger = create_logger("Google AI Studio")
limits = fetch_gemini_limits(logger)
# Example output:
# {
# "gemini-2.5-flash": {"tokens/minute": 250000, "requests/minute": 10},
# "gemma-3-27b": {"tokens/minute": 15000, "requests/minute": 2},
# ...
# }
print(limits.get("gemini-2.5-flash"))
```
--------------------------------
### Fetch Free OpenRouter Models
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
The `fetch_openrouter_models` function retrieves all models from the OpenRouter API, filtering for those that are free (completion and prompt pricing are zero) and have a ':free' suffix in their ID. It also excludes models listed in `OPENROUTER_IGNORED_MODELS`.
```python
from pull_available_models import fetch_openrouter_models, create_logger
logger = create_logger("OpenRouter")
models = fetch_openrouter_models(logger)
# Each model: {"id": "deepseek/deepseek-r1:free", "name": "DeepSeek R1",
# "limits": {"requests/minute": 20, "requests/day": 50}}
for m in models:
print(f" - {m['name']} ({m['id']})")
```
--------------------------------
### Fetch Groq Models with Rate Limits
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
The `fetch_groq_models` function queries the Groq API for available models and their rate limits by inspecting response headers from inference calls. It also handles Whisper models separately.
```python
import os, logging, requests
from pull_available_models import fetch_groq_models, create_logger
os.environ["GROQ_API_KEY"] = "gsk_..."
logger = create_logger("Groq")
models = fetch_groq_models(logger)
# Example output structure:
# [
# {"id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B", "limits": {"requests/day": 1000, "tokens/minute": 6000}},
# {"id": "whisper-large-v3", "name": "Whisper Large v3", "limits": {"audio-seconds/minute": 7200, "requests/day": 2000}},
# ...
# ]
for m in models[:3]:
print(f"{m['name']:40s} {m['limits']}")
```
--------------------------------
### Fetch Hyperbolic Inference Models
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Retrieves models from the Hyperbolic /v1/models endpoint, filtering out non-LLM entries. All remaining models share a flat limit of 60 requests per minute. Requires HYPERBOLIC_API_KEY.
```python
import os
from pull_available_models import fetch_hyperbolic_models, create_logger
os.environ["HYPERBOLIC_API_KEY"] = "hk-..."
logger = create_logger("Hyperbolic")
models = fetch_hyperbolic_models(logger)
# [{"id": "meta-llama/Llama-3.3-70B-Instruct", "name": "Llama 3.3 70B Instruct",
# "limits": {"requests/minute": 60}}, ...]
```
--------------------------------
### Map LLM Model IDs to Human-Readable Names
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Use the MODEL_TO_NAME_MAPPING dictionary to convert raw model IDs into display names. It supports various provider prefixes and suffixes. A helper function `get_model_name` provides a fallback to the raw ID for unknown models.
```python
from data import MODEL_TO_NAME_MAPPING
# Look up a Cloudflare-prefixed model ID
print(MODEL_TO_NAME_MAPPING["@cf/meta/llama-3.3-70b-instruct-fp8-fast"])
# Output: "Llama 3.3 70B Instruct (FP8)"
# Look up an OpenRouter free-tier model
print(MODEL_TO_NAME_MAPPING["deepseek/deepseek-r1:free"])
# Output: "DeepSeek R1"
# Graceful fallback for unknown IDs (handled by get_model_name())
def get_model_name(model_id: str) -> str:
model_id = model_id.lower()
return MODEL_TO_NAME_MAPPING.get(model_id, model_id) # falls back to raw ID
print(get_model_name("some/unknown-model-id"))
# Output: "some/unknown-model-id"
```
--------------------------------
### Generate GitHub-style Markdown TOC
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Scans Markdown content for '##' and '###' headings to create a nested bullet-list TOC with GitHub-compatible anchors.
```python
from pull_available_models import generate_toc
sample_md = """
# Free LLM API Resources
## Free Providers
### OpenRouter
### Groq
## Providers with Trial Credits
### Hyperbolic
"""
toc = generate_toc(sample_md)
print(toc)
# Output:
# - [Free Providers](#free-providers)
# - [OpenRouter](#openrouter)
# - [Groq](#groq)
# - [Providers with Trial Credits](#providers-with-trial-credits)
```
--------------------------------
### Scrape GitHub Marketplace Models
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Collects all models from the GitHub Marketplace by paginating through the API. Maps raw 'name' to 'friendly_name' directly from the GitHub response.
```python
from pull_available_models import fetch_github_models, create_logger
logger = create_logger("GitHub")
models = fetch_github_models(logger)
# [{"id": "openai-gpt-4o", "name": "GPT-4o"}, {"id": "meta-llama-3-70b-instruct", "name": "Meta Llama 3 70B Instruct"}, ...]
print(f"Total GitHub models: {len(models)}")
for m in models[:5]:
print(f" {m['name']}")
```
--------------------------------
### Format Rate Limits for Markdown
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Converts a model's limits dictionary into a human-readable string for Markdown display. The separator defaults to '
' for HTML tables but can be overridden.
```python
from pull_available_models import get_human_limits
model = {
"id": "llama-3.3-70b-versatile",
"name": "Llama 3.3 70B",
"limits": {"requests/day": 1000, "tokens/minute": 6000},
}
html_limits = get_human_limits(model)
print(html_limits)
# Output: "1,000 requests/day
6,000 tokens/minute"
plain_limits = get_human_limits(model, seperator="\n")
print(plain_limits)
# Output:
# 1,000 requests/day
# 6,000 tokens/minute
# Model without limits returns empty string
print(get_human_limits({"id": "x", "name": "X"}))
# Output: ""
```
--------------------------------
### Fetch Cohere Chat Models
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Paginates through the Cohere /v1/models endpoint to fetch active chat models, skipping deprecated ones. Requires COHERE_API_KEY.
```python
import os
from pull_available_models import fetch_cohere_models, create_logger
os.environ["COHERE_API_KEY"] = "co-..."
logger = create_logger("Cohere")
models = fetch_cohere_models(logger)
# [{"id": "command-r-plus", "name": "Command R+"}, {"id": "command-r", "name": "Command R"}, ...]
print(f"Active Cohere chat models: {len(models)}")
```
--------------------------------
### Fetch Cloudflare Workers AI Models
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Queries the Cloudflare Account AI model search endpoint for text-generation models. Requires CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_KEY environment variables. Cloudflare enforces a global limit of 10,000 neurons/day.
```python
import os
from pull_available_models import fetch_cloudflare_models, create_logger
os.environ["CLOUDFLARE_ACCOUNT_ID"] = "abc123"
os.environ["CLOUDFLARE_API_KEY"] = "cfkey..."
logger = create_logger("Cloudflare")
models = fetch_cloudflare_models(logger)
# Models have no "limits" key — Cloudflare enforces 10,000 neurons/day globally
# [{"id": "@cf/meta/llama-3.3-70b-instruct-fp8-fast", "name": "Llama 3.3 70B Instruct (FP8)"}, ...]
for m in models:
print(m["name"])
```
--------------------------------
### Manage Ignored LLM Models Per Provider
Source: https://context7.com/cheahjs/free-llm-api-resources/llms.txt
Utilize sets like HYPERBOLIC_IGNORED_MODELS, LAMBDA_IGNORED_MODELS, and OPENROUTER_IGNORED_MODELS to exclude specific model IDs from README generation. This is useful for filtering out non-text-generation, deprecated, or unusable models.
```python
from data import HYPERBOLIC_IGNORED_MODELS, LAMBDA_IGNORED_MODELS, OPENROUTER_IGNORED_MODELS
# Check whether a model should be skipped for Hyperbolic
model_id = "FLUX.1-dev"
if model_id in HYPERBOLIC_IGNORED_MODELS:
print(f"Skipping {model_id} — not a text-generation model")
# Output: Skipping FLUX.1-dev — not a text-generation model
# Check OpenRouter ignore list (all are unusable Gemini experimental free models)
print("google/gemini-exp-1206:free" in OPENROUTER_IGNORED_MODELS) # True
print("deepseek/deepseek-r1:free" in OPENROUTER_IGNORED_MODELS) # False
# Lambda ignore list targets specific broken model slugs
print(LAMBDA_IGNORED_MODELS)
# Output: {'lfm-40b-vllm', 'hermes3-405b-fp8-128k'}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.