from beanie import PydanticObjectId from fastapi import APIRouter, HTTPException, Depends from fastapi_filter import FilterDepends from fastapi_pagination import Page, add_pagination from fastapi_pagination.ext.motor import paginate from hub.auth import get_current_user from firm.core.models import CrudDocument from firm.core.schemas import Writer, Reader from firm.db import get_db_client #instance: str="westside", firm: str="cht", def get_tenant_db_cursor(db_client=Depends(get_db_client)): instance = "westside" firm = "cht" return db_client[f"tenant_{instance}_{firm}"] #instance: str="westside", firm: str="cht", def get_logged_tenant_db_cursor(db_client=Depends(get_db_client), user=Depends(get_current_user)): instance = "westside" firm = "cht" db_cursor = db_client[f"tenant_{instance}_{firm}"] db_cursor.user = user return db_cursor def get_crud_router(model: CrudDocument, model_create: Writer, model_read: Reader, model_update: Writer, model_filter): model_name = model.__name__ router = APIRouter() @router.get("/", response_model=Page[model_read], response_description=f"{model_name} records retrieved") async def read_list(filters: model_filter=FilterDepends(model_filter), db=Depends(get_logged_tenant_db_cursor)) -> Page[model_read]: return await paginate(**model.find(db, filters)) @router.post("/", response_description=f"{model_name} added to the database") async def create(schema: model_create, db=Depends(get_logged_tenant_db_cursor)) -> model_read: await schema.validate_foreign_key(db) record = await model.create(db, schema) return model_read.validate_model(record) @router.get("/{record_id}", response_description=f"{model_name} record retrieved") async def read_one(record_id: PydanticObjectId, db=Depends(get_logged_tenant_db_cursor)) -> model_read: record = await model.get(db, record_id) if not record: raise HTTPException( status_code=404, detail=f"{model_name} record not found!" ) return model_read.from_model(record) @router.put("/{record_id}", response_description=f"{model_name} record updated") async def update(record_id: PydanticObjectId, schema: model_update, db=Depends(get_logged_tenant_db_cursor)) -> model_read: record = await model.get(db, record_id) if not record: raise HTTPException( status_code=404, detail=f"{model_name} record not found!" ) record = await model.update(db, record, schema) return model_read.from_model(record) @router.delete("/{record_id}", response_description=f"{model_name} record deleted from the database") async def delete(record_id: PydanticObjectId, db=Depends(get_logged_tenant_db_cursor)) -> dict: record = await model.get(db, record_id) if not record: raise HTTPException( status_code=404, detail=f"{model_name} record not found!" ) await model.delete(db, record) return { "message": f"{model_name} deleted successfully" } add_pagination(router) return router