From 5499f10625cc02d77c36de2126b72df09ad78997 Mon Sep 17 00:00:00 2001 From: dnikolay-ebc Date: Thu, 30 Jun 2022 00:36:10 +0200 Subject: [PATCH] feat: use pydantic settings --- app/Entirety/.env.EXAMPLE | 8 + app/Entirety/entirety/asgi.py | 5 +- app/Entirety/entirety/settings.py | 252 +++++++++++++++--------------- app/Entirety/entirety/wsgi.py | 7 +- app/Entirety/manage.py | 6 +- app/Entirety/requirements.txt | 6 + 6 files changed, 151 insertions(+), 133 deletions(-) create mode 100644 app/Entirety/.env.EXAMPLE diff --git a/app/Entirety/.env.EXAMPLE b/app/Entirety/.env.EXAMPLE new file mode 100644 index 00000000..c7e88d1f --- /dev/null +++ b/app/Entirety/.env.EXAMPLE @@ -0,0 +1,8 @@ +OIDC_OP_AUTHORIZATION_ENDPOINT= +OIDC_OP_JWKS_ENDPOINT= +OIDC_OP_TOKEN_ENDPOINT= +OIDC_OP_USER_ENDPOINT= +OIDC_RP_CLIENT_ID= +OIDC_RP_CLIENT_SECRET= +LANGUAGE_CODE= +TIME_ZONE= diff --git a/app/Entirety/entirety/asgi.py b/app/Entirety/entirety/asgi.py index 4affac82..546f4b40 100644 --- a/app/Entirety/entirety/asgi.py +++ b/app/Entirety/entirety/asgi.py @@ -10,7 +10,8 @@ import os from django.core.asgi import get_asgi_application +from pydantic_settings import SetUp -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") - +# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") +SetUp().configure() application = get_asgi_application() diff --git a/app/Entirety/entirety/settings.py b/app/Entirety/entirety/settings.py index 225352b1..e62823e5 100644 --- a/app/Entirety/entirety/settings.py +++ b/app/Entirety/entirety/settings.py @@ -1,156 +1,152 @@ -""" -Django settings for entirety project. - -Generated by 'django-admin startproject' using Django 4.0.5. - -For more information on this file, see -https://docs.djangoproject.com/en/4.0/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/4.0/ref/settings/ -""" - import os from pathlib import Path - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent +from pydantic import BaseSettings, Field, AnyHttpUrl, FilePath __version__ = "0.1.0" -VERSION = __version__ -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "django-insecure-_8e5-lw61o*9ml#eds^!-wc%0g7kabh^8go)!_(7)8x13+fort" - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - -# Application definition - -INSTALLED_APPS = [ - "django.contrib.admin", - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.messages", - "django.contrib.staticfiles", - "mozilla_django_oidc", - "compressor", - "crispy_forms", - "crispy_bootstrap5", - "projects.apps.ProjectsConfig", - "examples.apps.ExamplesConfig", -] - -CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" - -CRISPY_TEMPLATE_PACK = "bootstrap5" - -MIDDLEWARE = [ - "django.middleware.security.SecurityMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", - "mozilla_django_oidc.middleware.SessionRefresh", -] - -ROOT_URLCONF = "entirety.urls" - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": ["templates"], - "APP_DIRS": True, - "OPTIONS": { - "context_processors": [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - ], + +class Settings(BaseSettings): + # Build paths inside the project like this: BASE_DIR / 'subdir'. + BASE_DIR = Path(__file__).resolve().parent.parent + + VERSION = __version__ + # Quick-start development settings - unsuitable for production + # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ + + # SECURITY WARNING: keep the secret key used in production secret! + SECRET_KEY = "django-insecure-_8e5-lw61o*9ml#eds^!-wc%0g7kabh^8go)!_(7)8x13+fort" + + # SECURITY WARNING: don't run with debug turned on in production! + DEBUG = True + + ALLOWED_HOSTS = [] + + # Application definition + + INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "mozilla_django_oidc", + "compressor", + "crispy_forms", + "crispy_bootstrap5", + "projects.apps.ProjectsConfig", + "examples.apps.ExamplesConfig", + ] + + CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" + + CRISPY_TEMPLATE_PACK = "bootstrap5" + + MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "mozilla_django_oidc.middleware.SessionRefresh", + ] + + ROOT_URLCONF = "entirety.urls" + + TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": ["templates"], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, }, - }, -] + ] -WSGI_APPLICATION = "entirety.wsgi.application" + WSGI_APPLICATION = "entirety.wsgi.application" -# Database -# https://docs.djangoproject.com/en/4.0/ref/settings/#databases + # Database + # https://docs.djangoproject.com/en/4.0/ref/settings/#databases -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", + DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } } -} -# Password validation -# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators + # Password validation + # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators + + AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, + ] -AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", - }, -] + AUTHENTICATION_BACKENDS = ("mozilla_django_oidc.auth.OIDCAuthenticationBackend",) -AUTHENTICATION_BACKENDS = ("mozilla_django_oidc.auth.OIDCAuthenticationBackend",) + OIDC_RP_SIGN_ALGO: str = Field(default="RS256", env="OIDC_RP_SIGN_ALGO") + OIDC_OP_JWKS_ENDPOINT: str = Field(env="OIDC_OP_JWKS_ENDPOINT") -OIDC_RP_SIGN_ALGO = "RS256" -OIDC_OP_JWKS_ENDPOINT = os.getenv("OIDC_OP_JWKS_ENDPOINT") + OIDC_RP_CLIENT_ID: str = Field(env="OIDC_RP_CLIENT_ID") + OIDC_RP_CLIENT_SECRET: str = Field(env="OIDC_RP_CLIENT_SECRET") + OIDC_OP_AUTHORIZATION_ENDPOINT: str = Field(env="OIDC_OP_AUTHORIZATION_ENDPOINT") + OIDC_OP_TOKEN_ENDPOINT: str = Field(env="OIDC_OP_TOKEN_ENDPOINT") + OIDC_OP_USER_ENDPOINT: str = Field(env="OIDC_OP_USER_ENDPOINT") -OIDC_RP_CLIENT_ID = os.getenv("OIDC_RP_CLIENT_ID") -OIDC_RP_CLIENT_SECRET = os.getenv("OIDC_RP_CLIENT_SECRET") -OIDC_OP_AUTHORIZATION_ENDPOINT = os.getenv("OIDC_OP_AUTHORIZATION_ENDPOINT") -OIDC_OP_TOKEN_ENDPOINT = os.getenv("OIDC_OP_TOKEN_ENDPOINT") -OIDC_OP_USER_ENDPOINT = os.getenv("OIDC_OP_USER_ENDPOINT") + # Internationalization + # https://docs.djangoproject.com/en/4.0/topics/i18n/ -# Internationalization -# https://docs.djangoproject.com/en/4.0/topics/i18n/ + LANGUAGE_CODE: str = Field(default="de-de", env="LANGUAGE_CODE") -LANGUAGE_CODE = "de-de" + TIME_ZONE: str = Field(default="Europe/Berlin", env="TIME_ZONE") -TIME_ZONE = "Europe/Berlin" + USE_I18N = True -USE_I18N = True + USE_TZ = True -USE_TZ = True + # Static files (CSS, JavaScript, Images) + # https://docs.djangoproject.com/en/4.0/howto/static-files/ -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.0/howto/static-files/ + STATIC_URL = "static/" + STATIC_ROOT = os.path.join(BASE_DIR, "static/") -STATIC_URL = "static/" -STATIC_ROOT = os.path.join(BASE_DIR, "static/") + STATICFILES_DIRS = [ + os.path.join(BASE_DIR, "static"), + ] -STATICFILES_DIRS = [ - os.path.join(BASE_DIR, "static"), -] + STATICFILES_FINDERS = [ + "django.contrib.staticfiles.finders.AppDirectoriesFinder", + "compressor.finders.CompressorFinder", + ] -STATICFILES_FINDERS = [ - "django.contrib.staticfiles.finders.AppDirectoriesFinder", - "compressor.finders.CompressorFinder", -] + COMPRESS_PRECOMPILERS = (("text/x-scss", "django_libsass.SassCompiler"),) -COMPRESS_PRECOMPILERS = (("text/x-scss", "django_libsass.SassCompiler"),) + # Default primary key field type + # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field -# Default primary key field type -# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field + DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + class Config: + case_sensitive = False + env_file = "../.env" + env_file_encoding = "utf-8" diff --git a/app/Entirety/entirety/wsgi.py b/app/Entirety/entirety/wsgi.py index c6483e9d..eaf206d1 100644 --- a/app/Entirety/entirety/wsgi.py +++ b/app/Entirety/entirety/wsgi.py @@ -7,10 +7,13 @@ https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ """ -import os +# import os from django.core.wsgi import get_wsgi_application +from pydantic_settings import SetUp -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") +# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") + +SetUp().configure() application = get_wsgi_application() diff --git a/app/Entirety/manage.py b/app/Entirety/manage.py index db1ec071..43bbe752 100644 --- a/app/Entirety/manage.py +++ b/app/Entirety/manage.py @@ -3,10 +3,14 @@ import os import sys +from pydantic_settings import SetUp + def main(): """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") + # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "entirety.settings") + SetUp().configure() + try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/app/Entirety/requirements.txt b/app/Entirety/requirements.txt index 2a38d71b..4086e793 100644 --- a/app/Entirety/requirements.txt +++ b/app/Entirety/requirements.txt @@ -12,6 +12,10 @@ django-appconf==1.0.5 django-compressor==4.0 django-crispy-forms==1.14.0 django-libsass==0.9 +django-ninja==0.19.0 +django-pydantic-settings==0.6.3 +dnspython==2.2.1 +email-validator==1.2.1 filelock==3.7.1 identify==2.5.1 idna==3.3 @@ -22,6 +26,7 @@ nodeenv==1.7.0 platformdirs==2.5.2 pre-commit==2.19.0 pycparser==2.21 +pydantic==1.9.1 pyOpenSSL==22.0.0 PyYAML==6.0 rcssmin==1.1.0 @@ -30,6 +35,7 @@ rjsmin==1.2.0 six==1.16.0 sqlparse==0.4.2 toml==0.10.2 +typing_extensions==4.2.0 tzdata==2022.1 urllib3==1.26.9 virtualenv==20.15.1