[{"data":1,"prerenderedAt":92},["ShallowReactive",2],{"qa-\u002Ffastapi\u002Fdependency-injection\u002Fadvanced-deps":3},{"page":4,"siblings":82,"blog":73},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":12,"path":20,"questions":21,"questionsCount":72,"related":73,"seo":74,"seoDescription":75,"stem":76,"subtopic":77,"topic":78,"topicSlug":79,"updated":80,"__hash__":81},"qa\u002Ffastapi\u002Fdependency-injection\u002Fadvanced-deps.md","Advanced Deps",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","FastAPI","fastapi",{},true,"\u002Ffastapi\u002Fdependency-injection\u002Fadvanced-deps",[22,27,31,35,39,43,47,51,55,59,63,67],{"id":23,"difficulty":24,"q":25,"a":26},"yield-dependency","medium","What is a yield dependency in FastAPI and what problem does it solve?","A **yield dependency** is a generator function that uses `yield` to split into\nsetup (before `yield`) and teardown (after `yield`). FastAPI runs the setup,\ninjects the yielded value, runs the handler, then runs the teardown — even if\nthe handler raises an exception.\n\n```python\nfrom sqlalchemy.orm import Session\nfrom app.db import SessionLocal\n\ndef get_db():\n    db = SessionLocal()\n    try:\n        yield db         # handler receives this\n    finally:\n        db.close()       # always runs after the handler\n\n@app.get(\"\u002Fusers\")\nasync def list_users(db: Session = Depends(get_db)):\n    return db.query(User).all()\n```\n\nThis is the standard pattern for DB sessions, file handles, and any resource\nthat must be cleaned up after the request.\n\nRule of thumb: use `yield` deps instead of separate open\u002Fclose functions —\nthe `finally` block guarantees cleanup even when the handler raises.\n",{"id":28,"difficulty":24,"q":29,"a":30},"async-yield-dep","How do you write an async yield dependency?","Use `async def` with `yield` — the same pattern but awaitable:\n\n```python\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom app.db import async_session_factory\n\nasync def get_async_db():\n    async with async_session_factory() as session:\n        yield session\n        await session.commit()   # auto-commit on success\n    # async context manager handles close\n```\n\nOr more explicitly:\n```python\nasync def get_async_db():\n    session = AsyncSession(engine)\n    try:\n        yield session\n        await session.commit()\n    except Exception:\n        await session.rollback()\n        raise\n    finally:\n        await session.close()\n```\n\nRule of thumb: for async databases always use an async yield dep — mixing sync\nSQLAlchemy sessions with `async def` handlers blocks the event loop.\n",{"id":32,"difficulty":14,"q":33,"a":34},"yield-dep-exception","What happens in a yield dependency if the handler raises an exception?","Code **after** `yield` still runs (inside the `finally` block), but code after\n`yield` and outside `finally` does **not** if an exception propagated.\n\n```python\ndef get_db():\n    db = SessionLocal()\n    try:\n        yield db\n        db.commit()    # ← skipped if handler raises\n    except Exception:\n        db.rollback()  # ← runs if handler raises, then re-raises\n        raise\n    finally:\n        db.close()     # ← always runs\n```\n\nFastAPI catches the exception from the handler, runs the dep's `except`\u002F`finally`\nblocks, then re-raises the exception so the error response is still sent to the client.\n\nRule of thumb: always put resource cleanup in `finally`, never rely on code\nafter `yield` running unconditionally — it only runs on success.\n",{"id":36,"difficulty":14,"q":37,"a":38},"multiple-yield-deps","What happens when multiple yield dependencies are active in the same request?","FastAPI runs teardowns in **reverse order** of setup — LIFO (last-in, first-out).\nIf dep A was set up before dep B, B tears down before A.\n\n```python\ndef dep_a():\n    print(\"A setup\")\n    yield \"a\"\n    print(\"A teardown\")   # runs second\n\ndef dep_b():\n    print(\"B setup\")\n    yield \"b\"\n    print(\"B teardown\")   # runs first\n\n@app.get(\"\u002F\")\nasync def handler(a = Depends(dep_a), b = Depends(dep_b)):\n    return {}\n# output: A setup, B setup, B teardown, A teardown\n```\n\nThis mirrors context manager nesting: inner closes before outer.\n\nRule of thumb: if dep B depends on A's resource (e.g., B uses the DB session\nfrom A), declare B's dependency on A explicitly so the order is guaranteed.\n",{"id":40,"difficulty":14,"q":41,"a":42},"background-task-yield-dep","Can a yield dependency's teardown access the response or run background tasks?","Teardown code (after `yield`) runs **after the response is sent** to the client\n— the same lifecycle as `BackgroundTasks`. You cannot modify the response headers\nat this point, but you can perform cleanup I\u002FO.\n\n```python\ndef audit_dep(request: Request):\n    start = time.time()\n    yield\n    elapsed = time.time() - start\n    # log_access(request.url, elapsed)   ← safe here, response already sent\n```\n\nYou **cannot** raise `HTTPException` in teardown (after yield) and expect it to\nchange the response — the response is already sent.\n\nRule of thumb: teardown code is for cleanup only (close sessions, release locks,\nwrite audit logs); never try to alter the HTTP response there.\n",{"id":44,"difficulty":24,"q":45,"a":46},"middleware-vs-dependency","When should you use middleware vs a dependency for cross-cutting concerns?","| Concern | Middleware | Dependency |\n|---------|-----------|-----------|\n| Applies to ALL routes | ✅ easy | Needs global `dependencies=` |\n| Access to response body | ✅ | ❌ |\n| Access to handler's return value | ❌ | ✅ (yield after) |\n| Testable via `dependency_overrides` | ❌ | ✅ |\n| Needs route parameters | ❌ (no routing yet) | ✅ |\n| Short-circuit before routing | ✅ | ❌ |\n\n```python\n# Middleware — good for request timing, response modification\nclass TimingMiddleware(BaseHTTPMiddleware):\n    async def dispatch(self, request, call_next):\n        start = time.time()\n        response = await call_next(request)\n        response.headers[\"X-Process-Time\"] = str(time.time() - start)\n        return response\n\n# Dependency — good for auth (needs decoded token in handler)\nasync def get_current_user(token = Depends(oauth2_scheme)): ...\n```\n\nRule of thumb: use middleware for HTTP-level concerns (timing, CORS, compression);\nuse dependencies for application-level concerns (auth, DB sessions, feature flags).\n",{"id":48,"difficulty":24,"q":49,"a":50},"parametrised-dep","How do you create a parameterised dependency (different instances with different config)?","Return a dependency function from a factory function:\n\n```python\nfrom fastapi import Depends, HTTPException\n\ndef require_role(role: str):\n    def _check(user: User = Depends(get_current_user)):\n        if user.role != role:\n            raise HTTPException(403, f\"Role '{role}' required\")\n        return user\n    return _check\n\n@app.get(\"\u002Fadmin\", dependencies=[Depends(require_role(\"admin\"))])\nasync def admin_panel(): ...\n\n@app.get(\"\u002Freports\", dependencies=[Depends(require_role(\"analyst\"))])\nasync def reports(): ...\n```\n\nOr use a class with `__call__` (see \"callable instance dep\" pattern).\n\nRule of thumb: parametrised deps via factory functions are cleaner than a dozen\n`require_admin`, `require_analyst`, etc. — the role is a parameter, not a copy.\n",{"id":52,"difficulty":24,"q":53,"a":54},"context-manager-dep","How do you turn an existing async context manager into a FastAPI dependency?","Use `contextlib.asynccontextmanager` or just write the yield dep directly. If\nthe resource is already an async context manager, delegate to it:\n\n```python\nimport httpx\nfrom fastapi import Depends\n\nasync def get_http_client():\n    async with httpx.AsyncClient() as client:\n        yield client   # handler gets the open client\n\n@app.get(\"\u002Fproxy\")\nasync def proxy(client: httpx.AsyncClient = Depends(get_http_client)):\n    resp = await client.get(\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n    return resp.json()\n```\n\nFastAPI closes the `AsyncClient` after the handler runs.\n\nRule of thumb: wrap third-party async context managers (httpx, aiofiles) in\nyield deps — you get proper lifecycle management without handler boilerplate.\n",{"id":56,"difficulty":14,"q":57,"a":58},"dep-caching-across-requests","Is dependency caching per-request or across requests?","**Per-request only**. FastAPI creates a new dependency cache for each incoming\nrequest; there is no cross-request singleton via `Depends()`.\n\nFor cross-request singletons (connection pools, ML models, HTTP clients):\n- Store them on `app.state` in the `lifespan` function.\n- Or use a module-level variable \u002F `@lru_cache`.\n\n```python\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    app.state.http_client = httpx.AsyncClient()\n    yield\n    await app.state.http_client.aclose()\n\n@app.get(\"\u002Fproxy\")\nasync def proxy(request: Request):\n    client = request.app.state.http_client   # cross-request singleton\n    return await client.get(\"https:\u002F\u002Fapi.example.com\u002F\")\n```\n\nRule of thumb: use `lifespan` + `app.state` for long-lived resources (DB pool,\nML model); use `Depends()` for per-request resources (sessions, auth context).\n",{"id":60,"difficulty":14,"q":61,"a":62},"dep-vs-middleware-order","In what order do global dependencies, middleware, and router dependencies execute?","```\nRequest →\n  Middleware (outermost first) →\n    FastAPI routing →\n      Global app dependencies →\n        Router-level dependencies →\n          Route-level dependencies →\n            Handler body\n          ← Route-level dep teardown\n        ← Router-level dep teardown\n      ← Global dep teardown\n    ← FastAPI exception handling\n  ← Middleware (innermost first on way out)\nResponse\n```\n\nMiddleware wraps everything, including dependency setup\u002Fteardown. Global deps\nset up before router deps, which set up before route deps.\n\nRule of thumb: auth middleware that checks a header before FastAPI even routes\nthe request is faster than a dep (no routing overhead) but less testable; choose\nbased on whether you need route-aware logic.\n",{"id":64,"difficulty":24,"q":65,"a":66},"dep-security-scheme","How do FastAPI security utilities (`OAuth2PasswordBearer`, `HTTPBearer`) relate to `Depends()`?","Security utilities are **callable classes** that implement `SecurityBase`. When\nyou use them with `Depends()`, FastAPI:\n1. Extracts the token (from header\u002Fcookie\u002Fquery).\n2. Adds the scheme to the OpenAPI security definitions automatically.\n3. Makes Swagger UI show the \"Authorize\" button.\n\n```python\nfrom fastapi.security import OAuth2PasswordBearer\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"\u002Ftoken\")\n\n@app.get(\"\u002Fme\")\nasync def me(token: str = Depends(oauth2_scheme)):\n    # token is the Bearer value from \"Authorization: Bearer \u003Ctoken>\"\n    ...\n```\n\nWithout security utilities, you'd read the header manually and lose the OpenAPI\nintegration.\n\nRule of thumb: always use FastAPI's security utilities (`OAuth2PasswordBearer`,\n`HTTPBearer`, `APIKeyHeader`) instead of plain `Header()` for auth — the OpenAPI\nintegration is a meaningful developer-experience benefit.\n",{"id":68,"difficulty":69,"q":70,"a":71},"dep-inject-request","easy","How do you access the raw `Request` object inside a FastAPI dependency?","Declare `Request` as a parameter of the dependency function — FastAPI injects it\nautomatically without `Depends()`:\n\n```python\nfrom fastapi import Request, Depends\n\ndef get_client_ip(request: Request) -> str:\n    return request.client.host\n\n@app.get(\"\u002Fitems\")\nasync def list_items(ip: str = Depends(get_client_ip)):\n    return {\"client_ip\": ip}\n```\n\nThe `Request` object gives access to headers, cookies, query string, client\naddress and the raw body stream.\n\nRule of thumb: inject `Request` into dependencies that need HTTP metadata\n(rate limiting by IP, request ID logging) — keep handlers clean of low-level\nHTTP details.\n",12,null,{"description":11},"FastAPI advanced dependency injection interview questions — yield dependencies, resource cleanup, middleware vs dependency, async generators and exception handling.","fastapi\u002Fdependency-injection\u002Fadvanced-deps","Advanced Dependencies","Dependency Injection","dependency-injection","2026-06-20","Kd6_1pFLpUON6E3jNf0HEsarOU83z-p0hxz5UcMwXYo",[83,87,88],{"subtopic":84,"path":85,"order":86},"Depends Basics","\u002Ffastapi\u002Fdependency-injection\u002Fdepends-basics",1,{"subtopic":77,"path":20,"order":12},{"subtopic":89,"path":90,"order":91},"Lifespan & App State","\u002Ffastapi\u002Fdependency-injection\u002Flifespan",3,1782244112944]