Skip to main content

parry

Zero-config rate limiting, caching, and cost control for LLM calls.

One line to install. No rewrites. Works with OpenAI, Anthropic, LangChain and LlamaIndex.

CI Python License

Documentation: www.anshumanbuilds.dev/parry

Drop parry in front of any OpenAI or Anthropic client and get response caching, per-model rate limiting, cost tracking, budget limits and retry with backoff. You don't configure anything or change your call sites, and it doesn't lock you into its own SDK. The hot path (hashing, LRU cache, token buckets, the pricing ledger) is Rust, exposed through PyO3.

Install

pip install llm-parry

The package is published as llm-parry; you import it as parry. Wheels are abi3, so one wheel per platform covers Python 3.10 – 3.14.

From source (needs a Rust toolchain):

pip install "git+https://github.com/IND-Anshuman/parry.git"

Quickstart

import parry
import openai

parry.install()  # ← this is the only line you add

client = openai.OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)
# ↑ cached, rate-limited, cost-tracked, retried on transient failure

print(parry.stats())
# ParryStats(cache_hits=0, cache_misses=1, tokens_cached=0, total_cost_usd=0.000043, ...)

Run the same request again and it comes back from memory: no network round trip and no cost.

What you get for free

  • ✅ Response caching: identical requests are served from an in-memory LRU (10,000 entries, 1 h TTL by default).
  • ✅ Per-model rate limiting: a token bucket per provider:model. The defaults match the providers' published tier-1 limits.
  • ✅ Cost tracking: per session and per model, and per day and lifetime when you turn on SQLite storage.
  • ✅ Hard budget limits: max_cost_usd=10 raises parry.BudgetExceeded before the request that would cross the limit is sent.
  • ✅ Retry with exponential backoff and jitter on 429s, timeouts, connection errors, 5xx and overload. It honours Retry-After and never retries 400/401/403/404.
  • ✅ Streaming: streams pass through untouched, are metered, and the assembled result is cached for the next non-streaming call.
  • ✅ Sync and async clients, .with_raw_response, the OpenAI Responses API, and Anthropic beta.messages.
  • ✅ LangChain and LlamaIndex: both work through install(), and both also have callback handlers.

Before / after

Before, every script reinvents the same thing:

for attempt in range(5):
    try:
        if prompt in my_cache:
            return my_cache[prompt]
        time.sleep(my_rate_limiter.wait_time("gpt-4o"))
        r = client.chat.completions.create(model="gpt-4o", messages=msgs)
        my_spend += r.usage.prompt_tokens * 2.5e-6 + r.usage.completion_tokens * 1e-5
        if my_spend > BUDGET:
            raise RuntimeError("over budget")
        my_cache[prompt] = r
        return r
    except openai.RateLimitError:
        time.sleep(2 ** attempt)

After:

parry.install(max_cost_usd=10)
r = client.chat.completions.create(model="gpt-4o", messages=msgs)

When to use parry

  1. Iterating on prompts and pipelines. Re-running a notebook or an eval script stops re-paying for every unchanged call.
  2. Batch jobs that hit 429s. The token bucket spaces requests out before the provider rejects them, and retries absorb the 429s that still happen.
  3. Agents and RAG apps with a spend ceiling. max_cost_usd is a hard stop, and parry.stats() tells you where the money went, model by model.

When NOT to use parry

  • Multi-process or multi-host deployments. The cache and rate limiter live in one process. Use a shared cache and an API gateway instead.
  • High-concurrency distributed systems. Limits are per process, not coordinated across replicas.
  • When you need sampled outputs to vary. Identical requests return the same cached answer even at temperature=1. Turn caching off with parry.install(cache=False) or with parry.bypass():.

Configuration

from parry import Parry

guard = Parry(
    cache=True,              # response cache
    rate_limit=True,         # per-model token buckets
    cost_tracking=True,      # accumulate spend
    retry=True,              # retry transient failures
    max_cost_usd=10.0,       # hard stop (default: None)
    cache_ttl=3600,          # seconds (None = no expiry, still size-bounded)
    cache_size=10_000,       # entries; the cache is always bounded
    on_rate_limit="wait",    # or "raise" → parry.RateLimited
    max_wait=60.0,           # longest parry will wait for a rate-limit slot
    max_attempts=3,          # total attempts per request, including the first
    storage="parry.db",      # optional SQLite persistence (cache + ledger)
)
guard.set_rate_limit("gpt-4o", requests_per_minute=60)
guard.set_rate_limit("gpt-4o-mini", requests_per_minute=500, tokens_per_minute=200_000)
guard.set_pricing("my-finetune", input_per_million=3.0, output_per_million=12.0)

parry.install(guard)        # whole process
with guard:                 # ...or just this block
    ...
guard.wrap(client)          # ...or just this client

print(guard.stats.summary())

Every option, default and failure mode is documented in docs/configuration.md.

Integrations

LangChain. ChatOpenAI and ChatAnthropic call the official SDKs underneath, so parry.install() covers them, caching included:

import parry
from langchain_openai import ChatOpenAI

parry.install()
llm = ChatOpenAI(model="gpt-4o-mini")
llm.invoke("What is a token bucket?")   # second identical call is a cache hit

If you'd rather not hook the SDK globally, add the callback. It does rate limiting, budget enforcement and cost tracking, but not caching, because LangChain callbacks can't return a response:

from parry import Parry
from parry.integrations.langchain import ParryCallback

guard = Parry(max_cost_usd=5)
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[ParryCallback(guard)])

LlamaIndex.

from llama_index.core import Settings
from llama_index.core.callbacks import CallbackManager
from parry.integrations.llamaindex import ParryHandler

Settings.callback_manager = CallbackManager([ParryHandler(guard)])

More detail is in docs/integrations.md.

Benchmarks

Measured with benches/overhead_bench.py, which drives the real OpenAI SDK through an in-memory HTTP transport. No network is involved, so the difference between rows is parry's own cost. Release build:

Path Time per call parry overhead
Unguarded SDK call (baseline, in-memory transport) 604 µs —
Guarded, cache miss 669 µs +65 µs (0.065 ms)
Guarded, cache hit (no HTTP at all) 10 µs 0.02× the baseline

Linux x86_64, Python 3.13.5, openai 2.54.0, median of 5 batches of 1000 calls.

How it works

parry.install() replaces create on the SDK resource classes (openai.resources.chat.completions.Completions, ...Responses, anthropic.resources.messages.Messages and their async twins) with a thin hook. On each call the hook finds the active guard and runs:

cache lookup → budget pre-check → rate-limit acquire → original create (with retry) → record cost → store in cache

With no active guard, the hook calls the original method directly. See docs/architecture.md.

License

MIT. See LICENSE.

Metadata

Release files for llm-parry 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llm-parry 0.1.0
File Size Uploaded Provenance
llm_parry-0.1.0.tar.gz 189.8 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for llm-parry 0.1.0
File
llm_parry-0.1.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
llm_parry-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
llm_parry-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
llm_parry-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
llm_parry-0.1.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
llm_parry-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 22.5 MB

Release files / llm_parry-0.1.0.tar.gz

Download URL llm_parry-0.1.0.tar.gz
Size 189.8 kB
Tags Source
SHA-256 checksum
How to use checksums
073aaf950355e61aa8c7e971f96766c2c9c6ad07177640f47927dba1cd3ea5be
BLAKE2b-256 checksum
How to use checksums
6ea27617795911c5634a36db1fe51bcafac3c9fd08d07287e4c938319039cca8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-win_amd64.whl

Download URL llm_parry-0.1.0-cp310-abi3-win_amd64.whl
Size 3.7 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
589ea0d0954d99815b26210cce831bc3a78dfe27cba0a294c17636b6b801bf25
BLAKE2b-256 checksum
How to use checksums
2d798cff4c5915e0bd3553b6b5a9fc26395517c0bff8e49b8b6a7eeb39d3b8ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL llm_parry-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl
Size 4.0 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
6df7f6307f4205d1aa5dd22718f6e906546479c4f7615edcdea1d14cefb0afe7
BLAKE2b-256 checksum
How to use checksums
29375d1f53e73dfa1f77b57b5ff45696cfa3176a75fbf7a9f0165be2a8af7edf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL llm_parry-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
c87cd7d7bbde23d90571bcbb49b8228967ec537d8cfbe3ba995164eddd13307e
BLAKE2b-256 checksum
How to use checksums
576343e31c59669593d6ec87daf33f0da048ca1abd6c55b3f927d119771852f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL llm_parry-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.7 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
dd42ef2bd0be941f1d4d30b7b8defd2b1728f5fd9031416fbc1a16827b88ac7b
BLAKE2b-256 checksum
How to use checksums
c03d91fb7aa060500d12bb1afe69a897541ee0653b183b16931fdf094cef4838
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL llm_parry-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Size 3.6 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cb2a6d69f2aa7be0facfe2f537b17d4cc96a900c06bd819130e0417d027a5d21
BLAKE2b-256 checksum
How to use checksums
545a96901b563e96e735a154bcf9dfd43c108c040bd2c6ef1e205c2dfddc0e76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / llm_parry-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL llm_parry-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 3.7 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
0826fdb0f7308343e826f15c896703b6f47551700daf2cd32af611533d2ce52b
BLAKE2b-256 checksum
How to use checksums
6ace52fb06b84576d247824e43f4f69d76f570abf3fd3e3a6a4ceb197395cac1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for llm-parry 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 7 files in this release have been uploaded with provenance metadata.

Select from 7 files

Attestation for llm_parry-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

7 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page