diff --git a/AUTHORS.rst b/AUTHORS.rst index 76d317db..463d543b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -14,3 +14,4 @@ David Zderic / dzderic Kirill Zaitsev / teferi Jon Dufresne Anès Foufa +Segyo Myung \ No newline at end of file diff --git a/README.rst b/README.rst index 8d597df7..03d6cf30 100644 --- a/README.rst +++ b/README.rst @@ -291,6 +291,21 @@ Let see an example, of how make it work with *lzma* compression format: } } +*Gzip* compression support: + +.. code-block:: python + + import gzip + + CACHES = { + "default": { + # ... + "OPTIONS": { + "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor", + } + } + } + Memcached exceptions behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/changelog.d/688.feature b/changelog.d/688.feature new file mode 100644 index 00000000..ca7fe07d --- /dev/null +++ b/changelog.d/688.feature @@ -0,0 +1 @@ +Support gzip compression \ No newline at end of file diff --git a/django_redis/compressors/gzip.py b/django_redis/compressors/gzip.py new file mode 100644 index 00000000..533499f4 --- /dev/null +++ b/django_redis/compressors/gzip.py @@ -0,0 +1,19 @@ +import gzip + +from django_redis.compressors.base import BaseCompressor +from django_redis.exceptions import CompressorError + + +class GzipCompressor(BaseCompressor): + min_length = 15 + + def compress(self, value: bytes) -> bytes: + if len(value) > self.min_length: + return gzip.compress(value) + return value + + def decompress(self, value: bytes) -> bytes: + try: + return gzip.decompress(value) + except gzip.BadGzipFile as e: + raise CompressorError from e diff --git a/setup.cfg b/setup.cfg index 473a71ab..8e474cf9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -91,6 +91,7 @@ commands = {envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_usock {posargs} {envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_zlib {posargs} {envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_zstd {posargs} + {envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_gzip {posargs} {envpython} -m coverage report {envpython} -m coverage xml diff --git a/tests/settings/sqlite_gzip.py b/tests/settings/sqlite_gzip.py new file mode 100644 index 00000000..7ebb1580 --- /dev/null +++ b/tests/settings/sqlite_gzip.py @@ -0,0 +1,41 @@ +SECRET_KEY = "django_tests_secret_key" + +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": ["redis://127.0.0.1:6379?db=1", "redis://127.0.0.1:6379?db=1"], + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor", + }, + }, + "doesnotexist": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": "redis://127.0.0.1:56379?db=1", + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor", + }, + }, + "sample": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": "redis://127.0.0.1:6379?db=1,redis://127.0.0.1:6379?db=1", + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor", + }, + }, + "with_prefix": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": "redis://127.0.0.1:6379?db=1", + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor", + }, + "KEY_PREFIX": "test-prefix", + }, +} + +INSTALLED_APPS = ["django.contrib.sessions"] + +USE_TZ = False