Skip to main content

fastapi-depgraph

fastapi-depgraph logo

PyPI version Supported Python versions CI status License

Introspection of a FastAPI app's Depends() tree: which dependencies each route resolves, which are shared across routes, which aren't cached, and export to ASCII or Mermaid.

Reads route.dependant — the structure FastAPI already builds internally when each route is registered — instead of reparsing signatures by hand.

Install

pip install fastapi-depgraph

Usage — CLI

depgraph show myapp.main:app
depgraph show myapp.main:app --shared --uncached
depgraph export myapp.main:app --format mermaid > graph.mmd

Usage — API

from fastapi_depgraph import inspect_app

report = inspect_app(app)

report.shared_dependencies()    # {callable: ["/route1", "/route2"]}
report.uncached_dependencies()  # ["module.get_request_id", ...]

for route in report.routes:
    print(route.path, route.root.name)

Example

$ depgraph show examples/basic_app.py:app --shared --uncached
GET /users/me
  basic_app.read_current_user (sync)
  └── basic_app.get_current_user (sync)
      ├── basic_app.get_db (async)
      │   └── basic_app.get_settings (sync)
      └── basic_app.get_request_id (sync) [no-cache]
...

Dependencies shared across routes:
  get_current_user: /orders, /orders/{order_id}, /users/me
  get_db: /orders, /orders/{order_id}, /users, /users/me
  get_settings: /orders, /orders/{order_id}, /users, /users/me
  get_request_id: /orders, /orders/{order_id}, /users/me
  get_orders_service: /orders, /orders/{order_id}

Dependencies with use_cache=False:
  basic_app.get_request_id

At a glance: get_db and get_settings get resolved on four different routes — if one gets expensive, that's where to look first. And get_request_id is intentionally marked as uncached (it comes from a per-request header), but in a real case that's the flag that warns you about a use_cache=False someone forgot or added by mistake.

What patterns it handles

Tested, with regression coverage, against the real patterns that broke early versions of this package:

  • APIRouter + include_router(), at any level of nesting and with any prefix (/api/v1/items correctly accumulates in the path).
  • Dependencies declared on include_router(router, dependencies=[...]) or FastAPI(dependencies=[...]) — an auth guard for an entire router shows up in the tree of every route it covers.
  • Apps mounted with app.mount(sub_app) (path caveat below).
  • Dependencies parametrized by a factory (def make_limiter(n): def check(): ...; return check) or functools.partial(fn, role="admin"): two instances with different captured/bound values show up as distinct nodes (check{n=5} vs. check{n=10}, require_role(role='admin') vs. require_role(role='editor')) instead of collapsing into one name.
  • Depends(SomeClass()) (instance) and Depends(SomeClass) (the class itself) — both "class as a dependency" patterns documented by FastAPI.

Known limitations

  • Apps mounted with app.mount(sub_app) are walked (Starlette exposes the sub-app's routes through Mount.routes), but the reported path is relative to the sub-app, without the mount's prefix.
  • Only HTTP routes are inspected; WebSocket routes aren't part of the tree (intentionally — Depends() on WebSocket doesn't have per-request caching or the same resolution model, see DESIGN.md §2).
  • If two different instances of the same class are used as dependencies on different routes, shared_dependencies() correctly treats them as not shared (it compares by identity), but they're shown with the same label in the tree/Mermaid unless the class itself is a closure — there's no generic way to give an arbitrary instance a readable name.
  • app.dependency_overrides (the standard mechanism for injecting test doubles) isn't reflected: the tree shows the dependency as declared in the code, not the one that would actually run under an active override — it's a static graph, see DESIGN.md §2.
  • The name of a parametrized dependency includes the repr() of its captured/bound values — if those values are secrets (tokens, API keys passed as defaults), they'll show up in depgraph show/export output. Don't paste that output into public channels without checking what parametrized dependencies your app has.
  • Merging the path/dependencies for included routers (include_router) uses, when available, an internal method with no public contract that Starlette exposes to resolve routes at request time; if that shape changes in a future version, the package silently degrades to the previous behavior (no accumulated prefix or inclusion dependencies) instead of failing — the CI matrix runs against several FastAPI versions to catch it early if that happens.

Why

FastAPI's DI system is implicit: nested Depends() resolve with no native way to see the tree. Two questions this package answers that today have no direct way to answer:

  • Which expensive dependencies are being recomputed instead of cached (use_cache=False)?
  • Which routes share an expensive dependency, so you know where to optimize once instead of in five different places?

See DESIGN.md for the rest of the scope and design decisions.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_depgraph-0.1.1.tar.gz (812.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_depgraph-0.1.1-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_depgraph-0.1.1.tar.gz.

File metadata

  • Download URL: fastapi_depgraph-0.1.1.tar.gz
  • Upload date:
  • Size: 812.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fastapi_depgraph-0.1.1.tar.gz
Algorithm Hash digest
SHA256 33d28b03233ea81b2522c8278e84277195cd614416f9b51b53013c33f9dd5dde
MD5 76fb935a419fe827b15d1c4ef253d5f0
BLAKE2b-256 4542e6448dbaffe50d6967e8f24f670d85b0e8efbb9d0b48c048d41a84f04c64

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_depgraph-0.1.1.tar.gz:

Publisher: release.yml on jmiguelmangas/fastapi-depgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastapi_depgraph-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_depgraph-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8e33ac6148b937e88751cd3c47bf343971192a767510d55b916d080693808e75
MD5 25d8c4c13e044ec20cbc9fdb29b63314
BLAKE2b-256 3a2562fd3b15fb2e45bbcebb6d7205ab2fc1116fe88b4418e354a4578d4e3e53

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_depgraph-0.1.1-py3-none-any.whl:

Publisher: release.yml on jmiguelmangas/fastapi-depgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page