Files
fa-agent/server/settings.py
2026-09-26 01:12:10 +08:00

103 lines
4.2 KiB
Python

import os
from pathlib import Path
from urllib.parse import unquote, urlparse
from django.core.exceptions import ImproperlyConfigured
BASE_DIR = Path(__file__).resolve().parent.parent
PRODUCTION = os.environ.get("APP_ENV") == "production"
SECRET_KEY = os.environ.get("SECRET_KEY", "development-only-not-for-production-traceiq")
if PRODUCTION and (len(SECRET_KEY) < 50 or SECRET_KEY.startswith("development")):
raise ImproperlyConfigured("Set a random SECRET_KEY of at least 50 characters")
DEBUG = not PRODUCTION
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "localhost,127.0.0.1,testserver").split(",")
CSRF_TRUSTED_ORIGINS = [x for x in os.environ.get("CSRF_TRUSTED_ORIGINS", "").split(",") if x]
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.staticfiles",
"finance",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"finance.middleware.SecurityHeaders",
]
ROOT_URLCONF = "server.urls"
WSGI_APPLICATION = "server.wsgi.application"
url = os.environ.get("DATABASE_URL")
if url:
db = urlparse(url)
if db.scheme not in ("postgres", "postgresql"):
raise ImproperlyConfigured("DATABASE_URL must be PostgreSQL")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": db.path[1:],
"USER": unquote(db.username or ""),
"PASSWORD": unquote(db.password or ""),
"HOST": db.hostname,
"PORT": db.port or 5432,
"CONN_MAX_AGE": 60,
"OPTIONS": {"sslmode": os.environ.get("DB_SSLMODE", "prefer")},
}
}
else:
if PRODUCTION:
raise ImproperlyConfigured("Production requires DATABASE_URL")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.environ.get("SQLITE_PATH", str(BASE_DIR / "var/db.sqlite3")),
"OPTIONS": {"timeout": 30},
}
}
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "OPTIONS": {"min_length": 12}},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
LANGUAGE_CODE = "zh-hans"
TIME_ZONE = "UTC"
USE_TZ = True
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_AGE = 8 * 3600
SESSION_COOKIE_SECURE = PRODUCTION
CSRF_COOKIE_SECURE = PRODUCTION
SECURE_SSL_REDIRECT = PRODUCTION and os.environ.get("SECURE_SSL_REDIRECT", "1") == "1"
SECURE_HSTS_SECONDS = 31536000 if PRODUCTION else 0
SECURE_HSTS_INCLUDE_SUBDOMAINS = PRODUCTION
SECURE_HSTS_PRELOAD = PRODUCTION
# Enable only behind the private reverse proxy which overwrites this header.
TRUST_PROXY = os.environ.get("TRUST_PROXY", "0") == "1"
if TRUST_PROXY:
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = "DENY"
DATA_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024
FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024
MEDIA_ROOT = Path(os.environ.get("MEDIA_ROOT", BASE_DIR / "var/uploads"))
STATIC_URL = "/assets/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_DIRS = [BASE_DIR / "frontend/dist/assets"] if (BASE_DIR / "frontend/dist/assets").exists() else []
MAX_UPLOAD_BYTES = int(os.environ.get("MAX_UPLOAD_BYTES", 64 * 1024 * 1024))
MAX_IMPORT_ROWS = int(os.environ.get("MAX_IMPORT_ROWS", 1000000))
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "")
AI_ENABLED = os.environ.get("AI_ENABLED", "0") == "1"
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {"console": {"class": "logging.StreamHandler"}},
"root": {"handlers": ["console"], "level": "INFO"},
}