Skip to main content

Response caching for HawkAPI — decorator + middleware + Redis/memory backends + tag-based invalidation

Project description

hawkapi-cache

Response caching for HawkAPI — decorator + middleware + Redis/memory backends + tag-based invalidation.

Install

pip install hawkapi-cache              # memory backend
pip install hawkapi-cache[redis]       # + Redis backend

Quickstart

from hawkapi import HawkAPI, Request
from hawkapi_cache import init_cache, cache, RedisCacheBackend

app = HawkAPI()
init_cache(app, backend=RedisCacheBackend.from_url("redis://localhost:6379/0"))

@app.get("/users/{user_id:int}")
@cache(ttl=60, tags=["users", "user:{user_id}"])
async def get_user(request: Request, user_id: int):
    return await db.fetch_user(user_id)

@app.post("/users/{user_id:int}/refresh")
async def refresh(request: Request, user_id: int):
    await app.state.cache.invalidate_tags([f"user:{user_id}"])
    return {"ok": True}

In-memory is the default (no Redis required):

from hawkapi_cache import init_cache
init_cache(app)   # MemoryCacheBackend(max_size=10_000)

@cache(...) reference

Arg Default Notes
ttl 60 Seconds.
tags () Group invalidation. {name} placeholders pulled from path params.
vary () Request headers that change the response. Values appended to the cache key.
key_func None (Request) -> str override. Replaces the default key entirely.
condition None (Request) -> bool — return False to bypass cache.

Only GET / HEAD requests with 2xx responses are cached. Other methods and non-2xx responses pass through.

Every cached response gets an X-Cache: HIT or X-Cache: MISS header.

Recipes

Per-user cache via vary

@cache(ttl=60, vary=("authorization",))
async def me(request: Request):
    ...

Bypass cache for authenticated users

@cache(ttl=60, condition=lambda r: not r.headers.get("authorization"))
async def feed(request: Request):
    ...

Tag-driven invalidation

@cache(ttl=300, tags=["posts", "post:{post_id}"])
async def get_post(request: Request, post_id: int): ...

@app.put("/posts/{post_id:int}")
async def update(request: Request, post_id: int):
    ...
    await app.state.cache.invalidate_tags([f"post:{post_id}"])

Custom key

@cache(ttl=60, key_func=lambda r: f"my:{r.url.path}:{r.headers.get('x-tenant')}")
async def list_orders(request: Request): ...

Backends

MemoryCacheBackend(max_size=10_000)

LRU + per-key TTL, single-process. Use for tests and small deployments.

RedisCacheBackend.from_url("redis://host/0", prefix="hawkapi-cache:")

Multi-process safe. Tag index uses Redis SETs; invalidate_tags is a pipelined SUNION + DEL. Add hawkapi-cache[redis] extra.

Development

git clone https://github.com/ashimov/hawkapi-cache.git
cd hawkapi-cache
uv sync --extra dev
uv run pytest -q
uv run ruff check . && uv run ruff format --check .
uv run pyright src/

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

hawkapi_cache-0.2.0.tar.gz (30.2 kB view details)

Uploaded Source

Built Distribution

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

hawkapi_cache-0.2.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file hawkapi_cache-0.2.0.tar.gz.

File metadata

  • Download URL: hawkapi_cache-0.2.0.tar.gz
  • Upload date:
  • Size: 30.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hawkapi_cache-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b227e8a73b0408bb2724f8ef9c7d52143616f8206735b133418f071ff1d12d5e
MD5 85945ddce4d2526cb95f0b3c2383cb30
BLAKE2b-256 fcda587c2f2b3b211519840d887f3747b141857aed33988e458d1ea4c0d65edb

See more details on using hashes here.

Provenance

The following attestation bundles were made for hawkapi_cache-0.2.0.tar.gz:

Publisher: release.yml on ashimov/hawkapi-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hawkapi_cache-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: hawkapi_cache-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hawkapi_cache-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6402b3861b2d49acea682479df9b28b9e88329fe3f7f10ed164b8d06dd452c6c
MD5 60143e1ea546701fe6b6a2b16323dfe4
BLAKE2b-256 feea7a23c7ef9989fa3d0ded740453a67b6bb72ef4b1d93e3aba6d1bcceb76a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for hawkapi_cache-0.2.0-py3-none-any.whl:

Publisher: release.yml on ashimov/hawkapi-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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