CodingNeed.

3 · Reliability and delivery · 30 MIN

FastAPI dependencies and cleanup

A yielded dependency owns a resource’s request lifetime.

A dependency can acquire a resource, yield it to an endpoint and release it in finally. This example provides a small in-memory SQLite connection for each request and closes it afterwards. Each connection gets an independent demo dataset; nothing is durable across requests. A production service should use a configured database pool and transaction policy. The synchronous route and dependency keep blocking SQLite work out of an async function; async def does not make blocking database calls nonblocking.

Verify parameters are bound rather than interpolated into SQL.

Read the example

# main.py
import sqlite3
from fastapi import Depends, FastAPI
app = FastAPI()
def database():
    connection = sqlite3.connect(":memory:", check_same_thread=False)
    try:
        connection.execute("CREATE TABLE courses(id INTEGER, title TEXT)")
        connection.execute("INSERT INTO courses VALUES(?, ?)", (1, "React"))
        yield connection
    finally:
        connection.close()
@app.get("/courses")
def courses(db=Depends(database)):
    return [{"id": row[0], "title": row[1]} for row in db.execute("SELECT id, title FROM courses ORDER BY id")]
Check the expected output
Every GET /courses returns the demo React row; the per-request connection is closed afterwards.

Your challenge

Override the dependency in tests with controlled data, inject a query failure and verify resource cleanup still runs.

Solution cost: O(p) rows returned plus query cost. time · O(p) response rows and this tiny per-request database. space

Common trap

check_same_thread=False permits thread access; it is not a complete concurrency or transaction strategy.

Study the project implementation
# main.py
import sqlite3
from fastapi import Depends, FastAPI
app = FastAPI()
def database():
    connection = sqlite3.connect(":memory:", check_same_thread=False)
    try:
        connection.execute("CREATE TABLE courses(id INTEGER, title TEXT)")
        connection.execute("INSERT INTO courses VALUES(?, ?)", (1, "React"))
        yield connection
    finally:
        connection.close()
@app.get("/courses")
def courses(db=Depends(database)):
    return [{"id": row[0], "title": row[1]} for row in db.execute("SELECT id, title FROM courses ORDER BY id")]

Further reading: Official documentation

Next lesson: Project · Test API behavior through HTTP

Essential cookies keep your account signed in. Optional analytics is not configured on this site. Your choice does not affect access to lessons.

Read the Privacy Policy. You can change this choice in the footer.