{"id":31557022,"url":"https://github.com/allmonday/fastapi-voyager","last_synced_at":"2026-05-12T14:01:30.125Z","repository":{"id":311267212,"uuid":"1042429884","full_name":"allmonday/fastapi-voyager","owner":"allmonday","description":"Visualize your API endpoints and explore them interactively, also support Django ninja \u0026 Litestar","archived":false,"fork":false,"pushed_at":"2026-02-13T08:22:29.000Z","size":1235,"stargazers_count":429,"open_issues_count":0,"forks_count":25,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-13T09:59:25.507Z","etag":null,"topics":["bff","d3","django-ninja","fastapi","graphviz","litestar","pydantic-resolve","visualization"],"latest_commit_sha":null,"homepage":"https://www.fastapi-voyager.top/voyager/?tag=demo\u0026mode=voyager","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allmonday.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-22T02:25:18.000Z","updated_at":"2026-02-13T08:22:06.000Z","dependencies_parsed_at":"2025-08-23T17:30:05.205Z","dependency_job_id":"7f6ff2c3-84d7-4336-b970-af572e90c0ea","html_url":"https://github.com/allmonday/fastapi-voyager","commit_stats":null,"previous_names":["allmonday/fastapi-router-viz","allmonday/fastapi-voyager"],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/allmonday/fastapi-voyager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Ffastapi-voyager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Ffastapi-voyager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Ffastapi-voyager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Ffastapi-voyager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allmonday","download_url":"https://codeload.github.com/allmonday/fastapi-voyager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allmonday%2Ffastapi-voyager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29966684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T09:33:09.965Z","status":"ssl_error","status_checked_at":"2026-03-01T09:25:48.915Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bff","d3","django-ninja","fastapi","graphviz","litestar","pydantic-resolve","visualization"],"created_at":"2025-10-04T23:21:24.746Z","updated_at":"2026-05-12T14:01:30.117Z","avatar_url":"https://github.com/allmonday.png","language":"Python","funding_links":[],"categories":["Utilities"],"sub_categories":[],"readme":"[![pypi](https://img.shields.io/pypi/v/fastapi-voyager.svg)](https://pypi.python.org/pypi/fastapi-voyager)\n![Python Versions](https://img.shields.io/pypi/pyversions/fastapi-voyager)\n[![PyPI Downloads](https://static.pepy.tech/badge/fastapi-voyager/month)](https://pepy.tech/projects/fastapi-voyager)\n\n\n# FastAPI Voyager\n\nVisualize your API endpoints and explore them interactively.\n\nIts vision is to make code easier to read and understand, serving as an ideal documentation tool.\n\n**Now supports multiple frameworks:** FastAPI, Django Ninja, and Litestar.\n\n\u003e This repo is still in early stage, it supports Pydantic v2 only.\n\n\u003e **Breaking Change**: Since v0.19, `fastapi-voyager` depends on `pydantic-resolve\u003e=4.0`. If you use `pydantic-resolve` v3, please pin `fastapi-voyager\u003c=0.18`.\n\n- **Live Demo**: https://www.newsyeah.fun/voyager/\n- **Example Source**: [composition-oriented-development-pattern](https://github.com/allmonday/composition-oriented-development-pattern)\n\n\u003cimg width=\"1597\" height=\"933\" alt=\"fastapi-voyager overview\" src=\"https://github.com/user-attachments/assets/020bf5b2-6c69-44bf-ba1f-39389d388d27\" /\u003e\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n- [Supported Frameworks](#supported-frameworks)\n- [Features](#features)\n- [Command Line Usage](#command-line-usage)\n- [About pydantic-resolve](#about-pydantic-resolve)\n- [Development](#development)\n- [Dependencies](#dependencies)\n- [Credits](#credits)\n\n## Quick Start\n\nWith simple configuration, fastapi-voyager can be embedded into your web application:\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi_voyager import create_voyager\n\napp = FastAPI()\n\n# ... define your routes ...\n\napp.mount('/voyager',\n          create_voyager(\n            app,\n            module_color={'src.services': 'tomato'},\n            module_prefix='src.services',\n            swagger_url=\"/docs\",\n            ga_id=\"G-XXXXXXXXVL\",\n            initial_page_policy='first',\n            online_repo_url='https://github.com/your-org/your-repo/blob/master',\n            enable_pydantic_resolve_meta=True))\n```\n\nVisit `http://localhost:8000/voyager` to explore your API visually.\n\nFor framework-specific examples (Django Ninja, Litestar), see [Supported Frameworks](#supported-frameworks).\n\n[View full example](https://github.com/allmonday/composition-oriented-development-pattern/blob/master/src/main.py#L48)\n\n## Installation\n\n### Install via pip\n\n```bash\npip install fastapi-voyager\n```\n\n### Install via uv\n\n```bash\nuv add fastapi-voyager\n```\n\n### Run with CLI\n\n```bash\nvoyager -m path.to.your.app.module --server\n```\n\nFor sub-application scenarios (e.g., `app.mount(\"/api\", api)`), specify the app name:\n\n```bash\nvoyager -m path.to.your.app.module --server --app api\n```\n\n\u003e **Note**: [Sub-Application mounts](https://fastapi.tiangolo.com/advanced/sub-applications/) are not supported yet, but you can specify the name of the FastAPI application with `--app`. Only a single application (default: `app`) can be selected.\n\n## Supported Frameworks\n\nfastapi-voyager automatically detects your framework and provides the appropriate integration. Currently supported frameworks:\n\n### FastAPI\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi_voyager import create_voyager\n\napp = FastAPI()\n\n@app.get(\"/hello\")\ndef hello():\n    return {\"message\": \"Hello World\"}\n\n# Mount voyager\napp.mount(\"/voyager\", create_voyager(app))\n```\n\nStart with:\n```bash\nuvicorn your_app:app --reload\n# Visit http://localhost:8000/voyager\n```\n\n### Django Ninja\n\n```python\nimport os\nimport django\nfrom django.core.asgi import get_asgi_application\nfrom ninja import NinjaAPI\nfrom fastapi_voyager import create_voyager\n\n# Configure Django\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"myapp.settings\")\ndjango.setup()\n\n# Create Django Ninja API\napi = NinjaAPI()\n\n@api.get(\"/hello\")\ndef hello(request):\n    return {\"message\": \"Hello World\"}\n\n# Create voyager ASGI app\nvoyager_app = create_voyager(api)\n\n# Create ASGI application that routes between Django and voyager\nasync def application(scope, receive, send):\n    if scope[\"type\"] == \"http\" and scope[\"path\"].startswith(\"/voyager\"):\n        await voyager_app(scope, receive, send)\n    else:\n        django_app = get_asgi_application()\n        await django_app(scope, receive, send)\n```\n\nStart with:\n```bash\nuvicorn your_app:application --reload\n# Visit http://localhost:8000/voyager\n```\n\n### Litestar\n\nLitestar doesn't support mounting to an existing app like FastAPI. The recommended pattern is to export `ROUTE_HANDLERS` from your main app:\n\n```python\n# In your main app file (e.g., app.py)\nfrom litestar import Litestar, Controller\n\nclass MyController(Controller):\n    # ... your routes ...\n\nROUTE_HANDLERS = [MyController]  # Export for extension\napp = Litestar(route_handlers=ROUTE_HANDLERS)\n```\n\nThen create voyager by reusing `ROUTE_HANDLERS`:\n\n```python\n# In your voyager embedding file\nfrom typing import Any, Awaitable, Callable\nfrom litestar import Litestar, asgi\nfrom fastapi_voyager import create_voyager\nfrom your_app import ROUTE_HANDLERS, app as your_app\n\nvoyager_app = create_voyager(your_app)\n\n@asgi(\"/voyager\", is_mount=True, copy_scope=True)\nasync def voyager_mount(\n    scope: dict[str, Any],\n    receive: Callable[[], Awaitable[dict[str, Any]]],\n    send: Callable[[dict[str, Any]], Awaitable[None]]\n) -\u003e None:\n    await voyager_app(scope, receive, send)\n\napp = Litestar(route_handlers=ROUTE_HANDLERS + [voyager_mount])\n```\n\nStart with:\n```bash\nuvicorn your_app:app --reload\n# Visit http://localhost:8000/voyager\n```\n\n## Features\n\nfastapi-voyager is designed for scenarios using web frameworks with Pydantic models (FastAPI, Django Ninja, Litestar). It helps visualize dependencies and serves as an architecture tool to identify implementation issues such as wrong relationships, overfetching, and more.\n\n**Best Practice**: When building view models following the ER model pattern, fastapi-voyager can fully realize its potential - quickly identifying which APIs use specific entities and vice versa.\n\n### Highlight Nodes and Links\n\nClick a node to highlight its upstream and downstream nodes. Figure out the related models of one page, or how many pages are related with one model.\n\n\u003cimg width=\"1100\" height=\"700\" alt=\"highlight nodes and dependencies\" src=\"https://github.com/user-attachments/assets/3e0369ea-5fa4-469a-82c1-ed57d407e53d\" /\u003e\n\n### View Source Code\n\nDouble-click a node or route to show source code or open the file in VSCode.\n\n\u003cimg width=\"1297\" height=\"940\" alt=\"view source code\" src=\"https://github.com/user-attachments/assets/c8bb2e7d-b727-42a6-8c9e-64dce297d2d8\" /\u003e\n\n### Quick Search\n\nSearch schemas by name and display their upstream and downstream dependencies. Use `Shift + Click` on any node to quickly search for it.\n\n\u003cimg width=\"1587\" height=\"873\" alt=\"quick search functionality\" src=\"https://github.com/user-attachments/assets/ee4716f3-233d-418f-bc0e-3b214d1498f7\" /\u003e\n\n### Display ER Diagram\n\nER diagram is a feature from pydantic-resolve which provides a solid expression for business descriptions. You can visualize application-level entity relationship diagrams.\n\n```python\nfrom pydantic_resolve import ErDiagram, Entity, Relationship\n\ndiagram = ErDiagram(\n    entities=[\n        Entity(\n            kls=Team,\n            relationships=[\n                Relationship(fk='id', name='sprints', target=list[Sprint], loader=sprint_loader.team_to_sprint_loader),\n                Relationship(fk='id', name='users', target=list[User], loader=user_loader.team_to_user_loader)\n            ]\n        ),\n        Entity(\n            kls=Sprint,\n            relationships=[\n                Relationship(fk='id', name='stories', target=list[Story], loader=story_loader.sprint_to_story_loader)\n            ]\n        ),\n        Entity(\n            kls=Story,\n            relationships=[\n                Relationship(fk='id', name='tasks', target=list[Task], loader=task_loader.story_to_task_loader),\n                Relationship(fk='owner_id', name='owner', target=User, loader=user_loader.user_batch_loader)\n            ]\n        ),\n        Entity(\n            kls=Task,\n            relationships=[\n                Relationship(fk='owner_id', name='owner', target=User, loader=user_loader.user_batch_loader)\n            ]\n        )\n    ]\n)\n\n# Display in voyager\napp.mount('/voyager', create_voyager(app, er_diagram=diagram))\n```\n\n\u003cimg width=\"1276\" height=\"613\" alt=\"ER diagram visualization\" src=\"https://github.com/user-attachments/assets/ea0091bb-ee11-4f71-8be3-7129d956c910\" /\u003e\n\n### Show Pydantic Resolve Meta Info\n\nSet `enable_pydantic_resolve_meta=True` in `create_voyager`, then toggle the \"pydantic resolve meta\" button to visualize resolve/post/expose/collect operations.\n\n\u003cimg width=\"1604\" height=\"535\" alt=\"pydantic resolve meta information\" src=\"https://github.com/user-attachments/assets/d1639555-af41-4a08-9970-4b8ef314596a\" /\u003e\n\n## Command Line Usage\n\n### Start Server\n\n```bash\n# FastAPI\nvoyager -m tests.demo --server --web fastapi\n\n# Django Ninja\nvoyager -m tests.demo --server --web django-ninja\n\n# Litestar\nvoyager -m tests.demo --server --web litestar\n\n# Custom port\nvoyager -m tests.demo --server --port=8002\n\n# Specify app name\nvoyager -m tests.demo --server --app my_app\n```\n\n\u003e **Note**: Server mode does not support ER diagram or pydantic-resolve metadata configuration. Use `create_voyager()` in your code with `er_diagram` and `enable_pydantic_resolve_meta` parameters to enable these features.\n\n### Generate DOT File\n\n```bash\n# Generate .dot file\nvoyager -m tests.demo\n\n# Specify app\nvoyager -m tests.demo --app my_app\n\n# Filter by schema\nvoyager -m tests.demo --schema Task\n\n# Show all fields\nvoyager -m tests.demo --show_fields all\n\n# Custom module colors\nvoyager -m tests.demo --module_color=tests.demo:red --module_color=tests.service:tomato\n\n# Output to file\nvoyager -m tests.demo -o my_visualization.dot\n\n# Version and help\nvoyager --version\nvoyager --help\n```\n\n## About pydantic-resolve\n\npydantic-resolve is a lightweight tool designed to build complex, nested data in a simple, declarative way. It provides `resolve_*` for loading associated data and `post_*` for computing derived fields, with automatic batch loading to eliminate N+1 queries.\n\nWhen relationship definitions start repeating across multiple models, use ER Diagram with `base_entity()` and `__relationships__` to centralize relationship declarations. `DefineSubset` helps safely pick fields from entity classes while preserving ER diagram references.\n\nDevelopers can use fastapi-voyager without needing to know anything about pydantic-resolve, but I still highly recommend everyone to give it a try.\n\n## Development\n\n### Setup Development Environment\n\n```bash\n# Fork and clone the repository\ngit clone https://github.com/your-username/fastapi-voyager.git\ncd fastapi-voyager\n\n# Install uv\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Create virtual environment and install dependencies\nuv venv\nsource .venv/bin/activate\nuv pip install \".[dev]\"\n\n# Run development server\nuvicorn tests.programatic:app --reload\n```\n\n### Test Different Frameworks\n\nYou can test the framework-specific examples:\n\n```bash\n# FastAPI example\nuvicorn tests.fastapi.embedding:app --reload\n\n# Django Ninja example\nuvicorn tests.django_ninja.embedding:app --reload\n\n# Litestar example\nuvicorn tests.litestar.embedding:asgi_app --reload\n```\n\nVisit `http://localhost:8000/voyager` to see changes.\n\n### Setup Git Hooks (Optional)\n\nEnable automatic code formatting before commits:\n\n```bash\n./setup-hooks.sh\n# or manually:\ngit config core.hooksPath .githooks\n```\n\nThis will run Prettier automatically before each commit. See [`.githooks/README.md`](./.githooks/README.md) for details.\n\n### Project Structure\n\n**Frontend:**\n- `src/fastapi_voyager/web/vue-main.js` - Main JavaScript entry\n\n**Backend:**\n- `voyager.py` - Main entry point\n- `render.py` - Generate DOT files\n- `server.py` - Server mode\n\n## Roadmap\n\n- [Ideas](./docs/idea.md)\n- [Changelog \u0026 Roadmap](./docs/changelog.md)\n\n## Dependencies\n\n- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)\n- [Quasar Framework](https://quasar.dev/)\n### Dev dependencies\n- [FastAPI](https://fastapi.tiangolo.com/)\n- [Django Ninja](https://django-ninja.rest-framework.com/)\n- [Litestar](https://litestar.dev/)\n\n## Credits\n\n- [graphql-voyager](https://apis.guru/graphql-voyager/) - Thanks for inspiration\n- [vscode-interactive-graphviz](https://github.com/tintinweb/vscode-interactive-graphviz) - Thanks for web visualization\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallmonday%2Ffastapi-voyager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallmonday%2Ffastapi-voyager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallmonday%2Ffastapi-voyager/lists"}