| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- from __future__ import annotations
- from functools import lru_cache
- from pathlib import Path
- from urllib.parse import quote_plus
- from pydantic_settings import BaseSettings, SettingsConfigDict
- PROJECT_ROOT = Path(__file__).resolve().parents[2]
- class Settings(BaseSettings):
- model_config = SettingsConfigDict(
- env_file=PROJECT_ROOT / ".env",
- env_file_encoding="utf-8",
- case_sensitive=False,
- extra="ignore",
- )
- app_name: str = "矿山通防智能管控平台"
- app_env: str = "development"
- debug: bool = True
- api_v1_prefix: str = "/api/v1"
- secret_key: str = "change-me-in-production"
- host: str = "0.0.0.0"
- port: int = 8090
- log_level: str = "INFO"
- database_dialect: str = "sqlite"
- sqlite_path: str = "data/vent_platform.sqlite"
- mysql_host: str = "127.0.0.1"
- mysql_port: int = 3306
- mysql_user: str = "root"
- mysql_password: str = ""
- mysql_database: str = "vent_platform"
- database_echo: bool = False
- openai_api_key: str = ""
- openai_base_url: str = "https://api.deepseek.com"
- deepagent_model: str = "deepseek-flash"
- deepagent_thinking: str = "off"
- openai_timeout: int = 180
- mineru_api_base: str = "https://mineru.net"
- mineru_token: str = ""
- mineru_timeout: int = 900
- mineru_poll_interval: float = 2.0
- document_extraction_max_chars: int = 80000
- knowledge_service_base: str = ""
- knowledge_service_api_key: str = ""
- knowledge_service_timeout: float = 30.0
- knowledge_catalog_cache_ttl: int = 300
- knowledge_search_mode: str = "keyword"
- knowledge_search_top_k: int = 5
- knowledge_search_min_score: float = 0.0
- knowledge_search_min_match_ratio: float = 0.0
- knowledge_rag_context_max_chars: int = 12000
- knowledge_rag_source_max_chars: int = 2800
- cors_origins: str = (
- "http://127.0.0.1:5173,http://localhost:5173,"
- "http://127.0.0.1:8080,http://localhost:8080"
- )
- default_mine_code: str = "shangwan"
- upload_dir: str = "data/uploads"
- storage_capacity_gb: float = 1024.0
- seed_demo_data: bool = False
- request_trace_header: str = "X-Trace-Id"
- @property
- def cors_origin_list(self) -> list[str]:
- return [item.strip() for item in self.cors_origins.split(",") if item.strip()]
- @property
- def sqlite_file(self) -> Path:
- path = Path(self.sqlite_path)
- return path if path.is_absolute() else PROJECT_ROOT / path
- @property
- def database_url(self) -> str:
- dialect = self.database_dialect.strip().lower()
- if dialect == "sqlite":
- return f"sqlite:///{self.sqlite_file.as_posix()}"
- if dialect in {"mysql", "mysql+pymysql"}:
- user = quote_plus(self.mysql_user)
- password = quote_plus(self.mysql_password)
- return (
- f"mysql+pymysql://{user}:{password}@"
- f"{self.mysql_host}:{self.mysql_port}/{self.mysql_database}"
- "?charset=utf8mb4"
- )
- raise ValueError("DATABASE_DIALECT 仅支持 sqlite 或 mysql")
- @property
- def upload_path(self) -> Path:
- path = Path(self.upload_dir)
- return path if path.is_absolute() else PROJECT_ROOT / path
- @property
- def model_configured(self) -> bool:
- return bool(self.openai_api_key)
- @property
- def knowledge_service_configured(self) -> bool:
- return bool(self.knowledge_service_base.strip())
- @lru_cache(maxsize=1)
- def get_settings() -> Settings:
- return Settings()
- settings = get_settings()
|