Skip to main content

Cramjam integration for Starlette ASGI framework.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starlette_cramjam-0.5.0.tar.gz (8.0 kB view details)

Uploaded Source

Built Distribution

starlette_cramjam-0.5.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file starlette_cramjam-0.5.0.tar.gz.

File metadata

  • Download URL: starlette_cramjam-0.5.0.tar.gz
  • Upload date:
  • Size: 8.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.3

File hashes

Hashes for starlette_cramjam-0.5.0.tar.gz
Algorithm Hash digest
SHA256 b42ed3adb0da9c71f5d10915164404382e4a72133c77266910323865cce37c1a
MD5 499b2600184a35e85bd93b4c69fcd6e4
BLAKE2b-256 cffc0e3c2fda8bdec84f542ef107d9ec95ff264bb3146675047f3e99661f3d92

See more details on using hashes here.

File details

Details for the file starlette_cramjam-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for starlette_cramjam-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b9fed2c3de5b9b88ac910c92b7ea5265621967d4062d20453553928b841e591d
MD5 895e7ba23609dfc2a69745255627ff78
BLAKE2b-256 bcd6dc0827918b19c836afd58904c8b856b9bba18b4a0ce0b4866f8f6b4cb42b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page