Skip to content

Commit 9bea17a

Browse files
committed
Azure blob storage additional config
- Add additional options to use Azure blob storage (Not used right now) - Use django new storages configuration structure https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-STORAGES
1 parent 64d218a commit 9bea17a

File tree

3 files changed

+184
-29
lines changed

3 files changed

+184
-29
lines changed

main/settings.py

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import environ
99
import pytz
10+
from azure.identity import DefaultAzureCredential
1011
from corsheaders.defaults import default_headers
1112
from django.utils.translation import gettext_lazy as _
1213
from urllib3.util.retry import Retry
@@ -24,9 +25,7 @@
2425
DOCKER_HOST_IP=(str, None),
2526
DJANGO_SECRET_KEY=str,
2627
DJANGO_MEDIA_URL=(str, "/media/"),
27-
DJANGO_MEDIA_ROOT=(str, os.path.join(BASE_DIR, "media")),
2828
DJANGO_STATIC_URL=(str, "/static/"),
29-
DJANGO_STATIC_ROOT=(str, os.path.join(BASE_DIR, "static")),
3029
DJANGO_ADDITIONAL_ALLOWED_HOSTS=(list, []), # Eg: api.go.ifrc.org, goadmin.ifrc.org, dsgocdnapi.azureedge.net
3130
GO_ENVIRONMENT=(str, "development"), # staging, production
3231
#
@@ -39,9 +38,17 @@
3938
DJANGO_DB_PASS=str,
4039
DJANGO_DB_HOST=str,
4140
DJANGO_DB_PORT=(int, 5432),
42-
# Azure storage
41+
# Storage
42+
# -- Azure storage
43+
AZURE_STORAGE_ENABLED=(bool, False),
44+
AZURE_STORAGE_CONNECTION_STRING=(str, None),
4345
AZURE_STORAGE_ACCOUNT=(str, None),
4446
AZURE_STORAGE_KEY=(str, None),
47+
AZURE_STORAGE_TOKEN_CREDENTIAL=(str, None),
48+
AZURE_STORAGE_MANAGED_IDENTITY=(bool, False),
49+
# -- Filesystem (default) XXX: Don't use for production
50+
DJANGO_MEDIA_ROOT=(str, os.path.join(BASE_DIR, "media")),
51+
DJANGO_STATIC_ROOT=(str, os.path.join(BASE_DIR, "static")),
4552
# Email
4653
EMAIL_USE_TLS=(bool, True),
4754
FORCE_USE_SMTP=(bool, False),
@@ -132,6 +139,7 @@
132139

133140
# Requires uppercase variable https://docs.djangoproject.com/en/2.1/topics/settings/#creating-your-own-settings
134141

142+
135143
def find_env_with_value(*keys: str) -> None | str:
136144
for key in keys:
137145
if env(key):
@@ -437,39 +445,65 @@ def parse_domain(*env_keys: str) -> str:
437445
IFRC_TRANSLATION_DOMAIN = env("IFRC_TRANSLATION_DOMAIN")
438446
IFRC_TRANSLATION_HEADER_API_KEY = env("IFRC_TRANSLATION_HEADER_API_KEY")
439447

440-
MEDIA_URL = env("DJANGO_MEDIA_URL")
441-
MEDIA_ROOT = env("DJANGO_MEDIA_ROOT")
448+
# Needed to generate correct https links when running behind a reverse proxy
449+
# when SSL is terminated at the proxy
450+
USE_X_FORWARDED_HOST = True
451+
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_SCHEME", "https")
442452

453+
# Storage
454+
MEDIA_URL = env("DJANGO_MEDIA_URL")
443455
STATIC_URL = env("DJANGO_STATIC_URL")
444-
STATIC_ROOT = env("DJANGO_STATIC_ROOT")
445456

446457
STATICFILES_DIRS = [
447458
os.path.join(BASE_DIR, "go-static"),
448459
]
449460

