""" MOXIE Configuration System Manages all settings via SQLite database with file-based fallback. """ import os import json from pathlib import Path from typing import Optional from pydantic_settings import BaseSettings from pydantic import Field class Settings(BaseSettings): """Application settings with environment variable support.""" # Server host: str = Field(default="0.0.0.0", description="Server host") port: int = Field(default=8000, description="Server port") debug: bool = Field(default=False, description="Debug mode") # Ollama ollama_host: str = Field(default="http://127.0.0.1:11434", description="Ollama server URL") ollama_model: str = Field(default="qwen2.5:2b", description="Default Ollama model for orchestration") embedding_model: str = Field(default="qwen3-embedding:4b", description="Embedding model for RAG") # Admin admin_path: str = Field(default="moxie-butterfly-ntl", description="Hidden admin UI path") # ComfyUI comfyui_host: str = Field(default="http://127.0.0.1:8188", description="ComfyUI server URL") # Data data_dir: str = Field( default="~/.moxie", description="Data directory for database and config" ) # API Keys (loaded from DB at runtime) gemini_api_key: Optional[str] = None openrouter_api_key: Optional[str] = None class Config: env_prefix = "MOXIE_" env_file = ".env" extra = "ignore" # Global settings instance settings = Settings() def get_data_dir() -> Path: """Get the data directory path, creating it if needed.""" data_dir = Path(settings.data_dir).expanduser() data_dir.mkdir(parents=True, exist_ok=True) return data_dir def get_db_path() -> Path: """Get the database file path.""" return get_data_dir() / "moxie.db" def get_workflows_dir() -> Path: """Get the ComfyUI workflows directory.""" workflows_dir = get_data_dir() / "workflows" workflows_dir.mkdir(parents=True, exist_ok=True) return workflows_dir def get_config_path() -> Path: """Get the config file path.""" return get_data_dir() / "config.json" def load_config_from_db() -> dict: """Load configuration from database or create default.""" import sqlite3 db_path = get_db_path() # Ensure database exists if not db_path.exists(): return {} try: conn = sqlite3.connect(str(db_path)) cursor = conn.cursor() # Check if config table exists cursor.execute(""" SELECT name FROM sqlite_master WHERE type='table' AND name='config' """) if cursor.fetchone(): cursor.execute("SELECT key, value FROM config") config = {row[0]: json.loads(row[1]) for row in cursor.fetchall()} conn.close() return config conn.close() return {} except Exception: return {} def save_config_to_db(key: str, value: any) -> None: """Save a configuration value to database.""" import sqlite3 db_path = get_db_path() conn = sqlite3.connect(str(db_path)) cursor = conn.cursor() # Ensure config table exists cursor.execute(""" CREATE TABLE IF NOT EXISTS config ( key TEXT PRIMARY KEY, value TEXT ) """) cursor.execute( "INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)", (key, json.dumps(value)) ) conn.commit() conn.close() # Runtime config loaded from database runtime_config = load_config_from_db()