From 39c37d83ea22aa2ecb8591a4f80f89531e9606e1 Mon Sep 17 00:00:00 2001 From: gofrendi Date: Wed, 20 Nov 2024 04:23:22 +0700 Subject: [PATCH] Regenerate fastapp --- amalgam/fastapp/common/app.py | 18 +++ amalgam/fastapp/common/app_factory.py | 9 -- amalgam/fastapp/common/db_engine.py | 5 + amalgam/fastapp/common/db_migration.py | 32 ---- amalgam/fastapp/common/db_repository.py | 140 ++++++++++++++++++ .../common/db_session_maker_factory.py | 8 - .../common/{base_usecase.py => usecase.py} | 0 amalgam/fastapp/config.py | 9 +- amalgam/fastapp/main.py | 6 +- amalgam/fastapp/microservices.db | Bin 12288 -> 0 bytes amalgam/fastapp/migrate.py | 2 +- .../fastapp/module/auth/client/api_client.py | 8 +- .../fastapp/module/auth/client/base_client.py | 14 +- .../module/auth/client/direct_client.py | 6 +- amalgam/fastapp/module/auth/client/factory.py | 8 +- amalgam/fastapp/module/auth/db/baseclass.py | 5 - amalgam/fastapp/module/auth/migration.py | 22 --- amalgam/fastapp/module/auth/route.py | 8 +- .../service/user/repository/db_repository.py | 132 +++++------------ .../auth/service/user/repository/factory.py | 10 +- .../service/user/repository/repository.py | 22 ++- .../module/auth/service/user/usecase.py | 46 +++--- amalgam/fastapp/module/gateway/route.py | 18 +-- amalgam/fastapp/monolith.db | Bin 12288 -> 12288 bytes amalgam/fastapp/requirements.txt | 4 +- amalgam/fastapp/schema/user.py | 22 ++- amalgam/fastapp/{_zrb_init.py => zrb_init.py} | 6 +- 27 files changed, 301 insertions(+), 259 deletions(-) create mode 100644 amalgam/fastapp/common/app.py delete mode 100644 amalgam/fastapp/common/app_factory.py create mode 100644 amalgam/fastapp/common/db_engine.py delete mode 100644 amalgam/fastapp/common/db_migration.py create mode 100644 amalgam/fastapp/common/db_repository.py delete mode 100644 amalgam/fastapp/common/db_session_maker_factory.py rename amalgam/fastapp/common/{base_usecase.py => usecase.py} (100%) delete mode 100644 amalgam/fastapp/microservices.db delete mode 100644 amalgam/fastapp/module/auth/db/baseclass.py rename amalgam/fastapp/{_zrb_init.py => zrb_init.py} (97%) diff --git a/amalgam/fastapp/common/app.py b/amalgam/fastapp/common/app.py new file mode 100644 index 00000000..75e2f0fe --- /dev/null +++ b/amalgam/fastapp/common/app.py @@ -0,0 +1,18 @@ +from contextlib import asynccontextmanager + +from common.db_engine import engine +from config import APP_MODE, APP_MODULES +from fastapi import FastAPI +from sqlmodel import SQLModel + + +@asynccontextmanager +async def lifespan(app: FastAPI): + SQLModel.metadata.create_all(engine) + yield + + +app_title = ( + "Fastapp" if APP_MODE == "monolith" else f"Fastapp - {', '.join(APP_MODULES)}" +) +app = FastAPI(title=app_title, lifespan=lifespan) diff --git a/amalgam/fastapp/common/app_factory.py b/amalgam/fastapp/common/app_factory.py deleted file mode 100644 index 47b83484..00000000 --- a/amalgam/fastapp/common/app_factory.py +++ /dev/null @@ -1,9 +0,0 @@ -from fastapi import FastAPI - -from ..config import APP_MODE, APP_MODULES - -app_title = ( - "Fastapp" if APP_MODE == "monolith" else f"Fastapp - {', '.join(APP_MODULES)}" -) - -app = FastAPI(title=app_title) diff --git a/amalgam/fastapp/common/db_engine.py b/amalgam/fastapp/common/db_engine.py new file mode 100644 index 00000000..b153b12b --- /dev/null +++ b/amalgam/fastapp/common/db_engine.py @@ -0,0 +1,5 @@ +from config import APP_DB_URL +from sqlmodel import create_engine + +connect_args = {"check_same_thread": False} +engine = create_engine(APP_DB_URL, connect_args=connect_args) diff --git a/amalgam/fastapp/common/db_migration.py b/amalgam/fastapp/common/db_migration.py deleted file mode 100644 index f908958e..00000000 --- a/amalgam/fastapp/common/db_migration.py +++ /dev/null @@ -1,32 +0,0 @@ -from alembic import context -from alembic.config import Config -from sqlalchemy import create_engine -from sqlalchemy.orm import DeclarativeBase - - -def run_db_migration( - db_url: str, migration_table_name: str, baseclass: DeclarativeBase -): - target_metadata = baseclass.metadata - # Set up the Alembic configuration - alembic_config = Config() - alembic_config.set_main_option("sqlalchemy.url", db_url) - alembic_config.set_main_option("script_location", "migrations") # Update this if needed - alembic_config.set_main_option("version_table", migration_table_name) - # Create the database engine - engine = create_engine(db_url) - - def run_migration_online(): - # Configure and run migrations - with engine.connect() as connection: - context.configure( - connection=connection, - target_metadata=target_metadata, - version_table=migration_table_name, # Custom migration table - ) - with context.begin_transaction(): - context.run_migrations() - - # Run migrations - with context.EnvironmentContext(alembic_config, target_metadata): - run_migration_online() diff --git a/amalgam/fastapp/common/db_repository.py b/amalgam/fastapp/common/db_repository.py new file mode 100644 index 00000000..d04c5b79 --- /dev/null +++ b/amalgam/fastapp/common/db_repository.py @@ -0,0 +1,140 @@ +from typing import Any, Callable, Generic, Type, TypeVar + +from sqlalchemy import Engine +from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession +from sqlmodel import Session, SQLModel, select + +DBModel = TypeVar("DBModel", bound=SQLModel) +ResponseModel = TypeVar("Model", bound=SQLModel) +CreateModel = TypeVar("CreateModel", bound=SQLModel) +UpdateModel = TypeVar("UpdateModel", bound=SQLModel) + + +class BaseDBRepository(Generic[DBModel, ResponseModel, CreateModel, UpdateModel]): + db_model: Type[DBModel] + response_model: Type[ResponseModel] + create_model: Type[CreateModel] + update_model: Type[UpdateModel] + column_preprocessors: dict[str, Callable[[Any], Any]] = {} + + def __init__(self, engine: Engine | AsyncEngine): + self.engine = engine + self.is_async = isinstance(engine, AsyncEngine) + + def _to_response(self, db_instance: DBModel) -> ResponseModel: + return self.response_model(**db_instance.model_dump()) + + async def create(self, data: CreateModel) -> ResponseModel: + data_dict = data.model_dump(exclude_unset=True) + for key, preprocessor in self.column_preprocessors.items(): + if key in data_dict: + data_dict[key] = preprocessor(data_dict[key]) + db_instance = self.db_model(**data_dict) + + if self.is_async: + async with AsyncSession(self.engine) as session: + session.add(db_instance) + await session.commit() + await session.refresh(db_instance) + else: + with Session(self.engine) as session: + session.add(db_instance) + session.commit() + session.refresh(db_instance) + + return self._to_response(db_instance) + + async def get_by_id(self, item_id: str) -> ResponseModel | None: + if self.is_async: + async with AsyncSession(self.engine) as session: + db_instance = await session.get(self.db_model, item_id) + else: + with Session(self.engine) as session: + db_instance = session.get(self.db_model, item_id) + + return self._to_response(db_instance) if db_instance else None + + async def get_all(self, page: int = 1, page_size: int = 10) -> list[ResponseModel]: + offset = (page - 1) * page_size + statement = select(self.db_model).offset(offset).limit(page_size) + + if self.is_async: + async with AsyncSession(self.engine) as session: + result = await session.execute(statement) + results = result.scalars().all() + else: + with Session(self.engine) as session: + results = session.exec(statement).all() + + return [self._to_response(instance) for instance in results] + + async def update(self, item_id: str, data: UpdateModel) -> ResponseModel | None: + update_data = data.model_dump(exclude_unset=True) + for key, value in update_data.items(): + if key in self.column_preprocessors: + update_data[key] = self.column_preprocessors[key](value) + + if self.is_async: + async with AsyncSession(self.engine) as session: + db_instance = await session.get(self.db_model, item_id) + if not db_instance: + return None + for key, value in update_data.items(): + setattr(db_instance, key, value) + session.add(db_instance) + await session.commit() + await session.refresh(db_instance) + else: + with Session(self.engine) as session: + db_instance = session.get(self.db_model, item_id) + if not db_instance: + return None + for key, value in update_data.items(): + setattr(db_instance, key, value) + session.add(db_instance) + session.commit() + session.refresh(db_instance) + + return self._to_response(db_instance) + + async def delete(self, item_id: str) -> bool: + if self.is_async: + async with AsyncSession(self.engine) as session: + db_instance = await session.get(self.db_model, item_id) + if not db_instance: + return False + await session.delete(db_instance) + await session.commit() + else: + with Session(self.engine) as session: + db_instance = session.get(self.db_model, item_id) + if not db_instance: + return False + session.delete(db_instance) + session.commit() + + return True + + async def create_bulk(self, data_list: list[CreateModel]) -> list[ResponseModel]: + db_instances = [] + for data in data_list: + data_dict = data.model_dump(exclude_unset=True) + for key, preprocessor in self.column_preprocessors.items(): + if key in data_dict: + data_dict[key] = preprocessor(data_dict[key]) + db_instances.append(self.db_model(**data_dict)) + + if self.is_async: + async with AsyncSession(self.engine) as session: + session.add_all(db_instances) + await session.commit() + for instance in db_instances: + await session.refresh(instance) + else: + with Session(self.engine) as session: + session.add_all(db_instances) + session.commit() + for instance in db_instances: + session.refresh(instance) + + return [self._to_response(instance) for instance in db_instances] diff --git a/amalgam/fastapp/common/db_session_maker_factory.py b/amalgam/fastapp/common/db_session_maker_factory.py deleted file mode 100644 index 2a5a4e6a..00000000 --- a/amalgam/fastapp/common/db_session_maker_factory.py +++ /dev/null @@ -1,8 +0,0 @@ -from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine -from sqlalchemy.orm import sessionmaker - -from ..config import APP_DB_URL - -db_engine = create_async_engine(APP_DB_URL, echo=True) -# Create an async session factory -session_maker = sessionmaker(db_engine, expire_on_commit=False, class_=AsyncSession) diff --git a/amalgam/fastapp/common/base_usecase.py b/amalgam/fastapp/common/usecase.py similarity index 100% rename from amalgam/fastapp/common/base_usecase.py rename to amalgam/fastapp/common/usecase.py diff --git a/amalgam/fastapp/config.py b/amalgam/fastapp/config.py index 904fcd24..833599e1 100644 --- a/amalgam/fastapp/config.py +++ b/amalgam/fastapp/config.py @@ -12,13 +12,10 @@ ) APP_REPOSITORY_TYPE = os.getenv("APP_REPOSITORY_TYPE", "db") -_DEFAULT_ASYNC_DB_URL = "sqlite+aiosqlite:///monolith.db" -_DEFAULT_SYNC_DB_URL = "sqlite:///monolith.db" +_DEFAULT_DB_URL = "sqlite:///monolith.db" if APP_MODE != "monolith": - _DEFAULT_ASYNC_DB_URL = "sqlite+aiosqlite:///microservices.db" - _DEFAULT_SYNC_DB_URL = "sqlite:///microservices.db" -APP_DB_URL = os.getenv("APP_DB_URL", _DEFAULT_ASYNC_DB_URL) -APP_DB_MIGRATION_URL = os.getenv("APP_DB_MIGRATION_URL", _DEFAULT_SYNC_DB_URL) + _DEFAULT_DB_URL = "sqlite:///microservices.db" +APP_DB_URL = os.getenv("APP_DB_URL", _DEFAULT_DB_URL) _DEFAULT_MIGRATION_TABLE = "migration_table" if APP_MODE != "monolith" and len(APP_MODULES) > 0: diff --git a/amalgam/fastapp/main.py b/amalgam/fastapp/main.py index e51e9d63..6fcccdbb 100644 --- a/amalgam/fastapp/main.py +++ b/amalgam/fastapp/main.py @@ -1,6 +1,6 @@ -from .common.app_factory import app -from .module.auth import route as auth_route -from .module.gateway import route as gateway_route +from common.app import app +from module.auth import route as auth_route +from module.gateway import route as gateway_route assert app assert gateway_route diff --git a/amalgam/fastapp/microservices.db b/amalgam/fastapp/microservices.db deleted file mode 100644 index a56a3a3b589c6cde08e5ebbc3c9f66d86f95ae4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#&r8EF6bJC6in_vn+;$S)v4tV%=ut41qSM;BtSZApsamzTw%T>#RsSLXv|T;g z3mo`eN;S&MPb4u}|Iyc}!gScJ;g7fJb4`Lf__ z=jx>1{9;;T#u~Hc=duIXhX4d1009U<00Izz00bZa0SNqq!23SmY+Dxp*e=4GaTHFA z#~_Ix^00`rH28B(v!x?^hkSA9I#hLv488Um-*$gxNe8^ zn%(z?z7##ruPhThKi$%~?41cYqElx?#*d<=ZXRhH?Q4s(IK7MBCNJZ%cMrzCw z`*odQw`x`O^;^obuBMin5D1Rwwb2tWV=5P$##AOHaftg3*nE{6VpRevw;1px>^ V00Izz00bZa0SG_<0uY!Bd;`*GW@G>W diff --git a/amalgam/fastapp/migrate.py b/amalgam/fastapp/migrate.py index 86f79e20..f203664c 100644 --- a/amalgam/fastapp/migrate.py +++ b/amalgam/fastapp/migrate.py @@ -1,3 +1,3 @@ -from .module.auth import migration as auth_migration +from module.auth import migration as auth_migration assert auth_migration diff --git a/amalgam/fastapp/module/auth/client/api_client.py b/amalgam/fastapp/module/auth/client/api_client.py index 0205f53e..38020cb1 100644 --- a/amalgam/fastapp/module/auth/client/api_client.py +++ b/amalgam/fastapp/module/auth/client/api_client.py @@ -1,7 +1,7 @@ -from ....config import APP_AUTH_BASE_URL -from ..service.user.usecase import user_usecase -from .base_client import BaseClient +from config import APP_AUTH_BASE_URL +from module.auth.client.base_client import BaseClient +from module.auth.service.user.usecase import user_usecase -class APIClient(BaseClient, user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL)): +class APIClient(user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL), BaseClient): pass diff --git a/amalgam/fastapp/module/auth/client/base_client.py b/amalgam/fastapp/module/auth/client/base_client.py index 76005a9b..7c952e00 100644 --- a/amalgam/fastapp/module/auth/client/base_client.py +++ b/amalgam/fastapp/module/auth/client/base_client.py @@ -1,27 +1,27 @@ from abc import ABC, abstractmethod -from ....schema.user import NewUserData, UpdateUserData, UserData +from schema.user import UserCreate, UserResponse, UserUpdate class BaseClient(ABC): @abstractmethod - async def get_user_by_id(self, user_id: str) -> UserData: + async def get_user_by_id(self, user_id: str) -> UserResponse: pass @abstractmethod - async def get_all_users(self) -> list[UserData]: + async def get_all_users(self) -> list[UserResponse]: pass @abstractmethod async def create_user( - self, data: NewUserData | list[NewUserData] - ) -> UserData | list[UserData]: + self, data: UserCreate | list[UserCreate] + ) -> UserResponse | list[UserResponse]: pass @abstractmethod - async def update_user(self, user_id: str, data: UpdateUserData) -> UserData: + async def update_user(self, user_id: str, data: UserUpdate) -> UserResponse: pass @abstractmethod - async def delete_user(self, user_id: str) -> UserData: + async def delete_user(self, user_id: str) -> UserResponse: pass diff --git a/amalgam/fastapp/module/auth/client/direct_client.py b/amalgam/fastapp/module/auth/client/direct_client.py index 9eed2724..1e7417a2 100644 --- a/amalgam/fastapp/module/auth/client/direct_client.py +++ b/amalgam/fastapp/module/auth/client/direct_client.py @@ -1,6 +1,6 @@ -from ..service.user.usecase import user_usecase -from .base_client import BaseClient +from module.auth.client.base_client import BaseClient +from module.auth.service.user.usecase import user_usecase -class DirectClient(BaseClient, user_usecase.as_direct_client()): +class DirectClient(user_usecase.as_direct_client(), BaseClient): pass diff --git a/amalgam/fastapp/module/auth/client/factory.py b/amalgam/fastapp/module/auth/client/factory.py index 92e2f26e..4119e8a6 100644 --- a/amalgam/fastapp/module/auth/client/factory.py +++ b/amalgam/fastapp/module/auth/client/factory.py @@ -1,7 +1,7 @@ -from ....config import APP_COMMUNICATION -from .api_client import APIClient -from .base_client import BaseClient -from .direct_client import DirectClient +from config import APP_COMMUNICATION +from module.auth.client.api_client import APIClient +from module.auth.client.base_client import BaseClient +from module.auth.client.direct_client import DirectClient if APP_COMMUNICATION == "direct": client: BaseClient = DirectClient() diff --git a/amalgam/fastapp/module/auth/db/baseclass.py b/amalgam/fastapp/module/auth/db/baseclass.py deleted file mode 100644 index fa2b68a5..00000000 --- a/amalgam/fastapp/module/auth/db/baseclass.py +++ /dev/null @@ -1,5 +0,0 @@ -from sqlalchemy.orm import DeclarativeBase - - -class Base(DeclarativeBase): - pass diff --git a/amalgam/fastapp/module/auth/migration.py b/amalgam/fastapp/module/auth/migration.py index 38385cd3..e69de29b 100644 --- a/amalgam/fastapp/module/auth/migration.py +++ b/amalgam/fastapp/module/auth/migration.py @@ -1,22 +0,0 @@ -from ...common.db_migration import run_db_migration -from ...config import ( - APP_DB_MIGRATION_TABLE, - APP_DB_MIGRATION_URL, - APP_MODE, - APP_MODULES, - APP_REPOSITORY_TYPE, -) -from .db.baseclass import Base - -if ( - APP_REPOSITORY_TYPE == "db" - and ( - (APP_MODE == "microservices" and "auth" in APP_MODULES) - or APP_MODE == "monolith" - ) -): - run_db_migration( - db_url=APP_DB_MIGRATION_URL, - migration_table_name=APP_DB_MIGRATION_TABLE, - baseclass=Base - ) diff --git a/amalgam/fastapp/module/auth/route.py b/amalgam/fastapp/module/auth/route.py index 986f644a..68c58680 100644 --- a/amalgam/fastapp/module/auth/route.py +++ b/amalgam/fastapp/module/auth/route.py @@ -1,7 +1,7 @@ -from ...common.app_factory import app -from ...common.schema import BasicResponse -from ...config import APP_MODE, APP_MODULES -from .service.user.usecase import user_usecase +from common.app import app +from common.schema import BasicResponse +from config import APP_MODE, APP_MODULES +from module.auth.service.user.usecase import user_usecase if APP_MODE == "microservices" and "auth" in APP_MODULES: diff --git a/amalgam/fastapp/module/auth/service/user/repository/db_repository.py b/amalgam/fastapp/module/auth/service/user/repository/db_repository.py index 615eb665..4cd921f3 100644 --- a/amalgam/fastapp/module/auth/service/user/repository/db_repository.py +++ b/amalgam/fastapp/module/auth/service/user/repository/db_repository.py @@ -1,97 +1,37 @@ -from uuid import uuid4 - -from sqlalchemy import String, delete, update -from sqlalchemy.future import select -from sqlalchemy.orm import Mapped, Session, mapped_column, sessionmaker - -from ......schema.user import NewUserData, UpdateUserData, UserData -from ....db.baseclass import Base -from .repository import UserRepository - - -class UserModel(Base): - __tablename__ = "users" - id: Mapped[str] = mapped_column(String(30), primary_key=True) - username: Mapped[str] = mapped_column(String(50)) - password: Mapped[str] = mapped_column(String(50)) - - -def create_user_model(new_user_data: NewUserData) -> UserModel: - return UserModel( - id=str(uuid4()), - username=new_user_data.username, - password=new_user_data.password, - ) - - -def get_user_data(user_model: UserModel) -> UserData: - return UserData( - id=user_model.id, - username=user_model.username, - ) - - -class UserDBRepository(UserRepository): - def __init__(self, session_maker: sessionmaker[Session]): - self.session_maker = session_maker - - async def create_user(self, new_user_data: NewUserData) -> UserData: - async with self.session_maker() as session: - user_model = create_user_model(new_user_data) - session.add(user_model) - await session.commit() - await session.refresh(user_model) - return get_user_data(user_model) - - async def get_user_by_id(self, user_id: str) -> UserData | None: - async with self.session_maker() as session: - result = await session.execute(select(UserModel).filter_by(id=user_id)) - user_model = result.scalar_one_or_none() - if user_model: - return get_user_data(user_model) - return None - - async def get_all_users(self) -> list[UserData]: - async with self.session_maker() as session: - result = await session.execute(select(UserModel)) - user_models = result.scalars().all() - return [get_user_data(user_model) for user_model in user_models] - - async def update_user( - self, user_id: str, update_user_data: UpdateUserData - ) -> UserData | None: - async with self.session_maker() as session: - stmt = ( - update(UserModel) - .where(UserModel.id == user_id) - .values(username=update_user_data.username) - .execution_options(synchronize_session="fetch") - ) - await session.execute(stmt) - await session.commit() - return await self.get_user_by_id(user_id) - - async def delete_user(self, user_id: str) -> None: - async with self.session_maker() as session: - stmt = delete(UserModel).where(UserModel.id == user_id) - await session.execute(stmt) - await session.commit() - - async def create_users_bulk( - self, new_users_data: list[NewUserData] - ) -> list[UserData]: - async with self.session_maker() as session: - user_models = [create_user_model(user_data) for user_data in new_users_data] - session.add_all(user_models) - await session.commit() - return [get_user_data(user_model) for user_model in user_models] - - async def get_user_by_username(self, username: str) -> UserData | None: - async with self.session_maker() as session: - result = await session.execute( - select(UserModel).filter_by(username=username) - ) - user_model = result.scalar_one_or_none() - if user_model: - return get_user_data(user_model) +from common.db_repository import BaseDBRepository +from module.auth.service.user.repository.repository import UserRepository +from passlib.context import CryptContext +from schema.user import User, UserCreate, UserResponse, UserUpdate +from sqlalchemy.ext.asyncio import AsyncSession +from sqlmodel import Session, select + +# Password hashing context +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +def hash_password(password: str) -> str: + return pwd_context.hash(password) + + +class UserDBRepository( + BaseDBRepository[User, UserResponse, UserCreate, UserUpdate], UserRepository +): + db_model = User + response_model = UserResponse + create_model = UserCreate + update_model = UserUpdate + column_preprocessors = {"password": hash_password} + + async def get_by_credentials( + self, username: str, password: str + ) -> UserResponse | None: + statement = select(User).where(User.username == username) + if self.is_async: + async with AsyncSession(self.engine) as session: + user = await session.exec(statement).first + else: + with Session(self.engine) as session: + user = session.exec(statement).first() + if not user or not pwd_context.verify(password, user.hashed_password): return None + return self._to_response(user) diff --git a/amalgam/fastapp/module/auth/service/user/repository/factory.py b/amalgam/fastapp/module/auth/service/user/repository/factory.py index 21354615..d90d7ed9 100644 --- a/amalgam/fastapp/module/auth/service/user/repository/factory.py +++ b/amalgam/fastapp/module/auth/service/user/repository/factory.py @@ -1,9 +1,9 @@ -from ......common.db_session_maker_factory import session_maker -from ......config import APP_REPOSITORY_TYPE -from .db_repository import UserDBRepository -from .repository import UserRepository +from common.db_engine import engine +from config import APP_REPOSITORY_TYPE +from module.auth.service.user.repository.db_repository import UserDBRepository +from module.auth.service.user.repository.repository import UserRepository if APP_REPOSITORY_TYPE == "db": - user_repository: UserRepository = UserDBRepository(session_maker) + user_repository: UserRepository = UserDBRepository(engine) else: user_repository: UserRepository = None diff --git a/amalgam/fastapp/module/auth/service/user/repository/repository.py b/amalgam/fastapp/module/auth/service/user/repository/repository.py index 7af3142e..ba719d9b 100644 --- a/amalgam/fastapp/module/auth/service/user/repository/repository.py +++ b/amalgam/fastapp/module/auth/service/user/repository/repository.py @@ -1,38 +1,36 @@ from abc import ABC, abstractmethod -from ......schema.user import NewUserData, UpdateUserData, UserData +from schema.user import User, UserCreate, UserResponse, UserUpdate class UserRepository(ABC): @abstractmethod - async def create_user(self, new_user_data: NewUserData) -> UserData: + async def create(self, user_data: UserCreate) -> UserResponse: pass @abstractmethod - async def get_user_by_id(self, user_id: str) -> UserData | None: + async def get_by_id(self, user_id: str) -> User | None: pass @abstractmethod - async def get_all_users(self) -> list[UserData]: + async def get_all(self) -> list[User]: pass @abstractmethod - async def update_user( - self, user_id: str, update_user_data: UpdateUserData - ) -> UserData | None: + async def update(self, user_id: str, user_data: UserUpdate) -> User | None: pass @abstractmethod - async def delete_user(self, user_id: str) -> None: + async def delete(self, user_id: str) -> User | None: pass @abstractmethod - async def create_users_bulk( - self, new_users_data: list[NewUserData] - ) -> list[UserData]: + async def create_bulk(self, user_data_list: list[UserCreate]) -> list[UserResponse]: pass @abstractmethod - async def get_user_by_username(self, username: str) -> UserData | None: + async def get_by_credentials( + self, username: str, password: str + ) -> UserResponse | None: pass diff --git a/amalgam/fastapp/module/auth/service/user/usecase.py b/amalgam/fastapp/module/auth/service/user/usecase.py index 0e5e9e37..3a0f7f71 100644 --- a/amalgam/fastapp/module/auth/service/user/usecase.py +++ b/amalgam/fastapp/module/auth/service/user/usecase.py @@ -1,41 +1,45 @@ -from .....common.base_usecase import BaseUsecase -from .....schema.user import NewUserData, UpdateUserData, UserData -from .repository.factory import user_repository +from common.usecase import BaseUsecase +from module.auth.service.user.repository.factory import user_repository +from schema.user import UserCreate, UserResponse, UserUpdate class UserUsecase(BaseUsecase): @BaseUsecase.route( - "/api/v1/users/{user_id}", methods=["get"], response_model=UserData + "/api/v1/users/{user_id}", methods=["get"], response_model=UserResponse ) - async def get_user_by_id(self, user_id: str) -> UserData: - return await user_repository.get_user_by_id(user_id) + async def get_user_by_id(self, user_id: str) -> UserResponse: + return await user_repository.get_by_id(user_id) - @BaseUsecase.route("/api/v1/users", methods=["get"], response_model=list[UserData]) - async def get_all_users(self) -> list[UserData]: - return await user_repository.get_all_users() + @BaseUsecase.route( + "/api/v1/users", methods=["get"], response_model=list[UserResponse] + ) + async def get_all_users(self) -> list[UserResponse]: + return await user_repository.get_all() @BaseUsecase.route( - "/api/v1/users", methods=["post"], response_model=UserData | list[UserData] + "/api/v1/users", + methods=["post"], + response_model=UserResponse | list[UserResponse], ) async def create_user( - self, data: NewUserData | list[NewUserData] - ) -> UserData | list[UserData]: - if isinstance(data, NewUserData): - return await user_repository.create_user(data) - return await user_repository.create_users_bulk(data) + self, data: UserCreate | list[UserCreate] + ) -> UserResponse | list[UserResponse]: + if isinstance(data, UserCreate): + return await user_repository.create(data) + return await user_repository.create_bulk(data) @BaseUsecase.route( - "/api/v1/users/{user_id}", methods=["put"], response_model=UserData + "/api/v1/users/{user_id}", methods=["put"], response_model=UserResponse ) - async def update_user(self, user_id: str, data: UpdateUserData) -> UserData: - return await user_repository.update_user(user_id, data) + async def update_user(self, user_id: str, data: UserUpdate) -> UserResponse: + return await user_repository.update(user_id, data) @BaseUsecase.route( - "/api/v1/users/{user_id}", methods=["delete"], response_model=UserData + "/api/v1/users/{user_id}", methods=["delete"], response_model=UserResponse ) - async def delete_user(self, user_id: str) -> UserData: - return await user_repository.delete_user(user_id) + async def delete_user(self, user_id: str) -> UserResponse: + return await user_repository.delete(user_id) user_usecase = UserUsecase() diff --git a/amalgam/fastapp/module/gateway/route.py b/amalgam/fastapp/module/gateway/route.py index 4b68a96d..b120f18a 100644 --- a/amalgam/fastapp/module/gateway/route.py +++ b/amalgam/fastapp/module/gateway/route.py @@ -1,8 +1,8 @@ -from ...common.app_factory import app -from ...common.schema import BasicResponse -from ...config import APP_MODE, APP_MODULES -from ...schema.user import NewUserData, UserData -from ..auth.client.factory import client as auth_client +from common.app import app +from common.schema import BasicResponse +from config import APP_MODE, APP_MODULES +from module.auth.client.factory import client as auth_client +from schema.user import UserCreate, UserResponse if APP_MODE == "monolith" or "gateway" in APP_MODULES: @@ -18,10 +18,10 @@ async def health(): async def readiness(): return BasicResponse(message="ok") - @app.get("/api/v1/users", response_model=list[UserData]) - async def auth_get_all_users(): + @app.get("/api/v1/users", response_model=list[UserResponse]) + async def auth_get_all_users() -> UserResponse: return await auth_client.get_all_users() - @app.post("/api/v1/users", response_model=NewUserData | list[NewUserData]) - async def auth_create_user(data: UserData | list[UserData]): + @app.post("/api/v1/users", response_model=UserResponse | list[UserResponse]) + async def auth_create_user(data: UserCreate | list[UserCreate]): return await auth_client.create_user(data) diff --git a/amalgam/fastapp/monolith.db b/amalgam/fastapp/monolith.db index bee9c4efb5de9688322d8ab11639a643f6603c9b..685cc7a080144cfcf0243afb15d3130ed701128c 100644 GIT binary patch delta 368 zcmZojXh@hK&B!!S##xYwK`-2km;VO?6TdwJzdir?&4L2w`RW^a8QH}}MHw4wOA?cE zQcH_di$IvkImp#9#8n~0(aFbE0VJZJ!Nr-Gq7dd7)so4B>;Kio~*~PWB8Jjpu5|eUL zb2HP65=%1k^Ww2_nVf@M9Yb6dLL8lZTousNDrj(VmZcUIgEZ%r<|>3a2042;25A@@ zX)5^nhbZ`k`uON5aB({O`vr#tIePkq08OYzu`a$KJ6Rzh$kW#`C{n@OHBvzX$v{mm zO> migrate_monolith >> migrate_all @@ -128,7 +128,7 @@ def migrate_microservice(name: str, module: str) -> Task: cwd=APP_DIR, cmd=[ ACTIVATE_VENV_SCRIPT, - f"python -m {APP_MODULE_NAME}.migrate", + # f"python -m {APP_MODULE_NAME}.migrate", ], auto_render_cmd=False, retries=0,