class _Gunicorn: """Configure Gunicorn""" # As whom Gunicorn should run the server GUNICORN_USER = values.Value(environ_prefix=None) GUNICORN_GROUP = values.Value(environ_prefix=None) # Path to Gunicorn GUNICORN_PATH = values.PathValue('~/.virtualenvs/pactf/bin/gunicorn', environ_prefix=None, check_exists=False) # Whether to use a socket or serve directly to an address GUNICORN_USE_SOCKFILE = values.BooleanValue(False, environ_prefix=None) # Socket to communicate with GUNICORN_SOCKFILE = values.PathValue(join(BASE_DIR, 'run', 'gunicorn.sock'), environ_prefix=None, check_exists=False) # Url to directly serve to GUNICORN_IP = values.IPValue('127.0.0.1', environ_prefix=None) GUNICORN_PORT = values.IntegerValue(8001, environ_prefix=None) # Number of worker processes Gunicorn should spawn GUNICORN_NUM_WORKERS = values.IntegerValue(1, environ_prefix=None)
class StaticMedia: """ Configuration for front-end assets """ # URLs STATIC_URL = values.Value('/static/') MEDIA_URL = values.Value('/media/') # Main directories STATIC_ROOT = values.PathValue(BASE_DIR / '_static', check_exists=False) MEDIA_ROOT = values.PathValue(BASE_DIR / '_media', check_exists=False) # Finders STATICFILES_DIRS = []
def MEDIA_ROOT(self) -> str: if self.STORAGE_TYPE == 's3': return '/%s/' % self.DEFAULT_S3_PATH else: return values.PathValue(default=os.path.join( self.BASE_DIR, 'media'), environ_name='MEDIA_ROOT', environ_prefix='KRYNEGGER')
def STATIC_ROOT(self): if self.STORAGE_TYPE == 's3': return "/%s/" % self.STATIC_S3_PATH else: return values.PathValue(default=os.path.join( self.BASE_DIR, 'static'), environ_name='STATIC_ROOT', environ_prefix='KRYNEGGER')
def logging_config(): """If DJANGO_LOGGING_CONFIG_FILE is not set, default django logging config is used""" var_name = 'LOGGING_CONFIG_FILE' if os.environ.get('DJANGO_' + var_name): with open(values.PathValue(environ_name=var_name)) as f: content = f.read() content = content.replace('{project_root}', PROJECT_ROOT_DIR) return json.loads(content)
class Core(Configuration, AWS, CORS): """Settings that will never change per-environment.""" # THIS_DIR = os.path.dirname(os.path.abspath(__file__)) # BASE_DIR = os.path.dirname(THIS_DIR) BASE_DIR = BASE_DIR STATIC_URL = "/" STATIC_ROOT = values.PathValue( os.path.join(BASE_DIR, "ui/build"), check_exists=False ) VERSION = get_version(BASE_DIR) INSTALLED_APPS = [ "django.contrib.contenttypes", "corsheaders", "dockerflow.django", "buildhub.main", "buildhub.api", "buildhub.ingest", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "dockerflow.django.middleware.DockerflowMiddleware", "buildhub.whitenoise_extra.BuildhubWhiteNoiseMiddleware", "buildhub.middleware.StatsMiddleware", ] ROOT_URLCONF = "buildhub.urls" WSGI_APPLICATION = "buildhub.wsgi.application" # Internationalization LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" USE_I18N = False USE_L10N = False USE_TZ = True DOCKERFLOW_CHECKS = [ # Defaults are documented here: # https://python-dockerflow.readthedocs.io/en/latest/django.html#dockerflow-checks "dockerflow.django.checks.check_database_connected", "dockerflow.django.checks.check_migrations_applied", "buildhub.dockerflow_extra.check_elasticsearch", ] # The default is that Whitenoise sets `Access-Control-Allow-Origin: *` for # static assets. We don't need that because we don't intend to serve the # static assets via a CDN. WHITENOISE_ALLOW_ALL_ORIGINS = False
def STATIC_ROOT(self): # noqa: N802 # Django staticfiles creates any intermediate directories which don't exist # TODO: allow from env? return values.PathValue( os.path.join(self.BASE_DIR, 'staticfiles'), environ=False, check_exists=False, # Disable late_binding, to make this return an actual str, not a Value, since some # "os" module functions (which are called with this) do strict nominal type checking. late_binding=False, )
class Prod(Common): """ The in-production settings """ DEBUG = False SECRET_KEY = values.SecretValue() ADMINS = values.SingleNestedTupleValue() ALLOWED_HOSTS = values.ListValue() DATABASES = values.DatabaseURLValue() EMAIL = values.EmailURLValue() REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', ), 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', ), } STATIC_ROOT = values.PathValue() LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'pilotwire_handler': { 'level': 'INFO', 'class': 'heating.log.PilotwireHandler', 'logLength': 500, }, }, 'loggers': { 'heating.pilotwire': { 'handlers': ['pilotwire_handler'], 'level': 'INFO', }, }, } # Authentication AUTHENTICATION_BACKENDS = [ 'core.auth.backends.SettingsBackend', ] + Common.AUTHENTICATION_BACKENDS # pylint: disable=no-member ADMIN_LOGIN = values.Value() ADMIN_PASSWORD = values.SecretValue()
class Common(Configuration): """Common configuration base class.""" SECRET_KEY = '(_j4e0=pbe(b+b1$^ch_48be0=gszglcgfzz^dy=(gnx=@m*b7' DEBUG = values.BooleanValue(False) MAIL_ADMINS = values.BooleanValue(False) ADMINS = AdminsValue((('Max Brauer', '*****@*****.**'), )) MANAGERS = ADMINS LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', }, 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { 'console': { 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', }, 'null': { 'class': 'logging.NullHandler', }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django': { 'handlers': ['console'], }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'django.security': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'django.security.DisallowedHost': { 'handlers': ['null'], 'propagate': False, }, 'py.warnings': { 'handlers': ['console'], }, } } ALLOWED_HOSTS = values.ListValue(['www.example.com']) SITE_ID = values.IntegerValue(1) # Internationalization # https://docs.djangoproject.com/en/dev/topics/i18n/ LANGUAGE_CODE = values.Value('en-us') TIME_ZONE = values.Value('Europe/Berlin') USE_I18N = True USE_L10N = True USE_TZ = True # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/var/www/example.com/media/" MEDIA_ROOT = values.PathValue(os.path.join(BaseDir.BASE_DIR, 'media')) # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://example.com/media/", "http://media.example.com/" MEDIA_URL = values.Value('/media/') # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/var/www/example.com/static/" STATIC_ROOT = values.PathValue( os.path.join(BaseDir.BASE_DIR, 'static_root')) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/dev/howto/static-files/ STATIC_URL = values.Value('/static/') # Additional locations of static files STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(BaseDir.BASE_DIR, 'static'), os.path.join(os.path.dirname(BaseDir.BASE_DIR), 'node_modules', 'normalize.css'), ) STATICFILES_FINDERS = values.ListValue([ 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'django.contrib.staticfiles.finders.FileSystemFinder', 'sass_processor.finders.CssFinder', # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ]) MIDDLEWARE_CLASSES = values.ListValue([ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', ]) ROOT_URLCONF = 'bureau.config.urls' WSGI_APPLICATION = 'bureau.config.wsgi.application' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BaseDir.BASE_DIR, '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', 'bureau.context_processors.django_version', ], 'debug': values.BooleanValue( False, environ_name='DJANGO_TEMPLATES_TEMPLATE_DEBUG'), 'string_if_invalid': values.Value( '', environ_name='DJANGO_TEMPLATES_STRING_IF_INVALID'), }, }, ] # the following line is only necessary because django-template-debug uses it TEMPLATE_DEBUG = TEMPLATES[0]['OPTIONS'].get('debug', False) FIXTURE_DIRS = (os.path.join(BaseDir.BASE_DIR, 'fixtures'), ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.admindocs', 'sass_processor', 'bureau.apps.core.apps.CoreConfig', ) CACHES = values.DictValue({ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } }) EMAIL_SUBJECT_PREFIX = '[bureau]' DEFAULT_FROM_EMAIL = values.EmailValue('*****@*****.**') SERVER_EMAIL = DEFAULT_FROM_EMAIL
class GCP: """Google Cloud Platform""" GOOGLE_APPLICATION_CREDENTIALS = values.PathValue( "google_service_account.json", environ_prefix=None)
class BasicConfiguration(Configuration, SentryConfigurationMixin, MailConfigurationMixin, CeleryConfigurationMixin): """ Basic CRM configuration, which satisfying the [ISO-27001](https://google.com), [ISO-270018](https://google.com), [SOC:AICPAA](https://google.com), and [HIPAA](https://google.com) standards. """ DEBUG = values.BooleanValue(False) # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = values.PathValue(default=os.path.dirname( os.path.dirname(os.path.abspath(__file__))), check_exists=True, environ_prefix='KRYNEGGER') SECRET_KEY = values.SecretValue(environ_prefix='KRYNEGGER') ALLOWED_HOSTS = ['*'] # Application definition LOGIN_REDIRECT_URL = values.PathValue( '/', check_exists=False, ) LOGIN_URL = values.PathValue( '/login/', check_exists=False, ) PLATFORM_INSTALLED_APPS = [ # 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.messages', 'django.contrib.sessions', 'django.contrib.staticfiles', 'simple_pagination', 'haystack', 'compressor', 'common', 'accounts', 'cases', 'contacts', 'emails', 'leads', 'opportunity', 'planner', 'sorl.thumbnail', 'phonenumber_field', 'storages', 'marketing', 'tasks', 'invoices', 'events', 'teams', ] # Password validation # https://docs.djangoproject.com/en/1.10/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', }, ] PLATFORM_MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR.value, "templates"), ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages', ], }, }, ] ROOT_URLCONF = 'crm.urls' WSGI_APPLICATION = 'crm.wsgi.application' # Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.postgresql', # 'NAME': 'dj_crm', # 'USER': '******', # 'PASSWORD': '******', # 'HOST': os.getenv('DB_HOST', '127.0.0.1'), # 'PORT': os.getenv('DB_PORT', '5432') # } # } DATABASES = values.DatabaseURLValue( default='postgres://*****:*****@localhost/krynegger_database', environ_name='DATABASES', environ_prefix='KRYNEGGER') # DATABASES = dict( # default=dj_database_url.config( # env='KRYNEGGER_DATABASE_PRIMARY_URL', # default='postgres://*****:*****@localhost/krynegger_database' # ) # ) # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = values.Value('en-us', environ_prefix='KRYNEGGER') TIME_ZONE = values.Value('Europe/Budapest', environ_prefix='KRYNEGGER') USE_I18N = values.BooleanValue(True, environ_prefix='KRYNEGGER') USE_L10N = values.BooleanValue(True, environ_prefix='KRYNEGGER') USE_TZ = values.BooleanValue(True, environ_prefix='KRYNEGGER') EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' # EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # EMAIL_HOST = 'localhost' # EMAIL_PORT = 25 # AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', ) EMAIL_HOST = values.Value('aspmx.l.google.com', environ_prefix='KRYNEGGER') EMAIL_HOST_USER = values.Value('*****@*****.**', environ_prefix='KRYNEGGER') EMAIL_HOST_PASSWORD = values.Value('Armageddon43254325', environ_prefix='KRYNEGGER') EMAIL_PORT = values.IntegerValue(587, environ_prefix='KRYNEGGER') EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = '*****@*****.**' AUTH_USER_MODEL = 'common.User' DEFAULT_S3_PATH = "static" AWS_STORAGE_BUCKET_NAME = AWS_BUCKET_NAME = os.getenv('AWSBUCKETNAME', '') AM_ACCESS_KEY = AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID', '') AM_PASS_KEY = AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY', '') S3_DOMAIN = AWS_S3_CUSTOM_DOMAIN = str( AWS_BUCKET_NAME) + '.s3.amazonaws.com' AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'} AWS_IS_GZIPPED = False AWS_ENABLED = False AWS_S3_SECURE_URLS = False # STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' DEFAULT_FILE_STORAGE = 'storages.backends.ftp.FTPStorage' # STATICFILES_STORAGE = 'storages.backends.ftp.FTPStorage' STATICFILES_STORAGE = 'crm.storages.StaticfilesFtpStorage' # DEFAULT_FILE_STORAGE = 'storages.backends.sftpstorage.SFTPStorage' STATIC_S3_PATH = "static" AWS_REGION = os.getenv('AWS_REGION', '') # Currently 'normal' and 's3' storage implemented. STORAGE_TYPE = values.Value(default='normal', environ_name='STORAGE_TYPE', environ_prefix='KRYNEGGER') # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ @property def STATIC_ROOT(self): if self.STORAGE_TYPE == 's3': return "/%s/" % self.STATIC_S3_PATH else: return values.PathValue(default=os.path.join( self.BASE_DIR, 'static'), environ_name='STATIC_ROOT', environ_prefix='KRYNEGGER') @property def STATIC_URL(self) -> str: if self.STORAGE_TYPE == 's3': return 'https://%s/' % (self.S3_DOMAIN) else: return values.Value( default='/static/', # check_exists=False, environ_name='STATIC_URL', environ_prefix='KRYNEGGER') @property def STATICFILES_DIRS(self) -> list: if self.STORAGE_TYPE == 's3': return [str(self.BASE_DIR) + '/static'] else: return values.ListValue(default=[ os.path.join(self.BASE_DIR, 'frontend'), ], environ_name='STATICFILES_DIRS', environ_prefix='KRYNEGGER') STATICFILES_FINDERS = [ 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'compressor.finders.CompressorFinder', ] @property def MEDIA_ROOT(self) -> str: if self.STORAGE_TYPE == 's3': return '/%s/' % self.DEFAULT_S3_PATH else: return values.PathValue(default=os.path.join( self.BASE_DIR, 'media'), environ_name='MEDIA_ROOT', environ_prefix='KRYNEGGER') @property def MEDIA_URL(self) -> str: if self.STORAGE_TYPE == 's3': return '//%s/%s/' % (self.S3_DOMAIN, self.DEFAULT_S3_PATH) else: return values.Value(default='/media/', environ_name='MEDIA_URL', environ_prefix='KRYNEGGER') @property def ADMIN_MEDIA_PREFIX(self) -> str: return self.STATIC_URL + 'admin/' CORS_ORIGIN_ALLOW_ALL = True # <editor-fold desc="Compressor configuration"> FTP_STORAGE_LOCATION = 'ftp://*****:*****@localhost:21' + str( BASE_DIR) FTP_STORAGE_ENCODING = 'uft-8' FTP_STORAGE_BASE_URL = '/static/' # </editor-fold> # <editor-fold desc="Compressor configuration"> # COMPRESS_STORAGE = 'compressor.storage.GzipCompressorFileStorage' COMPRESS_ROOT = values.PathValue(os.path.join(BASE_DIR.value, 'static')) COMPRESS_URL = '/static/' COMPRESS_ENABLED = values.BooleanValue(default=True, environ_name='COMPRESS_ENABLED', environ_prefix='KRYNEGGER') COMPRESS_PARSER = 'compressor.parser.AutoSelectParser' COMPRESS_STORAGE = 'compressor.storage.CompressorFileStorage' COMPRESS_DEBUG_TOGGLE = 'nocompress' COMPRESS_OUTPUT_DIR = 'CACHE' COMPRESS_REBUILD_TIMEOUT = 5400 COMPRESS_OFFLINE = True COMPRESS_VERBOSE = True COMPRESS_OFFLINE_MANIFEST = 'manifest.json' COMPRESS_OFFLINE_CONTEXT = { 'STATIC_URL': 'STATIC_URL', 'MEDIA_URL': 'MEDIA_URL', } COMPRESS_PRECOMPILERS = ( ('text/less', 'lessc {infile} {outfile}'), ('text/x-sass', 'sass {infile} {outfile}'), ('text/x-scss', 'sass --scss {infile} {outfile}'), ) COMPRESS_CACHEABLE_PRECOMPILERS = ( ('text/less', 'lessc {infile} {outfile}'), ('text/x-sass', 'sass {infile} {outfile}'), ('text/x-scss', 'sass --scss {infile} {outfile}'), ) COMPRESS_TEMPLATE_FILTER_CONTEXT = {'STATIC_URL': STATIC_URL} COMPRESS_URL_PLACEHOLDER = '/__compressor_url_placeholder__/' COMPRESS_FILTERS = dict(css=[ 'compressor.filters.template.TemplateFilter', 'compressor.filters.cssmin.CSSMinFilter', 'compressor.filters.css_default.CssAbsoluteFilter', ], js=[ 'compressor.filters.template.TemplateFilter', 'compressor.filters.jsmin.JSMinFilter', ]) COMPRESSORS = dict( css='compressor.css.CssCompressor', js='compressor.js.JsCompressor', ) # </editor-fold> LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'root': { 'level': 'WARNING', 'handlers': ['sentry'], }, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, }, 'handlers': { 'sentry': { 'level': 'ERROR', 'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler', }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'verbose' } }, 'loggers': { 'django.db.backends': { 'level': 'ERROR', 'handlers': ['console'], 'propagate': False, }, 'raven': { 'level': 'DEBUG', 'handlers': ['console'], 'propagate': False, }, 'sentry.errors': { 'level': 'DEBUG', 'handlers': ['console'], 'propagate': False, }, }, } HAYSTACK_CONNECTIONS = { 'default': { # 'ENGINE': 'haystack.backends.elasticsearch2_backend.Elasticsearch2SearchEngine', 'ENGINE': 'haystack_elasticsearch.elasticsearch5.Elasticsearch5SearchEngine', 'URL': 'http://127.0.0.1:9200/', 'INDEX_NAME': 'haystack', }, } HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } PASSWORD_RESET_MAIL_FROM_USER = os.getenv('PASSWORD_RESET_MAIL_FROM_USER', '*****@*****.**') @property def INSTALLED_APPS(self) -> list: if self.SENTRY_ENABLED: return self.PLATFORM_INSTALLED_APPS + self.SENTRY_INSTALLED_APPS else: return self.PLATFORM_INSTALLED_APPS @property def MIDDLEWARE(self): if self.SENTRY_ENABLED: return self.PLATFORM_MIDDLEWARE + self.SENTRY_MIDDLEWARE else: return self.PLATFORM_MIDDLEWARE
class Common(Configuration): # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = values.SecretValue() # SECURITY WARNING: don't run with debug turned on in production! DEBUG = values.BooleanValue(False) ALLOWED_HOSTS = values.ListValue(['*']) # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles', "rest_framework", "drf_firebase_auth", 'django_extensions', 'debug_toolbar', 'django_celery_results', "django_celery_beat", 'wrappr_backend.users', 'wrappr_backend.detection', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'wrappr_backend.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], '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 = 'wrappr_backend.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = values.DatabaseURLValue('sqlite:///{}'.format( os.path.join(BASE_DIR, 'db.sqlite3'))) # Password validation # https://docs.djangoproject.com/en/1.11/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', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' MEDIA_ROOT = values.PathValue("media") MEDIA_URL = "/media/" UPLOADED_FILES_USE_URL = True AUTH_USER_MODEL = 'users.User' CELERY_RESULT_BACKEND = 'django-db' REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'drf_firebase_auth.authentication.FirebaseAuthentication', ], } DRF_FIREBASE_AUTH = { 'FIREBASE_SERVICE_ACCOUNT_KEY': os.path.join(BASE_DIR, 'firebase.json'), 'FIREBASE_CREATE_LOCAL_USER': True, 'FIREBASE_ATTEMPT_CREATE_WITH_DISPLAY_NAME': True, 'FIREBASE_AUTH_HEADER_PREFIX': 'JWT', 'FIREBASE_CHECK_JWT_REVOKED': True, 'FIREBASE_AUTH_EMAIL_VERIFICATION': False } CORS_ORIGIN_ALLOW_ALL = values.BooleanValue(True)
class Base(BaseAuthConfigurationMixin, Configuration): # Application definition INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", "drf_spectacular", "corsheaders", "links", "api", ] + BaseAuthConfigurationMixin.MAFIASI_AUTH_APPS MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "corsheaders.middleware.CorsMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.middleware.cache.UpdateCacheMiddleware", "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.cache.FetchFromCacheMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "mafiasi_link_shortener.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [], "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 = "mafiasi_link_shortener.wsgi.application" # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases @property def DATABASES(self): return { "default": { "ENGINE": "django.db.backends.postgresql_psycopg2", "HOST": self.DB_HOST, "PORT": self.DB_PORT, "USER": self.DB_USER, "PASSWORD": self.DB_PASSWORD, "NAME": self.DB_NAME, } } @property def CACHES(self): return { "default": { "BACKEND": "django.core.cache.backends.locmem.LocMemCache" if not self.DEBUG else "django.core.cache.backends.dummy.DummyCache" } } # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ LANGUAGE_CODE = "en-us" TIME_ZONE = "Europe/Berlin" USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ STATIC_URL = "/static/" STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" WHITENOISE_ROOT = BASE_DIR / "mafiasi_link_shortener" / "root_static" LOGIN_REDIRECT_URL = "swagger-ui" LOGIN_URL = "/auth/" VERSION = "0.1.0" CORS_URLS_REGEX = r"^/api/.*$" APPEND_SLASH = True # rest framework REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": [ "rest_framework.authentication.SessionAuthentication", "django_auth_mafiasi.django_rest_framework.authentication.OpenIdAccessTokenAuthentication", ], "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.IsAuthenticated", ], "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", "PAGE_SIZE": 100, } # openapi schema settings # todo add oidc connect authorization documentation SPECTACULAR_SETTINGS = { "TITLE": "Mafiasi Link Shortener", "CONTACT": { "name": "Server-Ag", "email": "*****@*****.**", }, "VERSION": VERSION, "LICENSE": { "name": "MIT", "url": "https://github.com/fsinfuhh/mafiasi_link_shortener/blob/master/LICENSE", }, "SCHEMA_PATH_PREFIX": r"/api/", "COMPONENT_SPLIT_PATCH": True, "COMPONENT_SPLIT_REQUEST": True, } # Configurable properties SECRET_KEY = values.SecretValue() DEBUG = values.BooleanValue(default=False) ALLOWED_HOSTS = values.ListValue(environ_required=True) DB_HOST = values.Value(environ_required=True) DB_PORT = values.Value(default=5432) DB_USER = values.Value(default="mafiasi_link_shortener") DB_PASSWORD = values.SecretValue() DB_NAME = values.Value(default="mafiasi_link_shortener") LINK_SHORT_LENGTH = values.IntegerValue(default=6) STATIC_ROOT = values.PathValue(default=BASE_DIR.parent / "static") CORS_ALLOWED_ORIGIN_REGEXES = values.ListValue( default=[r"^https://\w+\.mafiasi\.de$"])
class BaseConfig(Configuration): DEBUG = values.BooleanValue(False) TEMPLATE_DEBUG = values.BooleanValue(DEBUG) DATABASES = values.DatabaseURLValue( 'postgres://%2Fvar%2Flib%2Fpostgresql/sls_blog') SECRET_KEY = values.SecretValue() CACHES = values.CacheURLValue('locmem://default') # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = (Path(__file__).parent / '../..').resolve(strict=True) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ ALLOWED_HOSTS = [] AUTH_USER_MODEL = 'slsblog_auth.User' # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'corsheaders', 'wagtail.contrib.forms', 'wagtail.contrib.redirects', "wagtail.contrib.search_promotions", "wagtail.contrib.modeladmin", 'wagtail.embeds', 'wagtail.sites', 'wagtail.users', 'wagtail.snippets', 'wagtail.documents', 'wagtail.images', 'wagtail.search', 'wagtail.admin', 'wagtail.core', 'modelcluster', 'taggit', 'wagtail.api.v2', 'rest_framework', "channels", "graphql_ws.django", "graphene_django", "grapple", 'sls_blog.auth', 'sls_blog.cms', 'wagtail_headless_preview', ] REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework_simplejwt.authentication.JWTAuthentication', ) } MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'wagtail.contrib.redirects.middleware.RedirectMiddleware', ] ROOT_URLCONF = 'sls_blog.urls' WAGTAIL_SITE_NAME = 'Stevenlsjr Blog' WAGTAIL_I18N_ENABLED = True LANGUAGES = WAGTAIL_CONTENT_LANGUAGES = [ ('en-us', _("English (United States)")), ('en-gb', _("English (United Kingdom)")), ('es-es', _("Spanish (Spain)")), ('es-mx', _("Spanish (Mexico)")), ] CORS_ORIGIN_WHITELIST = values.ListValue(default=[]) CORS_ORIGIN_ALLOW_ALL = values.BooleanValue(default=False) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], '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 = 'sls_blog.wsgi.application' # ASGI_APPLICATION = 'sls_blog.asgi.application' ASGI_APPLICATION = "graphql_ws.django.routing.application" # Password validation # https://docs.djangoproject.com/en/3.1/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', }, ] # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ DEFAULT_FILE_STORAGE = values.Value( 'django.core.files.storage.FileSystemStorage') STATICFILES_STORAGE = values.Value( 'django.contrib.staticfiles.storage.StaticFilesStorage') AZURE_ACCOUNT_NAME = values.Value(environ_required=False) AZURE_ACCOUNT_KEY = values.Value(environ_required=False) AZURE_CONTAINER = values.Value(environ_required=False) PUBLIC_AZURE_CONTAINER = values.Value(environ_required=False) AZURE_CONNECTION_STRING = values.Value(default=None, environ_required=False) AZURE_CUSTOM_CONNECTION_STRING = values.Value(default=None, environ_required=False) PUBLIC_AZURE_CONTAINER = values.Value(environ_required=False) STATIC_URL = values.Value('/static/') MEDIA_URL = values.Value('/media/') STATIC_ROOT = values.PathValue(BASE_DIR / '.static') MEDIA_ROOT = values.PathValue(BASE_DIR / '.media') def GRAPHENE(self): cfg = { "SCHEMA": "grapple.schema.schema", "MIDDLEWARE": ["grapple.middleware.GrappleMiddleware"], "SUBSCRIPTION_PATH": "/subscriptions" } if self.DEBUG: cfg['MIDDLEWARE'].insert( 0, 'graphene_django.debug.DjangoDebugMiddleware') return cfg GRAPPLE = { 'APPS': { "slsblog_cms": "" }, 'EXPOSE_GRAPHIQL': values.BooleanValue(True) } BASE_URL = values.URLValue('http://localhost:8000') HEADLESS_PREVIEW_CLIENT_URLS = values.DictValue({ 'default': 'http://localhost:3000/preview', }) HEADLESS_PREVIEW_LIVE = values.BooleanValue(True)
class Base(Configuration): u"""Configuração comum para todos os ambientes.""" DEBUG = values.BooleanValue(False) ADMINS = values.SingleNestedTupleValue( (('Sergio Garcia', '*****@*****.**'), )) MANAGERS = values.SingleNestedTupleValue( (('Sergio Garcia', '*****@*****.**'), )) DATABASES = values.DatabaseURLValue( 'postgres://postgres@localhost/postgres') CACHES = values.CacheURLValue('locmem://') EMAIL = values.EmailURLValue('console://') EMAIL_SUBJECT_PREFIX = values.Value('[%s] ' % SITE_NAME) TIME_ZONE = values.Value('America/Sao_Paulo') LANGUAGE_CODE = values.Value('pt-br') USE_I18N = values.BooleanValue(True) USE_L10N = values.BooleanValue(True) USE_TZ = values.BooleanValue(True) MEDIA_ROOT = normpath(join(SITE_ROOT, 'media')) MEDIA_URL = values.Value('/media/') STATIC_ROOT = values.PathValue(normpath(join(SITE_ROOT, 'static'))) STATIC_URL = values.Value('/static/') STATICFILES_DIRS = (normpath(join(SITE_ROOT, 'bower_components')), ) STATICFILES_FINDERS = [ 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ] SECRET_KEY = values.SecretValue() ALLOWED_HOSTS = [] FIXTURE_DIRS = (normpath(join(SITE_ROOT, 'fixtures')), ) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [normpath(join(SITE_ROOT, 'templates'))], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', ], 'debug': DEBUG }, }, ] MIDDLEWARE_CLASSES = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.locale.LocaleMiddleware', 'gestaolivre.apps.utils.middleware.GlobalRequestMiddleware', ] ROOT_URLCONF = '%s.urls' % SITE_NAME DJANGO_APPS = ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.postgres', 'django.contrib.humanize', 'django.contrib.admin', 'mptt', 'django_mptt_admin', 'widget_tweaks', 'brazil_fields') LOCAL_APPS = ( 'gestaolivre.apps.cadastro', 'gestaolivre.apps.utils', ) INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS LOGIN_REDIRECT_URL = '/' 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', }, ] WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME TEST_RUNNER = 'django.test.runner.DiscoverRunner' MIGRATION_MODULES = {} INSTALLED_APPS += ( 'rest_framework', 'rest_framework_jwt', 'corsheaders', ) REST_FRAMEWORK = values.DictValue({ 'PAGE_SIZE': 10, 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( # 'rest_framework.authentication.SessionAuthentication', # 'rest_framework.authentication.BasicAuthentication', 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), }) CORS_ORIGIN_ALLOW_ALL = values.Value(True) CORS_ALLOW_CREDENTIALS = values.Value(True) INSTALLED_APPS += ('compressor', ) STATICFILES_FINDERS += ('compressor.finders.CompressorFinder', ) COMPRESS_PRECOMPILERS = ( ('text/coffeescript', 'coffee --compile --stdio'), ('text/less', 'lessc --source-map-map-inline {infile} {outfile}'), ('text/x-sass', 'sass {infile} {outfile}'), ('text/x-scss', 'sass --scss {infile} {outfile}'), ) JWT_AUTH = values.DictValue({ 'JWT_EXPIRATION_DELTA': datetime.timedelta(minutes=5), 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), 'JWT_ALLOW_REFRESH': True, 'JWT_AUTH_HEADER_PREFIX': 'Bearer', 'JWT_RESPONSE_PAYLOAD_HANDLER': jwt_response_payload_handler }) @classmethod def pre_setup(cls): u"""Executado antes da Configuração.""" super(Base, cls).pre_setup() @classmethod def setup(cls): u"""Executado depois da Configuração.""" super(Base, cls).setup() logging.info('Configurações comuns carregadas: %s', cls) @classmethod def post_setup(cls): u"""Executado depois da Configuração.""" super(Base, cls).post_setup() logging.debug("done setting up! \o/")
class DjangoMixin: DEVELOPMENT = values.BooleanValue(default=False) @property def DEBUG(self) -> bool: return typing.cast( bool, values.BooleanValue(default=self.DEVELOPMENT, environ_name="DEBUG")) # where manage.py is located PROJECT_PATH = pathlib.Path(__file__).resolve().parent.parent.parent.parent # project name - name of PROJECT_PATH inside project root PROJECT_NAME = pathlib.Path(__file__).resolve().parent.parent.parent.name @property def ROOT_URLCONF(self) -> str: return f"{self.PROJECT_NAME}.urls" STATIC_URL = "/static/" @property def MEDIA_URL(self) -> str: if self.DEVELOPMENT: return "/media/" else: return f"https://s3.amazonaws.com/{self.AWS_STORAGE_BUCKET_NAME}/" STATIC_ROOT = values.PathValue( default=str(pathlib.Path(PROJECT_PATH) / PROJECT_NAME / "static")) MEDIA_ROOT = values.PathValue( default=str(pathlib.Path(PROJECT_PATH) / PROJECT_NAME / "media")) @property def STATICFILES_STORAGE(self) -> str: if self.DEVELOPMENT: return "django.contrib.staticfiles.storage.StaticFilesStorage" else: return "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" @property def DEFAULT_FILE_STORAGE(self) -> str: if self.DEVELOPMENT: return "django.core.files.storage.FileSystemStorage" else: return "storages.backends.s3boto3.S3Boto3Storage" AWS_ACCESS_KEY_ID = values.Value() AWS_SECRET_ACCESS_KEY = values.Value() AWS_STORAGE_BUCKET_NAME = values.Value() AWS_S3_REGION_NAME = values.Value() AWS_DEFAULT_ACL = None @property def WSGI_APPLICATION(self) -> str: return f"{self.PROJECT_NAME}.wsgi.application" DATABASES = values.DatabaseURLValue(default="sqlite:///db.sqlite3", conn_max_age=None, environ_prefix="DJANGO") INSTALLED_APPS_PROJECT: typing.List[str] = [] INSTALLED_APPS_OTHER: typing.List[str] = [] INSTALLED_APPS_CONTRIB = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.messages", "django.contrib.sessions", "django.contrib.staticfiles", ] INSTALLED_APPS_DEV = [ # conditially added when DEVELOPMENT=True "debug_toolbar", "django_extensions", ] @property def INSTALLED_APPS(self) -> typing.List[str]: additional = self.INSTALLED_APPS_DEV if self.DEVELOPMENT else [] return (self.INSTALLED_APPS_PROJECT + additional + self.INSTALLED_APPS_OTHER + self.INSTALLED_APPS_CONTRIB) MIDDLEWARE_RESPONSE_BEFORE_COMPRESSION: typing.List[str] = [] MIDDLEWARE_RESPONSE_AFTER_COMPRESSION: typing.List[str] = [] MIDDLEWARE_RESPONSE_BEFORE_MINIFY: typing.List[str] = [] MIDDLEWARE_RESPONSE_AFTER_MINIFY: typing.List[str] = [] @property def MIDDLEWARE(self) -> typing.List[str]: return [ i for i in (["firstrussian.middleware.structlog.StructLogMiddleware"] + self.MIDDLEWARE_RESPONSE_AFTER_COMPRESSION + [("django.middleware.gzip.GZipMiddleware" if not self.DEVELOPMENT else None)] + self.MIDDLEWARE_RESPONSE_BEFORE_COMPRESSION + [ ("django.middleware.security.SecurityMiddleware" if not self.DEVELOPMENT else None), ("firstrussian.middleware.whitenoise.StaticAndMediaMiddleware" if not self.DEVELOPMENT else None), ("debug_toolbar.middleware.DebugToolbarMiddleware" if "debug_toolbar" in self.INSTALLED_APPS else None), ("django.contrib.sessions.middleware.SessionMiddleware" if "django.contrib.sessions" in self.INSTALLED_APPS else None), "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", ("django.contrib.auth.middleware.AuthenticationMiddleware" if "django.contrib.auth" in self.INSTALLED_APPS else None), ("django.contrib.messages.middleware.MessageMiddleware" if "django.contrib.messages" in self.INSTALLED_APPS else None), "django.middleware.clickjacking.XFrameOptionsMiddleware", ("django.middleware.locale.LocaleMiddleware" if self. USE_I18N else None), ] + self.MIDDLEWARE_RESPONSE_AFTER_MINIFY + ["django_auxilium.middleware.html.MinifyHTMLMiddleware"] + self.MIDDLEWARE_RESPONSE_BEFORE_MINIFY) if i is not None ] ALLOWED_HOSTS = values.ListValue(default=["*"]) @property def SECRET_KEY(self) -> str: kwargs = {} cls = values.SecretValue if self.DEVELOPMENT: cls = values.Value kwargs["default"] = hashlib.sha256( f"{self.PROJECT_NAME}{socket.gethostname()}".encode( "utf-8")).hexdigest() return typing.cast(str, cls(environ_name="SECRET_KEY", **kwargs)) @property def TEMPLATES(self): return [{ "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [], "APP_DIRS": True, "OPTIONS": { "context_processors": [ i for i in [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.template.context_processors.media", "django.template.context_processors.static", ("django.template.context_processors.i18n" if self. USE_I18N else None), ("django.template.context_processors.tz" if self. USE_TZ else None), ("django.contrib.auth.context_processors.auth" if "django.contrib.auth" in self.INSTALLED_APPS else None ), ("django.contrib.messages.context_processors.messages" if "django.contrib.messages" in self.INSTALLED_APPS else None), ] if i ] }, }] LANGUAGE_CODE = values.Value(default="en") TIME_ZONE = "America/New_York" USE_I18N = True USE_L10N = True USE_TZ = True DEBUG_TOOLBAR_PANELS = [ "debug_toolbar.panels.versions.VersionsPanel", "debug_toolbar.panels.timer.TimerPanel", "debug_toolbar.panels.settings.SettingsPanel", "debug_toolbar.panels.headers.HeadersPanel", "debug_toolbar.panels.request.RequestPanel", "debug_toolbar.panels.sql.SQLPanel", "debug_toolbar.panels.staticfiles.StaticFilesPanel", "debug_toolbar.panels.templates.TemplatesPanel", "debug_toolbar.panels.cache.CachePanel", "debug_toolbar.panels.signals.SignalsPanel", "debug_toolbar.panels.logging.LoggingPanel", "debug_toolbar.panels.redirects.RedirectsPanel", "debug_toolbar.panels.profiling.ProfilingPanel", ] @property def DEBUG_TOOLBAR_CONFIG(self): return {"SHOW_TOOLBAR_CALLBACK": lambda r: self.DEVELOPMENT} REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "firstrussian.pagination.PageNumberPagination", "PAGE_SIZE": 100, }