config.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from pydantic_settings import BaseSettings, SettingsConfigDict
  2. from typing import Any, Dict, List
  3. from dotenv import load_dotenv
  4. import os
  5. load_dotenv()
  6. class Settings(BaseSettings):
  7. # 基础配置
  8. PROJECT_NAME: str = "Alien Cloud Python"
  9. API_V1_STR: str = "/api/v1"
  10. # 鉴权配置 (原 alien-gateway 职责)
  11. SECRET_KEY: str = os.getenv("SECRET_KEY")
  12. ALGORITHM: str = os.getenv("ALGORITHM")
  13. ACCESS_TOKEN_EXPIRE_MINUTES: int = os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES") # 7天
  14. # 数据库配置
  15. DB_USER: str = os.getenv("DB_USER")
  16. DB_PASSWORD: str = os.getenv("DB_PASSWORD")
  17. DB_HOST: str = os.getenv("DB_HOST")
  18. DB_PORT: int = os.getenv("DB_PORT")
  19. DB_NAME: str = os.getenv("DB_NAME")
  20. # Redis Sentinel 高可用配置
  21. # 例: REDIS_SENTINELS=192.168.2.251:36379,192.168.2.252:36379,192.168.2.253:36379
  22. REDIS_SENTINELS: str = os.getenv("REDIS_SENTINELS", "")
  23. REDIS_MASTER_NAME: str = os.getenv("REDIS_MASTER_NAME", "mymaster")
  24. REDIS_PASSWORD: str = os.getenv("REDIS_PASSWORD", "")
  25. REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
  26. REDIS_SENTINEL_USERNAME: str = os.getenv("REDIS_SENTINEL_USERNAME", "")
  27. REDIS_SENTINEL_PASSWORD: str = os.getenv("REDIS_SENTINEL_PASSWORD", "")
  28. REDIS_SOCKET_TIMEOUT: float = float(os.getenv("REDIS_SOCKET_TIMEOUT", "0.5"))
  29. REDIS_CONNECT_TIMEOUT: float = float(os.getenv("REDIS_CONNECT_TIMEOUT", "1.0"))
  30. # 下游服务地址
  31. STORE_BASE_URL: str = os.getenv("STORE_BASE_URL") # alien_store 服务地址
  32. # 阿里云短信配置
  33. ALIYUN_SMS_SIGN_NAME_CONTRACT: str = os.getenv("ALIYUN_SMS_SIGN_NAME_CONTRACT")
  34. ALIYUN_SMS_TEMPLATE_CODE_CONTRACT: str = os.getenv("ALIYUN_SMS_TEMPLATE_CODE_CONTRACT")
  35. ALIYUN_ACCESS_KEY_ID: str = os.getenv("ALIYUN_ACCESS_KEY_ID")
  36. ALIYUN_ACCESS_KEY_SECRET: str = os.getenv("ALIYUN_ACCESS_KEY_SECRET")
  37. @property
  38. def SQLALCHEMY_DATABASE_URI(self) -> str:
  39. return f"mysql+pymysql://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
  40. @property
  41. def REDIS_SENTINEL_NODES(self) -> List[tuple[str, int]]:
  42. nodes: List[tuple[str, int]] = []
  43. for item in self.REDIS_SENTINELS.split(","):
  44. entry = item.strip()
  45. if not entry:
  46. continue
  47. if ":" not in entry:
  48. raise ValueError(f"Invalid REDIS_SENTINELS entry: {entry}")
  49. host, port = entry.split(":", 1)
  50. nodes.append((host.strip(), int(port.strip())))
  51. return nodes
  52. @property
  53. def REDIS_SENTINEL_KWARGS(self) -> Dict[str, Any]:
  54. kwargs: Dict[str, Any] = {}
  55. if self.REDIS_SENTINEL_USERNAME:
  56. kwargs["username"] = self.REDIS_SENTINEL_USERNAME
  57. if self.REDIS_SENTINEL_PASSWORD:
  58. kwargs["password"] = self.REDIS_SENTINEL_PASSWORD
  59. return kwargs
  60. @property
  61. def REDIS_SENTINEL_URL(self) -> str:
  62. # Celery sentinel transport 需要 "sentinel://host:port;sentinel://host:port"
  63. return ";".join(
  64. f"sentinel://{host}:{port}" for host, port in self.REDIS_SENTINEL_NODES
  65. )
  66. @property
  67. def REDIS_SENTINEL_TRANSPORT_OPTIONS(self) -> Dict[str, Any]:
  68. return {
  69. "master_name": self.REDIS_MASTER_NAME,
  70. "sentinel_kwargs": self.REDIS_SENTINEL_KWARGS,
  71. "password": self.REDIS_PASSWORD,
  72. "db": self.REDIS_DB,
  73. }
  74. model_config = SettingsConfigDict(
  75. case_sensitive=True,
  76. env_file=".env",
  77. )
  78. settings = Settings()