Reputation: 73
I am trying to figure out how to make configuration/singleton available to different module. Perhaps there is a standard Python way of doing this that I don't know yet. So I create a configuration singleton that has all the app configurations and want to 'share' this with all modules. Same use-case would apply to sharing DB connection.
main.py
app = FastApi()
config = some_config_object_from_somewhere()
app.include_router(
collection.router,
prefix='/api/collection'
)
api/collection.py
router = APIRouter()
@router.post("/", status_code=201)
async def collect():
# I want to use config that is created/defined in main.py
# HOW? I thought dependency injection that is built into FastAPI would
# help, but can't seem to define something in a different module and have it
# available in the 'router' module
Upvotes: 4
Views: 8659
Reputation: 21929
According to @tiangolo (the creator of FastAPI):
"You can declare the same dependency at the router or decorator level and then declare it again in the path operation to get its value.
It won't be evaluated twice, it doesn't add any extra computation, there's a dependency cache in place that stores the values of already solved dependencies for a given request
https://github.com/tiangolo/fastapi/issues/424#issuecomment-584169213
So for the case of sharing a DB connection, you would simply need to re-import get_db
and re-declare it in the router file.
For the case of sharing configuration data, however, the FastAPI documentation states that dependencies are for "shared logic", sharing "database connections", and enforcing "security, authentication, role requirements"—which seems different than shared data.
Putting your configuration data into its own module does the job (doesn't need to be implemented as a singleton) and is officially Pythonic:
The canonical way to share information across modules within a single program is to create a special module (often called config or cfg). Just import the config module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere.
https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules
(The Singleton pattern is arguably less Pythonic.)
Upvotes: 2
Reputation: 1125
In general, about project structure, the basic structure of a FastAPI application is the the same as a Flask one, see here:
It’s time to start coding! Create the flaskr directory and add the
__init__.py
file. The__init__.py
serves double duty: it will contain the application factory, and it tells Python that the flaskr directory should be treated as a package
FastAPI (and also Flask and other functional-style framework) defines database access in terms of functions using sessions, see here.
Below on that documentation page:
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): # <<< injected here
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
Upvotes: 2