2026-01-31 03:04:51 +08:00
|
|
|
|
"""配置管理模块
|
|
|
|
|
|
|
|
|
|
|
|
从环境变量加载应用配置,使用pydantic-settings进行类型验证
|
|
|
|
|
|
"""
|
2026-02-27 22:22:23 +08:00
|
|
|
|
|
2026-01-31 03:04:51 +08:00
|
|
|
|
import os
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
from pydantic_settings import BaseSettings
|
|
|
|
|
|
from functools import lru_cache
|
|
|
|
|
|
from typing import Optional
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 获取项目根目录(config文件夹所在目录)
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).parent.parent.parent
|
|
|
|
|
|
CONFIG_DIR = PROJECT_ROOT / "config"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Settings(BaseSettings):
|
2026-02-27 22:22:23 +08:00
|
|
|
|
"""应用配置类,从环境变量加载
|
|
|
|
|
|
|
|
|
|
|
|
所有配置项都会自动从环境变量读取(小写转大写)
|
|
|
|
|
|
例如:tushare_token 会读取 TUSHARE_TOKEN 环境变量
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# Tushare API 配置
|
|
|
|
|
|
tushare_token: str = ""
|
|
|
|
|
|
|
|
|
|
|
|
# 数据存储配置
|
|
|
|
|
|
root_path: str = "" # 项目根路径,默认自动检测
|
|
|
|
|
|
data_path: str = "data" # 数据存储路径,相对于 root_path
|
2026-01-31 03:04:51 +08:00
|
|
|
|
|
2026-02-27 22:22:23 +08:00
|
|
|
|
# 数据库配置(可选,用于未来扩展)
|
2026-01-31 03:04:51 +08:00
|
|
|
|
database_host: str = "localhost"
|
|
|
|
|
|
database_port: int = 5432
|
|
|
|
|
|
database_name: str = "prostock"
|
2026-02-27 22:22:23 +08:00
|
|
|
|
database_user: Optional[str] = None
|
|
|
|
|
|
database_password: Optional[str] = None
|
2026-01-31 03:04:51 +08:00
|
|
|
|
|
2026-02-27 22:22:23 +08:00
|
|
|
|
# Redis配置(可选,用于未来扩展)
|
2026-01-31 03:04:51 +08:00
|
|
|
|
redis_host: str = "localhost"
|
|
|
|
|
|
redis_port: int = 6379
|
|
|
|
|
|
redis_password: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
|
# 应用配置
|
|
|
|
|
|
app_env: str = "development"
|
|
|
|
|
|
app_debug: bool = False
|
|
|
|
|
|
app_port: int = 8000
|
|
|
|
|
|
|
2026-02-27 22:22:23 +08:00
|
|
|
|
@property
|
|
|
|
|
|
def project_root(self) -> Path:
|
|
|
|
|
|
"""获取项目根路径。"""
|
|
|
|
|
|
if self.root_path:
|
|
|
|
|
|
return Path(self.root_path)
|
|
|
|
|
|
return PROJECT_ROOT
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
def data_path_resolved(self) -> Path:
|
|
|
|
|
|
"""获取解析后的数据路径(绝对路径)。"""
|
|
|
|
|
|
path = Path(self.data_path)
|
|
|
|
|
|
if path.is_absolute():
|
|
|
|
|
|
return path
|
|
|
|
|
|
return self.project_root / path
|
|
|
|
|
|
|
2026-01-31 03:04:51 +08:00
|
|
|
|
class Config:
|
|
|
|
|
|
# 从 config/ 目录读取 .env.local 文件
|
|
|
|
|
|
env_file = str(CONFIG_DIR / ".env.local")
|
|
|
|
|
|
env_file_encoding = "utf-8"
|
|
|
|
|
|
case_sensitive = False
|
2026-02-27 22:22:23 +08:00
|
|
|
|
extra = "ignore" # 忽略 .env.local 中的额外变量
|
2026-01-31 03:04:51 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@lru_cache()
|
|
|
|
|
|
def get_settings() -> Settings:
|
|
|
|
|
|
"""获取配置单例
|
|
|
|
|
|
|
|
|
|
|
|
使用lru_cache确保配置只加载一次
|
|
|
|
|
|
"""
|
|
|
|
|
|
return Settings()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 导出配置实例供全局使用
|
|
|
|
|
|
settings = get_settings()
|