config.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. """DMS环境配置。"""
  2. from __future__ import annotations
  3. import os
  4. from pathlib import Path
  5. from typing import Any
  6. from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
  7. BACKEND_ROOT = Path(__file__).resolve().parents[1]
  8. DEFAULT_STORAGE_ROOT = BACKEND_ROOT / "dms-storage"
  9. DEFAULT_UI_DICTIONARY_CONFIG_PATH = (
  10. BACKEND_ROOT / "dms" / "resources" / "ui-dictionaries.zh-CN.json"
  11. )
  12. DEFAULT_DATABASE_URL = (
  13. "mysql+pymysql://dms_app:change-me@127.0.0.1:3306/dms?charset=utf8mb4"
  14. )
  15. def _positive_int(name: str, default: int) -> int:
  16. raw_value = os.environ.get(name)
  17. if raw_value is None or not raw_value.strip():
  18. return default
  19. try:
  20. value = int(raw_value)
  21. except ValueError as exc:
  22. raise ValueError(f"{name}必须是正整数") from exc
  23. if value <= 0:
  24. raise ValueError(f"{name}必须是正整数")
  25. return value
  26. def load_dms_config() -> dict[str, Any]:
  27. """从环境变量加载DMS配置,不读取或覆盖现有AI配置。"""
  28. storage_value = os.environ.get("DMS_STORAGE_ROOT", "").strip()
  29. storage_root = Path(storage_value or DEFAULT_STORAGE_ROOT).expanduser()
  30. max_upload_size = _positive_int(
  31. "DMS_MAX_UPLOAD_SIZE", 100 * 1024 * 1024
  32. )
  33. max_file_size = _positive_int(
  34. "DMS_MAX_FILE_SIZE", min(50 * 1024 * 1024, max_upload_size)
  35. )
  36. if max_file_size > max_upload_size:
  37. raise ValueError("DMS_MAX_FILE_SIZE不得超过DMS_MAX_UPLOAD_SIZE")
  38. database_url = os.environ.get("DMS_DATABASE_URL", "").strip()
  39. ui_dictionary_config_value = os.environ.get(
  40. "DMS_UI_DICTIONARY_CONFIG_PATH", ""
  41. ).strip()
  42. ui_dictionary_config_path = Path(
  43. ui_dictionary_config_value or DEFAULT_UI_DICTIONARY_CONFIG_PATH
  44. ).expanduser()
  45. business_timezone = (
  46. os.environ.get("DMS_BUSINESS_TIMEZONE", "").strip()
  47. or "Asia/Shanghai"
  48. )
  49. try:
  50. ZoneInfo(business_timezone)
  51. except (ZoneInfoNotFoundError, ValueError) as exc:
  52. raise ValueError("DMS_BUSINESS_TIMEZONE必须是有效的IANA时区") from exc
  53. return {
  54. "SQLALCHEMY_DATABASE_URI": database_url or DEFAULT_DATABASE_URL,
  55. "SQLALCHEMY_TRACK_MODIFICATIONS": False,
  56. "SQLALCHEMY_ENGINE_OPTIONS": {
  57. "isolation_level": "READ COMMITTED",
  58. "pool_pre_ping": True,
  59. "pool_recycle": 1800,
  60. "connect_args": {
  61. "init_command": "SET time_zone = '+00:00'",
  62. },
  63. },
  64. "DMS_STORAGE_ROOT": str(storage_root.resolve()),
  65. "DMS_MAX_UPLOAD_SIZE": max_upload_size,
  66. "DMS_MAX_FILE_SIZE": max_file_size,
  67. "MAX_CONTENT_LENGTH": max_upload_size,
  68. "DMS_BATCH_MAX_FILES": _positive_int("DMS_BATCH_MAX_FILES", 50),
  69. "DMS_BUSINESS_TIMEZONE": business_timezone,
  70. "DMS_JWT_SECRET": os.environ.get("DMS_JWT_SECRET", ""),
  71. "DMS_JWT_ISSUER": "dms",
  72. "DMS_JWT_EXPIRES_SECONDS": 7200,
  73. "DMS_JWT_KEEP_SIGNED_IN_EXPIRES_SECONDS": 604800,
  74. "DMS_UI_DICTIONARY_CONFIG_PATH": str(
  75. ui_dictionary_config_path.resolve()
  76. ),
  77. }