glam/src/glam_extractor/api/config.py
2025-12-21 22:12:34 +01:00

76 lines
2.7 KiB
Python

"""
API Configuration
Settings management using Pydantic for environment variable handling.
"""
from functools import lru_cache
from typing import Literal
from pydantic import Field
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
"""Application settings loaded from environment variables."""
# API Configuration
api_title: str = "GLAM Heritage Custodian API"
api_description: str = "API for heritage custodian data services and SPARQL query generation"
api_version: str = "0.1.0"
debug: bool = False
# CORS settings
cors_origins: list[str] = Field(
default=["http://localhost:5173", "http://localhost:3000", "https://bronhouder.nl"]
)
# LLM Configuration for DSPy
# Providers: openai, anthropic, zai (Z.AI Coding Plan - free GLM models), groq (free, fast)
llm_provider: Literal["openai", "anthropic", "zai", "groq"] = "anthropic"
openai_api_key: str | None = None
anthropic_api_key: str | None = None
zai_api_token: str | None = None # Z.AI Coding Plan token
groq_api_key: str | None = None # Groq API key (free, very fast ~1-2s)
llm_model: str = "claude-sonnet-4-20250514" # or "gpt-4o" for OpenAI, "glm-4.6" for Z.AI
# Fast LLM for routing/extraction (uses cheaper/faster model for intermediate steps)
# Options: "groq" (FREE, fastest ~1-2s), "openai" (~1-2s, $0.15/1M), "zai" (FREE, ~13s)
# Default: openai (since we have the key; change to groq if GROQ_API_KEY is set)
fast_lm_provider: Literal["groq", "openai", "zai", "none"] = "openai"
# SPARQL Endpoint
sparql_endpoint: str = "http://localhost:7878/query"
# Ontology context for SPARQL generation
ontology_context_path: str = "schemas/20251121/linkml/01_custodian_name.yaml"
# Qdrant Vector Database Configuration
qdrant_host: str = "localhost"
qdrant_port: int = 6333
qdrant_collection: str = "heritage_custodians"
qdrant_enabled: bool = True
# Embedding Configuration
embedding_model: str = "text-embedding-3-small"
embedding_dim: int = 1536
# Redis Semantic Cache Configuration
redis_url: str = "redis://localhost:6379"
cache_enabled: bool = True
cache_distance_threshold: float = 0.10 # Cosine distance for semantic matching
cache_default_ttl: int = 3600 # 1 hour default TTL
cache_warmup_on_startup: bool = True
cache_embedding_model: str = "all-MiniLM-L6-v2" # Sentence transformer model
cache_cross_encoder_model: str = "cross-encoder/ms-marco-MiniLM-L-6-v2"
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
extra = "ignore"
@lru_cache
def get_settings() -> Settings:
"""Get cached settings instance."""
return Settings()