This commit is contained in:
itqop 2025-10-18 15:33:22 +03:00
parent 6748b97367
commit ce5bab1f29
4 changed files with 77 additions and 2 deletions

View File

@ -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)

View File

@ -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"])

View File

@ -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()

View File

@ -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):