| import os
|
| from dataclasses import dataclass
|
| from typing import List
|
|
|
| from dotenv import load_dotenv
|
|
|
|
|
| load_dotenv(override=False) |
|
|
|
|
| def _clean_env_value(value: str) -> str:
|
|
|
| v = value.strip()
|
| if len(v) >= 2 and ((v[0] == v[-1] == '"') or (v[0] == v[-1] == "'")):
|
| v = v[1:-1].strip()
|
| return v
|
|
|
|
|
| def _get_env(name: str, default: str | None = None) -> str:
|
| value = os.getenv(name, default)
|
| if value is None or value == "":
|
| raise RuntimeError(f"Missing required environment variable: {name}")
|
| return _clean_env_value(value)
|
|
|
|
|
| def _get_env_optional(name: str, default: str | None = None) -> str | None:
|
| value = os.getenv(name, default)
|
| if value is None or value == "":
|
| return None
|
| return _clean_env_value(value)
|
|
|
|
|
| def _get_bool_env(name: str, default: bool = False) -> bool: |
| raw = os.getenv(name) |
| if raw is None: |
| return default |
| return raw.strip().lower() in {"1", "true", "yes", "y", "on"} |
|
|
|
|
| def _get_bool_env_optional(name: str) -> bool | None: |
| raw = os.getenv(name) |
| if raw is None or raw.strip() == "": |
| return None |
| return raw.strip().lower() in {"1", "true", "yes", "y", "on"} |
|
|
|
|
| def _parse_cors_origins(raw: str | None) -> List[str]:
|
| if not raw:
|
| return ["*"]
|
| parts = [p.strip() for p in raw.split(",")]
|
| return [p for p in parts if p]
|
|
|
|
|
| @dataclass(frozen=True)
|
| class Settings: |
| groq_api_key: str |
| groq_model: str |
| voice_transcription_model: str |
| google_api_key: str | None |
| openrouter_api_key: str | None |
| default_provider: str |
| default_model: str |
| mongodb_uri: str |
| mongodb_tls: bool | None |
| mongodb_db: str |
| mongo_sessions_collection: str
|
| mongo_messages_collection: str
|
| mongo_users_collection: str
|
| max_history_messages: int
|
| max_attachment_chars_per_file: int
|
| max_total_attachment_chars: int
|
| temperature: float
|
| debug: bool
|
| cors_origins: List[str]
|
| jwt_secret: str
|
| jwt_algorithm: str
|
| jwt_exp_minutes: int
|
| tavily_api_key: str | None
|
| tavily_max_results: int
|
| google_client_id: str | None |
| google_client_secret: str | None |
| google_redirect_uri: str | None |
| google_scope: str |
| enable_vector_memory: bool |
| enable_local_vision: bool |
|
|
|
|
| def get_settings() -> Settings:
|
| debug = _get_bool_env("DEBUG", False)
|
| jwt_secret = _get_env_optional("JWT_SECRET", None)
|
| if not jwt_secret and not debug:
|
| raise RuntimeError(
|
| "Missing JWT_SECRET. Set it in your .env (or enable DEBUG=true for a dev-only insecure secret)."
|
| )
|
| return Settings( |
| groq_api_key=_get_env_optional("GROQ_API_KEY", None) or "", |
| groq_model=os.getenv("GROQ_MODEL", "llama-3.3-70b-versatile"), |
| voice_transcription_model=os.getenv("VOICE_TRANSCRIPTION_MODEL", "whisper-large-v3-turbo").strip(), |
| google_api_key=_get_env_optional("GOOGLE_API_KEY", None), |
| openrouter_api_key=_get_env_optional("OPENROUTER_API_KEY", None), |
| default_provider=os.getenv("DEFAULT_LLM_PROVIDER", "groq").strip().lower(), |
| default_model=os.getenv("DEFAULT_LLM_MODEL", "llama-3.3-70b-versatile").strip(), |
| mongodb_uri=_get_env("MONGODB_URI", "mongodb://localhost:27017"), |
| mongodb_tls=_get_bool_env_optional("MONGODB_TLS"), |
| mongodb_db=os.getenv("MONGODB_DB", "own_gpt"), |
| mongo_sessions_collection=os.getenv("MONGO_SESSIONS_COLLECTION", "sessions"),
|
| mongo_messages_collection=os.getenv("MONGO_MESSAGES_COLLECTION", "messages"),
|
| mongo_users_collection=os.getenv("MONGO_USERS_COLLECTION", "users"),
|
| max_history_messages=int(os.getenv("MAX_HISTORY_MESSAGES", "20")),
|
| max_attachment_chars_per_file=int(os.getenv("MAX_ATTACHMENT_CHARS_PER_FILE", "8000")),
|
| max_total_attachment_chars=int(os.getenv("MAX_TOTAL_ATTACHMENT_CHARS", "16000")),
|
| temperature=float(os.getenv("GROQ_TEMPERATURE", "0.2")),
|
| debug=debug,
|
| cors_origins=_parse_cors_origins(_get_env_optional("CORS_ORIGINS", "*")),
|
| jwt_secret=jwt_secret or "dev-only-insecure-jwt-secret",
|
| jwt_algorithm=os.getenv("JWT_ALGORITHM", "HS256"),
|
| jwt_exp_minutes=int(os.getenv("JWT_EXP_MINUTES", "60")),
|
| tavily_api_key=_get_env_optional("TAVILY_API_KEY", None),
|
| tavily_max_results=int(os.getenv("TAVILY_MAX_RESULTS", "5")),
|
| google_client_id=_get_env_optional("GOOGLE_CLIENT_ID", None), |
| google_client_secret=_get_env_optional("GOOGLE_CLIENT_SECRET", None), |
| google_redirect_uri=_get_env_optional("GOOGLE_REDIRECT_URI", None), |
| google_scope=os.getenv("GOOGLE_SCOPE", "openid email profile"), |
| enable_vector_memory=_get_bool_env("ENABLE_VECTOR_MEMORY", True), |
| enable_local_vision=_get_bool_env("ENABLE_LOCAL_VISION", False), |
| ) |
|
|
|
|