1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
from __future__ import annotations
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, Literal
from litestar.exceptions import ImproperlyConfiguredException
from litestar.middleware.compression import CompressionMiddleware
from litestar.middleware.compression.gzip_facade import GzipCompression
if TYPE_CHECKING:
from litestar.middleware.compression.facade import CompressionFacade
__all__ = ("CompressionConfig",)
@dataclass
class CompressionConfig:
"""Configuration for response compression.
To enable response compression, pass an instance of this class to the :class:`Litestar <.app.Litestar>` constructor
using the ``compression_config`` key.
"""
backend: Literal["gzip", "brotli"] | str
"""The backend to use.
If the value given is `gzip` or `brotli`, then the builtin gzip and brotli compression is used.
"""
minimum_size: int = field(default=500)
"""Minimum response size (bytes) to enable compression, affects all backends."""
gzip_compress_level: int = field(default=9)
"""Range ``[0-9]``, see :doc:`python:library/gzip`."""
brotli_quality: int = field(default=5)
"""Range ``[0-11]``, Controls the compression-speed vs compression-density tradeoff.
The higher the quality, the slower the compression.
"""
brotli_mode: Literal["generic", "text", "font"] = "text"
"""``MODE_GENERIC``, ``MODE_TEXT`` (for UTF-8 format text input, default) or ``MODE_FONT`` (for WOFF 2.0)."""
brotli_lgwin: int = field(default=22)
"""Base 2 logarithm of size.
Range is 10 to 24. Defaults to 22.
"""
brotli_lgblock: Literal[0, 16, 17, 18, 19, 20, 21, 22, 23, 24] = 0
"""Base 2 logarithm of the maximum input block size.
Range is ``16`` to ``24``. If set to ``0``, the value will be set based on the quality. Defaults to ``0``.
"""
brotli_gzip_fallback: bool = True
"""Use GZIP if Brotli is not supported."""
middleware_class: type[CompressionMiddleware] = CompressionMiddleware
"""Middleware class to use, should be a subclass of :class:`CompressionMiddleware`."""
exclude: str | list[str] | None = None
"""A pattern or list of patterns to skip in the compression middleware."""
exclude_opt_key: str | None = None
"""An identifier to use on routes to disable compression for a particular route."""
compression_facade: type[CompressionFacade] = GzipCompression
"""The compression facade to use for the actual compression."""
backend_config: Any = None
"""Configuration specific to the backend."""
gzip_fallback: bool = True
"""Use GZIP as a fallback if the provided backend is not supported by the client."""
def __post_init__(self) -> None:
if self.minimum_size <= 0:
raise ImproperlyConfiguredException("minimum_size must be greater than 0")
if self.backend == "gzip":
if self.gzip_compress_level < 0 or self.gzip_compress_level > 9:
raise ImproperlyConfiguredException("gzip_compress_level must be a value between 0 and 9")
elif self.backend == "brotli":
# Brotli is not guaranteed to be installed.
from litestar.middleware.compression.brotli_facade import BrotliCompression
if self.brotli_quality < 0 or self.brotli_quality > 11:
raise ImproperlyConfiguredException("brotli_quality must be a value between 0 and 11")
if self.brotli_lgwin < 10 or self.brotli_lgwin > 24:
raise ImproperlyConfiguredException("brotli_lgwin must be a value between 10 and 24")
self.gzip_fallback = self.brotli_gzip_fallback
self.compression_facade = BrotliCompression
|