fastapi-voyager 0.15.6__tar.gz → 0.16.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/PKG-INFO +133 -7
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/README.md +127 -5
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/docs/changelog.md +6 -2
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/pyproject.toml +13 -2
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/__init__.py +8 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/__init__.py +16 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/base.py +44 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/common.py +260 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/django_ninja_adapter.py +299 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/fastapi_adapter.py +165 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/adapters/litestar_adapter.py +188 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/er_diagram.py +15 -14
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/__init__.py +34 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/base.py +81 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/detector.py +123 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/django_ninja.py +114 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/fastapi.py +83 -0
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/introspectors/litestar.py +166 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/pydantic_resolve_util.py +4 -2
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/render.py +2 -2
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/render_style.py +0 -1
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/server.py +181 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/type_helper.py +2 -2
- fastapi_voyager-0.16.0a1/src/fastapi_voyager/version.py +2 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/voyager.py +75 -47
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/index.html +11 -14
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/store.js +2 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/vue-main.js +4 -0
- fastapi_voyager-0.16.0a1/tests/README.md +150 -0
- fastapi_voyager-0.16.0a1/tests/django_ninja/__init__.py +5 -0
- fastapi_voyager-0.16.0a1/tests/django_ninja/demo.py +151 -0
- fastapi_voyager-0.16.0a1/tests/django_ninja/embedding.py +86 -0
- fastapi_voyager-0.16.0a1/tests/django_ninja/settings.py +48 -0
- fastapi_voyager-0.16.0a1/tests/django_ninja/urls.py +10 -0
- fastapi_voyager-0.16.0a1/tests/embedding_test_utils.py +147 -0
- fastapi_voyager-0.16.0a1/tests/fastapi/__init__.py +6 -0
- {fastapi_voyager-0.15.6/tests → fastapi_voyager-0.16.0a1/tests/fastapi}/demo.py +5 -6
- {fastapi_voyager-0.15.6/tests → fastapi_voyager-0.16.0a1/tests/fastapi}/demo_anno.py +1 -1
- fastapi_voyager-0.15.6/tests/programatic.py → fastapi_voyager-0.16.0a1/tests/fastapi/embedding.py +3 -2
- fastapi_voyager-0.16.0a1/tests/litestar/__init__.py +5 -0
- fastapi_voyager-0.16.0a1/tests/litestar/demo.py +132 -0
- fastapi_voyager-0.16.0a1/tests/litestar/embedding.py +89 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/service/schema/extra.py +1 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/service/schema/schema.py +4 -2
- fastapi_voyager-0.16.0a1/tests/test_embedding_django_ninja.py +82 -0
- fastapi_voyager-0.16.0a1/tests/test_embedding_fastapi.py +80 -0
- fastapi_voyager-0.16.0a1/tests/test_embedding_litestar.py +82 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_resolve_util_impl.py +3 -1
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_type_helper.py +3 -1
- fastapi_voyager-0.16.0a1/uv.lock +1061 -0
- fastapi_voyager-0.15.6/src/fastapi_voyager/__init__.py +0 -8
- fastapi_voyager-0.15.6/src/fastapi_voyager/server.py +0 -302
- fastapi_voyager-0.15.6/src/fastapi_voyager/version.py +0 -2
- fastapi_voyager-0.15.6/uv.lock +0 -518
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.githooks/README.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.githooks/pre-commit +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.github/workflows/publish.yml +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.gitignore +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.prettierignore +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.prettierrc +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/.python-version +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/CONTRIBUTING.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/LICENSE +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/docs/claude/0_REFACTORING_RENDER_NOTES.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/docs/idea.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/package-lock.json +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/release.md +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/setup-hooks.sh +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/cluster.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/cluster_container.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/digraph.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/er_diagram.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/link.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/route_node.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/schema_node.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/dot/tag_node.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/html/colored_text.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/html/pydantic_meta.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/html/schema_field_row.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/html/schema_header.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/templates/html/schema_table.j2 +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/type.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/component/demo.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/graph-ui.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/__init__.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/service/schema/__init__.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/service/schema/base_entity.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_import.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/tests/test_module.py +0 -0
- {fastapi_voyager-0.15.6 → fastapi_voyager-0.16.0a1}/voyager.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-voyager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0a1
|
|
4
4
|
Summary: Visualize FastAPI application's routing tree and dependencies
|
|
5
5
|
Project-URL: Homepage, https://github.com/allmonday/fastapi-voyager
|
|
6
6
|
Project-URL: Source, https://github.com/allmonday/fastapi-voyager
|
|
@@ -18,11 +18,15 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
|
-
Requires-Dist: fastapi>=0.110
|
|
22
21
|
Requires-Dist: jinja2>=3.0.0
|
|
23
22
|
Requires-Dist: pydantic-resolve>=2.4.3
|
|
24
23
|
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: django-ninja; extra == 'dev'
|
|
25
|
+
Requires-Dist: fastapi>=0.110; extra == 'dev'
|
|
26
|
+
Requires-Dist: httpx; extra == 'dev'
|
|
27
|
+
Requires-Dist: litestar; extra == 'dev'
|
|
25
28
|
Requires-Dist: pytest; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
26
30
|
Requires-Dist: ruff; extra == 'dev'
|
|
27
31
|
Requires-Dist: uvicorn; extra == 'dev'
|
|
28
32
|
Description-Content-Type: text/markdown
|
|
@@ -34,10 +38,12 @@ Description-Content-Type: text/markdown
|
|
|
34
38
|
|
|
35
39
|
# FastAPI Voyager
|
|
36
40
|
|
|
37
|
-
Visualize your
|
|
41
|
+
Visualize your API endpoints and explore them interactively.
|
|
38
42
|
|
|
39
43
|
Its vision is to make code easier to read and understand, serving as an ideal documentation tool.
|
|
40
44
|
|
|
45
|
+
**Now supports multiple frameworks:** FastAPI, Django Ninja, and Litestar.
|
|
46
|
+
|
|
41
47
|
> This repo is still in early stage, it supports Pydantic v2 only.
|
|
42
48
|
|
|
43
49
|
- **Live Demo**: https://www.newsyeah.fun/voyager/
|
|
@@ -49,6 +55,7 @@ Its vision is to make code easier to read and understand, serving as an ideal do
|
|
|
49
55
|
|
|
50
56
|
- [Quick Start](#quick-start)
|
|
51
57
|
- [Installation](#installation)
|
|
58
|
+
- [Supported Frameworks](#supported-frameworks)
|
|
52
59
|
- [Features](#features)
|
|
53
60
|
- [Command Line Usage](#command-line-usage)
|
|
54
61
|
- [About pydantic-resolve](#about-pydantic-resolve)
|
|
@@ -58,7 +65,7 @@ Its vision is to make code easier to read and understand, serving as an ideal do
|
|
|
58
65
|
|
|
59
66
|
## Quick Start
|
|
60
67
|
|
|
61
|
-
With simple configuration, fastapi-voyager can be embedded into
|
|
68
|
+
With simple configuration, fastapi-voyager can be embedded into your web application:
|
|
62
69
|
|
|
63
70
|
```python
|
|
64
71
|
from fastapi import FastAPI
|
|
@@ -66,6 +73,8 @@ from fastapi_voyager import create_voyager
|
|
|
66
73
|
|
|
67
74
|
app = FastAPI()
|
|
68
75
|
|
|
76
|
+
# ... define your routes ...
|
|
77
|
+
|
|
69
78
|
app.mount('/voyager',
|
|
70
79
|
create_voyager(
|
|
71
80
|
app,
|
|
@@ -74,12 +83,14 @@ app.mount('/voyager',
|
|
|
74
83
|
swagger_url="/docs",
|
|
75
84
|
ga_id="G-XXXXXXXXVL",
|
|
76
85
|
initial_page_policy='first',
|
|
77
|
-
online_repo_url='https://github.com/
|
|
86
|
+
online_repo_url='https://github.com/your-org/your-repo/blob/master',
|
|
78
87
|
enable_pydantic_resolve_meta=True))
|
|
79
88
|
```
|
|
80
89
|
|
|
81
90
|
Visit `http://localhost:8000/voyager` to explore your API visually.
|
|
82
91
|
|
|
92
|
+
For framework-specific examples (Django Ninja, Litestar), see [Supported Frameworks](#supported-frameworks).
|
|
93
|
+
|
|
83
94
|
[View full example](https://github.com/allmonday/composition-oriented-development-pattern/blob/master/src/main.py#L48)
|
|
84
95
|
|
|
85
96
|
## Installation
|
|
@@ -110,9 +121,106 @@ voyager -m path.to.your.app.module --server --app api
|
|
|
110
121
|
|
|
111
122
|
> **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.
|
|
112
123
|
|
|
124
|
+
## Supported Frameworks
|
|
125
|
+
|
|
126
|
+
fastapi-voyager automatically detects your framework and provides the appropriate integration. Currently supported frameworks:
|
|
127
|
+
|
|
128
|
+
### FastAPI
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from fastapi import FastAPI
|
|
132
|
+
from fastapi_voyager import create_voyager
|
|
133
|
+
|
|
134
|
+
app = FastAPI()
|
|
135
|
+
|
|
136
|
+
@app.get("/hello")
|
|
137
|
+
def hello():
|
|
138
|
+
return {"message": "Hello World"}
|
|
139
|
+
|
|
140
|
+
# Mount voyager
|
|
141
|
+
app.mount("/voyager", create_voyager(app))
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Start with:
|
|
145
|
+
```bash
|
|
146
|
+
uvicorn your_app:app --reload
|
|
147
|
+
# Visit http://localhost:8000/voyager
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Django Ninja
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
import os
|
|
154
|
+
import django
|
|
155
|
+
from django.core.asgi import get_asgi_application
|
|
156
|
+
from ninja import NinjaAPI
|
|
157
|
+
from fastapi_voyager import create_voyager
|
|
158
|
+
|
|
159
|
+
# Configure Django
|
|
160
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
|
|
161
|
+
django.setup()
|
|
162
|
+
|
|
163
|
+
# Create Django Ninja API
|
|
164
|
+
api = NinjaAPI()
|
|
165
|
+
|
|
166
|
+
@api.get("/hello")
|
|
167
|
+
def hello(request):
|
|
168
|
+
return {"message": "Hello World"}
|
|
169
|
+
|
|
170
|
+
# Create voyager ASGI app
|
|
171
|
+
voyager_app = create_voyager(api)
|
|
172
|
+
|
|
173
|
+
# Create ASGI application that routes between Django and voyager
|
|
174
|
+
async def application(scope, receive, send):
|
|
175
|
+
if scope["type"] == "http" and scope["path"].startswith("/voyager"):
|
|
176
|
+
await voyager_app(scope, receive, send)
|
|
177
|
+
else:
|
|
178
|
+
django_app = get_asgi_application()
|
|
179
|
+
await django_app(scope, receive, send)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Start with:
|
|
183
|
+
```bash
|
|
184
|
+
uvicorn your_app:application --reload
|
|
185
|
+
# Visit http://localhost:8000/voyager
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Litestar
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from litestar import Litestar, get
|
|
192
|
+
from fastapi_voyager import create_voyager
|
|
193
|
+
|
|
194
|
+
# Create Litestar app
|
|
195
|
+
app = Litestar()
|
|
196
|
+
|
|
197
|
+
@get("/hello")
|
|
198
|
+
def hello() -> dict:
|
|
199
|
+
return {"message": "Hello World"}
|
|
200
|
+
|
|
201
|
+
# Create voyager app (returns a Litestar app)
|
|
202
|
+
voyager_app = create_voyager(app)
|
|
203
|
+
|
|
204
|
+
# Create ASGI application that routes between main app and voyager
|
|
205
|
+
async def asgi_app(scope, receive, send):
|
|
206
|
+
if scope["type"] == "http" and scope["path"].startswith("/voyager"):
|
|
207
|
+
# Remove /voyager prefix for voyager app
|
|
208
|
+
new_scope = dict(scope)
|
|
209
|
+
new_scope["path"] = scope["path"][8:] or "/"
|
|
210
|
+
await voyager_app(new_scope, receive, send)
|
|
211
|
+
else:
|
|
212
|
+
await app(scope, receive, send)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Start with:
|
|
216
|
+
```bash
|
|
217
|
+
uvicorn your_app:asgi_app --reload
|
|
218
|
+
# Visit http://localhost:8000/voyager
|
|
219
|
+
```
|
|
220
|
+
|
|
113
221
|
## Features
|
|
114
222
|
|
|
115
|
-
fastapi-voyager is designed for scenarios using
|
|
223
|
+
fastapi-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.
|
|
116
224
|
|
|
117
225
|
**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.
|
|
118
226
|
|
|
@@ -258,6 +366,21 @@ uv pip install ".[dev]"
|
|
|
258
366
|
uvicorn tests.programatic:app --reload
|
|
259
367
|
```
|
|
260
368
|
|
|
369
|
+
### Test Different Frameworks
|
|
370
|
+
|
|
371
|
+
You can test the framework-specific examples:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# FastAPI example
|
|
375
|
+
uvicorn tests.fastapi.embedding:app --reload
|
|
376
|
+
|
|
377
|
+
# Django Ninja example
|
|
378
|
+
uvicorn tests.django_ninja.embedding:app --reload
|
|
379
|
+
|
|
380
|
+
# Litestar example
|
|
381
|
+
uvicorn tests.litestar.embedding:asgi_app --reload
|
|
382
|
+
```
|
|
383
|
+
|
|
261
384
|
Visit `http://localhost:8000/voyager` to see changes.
|
|
262
385
|
|
|
263
386
|
### Setup Git Hooks (Optional)
|
|
@@ -289,9 +412,12 @@ This will run Prettier automatically before each commit. See [`.githooks/README.
|
|
|
289
412
|
|
|
290
413
|
## Dependencies
|
|
291
414
|
|
|
292
|
-
- [FastAPI](https://fastapi.tiangolo.com/)
|
|
293
415
|
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
294
416
|
- [Quasar Framework](https://quasar.dev/)
|
|
417
|
+
### Dev dependencies
|
|
418
|
+
- [FastAPI](https://fastapi.tiangolo.com/)
|
|
419
|
+
- [Django Ninja](https://django-ninja.rest-framework.com/)
|
|
420
|
+
- [Litestar](https://litestar.dev/)
|
|
295
421
|
|
|
296
422
|
## Credits
|
|
297
423
|
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
# FastAPI Voyager
|
|
7
7
|
|
|
8
|
-
Visualize your
|
|
8
|
+
Visualize your API endpoints and explore them interactively.
|
|
9
9
|
|
|
10
10
|
Its vision is to make code easier to read and understand, serving as an ideal documentation tool.
|
|
11
11
|
|
|
12
|
+
**Now supports multiple frameworks:** FastAPI, Django Ninja, and Litestar.
|
|
13
|
+
|
|
12
14
|
> This repo is still in early stage, it supports Pydantic v2 only.
|
|
13
15
|
|
|
14
16
|
- **Live Demo**: https://www.newsyeah.fun/voyager/
|
|
@@ -20,6 +22,7 @@ Its vision is to make code easier to read and understand, serving as an ideal do
|
|
|
20
22
|
|
|
21
23
|
- [Quick Start](#quick-start)
|
|
22
24
|
- [Installation](#installation)
|
|
25
|
+
- [Supported Frameworks](#supported-frameworks)
|
|
23
26
|
- [Features](#features)
|
|
24
27
|
- [Command Line Usage](#command-line-usage)
|
|
25
28
|
- [About pydantic-resolve](#about-pydantic-resolve)
|
|
@@ -29,7 +32,7 @@ Its vision is to make code easier to read and understand, serving as an ideal do
|
|
|
29
32
|
|
|
30
33
|
## Quick Start
|
|
31
34
|
|
|
32
|
-
With simple configuration, fastapi-voyager can be embedded into
|
|
35
|
+
With simple configuration, fastapi-voyager can be embedded into your web application:
|
|
33
36
|
|
|
34
37
|
```python
|
|
35
38
|
from fastapi import FastAPI
|
|
@@ -37,6 +40,8 @@ from fastapi_voyager import create_voyager
|
|
|
37
40
|
|
|
38
41
|
app = FastAPI()
|
|
39
42
|
|
|
43
|
+
# ... define your routes ...
|
|
44
|
+
|
|
40
45
|
app.mount('/voyager',
|
|
41
46
|
create_voyager(
|
|
42
47
|
app,
|
|
@@ -45,12 +50,14 @@ app.mount('/voyager',
|
|
|
45
50
|
swagger_url="/docs",
|
|
46
51
|
ga_id="G-XXXXXXXXVL",
|
|
47
52
|
initial_page_policy='first',
|
|
48
|
-
online_repo_url='https://github.com/
|
|
53
|
+
online_repo_url='https://github.com/your-org/your-repo/blob/master',
|
|
49
54
|
enable_pydantic_resolve_meta=True))
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
Visit `http://localhost:8000/voyager` to explore your API visually.
|
|
53
58
|
|
|
59
|
+
For framework-specific examples (Django Ninja, Litestar), see [Supported Frameworks](#supported-frameworks).
|
|
60
|
+
|
|
54
61
|
[View full example](https://github.com/allmonday/composition-oriented-development-pattern/blob/master/src/main.py#L48)
|
|
55
62
|
|
|
56
63
|
## Installation
|
|
@@ -81,9 +88,106 @@ voyager -m path.to.your.app.module --server --app api
|
|
|
81
88
|
|
|
82
89
|
> **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.
|
|
83
90
|
|
|
91
|
+
## Supported Frameworks
|
|
92
|
+
|
|
93
|
+
fastapi-voyager automatically detects your framework and provides the appropriate integration. Currently supported frameworks:
|
|
94
|
+
|
|
95
|
+
### FastAPI
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from fastapi import FastAPI
|
|
99
|
+
from fastapi_voyager import create_voyager
|
|
100
|
+
|
|
101
|
+
app = FastAPI()
|
|
102
|
+
|
|
103
|
+
@app.get("/hello")
|
|
104
|
+
def hello():
|
|
105
|
+
return {"message": "Hello World"}
|
|
106
|
+
|
|
107
|
+
# Mount voyager
|
|
108
|
+
app.mount("/voyager", create_voyager(app))
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Start with:
|
|
112
|
+
```bash
|
|
113
|
+
uvicorn your_app:app --reload
|
|
114
|
+
# Visit http://localhost:8000/voyager
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Django Ninja
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import os
|
|
121
|
+
import django
|
|
122
|
+
from django.core.asgi import get_asgi_application
|
|
123
|
+
from ninja import NinjaAPI
|
|
124
|
+
from fastapi_voyager import create_voyager
|
|
125
|
+
|
|
126
|
+
# Configure Django
|
|
127
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
|
|
128
|
+
django.setup()
|
|
129
|
+
|
|
130
|
+
# Create Django Ninja API
|
|
131
|
+
api = NinjaAPI()
|
|
132
|
+
|
|
133
|
+
@api.get("/hello")
|
|
134
|
+
def hello(request):
|
|
135
|
+
return {"message": "Hello World"}
|
|
136
|
+
|
|
137
|
+
# Create voyager ASGI app
|
|
138
|
+
voyager_app = create_voyager(api)
|
|
139
|
+
|
|
140
|
+
# Create ASGI application that routes between Django and voyager
|
|
141
|
+
async def application(scope, receive, send):
|
|
142
|
+
if scope["type"] == "http" and scope["path"].startswith("/voyager"):
|
|
143
|
+
await voyager_app(scope, receive, send)
|
|
144
|
+
else:
|
|
145
|
+
django_app = get_asgi_application()
|
|
146
|
+
await django_app(scope, receive, send)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Start with:
|
|
150
|
+
```bash
|
|
151
|
+
uvicorn your_app:application --reload
|
|
152
|
+
# Visit http://localhost:8000/voyager
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Litestar
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from litestar import Litestar, get
|
|
159
|
+
from fastapi_voyager import create_voyager
|
|
160
|
+
|
|
161
|
+
# Create Litestar app
|
|
162
|
+
app = Litestar()
|
|
163
|
+
|
|
164
|
+
@get("/hello")
|
|
165
|
+
def hello() -> dict:
|
|
166
|
+
return {"message": "Hello World"}
|
|
167
|
+
|
|
168
|
+
# Create voyager app (returns a Litestar app)
|
|
169
|
+
voyager_app = create_voyager(app)
|
|
170
|
+
|
|
171
|
+
# Create ASGI application that routes between main app and voyager
|
|
172
|
+
async def asgi_app(scope, receive, send):
|
|
173
|
+
if scope["type"] == "http" and scope["path"].startswith("/voyager"):
|
|
174
|
+
# Remove /voyager prefix for voyager app
|
|
175
|
+
new_scope = dict(scope)
|
|
176
|
+
new_scope["path"] = scope["path"][8:] or "/"
|
|
177
|
+
await voyager_app(new_scope, receive, send)
|
|
178
|
+
else:
|
|
179
|
+
await app(scope, receive, send)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Start with:
|
|
183
|
+
```bash
|
|
184
|
+
uvicorn your_app:asgi_app --reload
|
|
185
|
+
# Visit http://localhost:8000/voyager
|
|
186
|
+
```
|
|
187
|
+
|
|
84
188
|
## Features
|
|
85
189
|
|
|
86
|
-
fastapi-voyager is designed for scenarios using
|
|
190
|
+
fastapi-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.
|
|
87
191
|
|
|
88
192
|
**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.
|
|
89
193
|
|
|
@@ -229,6 +333,21 @@ uv pip install ".[dev]"
|
|
|
229
333
|
uvicorn tests.programatic:app --reload
|
|
230
334
|
```
|
|
231
335
|
|
|
336
|
+
### Test Different Frameworks
|
|
337
|
+
|
|
338
|
+
You can test the framework-specific examples:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# FastAPI example
|
|
342
|
+
uvicorn tests.fastapi.embedding:app --reload
|
|
343
|
+
|
|
344
|
+
# Django Ninja example
|
|
345
|
+
uvicorn tests.django_ninja.embedding:app --reload
|
|
346
|
+
|
|
347
|
+
# Litestar example
|
|
348
|
+
uvicorn tests.litestar.embedding:asgi_app --reload
|
|
349
|
+
```
|
|
350
|
+
|
|
232
351
|
Visit `http://localhost:8000/voyager` to see changes.
|
|
233
352
|
|
|
234
353
|
### Setup Git Hooks (Optional)
|
|
@@ -260,9 +379,12 @@ This will run Prettier automatically before each commit. See [`.githooks/README.
|
|
|
260
379
|
|
|
261
380
|
## Dependencies
|
|
262
381
|
|
|
263
|
-
- [FastAPI](https://fastapi.tiangolo.com/)
|
|
264
382
|
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
265
383
|
- [Quasar Framework](https://quasar.dev/)
|
|
384
|
+
### Dev dependencies
|
|
385
|
+
- [FastAPI](https://fastapi.tiangolo.com/)
|
|
386
|
+
- [Django Ninja](https://django-ninja.rest-framework.com/)
|
|
387
|
+
- [Litestar](https://litestar.dev/)
|
|
266
388
|
|
|
267
389
|
## Credits
|
|
268
390
|
|
|
@@ -176,8 +176,12 @@
|
|
|
176
176
|
- [x] internal refactor: graph-ui.js
|
|
177
177
|
- [x] enhance the selected and unselected node & edges
|
|
178
178
|
|
|
179
|
-
## 0.16
|
|
180
|
-
- 0.16.
|
|
179
|
+
## 0.16
|
|
180
|
+
- 0.16.0alpha-1
|
|
181
|
+
- [x] support django ninja and litestar
|
|
182
|
+
|
|
183
|
+
## 0.17, enhance er diagram
|
|
184
|
+
- 0.17.0
|
|
181
185
|
- [ ] show loader name
|
|
182
186
|
- [ ] show relationship list when double click entity in er diagram
|
|
183
187
|
- [ ] highlight entity in use case
|
|
@@ -8,7 +8,6 @@ readme = "README.md"
|
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
keywords = ["fastapi", "visualization", "routing", "openapi"]
|
|
10
10
|
dependencies = [
|
|
11
|
-
"fastapi>=0.110",
|
|
12
11
|
"pydantic-resolve>=2.4.3",
|
|
13
12
|
"jinja2>=3.0.0"
|
|
14
13
|
]
|
|
@@ -32,7 +31,7 @@ Homepage = "https://github.com/allmonday/fastapi-voyager"
|
|
|
32
31
|
Source = "https://github.com/allmonday/fastapi-voyager"
|
|
33
32
|
|
|
34
33
|
[project.optional-dependencies]
|
|
35
|
-
dev = ["uvicorn", "ruff", "pytest"]
|
|
34
|
+
dev = ["uvicorn", "ruff", "pytest", "pytest-asyncio", "httpx", "fastapi>=0.110", "django-ninja", "litestar"]
|
|
36
35
|
|
|
37
36
|
[build-system]
|
|
38
37
|
requires = ["hatchling"]
|
|
@@ -41,6 +40,9 @@ build-backend = "hatchling.build"
|
|
|
41
40
|
[tool.hatch.version]
|
|
42
41
|
path = "src/fastapi_voyager/version.py"
|
|
43
42
|
|
|
43
|
+
[tool.hatch.build.targets.wheel]
|
|
44
|
+
packages = ["src/fastapi_voyager"]
|
|
45
|
+
|
|
44
46
|
[tool.uv]
|
|
45
47
|
# You can pin resolution or indexes here later.
|
|
46
48
|
|
|
@@ -49,3 +51,12 @@ line-length = 100
|
|
|
49
51
|
|
|
50
52
|
[tool.ruff.lint]
|
|
51
53
|
select = ["E", "F", "I", "UP", "B"]
|
|
54
|
+
|
|
55
|
+
[dependency-groups]
|
|
56
|
+
dev = [
|
|
57
|
+
"django-ninja>=1.5.3",
|
|
58
|
+
"fastapi>=0.116.1",
|
|
59
|
+
"httpx>=0.28.1",
|
|
60
|
+
"litestar>=2.19.0",
|
|
61
|
+
"pytest-asyncio>=1.3.0",
|
|
62
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Framework adapters for fastapi-voyager.
|
|
3
|
+
|
|
4
|
+
This module provides adapters that allow voyager to work with different web frameworks.
|
|
5
|
+
"""
|
|
6
|
+
from fastapi_voyager.adapters.base import VoyagerAdapter
|
|
7
|
+
from fastapi_voyager.adapters.django_ninja_adapter import DjangoNinjaAdapter
|
|
8
|
+
from fastapi_voyager.adapters.fastapi_adapter import FastAPIAdapter
|
|
9
|
+
from fastapi_voyager.adapters.litestar_adapter import LitestarAdapter
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"VoyagerAdapter",
|
|
13
|
+
"FastAPIAdapter",
|
|
14
|
+
"DjangoNinjaAdapter",
|
|
15
|
+
"LitestarAdapter",
|
|
16
|
+
]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base adapter interface for framework-agnostic voyager server.
|
|
3
|
+
|
|
4
|
+
This module defines the abstract interface that all framework adapters must implement.
|
|
5
|
+
"""
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class VoyagerAdapter(ABC):
|
|
11
|
+
"""
|
|
12
|
+
Abstract base class for framework-specific voyager adapters.
|
|
13
|
+
|
|
14
|
+
Each adapter is responsible for:
|
|
15
|
+
1. Creating routes/endpoints for the voyager UI
|
|
16
|
+
2. Handling HTTP requests and responses in a framework-specific way
|
|
17
|
+
3. Returning an object that can be mounted/integrated with the target app
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def create_app(self) -> Any:
|
|
22
|
+
"""
|
|
23
|
+
Create and return a framework-specific application object.
|
|
24
|
+
|
|
25
|
+
The returned object should be mountable/integrable with the target framework.
|
|
26
|
+
For example:
|
|
27
|
+
- FastAPI: returns a FastAPI app
|
|
28
|
+
- Django Ninja: returns an ASGI application
|
|
29
|
+
- Litestar: returns a Litestar app
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
A framework-specific application object
|
|
33
|
+
"""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def get_mount_path(self) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Get the recommended mount path for the voyager UI.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The path where voyager should be mounted (e.g., "/voyager")
|
|
43
|
+
"""
|
|
44
|
+
pass
|