feat: add configuration management
- Add Settings class using pydantic-settings - Load config from environment variables with GM_ prefix - Support encrypt_key and api_token (required, no defaults for security) - Provide defaults for data_dir, host, port - Add computed properties for db_path, ssh_keys_dir, repos_dir - Add tests for config defaults and environment variable overrides - Add Base class to app.models to unblock conftest.py imports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
43
backend/app/config.py
Normal file
43
backend/app/config.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""应用配置,从环境变量加载."""
|
||||
|
||||
# 安全配置
|
||||
encrypt_key: str # AES-256 密钥 (base64)
|
||||
api_token: str # API 认证 Token
|
||||
|
||||
# 路径配置
|
||||
data_dir: Path = Path('./data')
|
||||
|
||||
# 服务器配置
|
||||
host: str = '0.0.0.0'
|
||||
port: int = 8000
|
||||
|
||||
model_config = SettingsConfigDict(
|
||||
env_prefix='GM_',
|
||||
env_file='.env',
|
||||
env_file_encoding='utf-8',
|
||||
)
|
||||
|
||||
@property
|
||||
def db_path(self) -> Path:
|
||||
"""SQLite 数据库路径."""
|
||||
return self.data_dir / 'git_manager.db'
|
||||
|
||||
@property
|
||||
def ssh_keys_dir(self) -> Path:
|
||||
"""SSH 密钥存储目录."""
|
||||
return self.data_dir / 'ssh_keys'
|
||||
|
||||
@property
|
||||
def repos_dir(self) -> Path:
|
||||
"""仓库镜像存储目录."""
|
||||
return self.data_dir / 'repos'
|
||||
|
||||
|
||||
settings = Settings()
|
||||
@@ -0,0 +1,11 @@
|
||||
"""ORM Models.
|
||||
|
||||
NOTE: This module is a placeholder until Task 2.1.
|
||||
The Base class is needed by conftest.py for database fixtures.
|
||||
"""
|
||||
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
"""Base class for all ORM models."""
|
||||
pass
|
||||
|
||||
32
backend/tests/test_config.py
Normal file
32
backend/tests/test_config.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import os
|
||||
import pytest
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
def test_config_defaults(test_env_vars, monkeypatch):
|
||||
"""测试配置默认值."""
|
||||
# Clear GM_DATA_DIR to test default value
|
||||
monkeypatch.delenv("GM_DATA_DIR", raising=False)
|
||||
|
||||
# Reload config to pick up the change
|
||||
from app.config import Settings
|
||||
settings = Settings()
|
||||
|
||||
assert settings.data_dir == Path('./data')
|
||||
assert settings.host == '0.0.0.0'
|
||||
assert settings.port == 8000
|
||||
|
||||
def test_config_from_env(monkeypatch):
|
||||
"""测试从环境变量读取配置."""
|
||||
# Set required security fields
|
||||
monkeypatch.setenv("GM_ENCRYPT_KEY", base64.b64encode(b'test-key-32-bytes-long-1234567890').decode())
|
||||
monkeypatch.setenv("GM_API_TOKEN", "test-token")
|
||||
monkeypatch.setenv("GM_DATA_DIR", "/custom/data")
|
||||
monkeypatch.setenv("GM_PORT", "9000")
|
||||
|
||||
# 重新加载配置
|
||||
from app.config import Settings
|
||||
settings = Settings()
|
||||
|
||||
assert settings.data_dir == Path('/custom/data')
|
||||
assert settings.port == 9000
|
||||
Reference in New Issue
Block a user