Skip to main content

Starcache

PyPI version Tests Code Coverage

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 Vary response headers for caching based on request headers with customizable normalization

Installation

pip install starcache

Usage

  1. Add the StarcacheMiddleware at the start of your middleware stack. If using the add_middleware utility, this means registering it last.
    • Especially make sure to add it before any middleware that adds a Vary header to the response, such as GZipMiddleware.
  2. If needed, specify a custom backend and serializer when adding the middleware.
  3. Configure caching for specific responses by adding appropriate Cache-Control headers.
  4. If your responses change based on the value of a request header, such as Accept, make sure to include the header's name in the Vary response 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,
    },
)

Metadata

Release files for starcache 0.1.1

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

Source distribution (sdist)

Source distribution for starcache 0.1.1
File Size Uploaded Provenance
starcache-0.1.1.tar.gz 9.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for starcache 0.1.1
File Interpreter ABI Platform
starcache-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 21.6 kB

Release files / starcache-0.1.1.tar.gz

Download URL starcache-0.1.1.tar.gz
Size 9.8 kB
Tags Source
SHA-256 checksum
How to use checksums
273e800be7f7e6873d968497560483d2f9e1721647f9fd09c02b9cdb9ab42318
BLAKE2b-256 checksum
How to use checksums
d5d50d2037c660893ba93fb8da6dd3f91c874a2904a448146c497a7f495d1bdb
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / starcache-0.1.1-py3-none-any.whl

Download URL starcache-0.1.1-py3-none-any.whl
Size 11.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8d564697a325caad566cda77af47b12a42eb1aaec0467906e632ee2b5b0d64e
BLAKE2b-256 checksum
How to use checksums
40d618fa5840e5417340dd2bb4aa1f13da2d7dc1a946278426abc637f4702a39
Upload date
Uploaded using Trusted Publishing?
What is 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}

Security for starcache 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No 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