feat: add dashboard API with quick links and widgets
Build and Push / build (release) Successful in 1m28s
Build and Push / build (release) Successful in 1m28s
- Dashboard domain with Quick Links CRUD + reorder endpoints - Dashboard widgets management endpoints - Database migrations for quick_links and dashboard_widgets tables - Static file controller for Organizr widgets - Default local user when OIDC is disabled - Domain-based architecture refactor (src/domains/, src/shared/) - Test suite updated for new structure (285 tests passing) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
e85c9a123d
commit
381d43b60b
@@ -0,0 +1,147 @@
|
||||
"""
|
||||
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
|
||||
cors_origins: list[str] = ["*"]
|
||||
cors_credentials: bool = True
|
||||
cors_methods: list[str] = ["*"]
|
||||
cors_headers: list[str] = ["*"]
|
||||
|
||||
# Logging
|
||||
log_level: str = "DEBUG"
|
||||
|
||||
# Ollama Configuration (for AI orchestration)
|
||||
ollama_base_url: str # Required - set OLLAMA_BASE_URL in .env
|
||||
ollama_timeout: int = 300 # 5 minutes
|
||||
|
||||
# Model Configuration
|
||||
default_model: str = "mistral-nemo-large:latest"
|
||||
agent_model: str = "mistral-nemo-large:latest"
|
||||
code_models: str = "mistral-nemo-large:latest"
|
||||
|
||||
# System Prompt Variant (for A/B testing)
|
||||
system_prompt_variant: str = "v8_holistic"
|
||||
|
||||
# Agent Configuration
|
||||
agent_fallback_enabled: bool = True
|
||||
|
||||
# Model Aliases (OpenAI → Local)
|
||||
alias_gpt35: str = "gemma:7b"
|
||||
alias_gpt4: str = "mistral:7b"
|
||||
alias_gpt4_turbo: str = "mixtral:8x7b"
|
||||
alias_gpt4_code: str = "codestral:latest"
|
||||
|
||||
# Memory Configuration
|
||||
memory_tier1_max_turns: int = 10
|
||||
memory_consolidation_threshold: int = 10
|
||||
|
||||
# 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"
|
||||
|
||||
# Embeddings (using Ollama)
|
||||
embedding_model: str = "nomic-embed-text"
|
||||
embedding_dimension: int = 768
|
||||
embedding_batch_size: int = 32
|
||||
|
||||
# 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
|
||||
oidc_issuer: str = "https://auth.schweitz.net/application/o/core-api/"
|
||||
oidc_audience: str = "core-api"
|
||||
|
||||
# Authentik API (for token validation and user management)
|
||||
authentik_url: str = "https://auth.schweitz.net"
|
||||
authentik_username: str = ""
|
||||
authentik_password: str = ""
|
||||
|
||||
@property
|
||||
def model_aliases(self) -> dict:
|
||||
"""Computed property for model aliases"""
|
||||
return {
|
||||
"gpt-3.5-turbo": self.alias_gpt35,
|
||||
"gpt-4": self.alias_gpt4,
|
||||
"gpt-4-turbo": self.alias_gpt4_turbo,
|
||||
"gpt-4-code": self.alias_gpt4_code,
|
||||
}
|
||||
|
||||
def get_code_models(self) -> list[str]:
|
||||
"""Parse comma-separated code models"""
|
||||
return [m.strip().strip('"').strip("'") for m in self.code_models.split(",") if m.strip()]
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
case_sensitive = False
|
||||
extra = "ignore"
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_settings() -> Settings:
|
||||
"""Cached settings instance"""
|
||||
return Settings()
|
||||
Reference in New Issue
Block a user