Connection lifecycle management helps you open and close resources like database connections safely during a web request. It keeps your app fast and avoids errors.
When you need to connect to a database for each web request.
When you want to open a file or external service only while handling a request.
When you want to clean up resources automatically after a request finishes.
When you want to avoid keeping connections open longer than needed.
When you want to share a connection setup across multiple routes safely.
Syntax
FastAPI
from fastapi import FastAPI, Depends
from contextlib import asynccontextmanager
@asynccontextmanager
def lifespan(app: FastAPI):
# setup code hereyield# cleanup code here
app = FastAPI(lifespan=lifespan)
# Or use dependencies with yieldasyncdef get_db():
db = connect_to_db()
try:
yield db
finally:
db.close()
Use @asynccontextmanager to define setup and cleanup around app lifespan.
Use yield in dependencies to manage resource opening and closing per request.
Examples
This runs code when the app starts and stops.
FastAPI
from fastapi import FastAPI
from contextlib import asynccontextmanager
@asynccontextmanager
def lifespan(app: FastAPI):
print('Starting app')
yieldprint('Stopping app')
app = FastAPI(lifespan=lifespan)
This opens a DB connection for each request and closes it after.
FastAPI
from fastapi import FastAPI, Depends
app = FastAPI()
asyncdef get_db():
db = open_db_connection()
try:
yield db
finally:
db.close()
@app.get('/')
asyncdef read_root(db=Depends(get_db)):
return {'message': 'Using DB'}
Sample Program
This example shows a fake database connection opening when a request starts and closing after it ends.
FastAPI
from fastapi import FastAPI, Depends
from contextlib import asynccontextmanager
class FakeDB:
def __init__(self):
print('DB connected')
def close(self):
print('DB closed')
asyncdef get_db():
db = FakeDB()
try:
yield db
finally:
db.close()
app = FastAPI()
@app.get('/')
asyncdef read_root(db=Depends(get_db)):
return {'message': 'Hello with DB'}
OutputSuccess
Important Notes
Always close connections to avoid resource leaks.
Use yield in dependencies to run cleanup code after the request.
FastAPI runs lifespan code only once when the app starts and stops.
Summary
Connection lifecycle management opens and closes resources safely.
Use yield in dependencies for per-request setup and cleanup.
Use @asynccontextmanager for app startup and shutdown tasks.
Practice
(1/5)
1. What is the main purpose of using yield in FastAPI dependencies for connection lifecycle management?
easy
A. To setup a resource before the request and clean it up after the request
B. To define a synchronous function only
C. To permanently keep a connection open for all requests
D. To return multiple values from a function
Solution
Step 1: Understand yield in dependencies
In FastAPI, yield is used in dependencies to create a setup before the request and a cleanup after the request finishes.
Step 2: Identify the lifecycle role
This pattern ensures resources like database connections open before and close after each request, preventing leaks.
Final Answer:
To setup a resource before the request and clean it up after the request -> Option A
Quick Check:
Yield in dependencies = setup and cleanup per request [OK]
Hint: Yield in dependencies means setup before and cleanup after request [OK]
Common Mistakes:
Thinking yield returns multiple values at once
Assuming yield keeps connection open forever
Confusing yield with async context managers
2. Which of the following is the correct way to define a FastAPI dependency that opens a connection before a request and closes it after using yield?
easy
A. def get_conn():
conn = open_conn()
yield conn
return
conn.close()
B. def get_conn():
conn = open_conn()
return conn
conn.close()
C. async def get_conn():
conn = open_conn()
yield conn
conn.close()
D. def get_conn():
conn = open_conn()
yield conn
conn.close()
Solution
Step 1: Check the use of yield for setup and cleanup
def get_conn():
conn = open_conn()
yield conn
conn.close() correctly uses yield to provide the connection and then closes it after the request.
Step 2: Identify syntax and flow correctness
def get_conn():
conn = open_conn()
return conn
conn.close() returns before closing, so cleanup never runs. async def get_conn():
conn = open_conn()
yield conn
conn.close() mixes async with a sync open_conn (may cause issues). def get_conn():
conn = open_conn()
yield conn
return
conn.close() returns early after yield, skipping cleanup.
A. Missing async keyword before function definition
B. Cannot combine @app.on_event with @asynccontextmanager on the same function
C. Yield cannot be used in async functions
D. No error, this is correct usage
Solution
Step 1: Understand decorator usage for startup events
The @app.on_event("startup") expects a normal async function, not an async context manager.
Step 2: Recognize conflict of decorators
Using @asynccontextmanager with @app.on_event on the same function is invalid because FastAPI expects a coroutine, not a context manager.
Final Answer:
Cannot combine @app.on_event with @asynccontextmanager on the same function -> Option B
Quick Check:
@app.on_event and @asynccontextmanager cannot be combined [OK]
Hint: Don't mix @app.on_event with @asynccontextmanager on one function [OK]
Common Mistakes:
Assuming yield is invalid in async functions
Forgetting async keyword
Thinking this pattern is valid
5. You want to manage a database connection pool that opens once when the FastAPI app starts and closes when it shuts down. Which is the best way to implement this lifecycle management?
hard
A. Use @app.on_event("startup") to open and @app.on_event("shutdown") to close the pool directly without context managers
B. Use a dependency with yield to open and close the pool per request
C. Open the pool globally outside FastAPI and never close it
D. Use @asynccontextmanager to create a context manager function and call it in @app.on_event("startup") and @app.on_event("shutdown")
Solution
Step 1: Understand app-wide resource lifecycle
A connection pool should open once at app startup and close at shutdown, not per request.
Step 2: Choose correct FastAPI pattern
Using @app.on_event("startup") and @app.on_event("shutdown") to open and close the pool directly is the simplest and recommended way.
Step 3: Why not others?
Use @asynccontextmanager to create a context manager function and call it in @app.on_event("startup") and @app.on_event("shutdown") misuses @asynccontextmanager with events. Use a dependency with yield to open and close the pool per request opens/closes per request, which is inefficient. Open the pool globally outside FastAPI and never close it never closes, risking resource leaks.
Final Answer:
Use @app.on_event("startup") to open and @app.on_event("shutdown") to close the pool directly without context managers -> Option A
Quick Check:
App startup/shutdown events manage global resources best [OK]
Hint: Use startup and shutdown events for global resource management [OK]
Common Mistakes:
Opening/closing pool per request wastes resources
Not closing pool causes leaks
Misusing asynccontextmanager for app events
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.