{"id":13690357,"url":"https://github.com/developmentseed/starlette-cramjam","last_synced_at":"2025-06-23T21:40:55.891Z","repository":{"id":38305283,"uuid":"370870150","full_name":"developmentseed/starlette-cramjam","owner":"developmentseed","description":"Compression middleware based on cramjam for Starlette ASGI framework.","archived":false,"fork":false,"pushed_at":"2025-04-18T13:30:37.000Z","size":57,"stargazers_count":15,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-03T12:13:49.186Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/developmentseed.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-05-26T01:16:20.000Z","updated_at":"2025-06-03T08:58:31.000Z","dependencies_parsed_at":"2025-05-02T06:32:45.940Z","dependency_job_id":"b55e9073-d27f-4fee-a53c-207e351366cf","html_url":"https://github.com/developmentseed/starlette-cramjam","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/developmentseed/starlette-cramjam","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developmentseed%2Fstarlette-cramjam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developmentseed%2Fstarlette-cramjam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developmentseed%2Fstarlette-cramjam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developmentseed%2Fstarlette-cramjam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developmentseed","download_url":"https://codeload.github.com/developmentseed/starlette-cramjam/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developmentseed%2Fstarlette-cramjam/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261561180,"owners_count":23177543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T16:01:04.006Z","updated_at":"2025-06-23T21:40:55.861Z","avatar_url":"https://github.com/developmentseed.png","language":"Python","readme":"# starlette-cramjam\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eCramjam integration for Starlette ASGI framework.\u003c/em\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/developmentseed/starlette-cramjam/actions?query=workflow%3ACI\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://github.com/developmentseed/starlette-cramjam/workflows/CI/badge.svg\" alt=\"Test\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/developmentseed/starlette-cramjam\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://codecov.io/gh/developmentseed/starlette-cramjam/branch/master/graph/badge.svg\" alt=\"Coverage\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/starlette-cramjam\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/pypi/v/starlette-cramjam?color=%2334D058\u0026label=pypi%20package\" alt=\"Package version\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypistats.org/packages/starlette-cramjam\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/pypi/dm/starlette-cramjam.svg\" alt=\"Downloads\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/developmentseed/starlette-cramjam/blob/master/LICENSE\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/license/developmentseed/starlette-cramjam.svg\" alt=\"Downloads\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Source Code**: \u003ca href=\"https://github.com/developmentseed/starlette-cramjam\" target=\"_blank\"\u003ehttps://github.com/developmentseed/starlette-cramjam\u003c/a\u003e\n\n---\n\nThe `starlette-cramjam` middleware aims to provide a unique Compression middleware to support **Brotli**, **GZip**, **Deflate** and **ZSTD** compression algorithms with a minimal requirement.\n\nThe middleware will compress responses for any request that includes \"br\", \"gzip\", \"deflate\" or \"zstd\" in the Accept-Encoding header.\n\nAs for the official `Starlette` middleware, the one provided by `starlette-cramjam` will handle both standard and streaming responses.\n\n`stralette-cramjam` is built on top of [pyrus-cramjam](https://github.com/milesgranger/pyrus-cramjam) an *Extremely thin Python bindings to de/compression algorithms in Rust*.\n\n## Installation\n\nYou can install `starlette-cramjam` from pypi\n\n```python\n$ pip install -U pip\n$ pip install starlette-cramjam\n```\n\nor install from source:\n\n```bash\n$ pip install -U pip\n$ pip install https://github.com/developmentseed/starlette-cramjam.git\n```\n\n## Usage\n\nThe following arguments are supported:\n\n- **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]`,\n- **compression_level** (Integer) - Compression level to use, form `0` (None) to `11` (High). Defaults to cramjam internal defaults for each compression backend.\n- **minimum_size** (Integer) - Do not compress responses that are smaller than this minimum size in bytes. Defaults to `500`.\n- **exclude_path** (Set of string) - Do not compress responses in response to specific `path` requests. Entries have to be valid regex expressions. Defaults to `{}`.\n- **exclude_mediatype** (Set of string) - Do not compress responses of specific media type (e.g `image/png`). Defaults to `{}`.\n\n#### Minimal (defaults) example\n\n```python\nimport uvicorn\n\nfrom starlette.applications import Starlette\nfrom starlette.middleware import Middleware\nfrom starlette.responses import PlainTextResponse\nfrom starlette.routing import Route\n\nfrom starlette_cramjam.middleware import CompressionMiddleware\n\ndef index(request):\n    return PlainTextResponse(\"Hello World\")\n\n\napp = Starlette(\n    routes=[Route(\"/\", endpoint=index)],\n    middleware=[\n        Middleware(CompressionMiddleware),\n    ],\n)\n\nif __name__ == \"__main__\":\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n#### Using options\n\n```python\nimport uvicorn\n\nfrom starlette.applications import Starlette\nfrom starlette.middleware import Middleware\nfrom starlette.responses import PlainTextResponse, Response\nfrom starlette.routing import Route\n\nfrom starlette_cramjam.compression import Compression\nfrom starlette_cramjam.middleware import CompressionMiddleware\n\ndef index(request):\n    return PlainTextResponse(\"Hello World\")\n\ndef img(request):\n    return Response(b\"This is a fake body\", status_code=200, media_type=\"image/jpeg\")\n\ndef foo(request):\n    return PlainTextResponse(\"Do not compress me.\")\n\n\napp = Starlette(\n    routes=[\n        Route(\"/\", endpoint=index),\n        Route(\"/image\", endpoint=img),\n        Route(\"/foo\", endpoint=foo),\n    ],\n    middleware=[\n        Middleware(\n            CompressionMiddleware,\n            compression=[Compression.gzip],  # Only support `gzip`\n            compression_level=6,  # Compression level to use\n            minimum_size=0,  # should compress everything\n            exclude_path={\"^/foo$\"},  # do not compress response for the `/foo` request\n            exclude_mediatype={\"image/jpeg\"},  # do not compress jpeg\n        ),\n    ],\n)\n\nif __name__ == \"__main__\":\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n## Performance\n\n```python\nimport gzip\nimport sys\n\nimport brotli\nimport cramjam\nimport httpx\n\npage = httpx.get(\"https://github.com/developmentseed/starlette-cramjam\").content\n\nlen(page)\n# 347686\n\n%timeit brotli.compress(page, quality=4)\n# 1.77 ms ± 19.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n\nsys.getsizeof(brotli.compress(page, quality=4))\n# 48766\n\n%timeit gzip.compress(page, compresslevel=6)\n# 4.62 ms ± 28 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n\nsys.getsizeof(gzip.compress(page, compresslevel=6))\n# 54888\n\n# ------------\n# With Cramjam\n# ------------\n%timeit cramjam.gzip.compress(page, level=6)\n# 4.12 ms ± 57.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n\ncramjam.gzip.compress(page, level=6).len()\n# 55221\n\n%timeit cramjam.brotli.compress(page, level=4)\n# 2.3 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n\ncramjam.brotli.compress(page, level=4).len()\n# 48742\n```\n\nRef: https://github.com/fullonic/brotli-asgi?tab=readme-ov-file#performance\n\n## Changes\n\nSee [CHANGES.md](https://github.com/developmentseed/starlette-cramjam/blob/master/CHANGES.md).\n\n## Contribution \u0026 Development\n\nSee [CONTRIBUTING.md](https://github.com/developmentseed/starlette-cramjam/blob/master/CONTRIBUTING.md)\n\n## License\n\nSee [LICENSE](https://github.com/developmentseed/starlette-cramjam/blob/master/LICENSE)\n\n## Authors\n\nCreated by [Development Seed](\u003chttp://developmentseed.org\u003e)\n\nSee [contributors](https://github.com/developmentseed/starlette-cramjam/graphs/contributors) for a listing of individual contributors.\n","funding_links":[],"categories":["Extensions"],"sub_categories":["Other","Compression"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopmentseed%2Fstarlette-cramjam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevelopmentseed%2Fstarlette-cramjam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopmentseed%2Fstarlette-cramjam/lists"}