Skip to main content

starlette-cramjam

Cramjam integration for Starlette ASGI framework.

Test Coverage Package version Downloads Downloads


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) to 11 (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 path requests. 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)

Source distribution for starlette-cramjam 0.7.0
File Size Uploaded
starlette_cramjam-0.7.0.tar.gz 7.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for starlette-cramjam 0.7.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

1 release file

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