From c5702753872c361fd480fb2703dafb3edd5b37c5 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 16:39:31 +0200 Subject: [PATCH] Add and configure django-storages --- .env.example | 11 +++++++++++ pyproject.toml | 1 + src/servala/settings.py | 33 +++++++++++++++++++++++++++++++++ uv.lock | 14 ++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/.env.example b/.env.example index 829b56e..13c1e64 100644 --- a/.env.example +++ b/.env.example @@ -47,3 +47,14 @@ SERVALA_DEFAULT_ORIGIN='1' SERVALA_KEYCLOAK_CLIENT_ID='portal.servala.com' SERVALA_KEYCLOAK_CLIENT_SECRET='' SERVALA_KEYCLOAK_SERVER_URL='' + +# S3 Storage settings (optional, for using S3 compatible storage for media files) +# If these are set, Django will use S3 for default file storage. +# Defaults are indicated if any. +# SERVALA_STORAGE_BUCKET_NAME='' +# SERVALA_S3_ENDPOINT_URL='' +# SERVALA_ACCESS_KEY_ID='' +# SERVALA_SECRET_ACCESS_KEY='' +# SERVALA_S3_REGION_NAME='eu-central-1' +# SERVALA_S3_ADDRESSING_STYLE='virtual' +# SERVALA_S3_SIGNATURE_VERSION='s3v4' diff --git a/pyproject.toml b/pyproject.toml index c8d634f..740bb70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ dependencies = [ "django-allauth>=65.5.0", "django-fernet-encrypted-fields>=0.3.0", "django-scopes>=2.0.0", + "django-storages>=1.14.6", "django-template-partials>=24.4", "jsonschema>=4.23.0", "kubernetes>=32.0.1", diff --git a/src/servala/settings.py b/src/servala/settings.py index 50b0c5e..c5905c2 100644 --- a/src/servala/settings.py +++ b/src/servala/settings.py @@ -87,6 +87,39 @@ SOCIALACCOUNT_PROVIDERS = { } } + +SERVALA_STORAGE_BUCKET_NAME = os.environ.get("SERVALA_STORAGE_BUCKET_NAME") +SERVALA_S3_ENDPOINT_URL = os.environ.get("SERVALA_S3_ENDPOINT_URL") +SERVALA_ACCESS_KEY_ID = os.environ.get("SERVALA_ACCESS_KEY_ID") +SERVALA_SECRET_ACCESS_KEY = os.environ.get("SERVALA_SECRET_ACCESS_KEY") +SERVALA_S3_REGION_NAME = os.environ.get("SERVALA_S3_REGION_NAME", "eu-central-1") +SERVALA_S3_ADDRESSING_STYLE = os.environ.get("SERVALA_S3_ADDRESSING_STYLE", "virtual") +SERVALA_S3_SIGNATURE_VERSION = os.environ.get("SERVALA_S3_SIGNATURE_VERSION", "s3v4") + +# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html +if all( + [ + SERVALA_STORAGE_BUCKET_NAME, + SERVALA_S3_ENDPOINT_URL, + SERVALA_ACCESS_KEY_ID, + SERVALA_SECRET_ACCESS_KEY, + ] +): + STORAGES = { + "default": { + "BACKEND": "storages.backends.s3.S3Storage", + "OPTIONS": { + "bucket_name": SERVALA_STORAGE_BUCKET_NAME, + "endpoint_url": SERVALA_S3_ENDPOINT_URL, + "access_key": SERVALA_ACCESS_KEY_ID, + "secret_key": SERVALA_SECRET_ACCESS_KEY, + "region_name": SERVALA_S3_REGION_NAME, + "addressing_style": SERVALA_S3_ADDRESSING_STYLE, + "signature_version": SERVALA_S3_SIGNATURE_VERSION, + }, + } + } + ####################################### # Non-configurable settings below # ####################################### diff --git a/uv.lock b/uv.lock index 461187f..f2e6662 100644 --- a/uv.lock +++ b/uv.lock @@ -336,6 +336,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/3d/94d82839c111a36145b5ec1fb407a85f9a460af5974a07f4c6d3cc414358/django_scopes-2.0.0-py3-none-any.whl", hash = "sha256:9cf521b4d543ffa2ff6369fb5a1dda03567e862ba89626c01405f3d93ca04724", size = 16660, upload-time = "2023-04-22T17:08:45.058Z" }, ] +[[package]] +name = "django-storages" +version = "1.14.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/d6/2e50e378fff0408d558f36c4acffc090f9a641fd6e084af9e54d45307efa/django_storages-1.14.6.tar.gz", hash = "sha256:7a25ce8f4214f69ac9c7ce87e2603887f7ae99326c316bc8d2d75375e09341c9", size = 87587, upload-time = "2025-04-02T02:34:55.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/21/3cedee63417bc5553eed0c204be478071c9ab208e5e259e97287590194f1/django_storages-1.14.6-py3-none-any.whl", hash = "sha256:11b7b6200e1cb5ffcd9962bd3673a39c7d6a6109e8096f0e03d46fab3d3aabd9", size = 33095, upload-time = "2025-04-02T02:34:53.291Z" }, +] + [[package]] name = "django-template-partials" version = "24.4" @@ -979,6 +991,7 @@ dependencies = [ { name = "django-allauth" }, { name = "django-fernet-encrypted-fields" }, { name = "django-scopes" }, + { name = "django-storages" }, { name = "django-template-partials" }, { name = "jsonschema" }, { name = "kubernetes" }, @@ -1013,6 +1026,7 @@ requires-dist = [ { name = "django-allauth", specifier = ">=65.5.0" }, { name = "django-fernet-encrypted-fields", specifier = ">=0.3.0" }, { name = "django-scopes", specifier = ">=2.0.0" }, + { name = "django-storages", specifier = ">=1.14.6" }, { name = "django-template-partials", specifier = ">=24.4" }, { name = "jsonschema", specifier = ">=4.23.0" }, { name = "kubernetes", specifier = ">=32.0.1" },