From 08e482a0e64356efa5d0d0f06116c512e9cafe59 Mon Sep 17 00:00:00 2001 From: itqop Date: Wed, 15 Oct 2025 22:33:29 +0300 Subject: [PATCH] fix: fix config --- pyproject.toml | 32 +++++----- src/hubgw/core/config.py | 133 +++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 32 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c2d55af..408638d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,24 +8,28 @@ version = "0.1.0" description = "FastAPI Gateway for HubMC" authors = ["itqop "] readme = "README.md" +packages = [ + {include = "hubgw", from = "src"} +] [tool.poetry.dependencies] -python = "^3.11" -fastapi = "^0.104.0" -uvicorn = {extras = ["standard"], version = "^0.24.0"} -pydantic = "^2.5.0" -pydantic-settings = "^2.1.0" -sqlalchemy = "^2.0.0" -asyncpg = "^0.29.0" -loguru = "^0.7.0" +python = "^3.12" +fastapi = "^0.116.0" +uvicorn = {extras = ["standard"], version = "^0.30.0"} +pydantic = "^2.12.0" +pydantic-settings = "^2.6.0" +sqlalchemy = "^2.0.44" +asyncpg = "^0.30.0" +loguru = "^0.7.3" [tool.poetry.group.dev.dependencies] -pytest = "^7.4.0" -pytest-asyncio = "^0.21.0" -httpx = "^0.25.0" +pytest = "^8.4.2" +pytest-asyncio = "^0.24.0" +httpx = "^0.27.0" +ruff = "^0.14.0" +black = "^24.10.0" +isort = "^6.0.1" +pytest-cov = "^5.0.0" [tool.poetry.scripts] hubgw = "hubgw.__main__:main" - -[tool.poetry.packages] -{include = "hubgw", from = "src"} diff --git a/src/hubgw/core/config.py b/src/hubgw/core/config.py index d761654..a82feff 100644 --- a/src/hubgw/core/config.py +++ b/src/hubgw/core/config.py @@ -1,27 +1,124 @@ """Application configuration using Pydantic Settings.""" -from pydantic_settings import BaseSettings +from pydantic import BaseModel, Field, computed_field +from pydantic_settings import BaseSettings, SettingsConfigDict from typing import Optional -class AppSettings(BaseSettings): +class DatabaseSettings(BaseModel): + """Database configuration settings.""" + + host: str = Field( + default="localhost", + description="Database host" + ) + port: int = Field( + default=5432, + ge=1, + le=65535, + description="Database port" + ) + user: str = Field( + default="user", + description="Database user" + ) + password: str = Field( + default="pass", + description="Database password" + ) + database: str = Field( + default="hubgw", + description="Database name" + ) + pool_size: int = Field( + default=10, + ge=1, + le=100, + description="Database connection pool size" + ) + max_overflow: int = Field( + default=10, + ge=0, + le=100, + description="Maximum number of overflow connections" + ) + echo: bool = Field( + default=False, + description="Enable SQLAlchemy query logging" + ) + + @computed_field + @property + def dsn(self) -> str: + """Generate database DSN from connection parameters.""" + return ( + f"postgresql+asyncpg://{self.user}:{self.password}" + f"@{self.host}:{self.port}/{self.database}" + ) + + +class SecuritySettings(BaseModel): + """Security configuration settings.""" + + api_key: str = Field( + default="your-api-key", + min_length=8, + description="API key for authentication" + ) + rate_limit_per_min: Optional[int] = Field( + default=None, + ge=1, + description="Rate limit per minute (None = disabled)" + ) + + +class AppSettings(BaseModel): """Application settings.""" - # App settings - APP_ENV: str = "dev" - APP_HOST: str = "0.0.0.0" - APP_PORT: int = 8080 - APP_LOG_LEVEL: str = "INFO" + env: str = Field( + default="dev", + description="Application environment (dev/prod/test)" + ) + host: str = Field( + default="0.0.0.0", + description="Application host" + ) + port: int = Field( + default=8080, + ge=1, + le=65535, + description="Application port" + ) + log_level: str = Field( + default="INFO", + description="Logging level" + ) + + +class Secrets(BaseSettings): + """Main configuration container with all settings.""" - # Database settings - DB_DSN: str = "postgresql+asyncpg://user:pass@localhost:5432/hubgw" - DB_POOL_SIZE: int = 10 - DB_MAX_OVERFLOW: int = 10 + app: AppSettings = Field( + default_factory=AppSettings, + description="Application settings" + ) + database: DatabaseSettings = Field( + default_factory=DatabaseSettings, + description="Database settings" + ) + security: SecuritySettings = Field( + default_factory=SecuritySettings, + description="Security settings" + ) - # Security settings - API_KEY: str = "your-api-key" - RATE_LIMIT_PER_MIN: Optional[int] = None - - class Config: - env_file = ".env" - case_sensitive = True + model_config = SettingsConfigDict( + env_file=".env", + env_file_encoding="utf-8", + env_nested_delimiter="__", + case_sensitive=True, + extra="ignore" + ) + + +# Global configuration instance +APP_CONFIG = Secrets()