starlette-cramjam
Cramjam integration for Starlette ASGI framework.
Source Code: https://github.com/developmentseed/starlette-cramjam
The starlette-cramjam middleware aims to provide a unique Compression middleware to support Brotli, GZip, Deflate and ZSTD compression algorithms with a minimal requirement.
The middleware will compress responses for any request that includes "br", "gzip", "deflate" or "zstd" in the Accept-Encoding header.
As for the official Starlette middleware, the one provided by starlette-cramjam will handle both standard and streaming responses.
stralette-cramjam is built on top of pyrus-cramjam an Extremely thin Python bindings to de/compression algorithms in Rust.
Installation
You can install starlette-cramjam from pypi
$ pip install -U pip
$ pip install starlette-cramjam
or install from source:
$ pip install -U pip
$ pip install https://github.com/developmentseed/starlette-cramjam.git
Usage
The following arguments are supported:
- compression (List of Compression) - List of available compression algorithm. This list also defines the order of preference. Defaults to
[Compression.gzip, Compression.deflate, Compression.br, Compression.zstd], - compression_level (Integer) - Compression level to use, form
0(None) to11(High). Defaults to cramjam internal defaults for each compression backend. - minimum_size (Integer) - Do not compress responses that are smaller than this minimum size in bytes. Defaults to
500. - exclude_path (Set of string) - Do not compress responses in response to specific
pathrequests. Entries have to be valid regex expressions. Defaults to{}. - exclude_mediatype (Set of string) - Do not compress responses of specific media type (e.g
image/png). Defaults to{}.
Minimal (defaults) example
import uvicorn
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.responses import PlainTextResponse
from starlette.routing import Route
from starlette_cramjam.middleware import CompressionMiddleware
def index(request):
return PlainTextResponse("Hello World")
app = Starlette(
routes=[Route("/", endpoint=index)],
middleware=[
Middleware(CompressionMiddleware),
],
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Using options
import uvicorn
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.responses import PlainTextResponse, Response
from starlette.routing import Route
from starlette_cramjam.compression import Compression
from starlette_cramjam.middleware import CompressionMiddleware
def index(request):
return PlainTextResponse("Hello World")
def img(request):
return Response(b"This is a fake body", status_code=200, media_type="image/jpeg")
def foo(request):
return PlainTextResponse("Do not compress me.")
app = Starlette(
routes=[
Route("/", endpoint=index),
Route("/image", endpoint=img),
Route("/foo", endpoint=foo),
],
middleware=[
Middleware(
CompressionMiddleware,
compression=[Compression.gzip], # Only support `gzip`
compression_level=6, # Compression level to use
minimum_size=0, # should compress everything
exclude_path={"^/foo$"}, # do not compress response for the `/foo` request
exclude_mediatype={"image/jpeg"}, # do not compress jpeg
),
],
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Performance
import gzip
import sys
import brotli
import cramjam
import httpx
page = httpx.get("https://github.com/developmentseed/starlette-cramjam").content
len(page)
# 347686
%timeit brotli.compress(page, quality=4)
# 1.77 ms ± 19.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
sys.getsizeof(brotli.compress(page, quality=4))
# 48766
%timeit gzip.compress(page, compresslevel=6)
# 4.62 ms ± 28 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
sys.getsizeof(gzip.compress(page, compresslevel=6))
# 54888
# ------------
# With Cramjam
# ------------
%timeit cramjam.gzip.compress(page, level=6)
# 4.12 ms ± 57.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cramjam.gzip.compress(page, level=6).len()
# 55221
%timeit cramjam.brotli.compress(page, level=4)
# 2.3 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cramjam.brotli.compress(page, level=4).len()
# 48742
Ref: https://github.com/fullonic/brotli-asgi?tab=readme-ov-file#performance
Changes
See CHANGES.md.
Contribution & Development
See CONTRIBUTING.md
License
See LICENSE
Authors
Created by Development Seed
See contributors for a listing of individual contributors.
Metadata
Release files for starlette-cramjam 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| starlette_cramjam-0.7.0.tar.gz | 7.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| starlette_cramjam-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.7 kB
Release files / starlette_cramjam-0.7.0.tar.gz
| Download URL | starlette_cramjam-0.7.0.tar.gz |
|---|---|
| Size | 7.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
38a70bea50d2fce91eb43acbddd544c1c7d4b5de4b26a482472d7dc142024edd
|
|
BLAKE2b-256 checksum How to use checksums |
a58379d2060127c8158849f375a21adf4116639d4829b84bbca598514a2ca871
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency logRelease files / starlette_cramjam-0.7.0-py3-none-any.whl
| Download URL | starlette_cramjam-0.7.0-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0754bd582aa5cdd7d2e9982ea0bd9c78521583099590971e9cf0482fe26b8a4
|
|
BLAKE2b-256 checksum How to use checksums |
a01f7611cb364b60e69f50afd6b5a5dc336c24450d6a1ed87431d944700b834c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency log