""" Base settings to build other settings files upon. """ import warnings from datetime import timedelta from pathlib import Path import environ import structlog from celery.schedules import crontab from urllib3.connectionpool import InsecureRequestWarning ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent # passfinder/ APPS_DIR = ROOT_DIR / "passfinder" env = environ.Env() READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=True) if READ_DOT_ENV_FILE: # OS environment variables take precedence over variables from .env env.read_env(str(ROOT_DIR / ".env")) # GENERAL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = env.bool("DJANGO_DEBUG", False) # Local time zone. Choices are # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # though not all of them may be available with every OS. # In Windows, this must be set to your system time zone. TIME_ZONE = "Europe/Moscow" # https://docs.djangoproject.com/en/dev/ref/settings/#language-code LANGUAGE_CODE = "en-us" # https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True # https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True # https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths LOCALE_PATHS = [str(ROOT_DIR / "locale")] # DATABASES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = { "default": env.db( "DATABASE_URL", "postgres://postgres:Ilvas2006@localhost:5432/passfinder" ) } DATABASES["default"]["ATOMIC_REQUESTS"] = True # https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_AUTO_FIELD DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # URLS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf ROOT_URLCONF = "config.urls" # https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = "config.wsgi.application" # APPS # ------------------------------------------------------------------------------ DJANGO_APPS = [ "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", # "django.contrib.humanize", # Handy template tags "django.contrib.admin", "django.forms", ] THIRD_PARTY_APPS = [ "django_celery_beat", "rest_framework", "rest_framework.authtoken", "corsheaders", "drf_spectacular", "location_field", "polymorphic", "django_clickhouse", ] LOCAL_APPS = ["passfinder.users", "passfinder.events", "passfinder.recomendations"] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # MIGRATIONS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#migration-modules MIGRATION_MODULES = {"sites": "passfinder.contrib.sites.migrations"} # AUTHENTICATION # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#authentication-backends AUTHENTICATION_BACKENDS = [ "django.contrib.auth.backends.ModelBackend", ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model AUTH_USER_MODEL = "users.User" # PASSWORDS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#password-hashers PASSWORD_HASHERS = [ # https://docs.djangoproject.com/en/dev/topics/auth/passwords/#using-argon2-with-django "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ] # https://docs.djangoproject.com/en/dev/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"}, ] # MIDDLEWARE # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#middleware MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "corsheaders.middleware.CorsMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.common.BrokenLinkEmailsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] # STATIC # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = str(ROOT_DIR / "staticfiles") # https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = "/static/" # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = [str(APPS_DIR / "static")] # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders STATICFILES_FINDERS = [ "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", ] # MEDIA # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#media-root MEDIA_ROOT = str(APPS_DIR / "media") # https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = "/media/" # TEMPLATES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#templates TEMPLATES = [ { # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND "BACKEND": "django.template.backends.django.DjangoTemplates", # https://docs.djangoproject.com/en/dev/ref/settings/#dirs "DIRS": [str(APPS_DIR / "templates")], # https://docs.djangoproject.com/en/dev/ref/settings/#app-dirs "APP_DIRS": True, "OPTIONS": { # https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors "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", ], }, } ] # https://docs.djangoproject.com/en/dev/ref/settings/#form-renderer FORM_RENDERER = "django.forms.renderers.TemplatesSetting" # FIXTURES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#fixture-dirs FIXTURE_DIRS = (str(APPS_DIR / "fixtures"),) # SECURITY # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-httponly SESSION_COOKIE_HTTPONLY = True # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly CSRF_COOKIE_HTTPONLY = True # https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter SECURE_BROWSER_XSS_FILTER = True # https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options X_FRAME_OPTIONS = "DENY" # ADMIN # ------------------------------------------------------------------------------ # Django Admin URL. ADMIN_URL = "admin/" # https://docs.djangoproject.com/en/dev/ref/settings/#admins ADMINS = [("""sanspie""", "sanspie@akarpov.ru")] # https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS # LOGGING # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#logging # See https://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { "json_formatter": { "()": structlog.stdlib.ProcessorFormatter, "processor": structlog.processors.JSONRenderer(), }, "plain_console": { "()": structlog.stdlib.ProcessorFormatter, "processor": structlog.dev.ConsoleRenderer(), }, "key_value": { "()": structlog.stdlib.ProcessorFormatter, "processor": structlog.processors.KeyValueRenderer( key_order=["timestamp", "level", "event", "logger"] ), }, }, "handlers": { "console": { "class": "logging.StreamHandler", "formatter": "plain_console", }, "json_file": { "class": "logging.handlers.WatchedFileHandler", "filename": "logs/json.log", "formatter": "json_formatter", }, "flat_line_file": { "class": "logging.handlers.WatchedFileHandler", "filename": "logs/flat_line.log", "formatter": "key_value", }, }, "loggers": { "django_structlog": { "handlers": ["console", "flat_line_file", "json_file"], "level": "INFO", }, # Make sure to replace the following logger's name for yours "django_structlog_demo_project": { "handlers": ["console", "flat_line_file", "json_file"], "level": "INFO", }, }, } structlog.configure( processors=[ structlog.contextvars.merge_contextvars, structlog.stdlib.filter_by_level, structlog.processors.TimeStamper(fmt="iso"), structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), structlog.stdlib.ProcessorFormatter.wrap_for_formatter, ], logger_factory=structlog.stdlib.LoggerFactory(), cache_logger_on_first_use=True, ) # CELERY # -------------------------------------------------------------------------------------------------- CELERY_REDIS_HOST = env("CELERY_REDIS_HOST", default="127.0.0.1") CELERY_REDIS_PORT = env.int("CELERY_REDIS_PORT", default=6379) CELERY_REDIS_USER = env("CELERY_REDIS_USER", default=None) CELERY_REDIS_PASSWORD = env("CELERY_REDIS_PASSWORD", default=None) CELERY_REDIS_DB = env("CELERY_REDIS_DB", default=0) CELERY_REDIS_SSL = env.bool("CELERY_REDIS_SSL", default=False) CELERY_BROKER_URL = env("CELERY_BROKER_URL", default="") CELERY_TASK_SERIALIZER = "json" CELERY_ACCEPT_CONTENT = ["application/json"] CELERY_ENABLE_UTC = True CELERY_BEAT_SCHEDULE = { "clickhouse_auto_sync": { "task": "django_clickhouse.tasks.clickhouse_auto_sync", "schedule": timedelta(seconds=5), "options": {"expires": 1}, }, "check_temperature": { "task": "passfinder.events.tasks.check_temperature", "schedule": crontab( minute="0", hour="3", day_of_week="*", day_of_month="*", month_of_year="*" ), }, "precalculate_nearest_points": { "task": "passfinder.recomendations.tasks.run_precalc", "schedule": crontab( minute="0", hour="7", day_of_week="*", day_of_month="*", month_of_year="*" ), }, } # DRF # ------------------------------------------------------------------------------- # django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( "rest_framework_simplejwt.authentication.JWTAuthentication", ), "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", } # django-cors-headers - https://github.com/adamchainz/django-cors-headers#setup CORS_URLS_REGEX = r"^/api/.*$" # By Default swagger ui is available only to admin user(s). You can change permission classes to change that # See more configuration options at https://drf-spectacular.readthedocs.io/en/latest/settings.html#settings SPECTACULAR_SETTINGS = { "TITLE": "Pass Finder API", "DESCRIPTION": "Documentation of API endpoints of Pass Finder", "VERSION": "1.0.0", "SERVE_PERMISSIONS": [], "SERVERS": [ {"url": "https://dev2.akarpov.ru", "description": "Production server"}, {"url": "http://127.0.0.1:8000", "description": "Local Development server"}, ], } LOCATION_FIELD = { "map.provider": "openstreetmap", "search.provider": "nominatim", } SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(days=30), "REFRESH_TOKEN_LIFETIME": timedelta(weeks=50), } # CLICKHOUSE # ------------------------------------------------------------------------------ CLICKHOUSE_DATABASES = { "default": { "db_url": env("CLICKHOUSE_URL", default="http://localhost:8123"), "db_name": env("CLICKHOUSE_DB", default="default"), "username": env("CLICKHOUSE_USER", default="default"), "password": env("CLICKHOUSE_PASSWORD", default="default"), "verify_ssl_cert": False, } } warnings.filterwarnings("ignore", category=InsecureRequestWarning) CLICKHOUSE_REDIS_CONFIG = { "host": env("CLICKHOUSE_REDIS_HOST", default="127.0.0.1"), "port": env("CLICKHOUSE_REDIS_PORT", default=6379), "db": env("CLICKHOUSE_REDIS_DB", default=0), "username": env("CLICKHOUSE_REDIS_USER", default=None), "password": env("CLICKHOUSE_REDIS_PASSWORD", default=None), "socket_timeout": 10, } YANDEX_TOKEN = env("YANDEX_TOKEN", default="")