Async generator dependencies let you run setup and cleanup code around your API calls. They help manage resources like database connections efficiently.
Async generator dependencies in FastAPI
async def dependency_name(): # setup code here yield resource # cleanup code here
The function must be async and use yield to separate setup and cleanup.
FastAPI runs the code before yield before the request and the code after yield after the request finishes.
async def get_db(): db = connect_to_db() try: yield db finally: db.close()
async def lifespan(): print('Start') yield print('End')
This FastAPI app uses an async generator dependency get_resource. It prints messages when setting up and cleaning up the resource. The endpoint uses the resource and returns it in JSON.
from fastapi import FastAPI, Depends app = FastAPI() async def get_resource(): print('Setup resource') yield 'resource data' print('Cleanup resource') @app.get('/') async def read_root(resource: str = Depends(get_resource)): print('Handling request') return {'data': resource}
Always use try/finally or code after yield to ensure cleanup runs.
Async generator dependencies work well with async database clients or other async resources.
FastAPI automatically handles calling the async generator before and after the request.
Async generator dependencies help manage setup and cleanup around requests.
Use async def with yield to create them.
They are great for managing resources like database connections safely.
Practice
async generator dependency in FastAPI?Solution
Step 1: Understand async generator dependencies
Async generator dependencies useasync defwithyieldto run setup code before yielding and cleanup code after.Step 2: Identify their purpose in FastAPI
This pattern is mainly used to manage resources safely, like opening and closing database connections around a request.Final Answer:
To manage setup and cleanup actions around a request automatically -> Option AQuick Check:
Async generator dependencies = setup + cleanup [OK]
- Confusing async generators with normal async functions
- Thinking they speed up synchronous code
- Assuming they replace all functions
Solution
Step 1: Identify async generator syntax
An async generator usesasync defandyieldinside the function body.Step 2: Compare options
async def resource(): yield 'data' usesasync defandyield, which is correct. Options A and B are synchronous, and C usesreturninstead ofyield.Final Answer:
async def resource(): yield 'data' -> Option AQuick Check:
Async + yield = async generator [OK]
- Using return instead of yield
- Forgetting async keyword
- Using synchronous def for async generator
async def resource():
print('Setup')
yield 'data'
print('Cleanup')
@app.get('/')
async def read(resource=Depends(resource)):
print('Inside endpoint')
return resourceSolution
Step 1: Understand async generator flow
When the endpoint is called, FastAPI runs the async generator up to the yield (prints 'Setup'), then runs the endpoint code (prints 'Inside endpoint'), then after response finishes, runs code after yield (prints 'Cleanup').Step 2: Order of prints
The prints happen in order: 'Setup', 'Inside endpoint', 'Cleanup'.Final Answer:
Setup, Inside endpoint, Cleanup -> Option DQuick Check:
Yield pauses, so Setup before, Cleanup after endpoint [OK]
- Assuming cleanup runs before endpoint
- Thinking yield returns immediately
- Ignoring async generator lifecycle
async def resource():
connection = await connect_db()
yield connection
await connection.close()
@app.get('/')
async def read(conn=Depends(resource)):
return {'status': 'ok'}Solution
Step 1: Check resource cleanup safety
Without try-finally, if an exception occurs,await connection.close()might not run, causing resource leaks.Step 2: Proper pattern for async generator cleanup
Use try-finally around yield to guarantee cleanup runs even on errors.Final Answer:
Not using try-finally to ensure cleanup -> Option CQuick Check:
Always use try-finally for cleanup in async generators [OK]
- Forgetting try-finally causes resource leaks
- Thinking yield needs await
- Believing Depends can't use async generators
Solution
Step 1: Ensure proper async resource management
Opening the connection must be awaited, and closing must happen even if errors occur.Step 2: Use try-finally around yield
Only async def db(): conn = await open_db() try: yield conn finally: await conn.close() uses try-finally to guaranteeawait conn.close()runs after yield, even on exceptions.Final Answer:
async def db(): conn = await open_db() try: yield conn finally: await conn.close() -> Option BQuick Check:
Try-finally ensures cleanup after yield [OK]
- Not awaiting open_db()
- Not using try-finally for cleanup
- Calling close() without await
Ready to prove it?
Pass the test and this pattern moves unknown
