Package: class-based-fastapi
Class based routing for FastAPIDocumentation:https://XDeepZeroX.github.io/class-based-fastapiSource Code:https://github.com/XDeepZeroX/class-based-fastapiFastAPIis a modern, fast web framework for building APIs with Python 3.6+.FeaturesWrite Fast API Controllers (Classes) that can inherit route information from it's parent.This also allows to create a path prefix from a template and add api version information in the template.You don't need to duplicate the code, you can inherit it.To generate OpenAPI documentation, you do not need to explicitly specify the type of the return value, use Generics !Do the same with API methods as before, only more convenient.See thedocsfor more details and examples.RequirementsThis package is intended for use with any recent version of FastAPI (depending onpydantic>=1.8.2), and Python 3.6+.Installationpipinstallclass-based-fastapiExampleimportuuidfromtypingimportList,Generic,TypeVar# 0. Importimportsqlalchemyimportuvicornfromclass_based_fastapiimportRoutable,get,put,post,deletefromfastapiimportFastAPI,DependsfromsqlalchemyimportselectfromsqlmodelimportSession,create_enginefromdatabaseimportrun_async_upgradefrommodels.modelsimportCategory,CategoryPUT,Book,BookPUTapp=FastAPI(debug=True)engine=create_engine('postgresql://postgres:123456@localhost:5432/fastapi_example',echo=True)@app.on_event("startup")defon_startup():print("Start migration")run_async_upgrade()print("DB success upgrade !")defget_session()->Session:withSession(engine)asconn:yieldconnT=TypeVar('T')# 1. Create generic typeTPut=TypeVar('TPut')# 1. Create generic typeclassBaseAPI(Routable,Generic[T,TPut]):# 2. Create generic base API controllerconn:Session=Depends(get_session)def__init__(self):self._type_db_model=self._get_type_generic(T)def_get_type_generic(self,tvar:TypeVar):returnnext(filter(lambdax:x['name']==tvar.__name__,self.__class__.__generic_attribute__))['type']@get("")defget_list_categories(self)->List[T]:# 3. Specifying  generic typesitems=self.conn.execute(select(self._type_db_model)).scalars().all()returnitems@post("")defadd_category(self,model:T)->T:self.conn.add(model)self.conn.commit()returnmodel@delete("{guid}")defdelete_category(self,guid:str)->bool:self.conn.execute(sqlalchemy.delete(self._type_db_model).filter(self._type_db_model.guid==uuid.UUID(guid)))self.conn.commit()returnTrue@put("{guid}")defupdate_category(self,guid:str,model:TPut)->T:# 3. Specifying  generic typesmodel_db=self.conn.execute(select(self._type_db_model).filter(self._type_db_model.guid==uuid.UUID(guid))).scalar()# Update fieldsforname,valinmodel.dict(exclude_unset=True).items():setattr(model_db,name,val)self.conn.commit()self.conn.refresh(model_db)returnmodel_db# CategoriesclassCategoryAPI(BaseAPI[Category,CategoryPUT]):# 4. Inheriting the base controllerNAME_MODULE=Category.__name__# BooksclassBookAPI(BaseAPI[Book,BookPUT]):# 4. Inheriting the base controllerNAME_MODULE=Book.__name__app.include_router(CategoryAPI.routes())# 5. Include routesapp.include_router(BookAPI.routes())# 5. Include routesif__name__=="__main__":uvicorn.run('main:app',host="localhost",port=8001,reload=True,debug=True)Next steps >>>LicenseThis project is licensed under the terms of
theMITlicense.