Files
scheduler/src/config.py
T
jpmschweitzerandClaude Opus 4.6 22ec600ef3
Build and Push / release (push) Successful in 28s
Build and Push / build (push) Successful in 6m56s
feat(backup): add GCS offsite backup executor
Add gcs_backup_executor with git_bundle mode for backing up bare git
repos to Google Cloud Storage. Includes retention management and
bundle verification. Adds google-cloud-storage dependency and
GCS_CREDENTIALS_FILE setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:16:45 +02:00

98 lines
3.8 KiB
Python

"""
Configuration management for The Scheduler.
Uses Pydantic BaseSettings for type-safe environment variable loading.
"""
import tomllib
from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings
from pydantic import Field
def _get_version_from_pyproject() -> tuple[str, str, str]:
"""Read version info from pyproject.toml."""
pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
if pyproject_path.exists():
with open(pyproject_path, "rb") as f:
data = tomllib.load(f)
project = data.get("project", {})
return (
project.get("name", "the-scheduler"),
project.get("version", "0.0.0"),
project.get("description", ""),
)
return ("the-scheduler", "0.0.0", "")
_PROJECT_NAME, _PROJECT_VERSION, _PROJECT_DESCRIPTION = _get_version_from_pyproject()
class Settings(BaseSettings):
"""Application settings loaded from environment variables."""
# Application
app_name: str = Field(default=_PROJECT_NAME, alias="APP_NAME")
app_version: str = Field(default=_PROJECT_VERSION, alias="APP_VERSION")
debug: bool = Field(default=False, alias="DEBUG")
host: str = Field(default="0.0.0.0", alias="HOST")
port: int = Field(default=8090, alias="PORT")
log_level: str = Field(default="INFO", alias="LOG_LEVEL")
# Security
scheduler_api_key: str = Field(default="dev-key-change-me", alias="SCHEDULER_API_KEY")
# PostgreSQL
postgres_host: str = Field(default="postgres-shared", alias="POSTGRES_HOST")
postgres_port: int = Field(default=5432, alias="POSTGRES_PORT")
postgres_db: str = Field(default="library_scheduler", alias="POSTGRES_DB")
postgres_user: str = Field(default="library_scheduler_user", alias="POSTGRES_USER")
postgres_password: str = Field(default="", alias="POSTGRES_PASSWORD")
# Redis
redis_host: str = Field(default="redis-shared", alias="REDIS_HOST")
redis_port: int = Field(default=6379, alias="REDIS_PORT")
redis_db: int = Field(default=3, alias="REDIS_DB")
# Gitea
gitea_url: str = Field(default="http://gitea:3000", alias="GITEA_URL")
gitea_user: str = Field(default="library", alias="GITEA_USER")
gitea_password: str = Field(default="", alias="GITEA_PASSWORD")
gitea_token: str = Field(default="", alias="GITEA_TOKEN") # API token with write:repository scope
gitea_ssh_host: str = Field(default="gitea", alias="GITEA_SSH_HOST")
gitea_ssh_port: int = Field(default=22, alias="GITEA_SSH_PORT")
# Backup Configuration
backup_retention_daily: int = Field(default=7, alias="BACKUP_RETENTION_DAILY")
backup_retention_weekly: int = Field(default=4, alias="BACKUP_RETENTION_WEEKLY")
backup_retention_monthly: int = Field(default=12, alias="BACKUP_RETENTION_MONTHLY")
# Google Cloud Storage
gcs_credentials_file: str = Field(default="", alias="GCS_CREDENTIALS_FILE")
# Documentation Mirroring
docs_mirror_path: str = Field(default="/docs-mirror", alias="DOCS_MIRROR_PATH")
docs_check_interval: int = Field(default=21600, alias="DOCS_CHECK_INTERVAL") # 6 hours
@property
def database_url(self) -> str:
"""PostgreSQL connection URL for APScheduler."""
return f"postgresql://{self.postgres_user}:{self.postgres_password}@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}"
@property
def redis_url(self) -> str:
"""Redis connection URL."""
return f"redis://{self.redis_host}:{self.redis_port}/{self.redis_db}"
class Config:
env_file = ".env"
case_sensitive = False
@lru_cache
def get_settings() -> Settings:
"""
Get cached settings instance.
Using lru_cache ensures we only create one Settings instance.
"""
return Settings()