4e3a4b4602
带 Web 操作界面的备份系统,支持: - 数据源:MySQL 数据库(mysqldump)、服务器目录(tar.gz) - 存储目标:本地目录、S3 兼容对象存储(MinIO/Ceph/AWS S3) - 触发方式:手动 + Cron 定时调度(APScheduler) - 备份还原:MySQL 库、目录 - JWT 登录认证 + Fernet 字段加密 - 保留策略:按数量 + 按天数双重清理 技术栈:FastAPI + SQLAlchemy 2 + APScheduler + aioboto3; 前端 Vite + React 18 + TypeScript + Ant Design 5 + Zustand。 Docker Compose 一键起。 Co-Authored-By: Claude <noreply@anthropic.com>
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""应用配置:从环境变量加载,启动时校验必填项。"""
|
||
from functools import lru_cache
|
||
from typing import List
|
||
|
||
from pydantic import Field, field_validator
|
||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||
|
||
|
||
class Settings(BaseSettings):
|
||
model_config = SettingsConfigDict(
|
||
env_file=".env",
|
||
env_file_encoding="utf-8",
|
||
case_sensitive=True,
|
||
extra="ignore",
|
||
)
|
||
|
||
# ===== 必填 =====
|
||
SECRET_KEY: str = Field(..., description="JWT 签名密钥(>= 32 字符)")
|
||
FERNET_KEY: str = Field(..., description="Fernet 字段加密密钥")
|
||
INITIAL_ADMIN_PASSWORD: str = Field(..., min_length=8)
|
||
|
||
# ===== 可选 =====
|
||
JWT_EXPIRE_MINUTES: int = 1440
|
||
DATABASE_URL: str = "sqlite:///./data/backup.db"
|
||
STORAGE_LOCAL_ROOT: str = "./data/backups"
|
||
LOG_LEVEL: str = "INFO"
|
||
CORS_ORIGINS: str = "http://localhost:5173,http://localhost:8000"
|
||
TZ: str = "UTC"
|
||
|
||
@field_validator("SECRET_KEY")
|
||
@classmethod
|
||
def _check_secret_key(cls, v: str) -> str:
|
||
if len(v) < 32:
|
||
raise ValueError("SECRET_KEY 长度必须 >= 32 字符(建议 openssl rand -hex 32)")
|
||
return v
|
||
|
||
@property
|
||
def cors_origins_list(self) -> List[str]:
|
||
return [o.strip() for o in self.CORS_ORIGINS.split(",") if o.strip()]
|
||
|
||
|
||
@lru_cache
|
||
def get_settings() -> Settings:
|
||
return Settings() # type: ignore[call-arg]
|