2026-07-09 21:40:29 +08:00
|
|
|
"""Runtime settings for backend infrastructure.
|
|
|
|
|
|
|
|
|
|
Model provider credentials live in ``model_resources`` and are resolved per
|
|
|
|
|
assistant. Keep this module limited to process-level settings such as database,
|
|
|
|
|
CORS, server bind address, and WebRTC ICE/TURN configuration.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
|
load_dotenv()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _split(value: str) -> list[str]:
|
|
|
|
|
return [item.strip() for item in value.split(",") if item.strip()]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---- Database ----
|
|
|
|
|
DATABASE_URL = os.getenv(
|
|
|
|
|
"DATABASE_URL",
|
|
|
|
|
"postgresql+asyncpg://postgres:postgres@localhost:5432/postgres",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# ---- Service ----
|
|
|
|
|
HOST = os.getenv("HOST", "0.0.0.0")
|
|
|
|
|
PORT = int(os.getenv("PORT", "8000"))
|
|
|
|
|
CORS_ORIGINS = _split(
|
|
|
|
|
os.getenv("CORS_ORIGINS", "http://localhost:3000,http://127.0.0.1:3000")
|
|
|
|
|
)
|
|
|
|
|
|
2026-07-09 23:27:50 +08:00
|
|
|
# ---- Admin auth ----
|
|
|
|
|
ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin")
|
|
|
|
|
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "znjj189981$")
|
|
|
|
|
AUTH_SECRET_KEY = os.getenv("AUTH_SECRET_KEY", "dev-secret-change-me")
|
|
|
|
|
AUTH_COOKIE_NAME = os.getenv("AUTH_COOKIE_NAME", "ai_video_admin_token")
|
|
|
|
|
AUTH_TOKEN_EXPIRE_MINUTES = int(os.getenv("AUTH_TOKEN_EXPIRE_MINUTES", "1440"))
|
|
|
|
|
AUTH_COOKIE_SECURE = os.getenv("AUTH_COOKIE_SECURE", "false").lower() == "true"
|
|
|
|
|
AUTH_COOKIE_SAMESITE = os.getenv("AUTH_COOKIE_SAMESITE", "lax")
|
|
|
|
|
|
2026-08-11 10:05:55 +08:00
|
|
|
# ---- Public Realtime API auth ----
|
|
|
|
|
# Keep public integration credentials separate from the admin login cookie.
|
|
|
|
|
# Production deployments should set a dedicated random secret.
|
|
|
|
|
REALTIME_TOKEN_SECRET = os.getenv("REALTIME_TOKEN_SECRET", AUTH_SECRET_KEY)
|
|
|
|
|
REALTIME_CLIENT_SECRET_TTL_SECONDS = int(
|
|
|
|
|
os.getenv("REALTIME_CLIENT_SECRET_TTL_SECONDS", "60")
|
|
|
|
|
)
|
2026-09-07 00:15:32 +08:00
|
|
|
RESPONSES_REQUEST_TIMEOUT_SECONDS = int(
|
|
|
|
|
os.getenv("RESPONSES_REQUEST_TIMEOUT_SECONDS", "120")
|
|
|
|
|
)
|
2026-08-11 10:05:55 +08:00
|
|
|
|
2026-08-05 14:05:22 +08:00
|
|
|
# ---- WebRTC STUN / TURN ----
|
|
|
|
|
# Override STUN_URL in remote deployments to use the colocated coturn server
|
|
|
|
|
# instead of waiting for a public STUN service that may be unreachable.
|
|
|
|
|
STUN_URL = os.getenv("STUN_URL", "stun:stun.l.google.com:19302")
|
|
|
|
|
|
2026-07-09 21:40:29 +08:00
|
|
|
# TURN_URLS example:
|
2026-08-05 14:05:22 +08:00
|
|
|
# turn:118.89.89.89:3478?transport=udp,turn:118.89.89.89:3478?transport=tcp
|
2026-07-09 21:40:29 +08:00
|
|
|
TURN_URLS = _split(os.getenv("TURN_URLS", ""))
|
|
|
|
|
TURN_SECRET = os.getenv("TURN_SECRET", "")
|
|
|
|
|
TURN_USERNAME = os.getenv("TURN_USERNAME", "")
|
|
|
|
|
TURN_PASSWORD = os.getenv("TURN_PASSWORD", "")
|
|
|
|
|
TURN_CREDENTIAL_TTL = int(os.getenv("TURN_CREDENTIAL_TTL", "86400"))
|
2026-07-12 13:58:47 +08:00
|
|
|
|
|
|
|
|
# ---- S3-compatible object storage (RustFS in local compose) ----
|
2026-08-05 21:28:51 +08:00
|
|
|
S3_ENDPOINT_URL = os.getenv("S3_ENDPOINT_URL", "http://127.0.0.1:9000")
|
2026-07-12 13:58:47 +08:00
|
|
|
S3_ACCESS_KEY = os.getenv("S3_ACCESS_KEY", "rustfsadmin")
|
|
|
|
|
S3_SECRET_KEY = os.getenv("S3_SECRET_KEY", "rustfsadmin")
|
|
|
|
|
S3_BUCKET = os.getenv("S3_BUCKET", "ai-video")
|
|
|
|
|
S3_REGION = os.getenv("S3_REGION", "us-east-1")
|
|
|
|
|
KNOWLEDGE_MAX_FILE_BYTES = int(os.getenv("KNOWLEDGE_MAX_FILE_BYTES", "20971520"))
|
|
|
|
|
KNOWLEDGE_TOP_K = int(os.getenv("KNOWLEDGE_TOP_K", "5"))
|
2026-08-05 19:52:37 +08:00
|
|
|
|
|
|
|
|
# ---- Realtime user-input image attachments ----
|
|
|
|
|
INPUT_IMAGE_MAX_BYTES = int(os.getenv("INPUT_IMAGE_MAX_BYTES", "10485760"))
|
|
|
|
|
INPUT_IMAGE_MAX_PIXELS = int(os.getenv("INPUT_IMAGE_MAX_PIXELS", "24000000"))
|
|
|
|
|
INPUT_IMAGE_MAX_EDGE = int(os.getenv("INPUT_IMAGE_MAX_EDGE", "2048"))
|
|
|
|
|
INPUT_IMAGE_TOKEN_TTL_SECONDS = int(
|
|
|
|
|
os.getenv("INPUT_IMAGE_TOKEN_TTL_SECONDS", "600")
|
|
|
|
|
)
|