Cramjam integration for Starlette ASGI framework.
Project description
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 and Deflate compression algorithms with a minimal requirement.
The middleware will compress responses for any request that includes "br", "gzip" or "deflate" 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_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
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
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
File details
Details for the file starlette_cramjam-0.4.0.tar.gz
.
File metadata
- Download URL: starlette_cramjam-0.4.0.tar.gz
- Upload date:
- Size: 7.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.32.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | bd36e68109b13c29d1e7aa0ddb7eaf614bfd144be99d8dcb5ece95c96dbcec17 |
|
MD5 | d803984a285661fe1ea1827549dafd2c |
|
BLAKE2b-256 | 2b054a478b9d43b73496b2f22b9af8239902065f1e1cd39d7f98cf269f776041 |
Provenance
File details
Details for the file starlette_cramjam-0.4.0-py3-none-any.whl
.
File metadata
- Download URL: starlette_cramjam-0.4.0-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.32.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c1943087641c8ed5a08fc166664875a1f44c6f1de4301ed21f23a261df821c1b |
|
MD5 | 416ab0dc7720fbe17966e40cb87957ea |
|
BLAKE2b-256 | ca46de94ca00de3505c2d7b802ac5e581eef1fb0b3039966d7655aa7b53f6821 |