Metadata-Version: 2.4
Name: llm-catalogue
Version: 0.1.0
Summary: Model names, pricing, and free-tier metadata for OpenAI, Anthropic, and Google Gemini.
Project-URL: Homepage, https://github.com/Ruyzambrano/llm_catalogue
Project-URL: Repository, https://github.com/Ruyzambrano/llm_catalogue
Project-URL: Issues, https://github.com/Ruyzambrano/llm_catalogue/issues
Author: Ruy Zambrano
License: MIT
License-File: LICENSE
Keywords: ai,anthropic,claude,free-tier,gemini,llm,models,openai,pricing
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: pytest; extra == 'dev'
Provides-Extra: scraper
Requires-Dist: requests; extra == 'scraper'
Description-Content-Type: text/markdown

# llm-catalogue

Model names, pricing, and free-tier metadata for OpenAI, Anthropic, and Google
Gemini, in one small zero-dependency package.

```bash
pip install llm-catalogue
```

## Usage

```python
from llm_catalogue import Catalog

catalog = Catalog()

# All free-tier-eligible models for a provider ([] if none)
free_gemini = catalog.get_free_models("google")
free_openai = catalog.get_free_models("openai")  # -> []

# All models for a provider
claude_models = catalog.get_models("anthropic")

# UI toggle helper
if catalog.has_free_tier("google"):
    ...

# Free models across every provider
for model in catalog.find_free_models():
    print(model.id, model.vendor.value)

# Look up one model and estimate a request's cost
model = catalog.get_model("gemini-2.5-flash")
cost_usd = model.calculate_cost(input_tokens=50_000, output_tokens=2_000)
```

`get_models`/`get_free_models`/`has_free_tier` accept `"openai"`, `"anthropic"`
(or `"claude"`), and `"google"` (or `"gemini"`).

## Data freshness

`Catalog()` never makes a network call — it reads the `registry.json` bundled
with the package (or a previously cached one under `~/.cache/llm_catalogue/`),
so imports stay fast and offline-safe. To pull the latest data from GitHub:

```python
catalog = Catalog(auto_update=True)   # fetch on construction
catalog.refresh()                     # or fetch explicitly, any time
catalog.refresh(force=True)           # bypass the 24h cache TTL
```

`refresh()` never raises — on failure (offline, timeout, bad response) it
leaves the currently loaded data untouched and returns `False`.

## Keeping the bundled registry up to date

The registry is rebuilt from each provider's public pricing docs:

- [Gemini pricing](https://ai.google.dev/gemini-api/docs/pricing.md.txt)
- [Claude pricing](https://platform.claude.com/docs/en/about-claude/pricing.md)
- [OpenAI pricing](https://developers.openai.com/api/docs/pricing.md)

```bash
pip install -e ".[scraper]"
python -m llm_catalogue.scraper
```

This overwrites `src/llm_catalogue/data/registry.json`. Commit the result and
cut a new release so it ships in the next `pip install`.

## Scope and known limitations (v1)

- Only "Standard" tier, text-in/text-out pricing is captured. Batch pricing is
  included where the source table has it; Flex/Priority tiers are not.
- Multimodal, audio, image, video, and embedding-specialist models are out of
  scope — this tracks general-purpose chat/text LLMs.
- `cached_input` is the cache-*read* price. Separate cache-*write* premiums
  (e.g. Anthropic's 5m/1h cache writes, OpenAI's gpt-5.6-family write cost)
  aren't modelled yet.
- `free_tier.rate_limit_rpm` isn't populated — Gemini's free-tier RPM limits
  live on a separate rate-limits doc this scraper doesn't fetch yet.
- Gemini's tiered (>200k token) pricing is captured via `tiered_pricing`;
  OpenAI's `<272K context length` models are recorded with `context_window`
  but don't have a documented over-the-limit rate, so they aren't tiered.

Data last refreshed: 2026-07-26.