450-
# Needed to generate correct https links when running behind a reverse proxy
451-
# when SSL is terminated at the proxy
452-
USE_X_FORWARDED_HOST = True
453-
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_SCHEME", "https")
454-
461+
# NOTE: This is used by api/logger.py which sends logs to azure storage
462+
# FIXME: Do we need this? We are also using loki for log collections
455463
AZURE_STORAGE_ACCOUNT = env("AZURE_STORAGE_ACCOUNT")
456464
AZURE_STORAGE_KEY = env("AZURE_STORAGE_KEY")
457465

458-
AZURE_STORAGE = {
459-
"CONTAINER": "api",
460-
"ACCOUNT_NAME": AZURE_STORAGE_ACCOUNT,
461-
"ACCOUNT_KEY": AZURE_STORAGE_KEY,
462-
"CDN_HOST": None,
463-
"USE_SSL": False,
464-
}
465-
# instead of: if AZURE_STORAGE_ACCOUNT: DEFAULT_FILE_STORAGE = "api.storage.AzureStorage"
466-
# > https://django-storages.readthedocs.io/en/latest/backends/azure.html
467-
468-
AZURE_ACCOUNT_NAME = env("AZURE_STORAGE_ACCOUNT")
469-
AZURE_ACCOUNT_KEY = env("AZURE_STORAGE_KEY")
470-
AZURE_CONTAINER = "api"
471-
if AZURE_STORAGE_ACCOUNT:
472-
DEFAULT_FILE_STORAGE = "storages.backends.azure_storage.AzureStorage"
466+
if env("AZURE_STORAGE_ENABLED"):
467+
468+
AZURE_STORAGE_CONFIG_OPTIONS = {
469+
"connection_string": env("AZURE_STORAGE_CONNECTION_STRING"),
470+
"overwrite_files": False,
471+
}
472+
473+
if not env("AZURE_STORAGE_CONNECTION_STRING"):
474+
AZURE_STORAGE_CONFIG_OPTIONS.update(
475+
{
476+
"account_name": env("AZURE_STORAGE_ACCOUNT"),
477+
"account_key": env("AZURE_STORAGE_KEY"),
478+
"token_credential": env("AZURE_STORAGE_TOKEN_CREDENTIAL"),
479+
}
480+
)
481+
482+
if env("AZURE_STORAGE_MANAGED_IDENTITY"):
483+
AZURE_STORAGE_CONFIG_OPTIONS["token_credential"] = DefaultAzureCredential()
484+
485+
STORAGES = {
486+
"default": {
487+
"BACKEND": "storages.backends.azure_storage.AzureStorage",
488+
"OPTIONS": {
489+
**AZURE_STORAGE_CONFIG_OPTIONS,
490+
"azure_container": "api",
491+
},
492+
},
493+
# TODO: Use this instead of nginx for staticfiles
494+
# "staticfiles": {
495+
# "BACKEND": "storages.backends.azure_storage.AzureStorage",
496+
# "OPTIONS": {
497+
# **AZURE_STORAGE_CONFIG_OPTIONS,
498+
# "azure_container": env("AZURE_STORAGE_STATIC_CONTAINER"),
499+
# "overwrite_files": True,
500+
# },
501+
# },
502+
}
503+
else:
504+
# Filesystem
505+
MEDIA_ROOT = env("DJANGO_MEDIA_ROOT")
506+
STATIC_ROOT = env("DJANGO_STATIC_ROOT")
473507

474508
# Email config
475509
FORCE_USE_SMTP = env("FORCE_USE_SMTP")

poetry.lock

Lines changed: 122 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ django-modeltranslation = "==0.17.5"
4141
django-read-only = "==1.12.0"
4242
django-reversion-compare = "==0.16.2"
4343
django-reversion = "==5.0.12"
44-
django-storages = "==1.11.1"
44+
django-storages = { version = "==1.11.1", extras = ["azure"] }
4545
django-tinymce = "==4.1.0"
4646
django-oauth-toolkit = "3.0.1"
4747
djangorestframework-csv = "==2.1.1"
@@ -88,7 +88,7 @@ drf-spectacular = "*"
8888
pyjwt = "*"
8989
shapely = "*"
9090
colorlog = "*"
91-
91+
azure-identity = "*" # Required by django-storages[azure] if used
9292
mapbox-tilesets = "*"
9393
ipython = "*"
9494
tiktoken = "*"

0 commit comments

Comments
 (0)