- Support multiple OAuth providers (core-api, tatlock-ui, tatlock) - Changed oidc_issuer (string) to oidc_issuers (list) - Per-issuer JWKS caching - Validates token issuer against allowed list - Consolidated config files (removed deprecated src/config.py, src/security.py) - Updated imports to use src/shared/config and src/shared/security 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
117 lines
3.5 KiB
Python
117 lines
3.5 KiB
Python
"""
|
|
Global configuration for Core Code API
|
|
|
|
All configuration is loaded from environment variables or .env file.
|
|
See .env.example for available settings.
|
|
"""
|
|
import tomllib
|
|
from pathlib import Path
|
|
from pydantic_settings import BaseSettings
|
|
from functools import lru_cache
|
|
|
|
|
|
def _get_version_from_pyproject() -> str:
|
|
"""Load version from pyproject.toml"""
|
|
pyproject_path = Path(__file__).parent.parent.parent / "pyproject.toml"
|
|
try:
|
|
with open(pyproject_path, "rb") as f:
|
|
data = tomllib.load(f)
|
|
return data.get("project", {}).get("version", "0.0.0")
|
|
except FileNotFoundError:
|
|
return "0.0.0"
|
|
|
|
|
|
__version__ = _get_version_from_pyproject()
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
"""Global application settings"""
|
|
|
|
# Application
|
|
app_name: str = "Core Code API"
|
|
app_version: str = __version__
|
|
debug: bool = False
|
|
|
|
# Server
|
|
host: str = "0.0.0.0"
|
|
port: int = 8083
|
|
|
|
# CORS - Note: When cors_credentials is True, cannot use "*" for origins
|
|
# Set CORS_ORIGINS env var to override (comma-separated list)
|
|
cors_origins: list[str] = [
|
|
"https://home.schweitz.net",
|
|
"https://tatlock.schweitz.net",
|
|
"http://localhost:8080",
|
|
"http://localhost:3000",
|
|
"http://127.0.0.1:8080",
|
|
]
|
|
cors_credentials: bool = True
|
|
cors_methods: list[str] = ["*"]
|
|
cors_headers: list[str] = ["*"]
|
|
|
|
# Logging
|
|
log_level: str = "DEBUG"
|
|
|
|
# Qdrant Configuration
|
|
qdrant_host: str = "qdrant"
|
|
qdrant_port: int = 6333
|
|
qdrant_collection_conversations: str = "core_api_conversations"
|
|
qdrant_collection_documents: str = "core_api_documents"
|
|
qdrant_collection_user_facts: str = "core_api_user_facts"
|
|
|
|
# Search Configuration
|
|
search_provider: str = "searxng"
|
|
searxng_url: str # Required - set SEARXNG_URL in .env
|
|
|
|
# Infrastructure Management (Portainer)
|
|
portainer_url: str # Required
|
|
portainer_api_key: str # Required
|
|
|
|
# Infrastructure Management (Nginx Proxy Manager)
|
|
npm_url: str # Required
|
|
npm_email: str # Required
|
|
npm_password: str # Required
|
|
|
|
# Home Assistant Configuration
|
|
homeassistant_url: str # Required
|
|
homeassistant_token: str # Required
|
|
homeassistant_timeout: int = 30
|
|
|
|
# PostgreSQL Database
|
|
postgres_host: str # Required
|
|
postgres_user: str = "core_api"
|
|
postgres_password: str # Required
|
|
postgres_database: str = "core_api"
|
|
|
|
@property
|
|
def database_url(self) -> str:
|
|
"""Construct database URL from components"""
|
|
return f"postgresql://{self.postgres_user}:{self.postgres_password}@{self.postgres_host}/{self.postgres_database}"
|
|
|
|
# OIDC Authentication (Authentik)
|
|
oidc_enabled: bool = False
|
|
# Accept tokens from multiple OAuth providers (each has its own issuer/JWKS)
|
|
oidc_issuers: list[str] = [
|
|
"https://auth.schweitz.net/application/o/core-api/",
|
|
"https://auth.schweitz.net/application/o/tatlock-ui/",
|
|
"https://auth.schweitz.net/application/o/tatlock/",
|
|
]
|
|
# Accept tokens from multiple clients
|
|
oidc_audiences: list[str] = ["core-api", "tatlock-ui", "tatlock"]
|
|
|
|
# Authentik API (for token validation and user management)
|
|
authentik_url: str = "https://auth.schweitz.net"
|
|
authentik_username: str = ""
|
|
authentik_password: str = ""
|
|
|
|
class Config:
|
|
env_file = ".env"
|
|
case_sensitive = False
|
|
extra = "ignore"
|
|
|
|
|
|
@lru_cache()
|
|
def get_settings() -> Settings:
|
|
"""Cached settings instance"""
|
|
return Settings()
|