File size: 4,915 Bytes
1dab660 f73bfd0 1dab660 f991885 1dab660 f21ff52 1dab660 5fb63e2 1dab660 637ed9b 1dab660 5fb63e2 1dab660 5fb63e2 1dab660 5fb63e2 1dab660 5fb63e2 1dab660 f73bfd0 1dab660 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
"""
Configuration management for A11y Expert system.
This module provides centralized configuration using Pydantic settings.
All settings can be configured via environment variables or .env file.
"""
from pydantic_settings import BaseSettings
from pydantic import Field, field_validator
from functools import lru_cache
import os
from typing import Optional
class Settings(BaseSettings):
"""
Application settings loaded from environment variables or .env file.
All settings have sensible defaults except for the OpenAI API key,
which must be provided via the OPENAI_API_KEY environment variable.
Attributes:
openai_api_key: OpenAI API key (required)
llm_model: Language model to use for chat completions
llm_base_url: Base URL for OpenAI API (supports GitHub Models)
embedding_model: Model to use for text embeddings
lancedb_uri: Path to LanceDB database directory
lancedb_table: Name of the LanceDB table
chunk_size: Target size for text chunks in characters
chunk_overlap: Overlap between consecutive chunks
log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
server_host: Gradio server host address
server_port: Gradio server port
Examples:
>>> settings = get_settings()
>>> print(settings.llm_model)
'gpt-4o'
"""
# API Configuration (required)
openai_api_key: str = Field(
default="",
description="OpenAI API key - required for LLM and embeddings"
)
# LLM Configuration
llm_model: str = Field(
default="gpt-4o",
description="Language model for chat completions"
)
llm_base_url: Optional[str] = Field(
default=None,
description="Base URL for OpenAI-compatible API (optional)"
)
# Embeddings Configuration
embedding_model: str = Field(
default="text-embedding-3-large",
description="Model for text embeddings"
)
# Database Configuration
lancedb_uri: str = Field(
default="./lancedb",
description="Path to LanceDB database directory"
)
lancedb_table: str = Field(
default="a11y_expert",
description="Name of the LanceDB table"
)
# ETL Configuration
chunk_size: int = Field(
default=1000,
ge=100,
le=4000,
description="Target chunk size in characters"
)
chunk_overlap: int = Field(
default=200,
ge=0,
le=1000,
description="Overlap between chunks in characters"
)
# Logging Configuration
log_level: str = Field(
default="INFO",
description="Logging level (DEBUG, INFO, WARNING, ERROR)"
)
# UI Configuration
server_host: str = Field(
default="127.0.0.1",
description="Gradio server host address"
)
server_port: int = Field(
default=7860,
ge=1024,
le=65535,
description="Gradio server port"
)
@field_validator("openai_api_key")
@classmethod
def validate_api_key(cls, v):
"""Ensure API key is provided and not empty."""
v = v or ""
v = v.strip()
if not v:
import os
if not os.getenv("SPACE_ID"):
raise ValueError(
"OPENAI_API_KEY is required. "
"Set it in your .env file or environment variables."
)
return v
@field_validator("log_level")
@classmethod
def validate_log_level(cls, v):
"""Ensure log level is valid."""
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
v_upper = v.upper()
if v_upper not in valid_levels:
raise ValueError(
f"Invalid log level: {v}. "
f"Must be one of: {', '.join(valid_levels)}"
)
return v_upper
@field_validator("chunk_overlap")
@classmethod
def validate_overlap(cls, v, info):
"""Ensure chunk overlap is less than chunk size."""
if info.data and "chunk_size" in info.data and v >= info.data["chunk_size"]:
raise ValueError(
f"chunk_overlap ({v}) must be less than chunk_size ({info.data['chunk_size']})"
)
return v
model_config = {
"env_file": ".env",
"env_file_encoding": "utf-8",
"case_sensitive": False,
"extra": "ignore",
}
@lru_cache()
def get_settings() -> Settings:
"""
Get cached settings instance (singleton pattern).
Returns:
Settings: Configured application settings
Raises:
ValidationError: If required settings are missing or invalid
Examples:
>>> settings = get_settings()
>>> print(settings.llm_model)
'gpt-4o'
"""
return Settings()
|