ProvenPin Install

FastAPI dependency_overrides tested offline with httpx ASGITransport: working versions (tested 2026-10-15)

Override FastAPI dependencies (including nested ones) and drive the app in-process with httpx.ASGITransport, no network and no running server.

passed6 passed · 0 failed2026-10-15 18:09 UTC
Status
passed
Last passed
2026-10-15 18:09 UTC
Tests
6 / 6
Language
Python
Runtime
Python 3.13.16
pinned versions4
fastapi@0.143.2httpx@0.28.1pytest@9.1.1pytest-asyncio@1.4.0
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 38783276983

The code

Exactly the files that passed. Your agent can pull them with get_recipe("fastapi-dependency-overrides-httpx") (install), or see them on GitHub.

requirements.txt
fastapi==0.143.2
httpx==0.28.1
pytest==9.1.1
pytest-asyncio==1.4.0
app.py
from __future__ import annotations

import sqlite3
from contextlib import asynccontextmanager

from fastapi import Depends, FastAPI, HTTPException
from pydantic import BaseModel


class Todo(BaseModel):
    id: int
    title: str


def create_connection() -> sqlite3.Connection:
    conn = sqlite3.connect(":memory:", check_same_thread=False)
    conn.row_factory = sqlite3.Row
    conn.execute("CREATE TABLE todos (id INTEGER PRIMARY KEY, title TEXT)")
    conn.execute("INSERT INTO todos (id, title) VALUES (1, 'write a recipe')")
    conn.commit()
    return conn


@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.conn = create_connection()
    try:
        yield
    finally:
        app.state.conn.close()


app = FastAPI(lifespan=lifespan)


def get_conn() -> sqlite3.Connection:
    return app.state.conn


class TodoRepo:
    def __init__(self, conn: sqlite3.Connection):
        self.conn = conn

    def get(self, todo_id: int) -> Todo | None:
        row = self.conn.execute(
            "SELECT id, title FROM todos WHERE id = ?", (todo_id,)
        ).fetchone()
        return Todo(id=row["id"], title=row["title"]) if row else None


def get_repo(conn: sqlite3.Connection = Depends(get_conn)) -> TodoRepo:
    return TodoRepo(conn)


@app.get("/todos/{todo_id}", response_model=Todo)
def read_todo(todo_id: int, repo: TodoRepo = Depends(get_repo)) -> Todo:
    todo = repo.get(todo_id)
    if todo is None:
        raise HTTPException(status_code=404, detail="todo not found")
    return todo
tests/test_app.py
import httpx
import pytest

from app import Todo, app, create_connection, get_conn, get_repo


@pytest.fixture(autouse=True)
def clean_overrides():
    app.dependency_overrides.clear()
    yield
    app.dependency_overrides.clear()


def make_client() -> httpx.AsyncClient:
    return httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url="http://test")


class FakeRepo:
    def __init__(self, todo: Todo | None):
        self.todo = todo

    def get(self, todo_id: int) -> Todo | None:
        return self.todo if self.todo and self.todo.id == todo_id else None


async def test_asgi_transport_skips_lifespan():
    async with make_client() as client:
        with pytest.raises(AttributeError):
            await client.get("/todos/1")


async def test_override_route_dependency():
    app.dependency_overrides[get_repo] = lambda: FakeRepo(Todo(id=1, title="mocked"))
    async with make_client() as client:
        r = await client.get("/todos/1")
    assert r.status_code == 200
    assert r.json() == {"id": 1, "title": "mocked"}


async def test_override_parent_propagates_to_child():
    app.dependency_overrides[get_conn] = create_connection
    async with make_client() as client:
        r = await client.get("/todos/1")
    assert r.json()["title"] == "write a recipe"


async def test_missing_todo_returns_404():
    app.dependency_overrides[get_repo] = lambda: FakeRepo(None)
    async with make_client() as client:
        r = await client.get("/todos/1")
    assert r.status_code == 404
    assert r.json()["detail"] == "todo not found"


async def test_generator_override_runs_teardown():
    events: list[str] = []

    def fake_repo():
        events.append("open")
        yield FakeRepo(Todo(id=1, title="yielded"))
        events.append("close")

    app.dependency_overrides[get_repo] = fake_repo
    async with make_client() as client:
        r = await client.get("/todos/1")
    assert r.json()["title"] == "yielded"
    assert events == ["open", "close"]


async def test_overrides_start_clean():
    assert app.dependency_overrides == {}
pytest.ini
[pytest]
pythonpath = .
asyncio_mode = auto

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.