-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
17d99dc
commit 39c37d8
Showing
27 changed files
with
301 additions
and
259 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
from .module.auth import migration as auth_migration | ||
from module.auth import migration as auth_migration | ||
|
||
assert auth_migration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.