Files
wger/settings/main.py
Github-actions ea626844af Automatic linting
2026-01-11 20:29:13 +00:00

278 lines
9.8 KiB
Python

# This file is part of wger Workout Manager.
#
# wger Workout Manager is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wger Workout Manager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# ruff: noqa: F405
# Third Party
import environ
# wger
from .settings_global import * # noqa: F403
"""
Main settings file for a production deployment of wger.
For a more commented version of the options used here, please refer to
https://github.com/wger-project/docker/blob/master/config/prod.env
"""
env = environ.Env(
# set casting, default value
DJANGO_DEBUG=(bool, False)
)
# Use 'DEBUG = True' to get more details for server errors
DEBUG = env('DJANGO_DEBUG')
if os.environ.get('DJANGO_ADMINS'):
ADMINS = [
env.tuple('DJANGO_ADMINS'),
]
MANAGERS = ADMINS
if os.environ.get('DJANGO_DB_ENGINE'):
DATABASES = {
'default': {
'ENGINE': env.str('DJANGO_DB_ENGINE'),
'NAME': env.str('DJANGO_DB_DATABASE'),
'USER': env.str('DJANGO_DB_USER'),
'PASSWORD': env.str('DJANGO_DB_PASSWORD'),
'HOST': env.str('DJANGO_DB_HOST'),
'PORT': env.int('DJANGO_DB_PORT'),
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': env.str('DJANGO_DB_DATABASE', '/home/wger/db/database.sqlite'),
}
}
# Timezone for this installation. Consult settings_global.py for more information
TIME_ZONE = env.str('TIME_ZONE', 'Europe/Berlin')
# Make this unique, and don't share it with anybody.
# Generate e.g. with: python -c "import secrets; print(secrets.token_urlsafe(50))" or https://djecrety.ir/
SECRET_KEY = env.str('SECRET_KEY', 'wger-docker-supersecret-key-1234567890!@#$%^&*(-_)')
# Your reCaptcha keys
RECAPTCHA_PUBLIC_KEY = env.str('RECAPTCHA_PUBLIC_KEY', '')
RECAPTCHA_PRIVATE_KEY = env.str('RECAPTCHA_PRIVATE_KEY', '')
# The site's URL (e.g. http://www.my-local-gym.com or http://localhost:8000)
# This is needed for uploaded files and images (exercise images, etc.) to be
# properly served.
SITE_URL = env.str('SITE_URL', 'http://localhost:8000')
# Path to uploaded files
# Absolute filesystem path to the directory that will hold user-uploaded files.
MEDIA_ROOT = env.str('DJANGO_MEDIA_ROOT', '/home/wger/media')
STATIC_ROOT = env.str('DJANGO_STATIC_ROOT', '/home/wger/static')
# If you change these, adjust nginx alias definitions as well
MEDIA_URL = env.str('MEDIA_URL', '/media/')
STATIC_URL = env.str('STATIC_URL', '/static/')
LOGIN_REDIRECT_URL = env.str('LOGIN_REDIRECT_URL', '/')
# Allow all hosts to access the application. Change if used in production.
ALLOWED_HOSTS = [
'*',
]
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# Configure a real backend in production
if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
if env.bool('ENABLE_EMAIL', False):
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = env.str('EMAIL_HOST')
EMAIL_PORT = env.int('EMAIL_PORT')
EMAIL_HOST_USER = env.str('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = env.str('EMAIL_HOST_PASSWORD')
EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', True)
EMAIL_USE_SSL = env.bool('EMAIL_USE_SSL', False)
EMAIL_TIMEOUT = 60
# Sender address used for sent emails
DEFAULT_FROM_EMAIL = env.str('FROM_EMAIL', 'wger Workout Manager <wger@example.com>')
WGER_SETTINGS['EMAIL_FROM'] = DEFAULT_FROM_EMAIL
SERVER_EMAIL = DEFAULT_FROM_EMAIL
EMAIL_FROM_ADDRESS = DEFAULT_FROM_EMAIL
# Management
WGER_SETTINGS['ALLOW_GUEST_USERS'] = env.bool('ALLOW_GUEST_USERS', True)
WGER_SETTINGS['ALLOW_REGISTRATION'] = env.bool('ALLOW_REGISTRATION', True)
WGER_SETTINGS['ALLOW_UPLOAD_VIDEOS'] = env.bool('ALLOW_UPLOAD_VIDEOS', True)
WGER_SETTINGS['DOWNLOAD_INGREDIENTS_FROM'] = env.str('DOWNLOAD_INGREDIENTS_FROM', 'WGER')
WGER_SETTINGS['EXERCISE_CACHE_TTL'] = env.int('EXERCISE_CACHE_TTL', 3600)
WGER_SETTINGS['MIN_ACCOUNT_AGE_TO_TRUST'] = env.int('MIN_ACCOUNT_AGE_TO_TRUST', 21) # in days
WGER_SETTINGS['SYNC_EXERCISES_CELERY'] = env.bool('SYNC_EXERCISES_CELERY', False)
WGER_SETTINGS['SYNC_EXERCISE_IMAGES_CELERY'] = env.bool('SYNC_EXERCISE_IMAGES_CELERY', False)
WGER_SETTINGS['SYNC_EXERCISE_VIDEOS_CELERY'] = env.bool('SYNC_EXERCISE_VIDEOS_CELERY', False)
WGER_SETTINGS['SYNC_INGREDIENTS_CELERY'] = env.bool('SYNC_INGREDIENTS_CELERY', False)
WGER_SETTINGS['SYNC_OFF_DAILY_DELTA_CELERY'] = env.bool('SYNC_OFF_DAILY_DELTA_CELERY', False)
WGER_SETTINGS['USE_RECAPTCHA'] = env.bool('USE_RECAPTCHA', False)
WGER_SETTINGS['USE_CELERY'] = env.bool('USE_CELERY', False)
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY'] = env.bool('CACHE_API_EXERCISES_CELERY', False)
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY_FORCE_UPDATE'] = env.bool(
'CACHE_API_EXERCISES_CELERY_FORCE_UPDATE', False
)
#
# Auth Proxy Authentication
# https://wger.readthedocs.io/en/latest/administration/auth_proxy.html
AUTH_PROXY_HEADER = env.str('AUTH_PROXY_HEADER', '')
AUTH_PROXY_TRUSTED_IPS = env.list('AUTH_PROXY_TRUSTED_IPS', default=[])
AUTH_PROXY_CREATE_UNKNOWN_USER = env.bool('AUTH_PROXY_CREATE_UNKNOWN_USER', False)
AUTH_PROXY_USER_EMAIL_HEADER = env.str('AUTH_PROXY_USER_EMAIL_HEADER', '')
AUTH_PROXY_USER_NAME_HEADER = env.str('AUTH_PROXY_USER_NAME_HEADER', '')
# Cache
if os.environ.get('DJANGO_CACHE_BACKEND'):
CACHES = {
'default': {
'BACKEND': env.str('DJANGO_CACHE_BACKEND'),
'LOCATION': env.str('DJANGO_CACHE_LOCATION', ''),
'TIMEOUT': env.int('DJANGO_CACHE_TIMEOUT', 300),
'OPTIONS': {'CLIENT_CLASS': env.str('DJANGO_CACHE_CLIENT_CLASS', '')},
}
}
if os.environ.get('DJANGO_CACHE_CLIENT_PASSWORD'):
CACHES['default']['OPTIONS']['PASSWORD'] = env.str('DJANGO_CACHE_CLIENT_PASSWORD')
CONNECTION_POOL_KWARGS = dict()
if 'DJANGO_CACHE_CLIENT_SSL_KEYFILE' in os.environ:
CONNECTION_POOL_KWARGS['ssl_keyfile'] = env.str('DJANGO_CACHE_CLIENT_SSL_KEYFILE')
if 'DJANGO_CACHE_CLIENT_SSL_CERTFILE' in os.environ:
CONNECTION_POOL_KWARGS['ssl_certfile'] = env.str('DJANGO_CACHE_CLIENT_SSL_CERTFILE')
if 'DJANGO_CACHE_CLIENT_SSL_CERT_REQS' in os.environ:
CONNECTION_POOL_KWARGS['ssl_cert_reqs'] = env.str('DJANGO_CACHE_CLIENT_SSL_CERT_REQS')
if 'DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME' in os.environ:
CONNECTION_POOL_KWARGS['ssl_check_hostname'] = env.bool(
'DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME'
)
if CONNECTION_POOL_KWARGS:
CACHES['default']['OPTIONS']['CONNECTION_POOL_KWARGS'] = CONNECTION_POOL_KWARGS
#
# Django Compressor
# Consult https://django-compressor.readthedocs.io/en/stable/ for more information
# (specially the offline compression part)
#
COMPRESS_ROOT = STATIC_ROOT
COMPRESS_ENABLED = env.bool('COMPRESS_ENABLED', not DEBUG)
COMPRESS_OFFLINE = env.bool('COMPRESS_OFFLINE', False)
# The site's domain as used by the email verification workflow
EMAIL_PAGE_DOMAIN = SITE_URL
#
# Django Axes
#
AXES_ENABLED = env.bool('AXES_ENABLED', True)
AXES_LOCKOUT_PARAMETERS = env.list('AXES_LOCKOUT_PARAMETERS', default=['ip_address'])
AXES_FAILURE_LIMIT = env.int('AXES_FAILURE_LIMIT', 10)
AXES_COOLOFF_TIME = timedelta(minutes=env.float('AXES_COOLOFF_TIME', 30))
AXES_HANDLER = env.str('AXES_HANDLER', 'axes.handlers.cache.AxesCacheHandler')
AXES_IPWARE_PROXY_COUNT = env.int('AXES_IPWARE_PROXY_COUNT', 0)
AXES_IPWARE_META_PRECEDENCE_ORDER = env.list(
'AXES_IPWARE_META_PRECEDENCE_ORDER', default=['REMOTE_ADDR']
)
#
# Django Rest Framework SimpleJWT
#
SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'] = timedelta(minutes=env.int('ACCESS_TOKEN_LIFETIME', 15))
SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'] = timedelta(hours=env.int('REFRESH_TOKEN_LIFETIME', 24))
SIMPLE_JWT['SIGNING_KEY'] = env.str('SIGNING_KEY', SECRET_KEY)
#
# https://docs.djangoproject.com/en/4.1/ref/csrf/
#
CSRF_TRUSTED_ORIGINS = env.list(
'CSRF_TRUSTED_ORIGINS',
default=['http://127.0.0.1', 'http://localhost', 'https://localhost'],
)
if env.bool('X_FORWARDED_PROTO_HEADER_SET', False):
SECURE_PROXY_SSL_HEADER = (
env.str('SECURE_PROXY_SSL_HEADER', 'HTTP_X_FORWARDED_PROTO'),
'https',
)
REST_FRAMEWORK['NUM_PROXIES'] = env.int('NUMBER_OF_PROXIES', 1)
#
# Celery message queue configuration
#
CELERY_BROKER_URL = env.str('CELERY_BROKER', 'redis://cache:6379/2')
CELERY_RESULT_BACKEND = env.str('CELERY_BACKEND', 'redis://cache:6379/2')
#
# Prometheus metrics
#
EXPOSE_PROMETHEUS_METRICS = env.bool('EXPOSE_PROMETHEUS_METRICS', False)
PROMETHEUS_URL_PATH = env.str('PROMETHEUS_URL_PATH', 'super-secret-path')
#
# Logging
#
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': 'level={levelname} ts={asctime} module={module} path={pathname} line={lineno} message={message}',
'style': '{',
},
},
'handlers': {
'console': {'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple'},
},
'loggers': {
'': {
'handlers': ['console'],
'level': env.str('LOG_LEVEL_PYTHON', 'INFO').upper(),
'propagate': True,
},
},
}
#
# Storage options
#
STORAGES = {
'default': {
'BACKEND': env.str(
'DJANGO_STORAGES_DEFAULT_BACKEND', 'django.core.files.storage.FileSystemStorage'
),
},
# django.contrib.staticfiles.storage.StaticFilesStorage
'staticfiles': {
'BACKEND': env.str(
'DJANGO_STORAGES_STATICFILES_BACKEND',
'wger.core.storage.LenientManifestStaticFilesStorage',
),
},
}