Package: fast-depends
FastDependsDocumentation:https://lancetnik.github.io/FastDepends/FastDepends - FastAPI Dependency Injection system extracted from FastAPI and cleared of all HTTP logic.
This is a small library which provides you with the ability to use lovely FastAPI interfaces in your own
projects or tools.Thanks tofastapiandpydanticprojects for this
great functionality. This package is just a small change of the original FastAPI sources to provide DI functionality in a pure-Python way.Async and sync modes are both supported.For why?This project should be extremely helpful to boost your not-FastAPIapplications (evenFlask, I know that u like some legacy).Also the project can be a core of your own framework for anything. Actually, it was build for my another project - :rocket:Propan:rocket: (andFastStream), check it to see full-featuredFastDependsusage example.Installationpipinstallfast-dependsUsageThere is no way to make Dependency Injection easierYou can use this library without any frameworks in bothsyncandasynccode.Async codeimportasynciofromfast_dependsimportinject,Dependsasyncdefdependency(a:int)->int:returna@injectasyncdefmain(a:int,b:int,c:int=Depends(dependency))->float:returna+b+cassertasyncio.run(main("1",2))==4.0Sync codefromfast_dependsimportinject,Dependsdefdependency(a:int)->int:returna@injectdefmain(a:int,b:int,c:int=Depends(dependency))->float:returna+b+cassertmain("1",2)==4.0@injectdecorator plays multiple roles at the same time:resolveDependsclassescast types according to Python annotationvalidate incoming parameters usingpydanticFeaturesSynchronous code is fully supported in this package: without anyasync_to_sync,run_sync,syncifyor any other tricks.Also,FastDependscasts functions' return values the same way, it can be very helpful in building your own tools.These are two main defferences from native FastAPI DI System.Dependencies OverridingAlso,FastDependscan be used as a lightweight DI container. Using it, you can easily override basic dependencies with application startup or in tests.fromtypingimportAnnotatedfromfast_dependsimportDepends,dependency_provider,injectdefabc_func()->int:raiseNotImplementedError()defreal_func()->int:return1@injectdeffunc(dependency:Annotated[int,Depends(abc_func)])->int:returndependencywithdependency_provider.scope(abc_func,real_func):assertfunc()==1dependency_providerin this case is just a default container already declared in the library. But you can use your own the same way:fromtypingimportAnnotatedfromfast_dependsimportDepends,Provider,injectprovider=Provider()defabc_func()->int:raiseNotImplementedError()defreal_func()->int:return1@inject(dependency_overrides_provider=provider)deffunc(dependency:Annotated[int,Depends(abc_func)])->int:returndependencywithprovider.scope(abc_func,real_func):assertfunc()==1This way you can inherit the basicProviderclass and define any extra logic you want!Custom FieldsIf you wish to write your own FastAPI or another closely by architecture tool, you should define your own custom fields to specify application behavior.Custom fields can be used to adding something specific to a function arguments (like a BackgroundTask) or parsing incoming objects special way. You able decide by own, why and how you will use these tools.FastDepends grants you this opportunity a very intuitive and comfortable way.fromfast_dependsimportinjectfromfast_depends.libraryimportCustomFieldclassHeader(CustomField):defuse(self,/,**kwargs:AnyDict)->AnyDict:kwargs=super().use(**kwargs)kwargs[self.param_name]=kwargs["headers"][self.param_name]returnkwargs@injectdefmy_func(header_field:int=Header()):returnheader_fieldassertmy_func(headers={"header_field":"1"})==1