diff --git a/src/hubgw/api/deps.py b/src/hubgw/api/deps.py index 766e8bc..b6018aa 100644 --- a/src/hubgw/api/deps.py +++ b/src/hubgw/api/deps.py @@ -31,6 +31,14 @@ async def get_session( yield session +async def get_azuriom_session( + context: Annotated[AppContext, Depends(get_context)] +) -> AsyncGenerator[AsyncSession, None]: + """Get Azuriom database session.""" + async with context.azuriom_session_factory() as session: + yield session + + async def verify_api_key( x_api_key: Annotated[str, Header(alias="X-API-Key")], context: Annotated[AppContext, Depends(get_context)] @@ -86,6 +94,6 @@ def get_teleport_history_service(session: Annotated[AsyncSession, Depends(get_se return TeleportHistoryService(session) -def get_user_service(session: Annotated[AsyncSession, Depends(get_session)]) -> UserService: +def get_user_service(session: Annotated[AsyncSession, Depends(get_azuriom_session)]) -> UserService: """Get user service.""" return UserService(session) diff --git a/src/hubgw/api/v1/router.py b/src/hubgw/api/v1/router.py index 9e96ba1..383e3f5 100644 --- a/src/hubgw/api/v1/router.py +++ b/src/hubgw/api/v1/router.py @@ -1,7 +1,7 @@ """Main API v1 router.""" from fastapi import APIRouter -from hubgw.api.v1 import health, homes, kits, cooldowns, warps, whitelist, punishments, audit, luckperms, teleport_history +from hubgw.api.v1 import health, homes, kits, cooldowns, warps, whitelist, punishments, audit, luckperms, teleport_history, users api_router = APIRouter() @@ -16,3 +16,4 @@ api_router.include_router(punishments.router, prefix="/punishments", tags=["puni api_router.include_router(audit.router, prefix="/audit", tags=["audit"]) api_router.include_router(luckperms.router, prefix="/luckperms", tags=["luckperms"]) api_router.include_router(teleport_history.router, prefix="/teleport-history", tags=["teleport-history"]) +api_router.include_router(users.router, prefix="/users", tags=["users"]) diff --git a/src/hubgw/context.py b/src/hubgw/context.py index d9ce482..456b885 100644 --- a/src/hubgw/context.py +++ b/src/hubgw/context.py @@ -23,6 +23,8 @@ class AppContext(metaclass=Singleton): self.settings = APP_CONFIG self._engine = None self._session_factory = None + self._azuriom_engine = None + self._azuriom_session_factory = None @property def engine(self): @@ -59,6 +61,42 @@ class AppContext(metaclass=Singleton): ) return self._session_factory + @property + def azuriom_engine(self): + if self._azuriom_engine is None: + connect_args = { + "statement_cache_size": 0, + "timeout": 20, + } + engine_kwargs = { + "connect_args": connect_args, + "pool_pre_ping": True, + } + + self._azuriom_engine = create_async_engine( + self.settings.database.azuriom_dsn, + pool_size=self.settings.database.pool_size, + max_overflow=self.settings.database.max_overflow, + pool_recycle=True, + echo=self.settings.database.echo, + **engine_kwargs, + ) + + # Azuriom использует ту же Base, но с другим engine + Base.metadata.bind = self._azuriom_engine + + return self._azuriom_engine + + @property + def azuriom_session_factory(self) -> async_sessionmaker[AsyncSession]: + if self._azuriom_session_factory is None: + self._azuriom_session_factory = async_sessionmaker( + bind=self.azuriom_engine, + class_=AsyncSession, + expire_on_commit=False, + ) + return self._azuriom_session_factory + async def get_db_session(self) -> AsyncGenerator[AsyncSession, None]: session = self.session_factory() try: @@ -66,6 +104,13 @@ class AppContext(metaclass=Singleton): finally: await session.close() + async def get_azuriom_db_session(self) -> AsyncGenerator[AsyncSession, None]: + session = self.azuriom_session_factory() + try: + yield session + finally: + await session.close() + async def startup(self): pass @@ -76,6 +121,13 @@ class AppContext(metaclass=Singleton): self._engine = None except Exception as e: print(f"Error disposing engine: {e}") + + try: + if self._azuriom_engine is not None: + await self._azuriom_engine.dispose() + self._azuriom_engine = None + except Exception as e: + print(f"Error disposing azuriom engine: {e}") APP_CTX = AppContext() diff --git a/src/hubgw/core/config.py b/src/hubgw/core/config.py index ef459d4..7c00cff 100644 --- a/src/hubgw/core/config.py +++ b/src/hubgw/core/config.py @@ -39,6 +39,11 @@ class DatabaseSettings(BaseSettings): validation_alias="DATABASE__DATABASE", description="Database name" ) + azuriom_database: str = Field( + default="azuriom", + validation_alias="DATABASE__AZURIOM_DATABASE", + description="Azuriom database name" + ) pool_size: int = Field( default=10, validation_alias="DATABASE__POOL_SIZE", @@ -67,6 +72,15 @@ class DatabaseSettings(BaseSettings): f"postgresql+asyncpg://{self.user}:{quote_plus(self.password)}" f"@{self.host}:{self.port}/{self.database}" ) + + @computed_field + @property + def azuriom_dsn(self) -> str: + """Generate Azuriom database DSN from connection parameters.""" + return ( + f"postgresql+asyncpg://{self.user}:{quote_plus(self.password)}" + f"@{self.host}:{self.port}/{self.azuriom_database}" + ) class SecuritySettings(BaseSettings):