knowledge-engine / core /config.py
m97j's picture
fix(config): use computed_field for dynamic path resolution
02a8a1c
# core/config.py
import os
from functools import lru_cache
from pydantic import Field, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""
This is a class that manages application global settings.
It reads values ​​from .env files or system environment variables and strictly validates types using Pydantic.
"""
# 1. Project Info
PROJECT_NAME: str = Field(default="Knowledge Engine", description="Project name")
VERSION: str = Field(default="1.0.0", description="API version")
ENVIRONMENT: str = Field(default="development", description="Execution environment (development, staging, production)")
LOG_LEVEL: str = Field(default="INFO", description="Global logging level")
DATA_DIR: str = Field(default="./data", description="Data storage directory path")
REPO_ID: str = Field(default="m97j/ke-store", description="Hugging Face repository ID")
# 2. Storage Settings (Vector DB & RDBMS)
QDRANT_COLLECTION: str = Field(default="knowledge_base", description="Qdrant collection name")
QDRANT_URL: str = Field(default="http://localhost:6333", description="Qdrant server URL (if using client-server mode)")
@computed_field
@property
def SQLITE_PATH(self) -> str:
"""
Computed property to ensure that the SQLite path is always correctly resolved based on the DATA_DIR.
This allows dynamic changes to DATA_DIR without breaking the SQLITE_PATH reference.
"""
return os.path.join(self.DATA_DIR, "knowledge_base/corpus.sqlite")
@computed_field
@property
def QDRANT_PATH(self) -> str:
"""
Computed property to ensure that the Qdrant path is always correctly resolved based on the DATA_DIR.
This allows dynamic changes to DATA_DIR without breaking the QDRANT_PATH reference.
"""
return os.path.join(self.DATA_DIR, "vector_store/qdrant")
# 3. Model Settings (Embedder & Reranker)
EMBEDDER_NAME: str = Field(default="BAAI/bge-m3", description="FlagEmbedding model name")
RERANKER_NAME: str = Field(default="BAAI/bge-reranker-v2-m3", description="Cross-Encoder model name")
USE_FP16: bool = Field(default=True, description="Whether to use FP16 precision in GPU environment")
# 4. Search Hyperparameters
DEFAULT_TOP_K: int = Field(default=5, description="Final number of documents to return")
QDRANT_FETCH_LIMIT: int = Field(default=50, description="Number of candidates to fetch from Vector DB before reranking")
# Pydantic v2 settings
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True, # case-sensitive environment variables
extra="ignore" # ignore unexpected fields in .env or environment variables
)
@lru_cache()
def get_settings() -> Settings:
"""
It caches and returns the Settings object as a Singleton.
It offers performance advantages as it does not read or parse the file every time.
"""
return Settings()
# Instantiate as a global variable so that it can be easily imported from other modules
settings = get_settings()