fix: improve config module with lazy init and validation
Fixes from code review: Critical: - Replace module-level `settings = Settings()` with lazy initialization via `get_settings()` function to avoid import failures when env vars not set Important: - Remove unused `import os` from test_config.py - Add tests for computed properties (db_path, ssh_keys_dir, repos_dir) - Add field validation for encrypt_key: * Validates base64 format * Ensures decoded key is at least 32 bytes for AES-256 - Fix Python 3.8 compatibility (use Optional[Settings] instead of | union) All tests pass (6/6). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import base64
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
from typing import Optional
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@@ -24,6 +25,22 @@ class Settings(BaseSettings):
|
||||
env_file_encoding='utf-8',
|
||||
)
|
||||
|
||||
@field_validator('encrypt_key')
|
||||
@classmethod
|
||||
def validate_encrypt_key(cls, v: str) -> str:
|
||||
"""验证 encrypt_key 是否为有效的 base64 格式且长度足够."""
|
||||
# Check if valid base64
|
||||
try:
|
||||
decoded = base64.b64decode(v, validate=True)
|
||||
except Exception:
|
||||
raise ValueError('encrypt_key must be valid base64 string')
|
||||
|
||||
# Check length (AES-256 requires 32 bytes)
|
||||
if len(decoded) < 32:
|
||||
raise ValueError('encrypt_key must decode to at least 32 bytes for AES-256')
|
||||
|
||||
return v
|
||||
|
||||
@property
|
||||
def db_path(self) -> Path:
|
||||
"""SQLite 数据库路径."""
|
||||
@@ -40,4 +57,13 @@ class Settings(BaseSettings):
|
||||
return self.data_dir / 'repos'
|
||||
|
||||
|
||||
settings = Settings()
|
||||
# Lazy initialization - settings is loaded on first access
|
||||
_settings: Optional[Settings] = None
|
||||
|
||||
|
||||
def get_settings() -> Settings:
|
||||
"""获取全局配置实例(懒加载)."""
|
||||
global _settings
|
||||
if _settings is None:
|
||||
_settings = Settings()
|
||||
return _settings
|
||||
|
||||
Reference in New Issue
Block a user