Implement global application configuration and custom Pydantic models following FastAPI best practices. Core Configuration (src/core/config.py): - BaseSettings with environment variable support - Split configuration by domain (following best practices) - Ollama connection settings (host, model, timeouts) - API configuration (host, port, prefix) - CORS settings - 20-second streaming timeout per turn - Cached configuration with @lru_cache Custom Base Models (src/core/models.py): - CustomBaseModel for consistent serialization - ISO datetime formatting - Alias population support - Enum value serialization - Validation on assignment - serializable_dict() for logging/debugging Exception Handling (src/core/exceptions.py): - Base AppException with status codes - OllamaConnectionError (503) - OllamaTimeoutError (504) - ModelNotFoundError (404) - ValidationError (422) - OpenAI-compatible error structure Benefits: - Consistent configuration across domains - Type-safe settings with validation - Easy environment override via .env - Predictable error responses - Better debugging with serializable models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
"""
|
|
Global exception definitions.
|
|
Domain-specific exceptions should be in their respective modules.
|
|
"""
|
|
from typing import Any
|
|
|
|
|
|
class AppException(Exception):
|
|
"""Base exception for all application errors."""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "An error occurred",
|
|
status_code: int = 500,
|
|
details: dict[str, Any] | None = None,
|
|
):
|
|
self.message = message
|
|
self.status_code = status_code
|
|
self.details = details or {}
|
|
super().__init__(self.message)
|
|
|
|
|
|
class OllamaConnectionError(AppException):
|
|
"""Raised when cannot connect to Ollama service."""
|
|
|
|
def __init__(self, message: str = "Cannot connect to Ollama service"):
|
|
super().__init__(message=message, status_code=503)
|
|
|
|
|
|
class OllamaTimeoutError(AppException):
|
|
"""Raised when Ollama request times out."""
|
|
|
|
def __init__(self, message: str = "Ollama request timed out"):
|
|
super().__init__(message=message, status_code=504)
|
|
|
|
|
|
class ModelNotFoundError(AppException):
|
|
"""Raised when requested model is not available."""
|
|
|
|
def __init__(self, model_name: str):
|
|
super().__init__(
|
|
message=f"Model '{model_name}' not found",
|
|
status_code=404,
|
|
details={"model": model_name}
|
|
)
|
|
|
|
|
|
class ValidationError(AppException):
|
|
"""Raised for validation errors."""
|
|
|
|
def __init__(self, message: str, details: dict[str, Any] | None = None):
|
|
super().__init__(message=message, status_code=422, details=details)
|