Bird
Raised Fist0
FastAPIframework~20 mins

Connection lifecycle management in FastAPI - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Connection Lifecycle Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ lifecycle
intermediate
2:00remaining
What happens when a FastAPI dependency uses yield?

Consider a FastAPI dependency function that uses yield to provide a database connection. What is the behavior of this dependency during a request?

FastAPI
from fastapi import Depends, FastAPI
from contextlib import asynccontextmanager

app = FastAPI()

@asynccontextmanager
def get_db():
    db = "db connection"
    try:
        yield db
    finally:
        print("Closing db connection")

@app.get("/items/")
async def read_items(db=Depends(get_db)):
    return {"db": db}
AThe code opens the connection before the request and closes it after the response is sent.
BThe connection is opened and closed multiple times during the request processing.
CThe connection is never closed because yield does not support cleanup.
DThe connection is opened after the response is sent.
Attempts:
2 left
💡 Hint

Think about how yield works in Python generators and how FastAPI uses it for dependencies.

❓ state_output
intermediate
2:00remaining
What is the output when a FastAPI dependency raises an exception after yield?

Given this FastAPI dependency that yields a resource and then raises an exception in the cleanup code, what happens when the endpoint is called?

FastAPI
from fastapi import Depends, FastAPI

app = FastAPI()

def resource():
    print("Setup resource")
    yield "resource"
    print("Cleanup resource")
    raise RuntimeError("Error during cleanup")

@app.get("/test")
async def test(dep=Depends(resource)):
    return {"message": "success"}
AThe endpoint returns {"message": "success"} and logs the cleanup error after response.
BThe endpoint never runs the cleanup code because of the exception.
CThe endpoint returns an error response with status 500 immediately.
DThe endpoint raises RuntimeError and does not return a response.
Attempts:
2 left
💡 Hint

Consider when the cleanup code after yield runs in FastAPI dependencies.

🔧 Debug
advanced
2:00remaining
Why does this FastAPI dependency not close the connection?

Examine this FastAPI dependency that tries to open and close a connection. Why does the connection never close?

FastAPI
from fastapi import Depends, FastAPI

app = FastAPI()

def get_conn():
    conn = "open connection"
    return conn
    print("Closing connection")

@app.get("/data")
async def data(conn=Depends(get_conn)):
    return {"conn": conn}
AThe dependency must use yield to open and close connections properly.
BFastAPI requires async functions for dependencies to close connections.
CThe print statement after return never runs, so connection is never closed.
DThe connection closes automatically after the request without explicit code.
Attempts:
2 left
💡 Hint

Think about what happens to code after a return statement in Python functions.

🧠 Conceptual
advanced
2:00remaining
How does FastAPI manage lifespan events for connections?

FastAPI allows defining lifespan events to manage resources like database connections. Which statement best describes how lifespan events work?

ALifespan events run before and after every request to open and close connections.
BLifespan events run code once when the app starts and once when it shuts down, managing global resources.
CLifespan events are deprecated and replaced by dependencies with yield.
DLifespan events only run if the app uses synchronous endpoints.
Attempts:
2 left
💡 Hint

Think about app startup and shutdown phases versus request handling.

❓ component_behavior
expert
3:00remaining
What is the behavior of nested FastAPI dependencies with yield?

Given two nested dependencies where the outer depends on the inner, both using yield to manage connections, what is the order of opening and closing connections during a request?

FastAPI
from fastapi import Depends, FastAPI

app = FastAPI()

def inner_conn():
    print("Open inner connection")
    yield "inner"
    print("Close inner connection")

def outer_conn(inner=Depends(inner_conn)):
    print("Open outer connection")
    yield f"outer uses {inner}"
    print("Close outer connection")

@app.get("/nested")
async def nested(dep=Depends(outer_conn)):
    return {"connection": dep}
AOpen outer, open inner, close inner, close outer
BOpen inner, open outer, close inner, close outer
COpen outer, open inner, close outer, close inner
DOpen inner, open outer, close outer, close inner
Attempts:
2 left
💡 Hint

Consider how Python generators and context managers nest when using yield in dependencies.

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

  1. 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.
  2. Step 2: Identify the lifecycle role

    This pattern ensures resources like database connections open before and close after each request, preventing leaks.
  3. Final Answer:

    To setup a resource before the request and clean it up after the request -> Option A
  4. 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

  1. 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.
  2. 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.
  3. Final Answer:

    def get_conn(): conn = open_conn() yield conn conn.close() -> Option D
  4. Quick Check:

    Yield then cleanup = correct dependency pattern [OK]
Hint: Yield must be followed by cleanup code, not return [OK]
Common Mistakes:
  • Placing return before cleanup code
  • Using async without async resource
  • Returning after yield instead of cleanup
3. Given this FastAPI dependency:
async def get_db():
    db = await connect_db()
    try:
        yield db
    finally:
        await db.disconnect()
What happens when a request finishes using this dependency?
medium
A. An error occurs because yield cannot be used with async
B. The database connection remains open for reuse
C. The database connection is closed asynchronously after the request
D. The connection is closed before the request starts

Solution

  1. Step 1: Analyze async dependency with yield and finally

    The yield pauses the function to provide db during the request, then finally runs cleanup after the request.
  2. Step 2: Understand async cleanup

    The await db.disconnect() runs after the request finishes, closing the connection asynchronously.
  3. Final Answer:

    The database connection is closed asynchronously after the request -> Option C
  4. Quick Check:

    Async yield with finally = async cleanup after request [OK]
Hint: Async yield with finally cleans up after request ends [OK]
Common Mistakes:
  • Thinking yield can't be async
  • Assuming connection stays open
  • Confusing order of cleanup
4. Identify the error in this FastAPI startup event handler:
@app.on_event("startup")
@asynccontextmanager
async def startup():
    await connect_to_service()
    yield
    await disconnect_from_service()
medium
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

  1. Step 1: Understand decorator usage for startup events

    The @app.on_event("startup") expects a normal async function, not an async context manager.
  2. 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.
  3. Final Answer:

    Cannot combine @app.on_event with @asynccontextmanager on the same function -> Option B
  4. 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

  1. Step 1: Understand app-wide resource lifecycle

    A connection pool should open once at app startup and close at shutdown, not per request.
  2. 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.
  3. 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.
  4. Final Answer:

    Use @app.on_event("startup") to open and @app.on_event("shutdown") to close the pool directly without context managers -> Option A
  5. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard