config di lifespan
parent
327ab86d1f
commit
c809f14fdc
|
@ -10,11 +10,14 @@ from api.infrastructure.dependencies.adapters import (
|
||||||
new_session,
|
new_session,
|
||||||
new_unit_of_work,
|
new_unit_of_work,
|
||||||
)
|
)
|
||||||
|
from api.infrastructure.dependencies.configs import app_settings
|
||||||
from api.infrastructure.dependencies.repositories import get_user_repository
|
from api.infrastructure.dependencies.repositories import get_user_repository
|
||||||
from api.infrastructure.dependencies.usecases import provide_create_user
|
from api.infrastructure.dependencies.usecases import provide_create_user
|
||||||
|
from api.infrastructure.settings import Settings
|
||||||
|
|
||||||
|
|
||||||
def init_dependencies(app: FastAPI) -> None:
|
def init_dependencies(app: FastAPI) -> None:
|
||||||
|
app.dependency_overrides[Settings] = app_settings
|
||||||
app.dependency_overrides[AsyncEngine] = create_engine
|
app.dependency_overrides[AsyncEngine] = create_engine
|
||||||
app.dependency_overrides[async_sessionmaker[AsyncSession]] = create_session_maker
|
app.dependency_overrides[async_sessionmaker[AsyncSession]] = create_session_maker
|
||||||
app.dependency_overrides[AsyncSession] = new_session
|
app.dependency_overrides[AsyncSession] = new_session
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
from collections.abc import AsyncGenerator
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
from api.app_builder.dependencies import init_dependencies
|
from api.app_builder.dependencies import init_dependencies
|
||||||
|
@ -5,8 +8,16 @@ from api.app_builder.dependencies import init_dependencies
|
||||||
from .routers import init_routers
|
from .routers import init_routers
|
||||||
|
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI) -> AsyncGenerator:
|
||||||
|
print("init lifespan")
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
def app_factory() -> FastAPI:
|
def app_factory() -> FastAPI:
|
||||||
app = FastAPI()
|
app = FastAPI(
|
||||||
|
lifespan=lifespan,
|
||||||
|
)
|
||||||
init_dependencies(app)
|
init_dependencies(app)
|
||||||
init_routers(app)
|
init_routers(app)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ from sqlalchemy.ext.asyncio import (
|
||||||
from api.application.abstractions import UnitOfWork
|
from api.application.abstractions import UnitOfWork
|
||||||
from api.infrastructure.dependencies.stub import Stub
|
from api.infrastructure.dependencies.stub import Stub
|
||||||
from api.infrastructure.persistence.uow import SqlAlchemyUnitOfWork
|
from api.infrastructure.persistence.uow import SqlAlchemyUnitOfWork
|
||||||
|
from api.infrastructure.settings import Settings
|
||||||
|
|
||||||
|
|
||||||
def new_unit_of_work(
|
def new_unit_of_work(
|
||||||
|
@ -20,15 +21,16 @@ def new_unit_of_work(
|
||||||
return SqlAlchemyUnitOfWork(session)
|
return SqlAlchemyUnitOfWork(session)
|
||||||
|
|
||||||
|
|
||||||
def create_engine() -> AsyncEngine:
|
def create_engine(
|
||||||
return create_async_engine("postgresql+asyncpg://postgresql+asyncpg//demo_user:user_pass@db:5432/serviceman_db")
|
settings: Annotated[Settings, Depends(Stub(Settings))],
|
||||||
|
) -> AsyncEngine:
|
||||||
|
return create_async_engine(settings.db.db_url)
|
||||||
|
|
||||||
|
|
||||||
def create_session_maker(
|
def create_session_maker(
|
||||||
engine: Annotated[AsyncEngine, Depends(Stub(AsyncEngine))],
|
engine: Annotated[AsyncEngine, Depends(Stub(AsyncEngine))],
|
||||||
) -> async_sessionmaker[AsyncSession]:
|
) -> async_sessionmaker[AsyncSession]:
|
||||||
maker = async_sessionmaker(engine, expire_on_commit=False)
|
maker = async_sessionmaker(engine, expire_on_commit=False)
|
||||||
print("session_maker id:", id(maker))
|
|
||||||
return maker
|
return maker
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import os
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
import yaml # type: ignore
|
||||||
|
|
||||||
|
from api.infrastructure.persistence.db_setings import DBSettings
|
||||||
|
from api.infrastructure.settings import Settings
|
||||||
|
|
||||||
|
|
||||||
|
def yaml_loader(file: str) -> dict[str, dict[str, str]]:
|
||||||
|
with open(file) as f:
|
||||||
|
yaml_data: dict = yaml.safe_load(f)
|
||||||
|
return yaml_data
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def app_settings() -> Settings:
|
||||||
|
config_data = yaml_loader(
|
||||||
|
file=os.getenv("CONFIG_PATH", "./config/api_config.yml"),
|
||||||
|
)
|
||||||
|
|
||||||
|
return Settings(
|
||||||
|
db=DBSettings(
|
||||||
|
pg_user=config_data["db"]["user"],
|
||||||
|
pg_pass=config_data["db"]["password"],
|
||||||
|
pg_host=config_data["db"]["host"],
|
||||||
|
pg_port=int(config_data["db"]["port"]),
|
||||||
|
pg_db=config_data["db"]["database"],
|
||||||
|
),
|
||||||
|
)
|
|
@ -5,10 +5,11 @@ from fastapi import Depends
|
||||||
from api.application.abstractions.uow import UnitOfWork
|
from api.application.abstractions.uow import UnitOfWork
|
||||||
from api.application.usecase.create_user import CreateUser
|
from api.application.usecase.create_user import CreateUser
|
||||||
from api.domain.user.repository import UserRepository
|
from api.domain.user.repository import UserRepository
|
||||||
|
from api.infrastructure.dependencies.stub import Stub
|
||||||
|
|
||||||
|
|
||||||
def provide_create_user(
|
def provide_create_user(
|
||||||
user_repository: Annotated[UserRepository, Depends()],
|
user_repository: Annotated[UserRepository, Depends(Stub(UserRepository))],
|
||||||
uow: Annotated[UnitOfWork, Depends()],
|
uow: Annotated[UnitOfWork, Depends()],
|
||||||
) -> CreateUser:
|
) -> CreateUser:
|
||||||
return CreateUser(uow=uow, user_repository=user_repository)
|
return CreateUser(uow=uow, user_repository=user_repository)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class DBSettings:
|
||||||
|
pg_user: str
|
||||||
|
pg_pass: str
|
||||||
|
pg_host: str
|
||||||
|
pg_port: int
|
||||||
|
pg_db: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def db_url(self) -> str:
|
||||||
|
return "postgresql+asyncpg://{}:{}@{}:{}/{}".format(
|
||||||
|
self.pg_user,
|
||||||
|
self.pg_pass,
|
||||||
|
self.pg_host,
|
||||||
|
self.pg_port,
|
||||||
|
self.pg_db,
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
from sqlalchemy.orm import DeclarativeBase
|
||||||
|
|
||||||
|
|
||||||
|
class Base(DeclarativeBase):
|
||||||
|
...
|
|
@ -0,0 +1,18 @@
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from sqlalchemy import UUID
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from api.infrastructure.persistence.models.base import Base
|
||||||
|
|
||||||
|
|
||||||
|
class UserModel(Base):
|
||||||
|
__tablename__ = "user"
|
||||||
|
|
||||||
|
id: Mapped[uuid.UUID] = mapped_column(
|
||||||
|
UUID(as_uuid=True),
|
||||||
|
primary_key=True,
|
||||||
|
)
|
||||||
|
name: Mapped[str]
|
||||||
|
email: Mapped[str] = mapped_column(unique=True)
|
||||||
|
hashed_password: Mapped[str]
|
|
@ -1,6 +1,8 @@
|
||||||
|
from sqlalchemy import insert
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from api.domain.user import User, UserRepository
|
from api.domain.user import User, UserRepository
|
||||||
|
from api.infrastructure.persistence.models.user import UserModel
|
||||||
|
|
||||||
|
|
||||||
class SqlAlchemyUserRepository(UserRepository):
|
class SqlAlchemyUserRepository(UserRepository):
|
||||||
|
@ -8,7 +10,13 @@ class SqlAlchemyUserRepository(UserRepository):
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
async def create_user(self, user: User) -> None:
|
async def create_user(self, user: User) -> None:
|
||||||
pass
|
stmt = insert(UserModel).values(
|
||||||
|
id=user.id,
|
||||||
|
name=user.name,
|
||||||
|
email=user.email,
|
||||||
|
hashed_password=user.password,
|
||||||
|
)
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
|
||||||
async def get_user(self, filter: dict) -> User | None:
|
async def get_user(self, filter: dict) -> User | None:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from api.infrastructure.persistence.db_setings import DBSettings
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass()
|
||||||
|
class Settings:
|
||||||
|
db: DBSettings
|
|
@ -14,8 +14,8 @@ async def get_all_users() -> list[UserResponse]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
@user_router.post("/")
|
@user_router.post("/", status_code=201)
|
||||||
async def create_task(
|
async def create_user(
|
||||||
request: UserCreateRequest,
|
request: UserCreateRequest,
|
||||||
usecase: Annotated[CreateUser, Depends(Stub(CreateUser))],
|
usecase: Annotated[CreateUser, Depends(Stub(CreateUser))],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
db:
|
db:
|
||||||
host: "localhost"
|
host: "db"
|
||||||
port: 5432
|
port: 5432
|
||||||
database: "serviceman_db"
|
database: "serviceman_db"
|
||||||
user: "demo_user"
|
user: "demo_user"
|
||||||
|
|
Loading…
Reference in New Issue