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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b227e8a73b0408bb2724f8ef9c7d52143616f8206735b133418f071ff1d12d5e
|
|
| MD5 |
85945ddce4d2526cb95f0b3c2383cb30
|
|
| BLAKE2b-256 |
fcda587c2f2b3b211519840d887f3747b141857aed33988e458d1ea4c0d65edb
|
Provenance
The following attestation bundles were made for hawkapi_cache-0.2.0.tar.gz:
Publisher:
release.yml on ashimov/hawkapi-cache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_cache-0.2.0.tar.gz -
Subject digest:
b227e8a73b0408bb2724f8ef9c7d52143616f8206735b133418f071ff1d12d5e - Sigstore transparency entry: 1553516703
- Sigstore integration time:
-
Permalink:
ashimov/hawkapi-cache@84aed125ec08c38de13b4305186850d707fe1e5a -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ashimov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@84aed125ec08c38de13b4305186850d707fe1e5a -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6402b3861b2d49acea682479df9b28b9e88329fe3f7f10ed164b8d06dd452c6c
|
|
| MD5 |
60143e1ea546701fe6b6a2b16323dfe4
|
|
| BLAKE2b-256 |
feea7a23c7ef9989fa3d0ded740453a67b6bb72ef4b1d93e3aba6d1bcceb76a6
|
Provenance
The following attestation bundles were made for hawkapi_cache-0.2.0-py3-none-any.whl:
Publisher:
release.yml on ashimov/hawkapi-cache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_cache-0.2.0-py3-none-any.whl -
Subject digest:
6402b3861b2d49acea682479df9b28b9e88329fe3f7f10ed164b8d06dd452c6c - Sigstore transparency entry: 1553516718
- Sigstore integration time:
-
Permalink:
ashimov/hawkapi-cache@84aed125ec08c38de13b4305186850d707fe1e5a -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ashimov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@84aed125ec08c38de13b4305186850d707fe1e5a -
Trigger Event:
release
-
Statement type: