Skip to content

Commit a0c6f38

Browse files
committed
refractor: update docs + lint code
1 parent 5a4eb90 commit a0c6f38

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

docs/middleware.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,27 @@ The following arguments are supported:
230230

231231
* `minimum_size` - Do not GZip responses that are smaller than this minimum size in bytes. Defaults to `500`.
232232
* `compresslevel` - Used during GZip compression. It is an integer ranging from 1 to 9. Defaults to `9`. Lower value results in faster compression but larger file sizes, while higher value results in slower compression but smaller file sizes.
233+
* `excluded_content_types` - A tuple of content type prefixes that should not be compressed. Defaults to `("text/event-stream", "application/zip", "application/gzip", "application/x-gzip", "image/", "video/", "audio/")`. You can customize this to add or remove content types as needed.
233234

234-
The middleware won't GZip responses that already have either a `Content-Encoding` set, to prevent them from
235-
being encoded twice, or a `Content-Type` set to `text/event-stream`, to avoid compressing server-sent events.
235+
The middleware won't GZip responses that:
236+
237+
* Already have a `Content-Encoding` set, to prevent them from being encoded twice
238+
* Have a `Content-Type` that starts with any of the prefixes in `excluded_content_types`
239+
240+
By default, the following content types are excluded:
241+
242+
* `text/event-stream` - Server-sent events should not be compressed
243+
* Already compressed formats: `application/zip`, `application/gzip`, `application/x-gzip`
244+
* Media files: `image/*`, `video/*`, `audio/*` (any image, video, or audio format)
245+
246+
### Customizing excluded content types
247+
248+
You can provide your own list of excluded content types:
249+
```python
250+
middleware = [
251+
Middleware(GZipMiddleware, minimum_size=1000, compresslevel=9, excluded_content_types=("text/event-stream", "image/"))
252+
]
253+
```
236254

237255
## BaseHTTPMiddleware
238256

starlette/middleware/gzip.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@
77

88

99
class GZipMiddleware:
10-
def __init__(self, app: ASGIApp, minimum_size: int = 500, compresslevel: int = 9, excluded_content_types: tuple[str, ...] = (
10+
def __init__(
11+
self,
12+
app: ASGIApp,
13+
minimum_size: int = 500,
14+
compresslevel: int = 9,
15+
excluded_content_types: tuple[str, ...] = (
1116
"text/event-stream",
1217
"application/zip",
1318
"application/gzip",
1419
"application/x-gzip",
1520
"image/",
1621
"video/",
1722
"audio/",
18-
)) -> None:
23+
),
24+
) -> None:
1925
self.app = app
2026
self.minimum_size = minimum_size
2127
self.compresslevel = compresslevel
@@ -29,7 +35,9 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
2935
headers = Headers(scope=scope)
3036
responder: ASGIApp
3137
if "gzip" in headers.get("Accept-Encoding", ""):
32-
responder = GZipResponder(self.app, self.minimum_size, self.excluded_content_types, compresslevel=self.compresslevel)
38+
responder = GZipResponder(
39+
self.app, self.minimum_size, self.excluded_content_types, compresslevel=self.compresslevel
40+
)
3341
else:
3442
responder = IdentityResponder(self.app, self.minimum_size, self.excluded_content_types)
3543

@@ -39,7 +47,12 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
3947
class IdentityResponder:
4048
content_encoding: str
4149

42-
def __init__(self, app: ASGIApp, minimum_size: int, excluded_content_types: tuple[str, ...],) -> None:
50+
def __init__(
51+
self,
52+
app: ASGIApp,
53+
minimum_size: int,
54+
excluded_content_types: tuple[str, ...],
55+
) -> None:
4356
self.app = app
4457
self.minimum_size = minimum_size
4558
self.send: Send = unattached_send
@@ -62,8 +75,7 @@ async def send_with_compression(self, message: Message) -> None:
6275
headers = Headers(raw=self.initial_message["headers"])
6376
self.content_encoding_set = "content-encoding" in headers
6477
self.content_type_is_excluded = any(
65-
headers.get("content-type", "").startswith(ct)
66-
for ct in self.excluded_content_types
78+
headers.get("content-type", "").startswith(ct) for ct in self.excluded_content_types
6779
)
6880
elif message_type == "http.response.body" and (self.content_encoding_set or self.content_type_is_excluded):
6981
if not self.started:
@@ -130,7 +142,9 @@ def apply_compression(self, body: bytes, *, more_body: bool) -> bytes:
130142
class GZipResponder(IdentityResponder):
131143
content_encoding = "gzip"
132144

133-
def __init__(self, app: ASGIApp, minimum_size: int, excluded_content_types: tuple[str, ...], compresslevel: int = 9) -> None:
145+
def __init__(
146+
self, app: ASGIApp, minimum_size: int, excluded_content_types: tuple[str, ...], compresslevel: int = 9
147+
) -> None:
134148
super().__init__(app, minimum_size, excluded_content_types)
135149

136150
self.gzip_buffer = io.BytesIO()

tests/middleware/test_gzip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from starlette.middleware import Middleware
99
from starlette.middleware.gzip import GZipMiddleware
1010
from starlette.requests import Request
11-
from starlette.responses import ContentStream, FileResponse, PlainTextResponse, StreamingResponse, Response
11+
from starlette.responses import ContentStream, FileResponse, PlainTextResponse, Response, StreamingResponse
1212
from starlette.routing import Route
1313
from starlette.types import Message
1414
from tests.types import TestClientFactory

0 commit comments

Comments
 (0)