A modern HTTP caching library for Starlette and FastAPI.
Project description
Starcache
A modern, high-performance HTTP caching library for Starlette and FastAPI.
This library was created for self-hosted applications in an air-gapped environment where using third-party caching solutions is not an option. It provides a flexible middleware that can be easily integrated into existing FastAPI or Starlette applications to enable HTTP caching based on standard HTTP caching headers.
Features
- Simple and intuitive API
- Supports custom serializers and cache backends (see examples)
- In-memory caching backend included for development and testing purposes
- Full control over caching behavior via request and response headers
- Public and private caching support
- Supports
Varyresponse headers for caching based on request headers with customizable normalization
Installation
pip install starcache
Usage
- Add the
StarcacheMiddlewareat the start of your middleware stack. If using theadd_middlewareutility, this means registering it last.- Especially make sure to add it before any middleware that adds a
Varyheader to the response, such asGZipMiddleware.
- Especially make sure to add it before any middleware that adds a
- If needed, specify a custom backend and serializer when adding the middleware.
- Configure caching for specific responses by adding appropriate
Cache-Controlheaders. - If your responses change based on the value of a request header, such as
Accept, make sure to include the header's name in theVaryresponse header.
Basic
Basic usecases which only need non-persistent in-memory caching should only be used during development or testing. Below is a simple example of how to use Starcache with FastAPI:
import random
import string
from fastapi import FastAPI, Response
from fastapi.middleware.gzip import GZipMiddleware
from starcache import StarcacheMiddleware
app = FastAPI()
app.add_middleware(GZipMiddleware)
# add gzip middleware first, as well as any other middlewares which add a Vary header.
app.add_middleware(StarcacheMiddleware)
@app.get("/data")
async def get_data(response: Response):
# Opt in to caching for this response by adding the cache-control header
response.headers["Cache-Control"] = "public, max-age=3600"
return {
"random_message": ''.join(random.choices(string.ascii_letters + string.digits, k=32)),
}
Valkey/Redis backend
A common use case is to use Valkey or Redis as the cache backend. Below is an example of how to implement a Redis backend for Starcache using the redis module.
import redis.asyncio as redis
from fastapi import FastAPI
from starcache import StarcacheMiddleware, CacheBackend
class RedisBackend(CacheBackend):
def __init__(self):
# Connect to a localhost redis or valkey server
self.client = aioredis.Redis(host='localhost', port=6379, db=0)
self.ttl = 31536000 # 1 year in seconds
async def get(self, key: str) -> bytes | None:
return await self.client.get(key)
async def set(self, key: str, value: bytes) -> None:
# ttl only effects how long the cache entry is stored
# The actual ttl is done via the cache-control header max-age directive
await self.client.set(key, value, ex=self.ttl)
app = FastAPI()
app.add_middleware(StarcacheMiddleware, backend=RedisBackend())
Vary normalization/deduplication
If your responses vary based on certain request headers, you can configure custom normalization functions for those headers using the vary_normalizers parameter of the StarcacheMiddleware. This is useful for headers like Accept-Encoding and Accept-Language, where you may want to normalize the values to a specific set.
The starcache.vary module provides some built-in normalizers that you can use:
from starlette_compress import CompressMiddleware
from starcache import vary
app.add_middleware(CompressMiddleware)
app.add_middleware(
StarcacheMiddleware,
vary_normalizers={
# Normalize Accept-Encoding to prefer zstd, br, then gzip, ignoring weights.
# This copies the behavior of starlette-compress
"accept-encoding": vary.simple_normalizer(["zstd", "br", "gzip"]),
# Normalize Accept-Language to consider only en, fr, and de with weights
"accept-language": vary.weighted_normalizer(["en", "fr", "de"]),
},
)
Custom normalizers can also be defined as callables that take a header string value and return a normalized string.
def my_custom_normalizer(value: str) -> str:
# Custom normalization logic here
return normalized_value
app.add_middleware(
StarcacheMiddleware,
vary_normalizers={
"my-header": my_custom_normalizer,
},
)
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 starcache-0.1.1.tar.gz.
File metadata
- Download URL: starcache-0.1.1.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
273e800be7f7e6873d968497560483d2f9e1721647f9fd09c02b9cdb9ab42318
|
|
| MD5 |
8fc9a5627de4502aca72254aca99c2eb
|
|
| BLAKE2b-256 |
d5d50d2037c660893ba93fb8da6dd3f91c874a2904a448146c497a7f495d1bdb
|
File details
Details for the file starcache-0.1.1-py3-none-any.whl.
File metadata
- Download URL: starcache-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8d564697a325caad566cda77af47b12a42eb1aaec0467906e632ee2b5b0d64e
|
|
| MD5 |
fbf780291ad1ca93ccd4eba744ac2067
|
|
| BLAKE2b-256 |
40d618fa5840e5417340dd2bb4aa1f13da2d7dc1a946278426abc637f4702a39
|