Skip to main content

An httpx client with persistent caching and rate limiting for data pipelines

Project description

httpx-frugal

An httpx client with persistent caching (hishel) and per-domain rate limiting (pyrate-limiter), designed for data pipelines that need to conserve API quota across process restarts.

Cache is checked before rate limiting, so cached responses do not consume rate-limit tokens.

Install

pip install httpx-frugal

Optional extras:

pip install httpx-frugal[http2]   # HTTP/2 inner transport

Quickstart (sync)

import pathlib

from pyrate_limiter import Duration, Rate

from httpx_frugal import RateLimitedCacheClient

rates = [Rate(5, Duration.MINUTE)]
cache_db = pathlib.Path("~/.cache/myapp/http-cache.sqlite").expanduser()
rate_db = pathlib.Path("~/.cache/myapp/rate-limiter.sqlite").expanduser()
cache_db.parent.mkdir(parents=True, exist_ok=True)
rate_db.parent.mkdir(parents=True, exist_ok=True)

client_wrapper = RateLimitedCacheClient(
    rates=rates,
    cache_db_path=cache_db,
    rate_limiter_db_path=rate_db,
)

if client_wrapper.would_hit_cache("https://api.example.com/data"):
    print("served from cache on next request")

with client_wrapper as client:
    response = client.get("https://api.example.com/data")
    print(response.extensions.get("hishel_from_cache"))

Async

from httpx_frugal import AsyncRateLimitedCacheClient

async with AsyncRateLimitedCacheClient(
    rates=rates,
    cache_db_path=cache_db,
    rate_limiter_db_path=rate_db,
) as client:
    response = await client.get("https://api.example.com/data")

Blocking mode

Wait for a rate-limit token instead of raising immediately:

client_wrapper = RateLimitedCacheClient(
    rates=rates,
    cache_db_path=cache_db,
    rate_limiter_db_path=rate_db,
    blocking=True,
    rate_limit_timeout_seconds=30.0,
)

Per-request cache TTL

Override TTL for a single request via httpx extensions:

with client_wrapper as client:
    client.get("https://api.example.com/short-lived", extensions={"hishel_ttl": 60})

Or use the helper:

from httpx_frugal import request_with_ttl

with client_wrapper as client:
    req = request_with_ttl(client, "GET", "https://api.example.com/x", ttl=120)
    client.send(req)

Rate limit introspection

remaining = client_wrapper.tokens_available("api.example.com")
# e.g. {"5/60000s": 3}

Cache invalidation

client_wrapper.clear_cache()                    # all entries
client_wrapper.clear_cache_for("https://...")  # one URL
client_wrapper.clear_rate_limiter()            # reset tokens

Multi-process pipelines

Enable SQLite file locking on the rate limiter bucket:

RateLimitedCacheClient(..., use_file_lock=True)

would_hit_cache caveat

would_hit_cache() uses hishel internal APIs and may break if hishel changes them. Prefer checking response.extensions["hishel_from_cache"] after requests when possible. httpx-frugal pins hishel>=1.2,<2.

Development

uv sync
uv run ruff check .
uv run pytest

License

MIT

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

httpx_frugal-0.2.1.tar.gz (49.8 kB view details)

Uploaded Source

Built Distribution

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

httpx_frugal-0.2.1-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

Details for the file httpx_frugal-0.2.1.tar.gz.

File metadata

  • Download URL: httpx_frugal-0.2.1.tar.gz
  • Upload date:
  • Size: 49.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for httpx_frugal-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ea9d8e04b399ac237f10616ec4f6afb2612735afae6ab5cb20107c034b2c9e99
MD5 d6dbfe0b41ecf6f488ab5d81a5c516af
BLAKE2b-256 3c339ee63e8dc3bd8e03ce4b1b5281557fa9b8dd0c3e3b62fe66071c6952588f

See more details on using hashes here.

File details

Details for the file httpx_frugal-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: httpx_frugal-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for httpx_frugal-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1851e437bf471fc23df336a048757a0033c15a57c362e72b04d2b163e3b12e06
MD5 ff925de823ccac678d604b86ade51e6a
BLAKE2b-256 658cabd2d99e899e7b94168c1f3e5c5f63fe94f33fb47a69ddabaa36193f4ef1

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