Files
classifieds/app/config.py
T
2026-06-15 11:23:05 -04:00

86 lines
2.8 KiB
Python

"""Application configuration. Env-driven, Dev/Prod classes."""
import os
from dotenv import load_dotenv
load_dotenv()
def _bool(val, default=False):
if val is None:
return default
return str(val).strip().lower() in ("1", "true", "yes", "on")
class BaseConfig:
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-insecure-change-me")
# --- Database ---
@staticmethod
def _database_uri():
url = os.environ.get("DATABASE_URL")
if url:
return url
user = os.environ.get("DB_USER", "classifieds")
pwd = os.environ.get("DB_PASSWORD", "")
host = os.environ.get("DB_HOST", "127.0.0.1")
port = os.environ.get("DB_PORT", "3306")
name = os.environ.get("DB_NAME", "classifieds")
return f"mysql+pymysql://{user}:{pwd}@{host}:{port}/{name}?charset=utf8mb4"
SQLALCHEMY_DATABASE_URI = _database_uri.__func__()
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ENGINE_OPTIONS = {"pool_pre_ping": True, "pool_recycle": 280}
# --- Redis ---
REDIS_URL = os.environ.get("REDIS_URL", "redis://127.0.0.1:6379/0")
RATELIMIT_STORAGE_URI = REDIS_URL
# --- i18n ---
DEFAULT_LOCALE = os.environ.get("DEFAULT_LOCALE", "en")
SUPPORTED_LOCALES = [
s.strip() for s in os.environ.get("SUPPORTED_LOCALES", "en,vi,es").split(",") if s.strip()
]
BABEL_DEFAULT_LOCALE = DEFAULT_LOCALE
BABEL_TRANSLATION_DIRECTORIES = "translations"
# --- Email ---
MAIL_SERVER = os.environ.get("MAIL_SERVER", "")
MAIL_PORT = int(os.environ.get("MAIL_PORT", "587"))
MAIL_USE_TLS = _bool(os.environ.get("MAIL_USE_TLS"), True)
MAIL_USERNAME = os.environ.get("MAIL_USERNAME", "")
MAIL_PASSWORD = os.environ.get("MAIL_PASSWORD", "")
MAIL_FROM = os.environ.get("MAIL_FROM", "no-reply@example.com")
MAIL_FROM_NAME = os.environ.get("MAIL_FROM_NAME", "Classifieds")
# --- Turnstile ---
TURNSTILE_SITE_KEY = os.environ.get("TURNSTILE_SITE_KEY", "")
TURNSTILE_SECRET_KEY = os.environ.get("TURNSTILE_SECRET_KEY", "")
# --- Token lifetimes ---
TOKEN_VERIFY_MAX_AGE = int(os.environ.get("TOKEN_VERIFY_MAX_AGE", "86400"))
TOKEN_RESET_MAX_AGE = int(os.environ.get("TOKEN_RESET_MAX_AGE", "3600"))
# --- Media (uploaded images) ---
MEDIA_ROOT = os.environ.get("MEDIA_ROOT") or None # default: instance/media
# --- Session cookie hardening ---
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
PREFERRED_URL_SCHEME = "https"
class DevConfig(BaseConfig):
DEBUG = True
SESSION_COOKIE_SECURE = False
class ProdConfig(BaseConfig):
DEBUG = False
SESSION_COOKIE_SECURE = True
SERVER_NAME = os.environ.get("SERVER_NAME") or None
def get_config():
name = os.environ.get("FLASK_CONFIG", "dev").lower()
return ProdConfig if name == "prod" else DevConfig