Closed lasryariel closed 2 months ago
So far from a brief look at the docs, it looks like the Depends()
mechanism available in FastAPI will be handy for abstracting some common processes (along with middlewares), but a bit different than DI within OOP frameworks as the top-level injected Callable
's only passed arguments will be parameters equivalent to the Path
operations within FastAPI.
Thinking about database, logging, etc dependencies we might consider using global singletons, and allow the ContextManager
to handle any open and close operations on e.g. connections.
Overall so far it looks like existing code will port without too much headache, but @paulespinosa may catch something I missed on this read through.
@tylerthome got the basics down. I also second the assertion that porting the existing code base can be done.
The Dependency Injection system in FastAPI is easy to use and capable of doing lots for us. The tutorial is extensive https://fastapi.tiangolo.com/tutorial/dependencies/ with details that provide guidance on injecting database dependencies, security related dependencies, and more. In addition, the Advanced provides another way to make an instance of a class callable and use it as a dependency.
The tutorial tells us FastAPI will create a Context Manager for any dependency with yield
and also provides guidance on how to create custom Context Managers. https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#what-are-context-managers.
The tutorial on writing bigger applications guides us to put dependencies into its own module. https://fastapi.tiangolo.com/tutorial/bigger-applications/#dependencies. This can aid us in maintaining easy to understand code structure.
For logging, it appears the standard is to use Python's logging
facility for all logging. The logger can be customized at startup and removes the need for associating DI and logging. https://docs.python.org/3/library/logging.html
import logging
import mylib
logger = logging.getLogger(__name__)
The FastAPI project template also uses this technique for logging. For example: https://github.com/fastapi/full-stack-fastapi-template/blob/master/backend/app/backend_pre_start.py
Regarding, best practices. I think it's too early to know what they are until we have designed the API's architecture(s).
Below is a just a brainstorm for how DI could be used to inject the current user as a guest and case manager.
@router.post("/intake_profile")
def submit_intake_profile(intake_profile: IntakeProfile, guest: Annotated[Guest, Depends(get_current_user_as_guest)], case_manager: Annotated[CaseManager, Depends(get_case_manager)]):
case = case_manager.caseFor(guest)
case.submit_intake_profile(intake_profile)
Conversation between Ariel and Paul 9/4
As a follow up we need to design for both infrastructure and business objects
Infrastructure
Business objects
Current state of dependency injection in HUU code
Decision Record Created: https://github.com/hackforla/HomeUniteUs/wiki/Migrating-from-Flask-to-FastAPI
Overview
As part of our ongoing effort to improve code readability and accessibility for junior developers, we are exploring the use of Dependency Injection (DI) in FastAPI. The goal is to leverage FastAPI’s DI capabilities to create a more modular, testable, and maintainable codebase.
Action Items
Understand FastAPI's Dependency Injection System
Evaluate Current Codebase for DI Opportunities
Decision Record
Resources/Instructions
A well-researched assessment of Dependency Injection system in FastAPI and documentation of areas to implement.