fastapi-voyager 0.9.1__tar.gz → 0.9.3__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.9.1 → fastapi_voyager-0.9.3}/PKG-INFO +61 -43
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/README.md +60 -42
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/version.py +1 -1
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/route-code-display.js +4 -14
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/schema-code-display.js +19 -26
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/schema-field-filter.js +6 -3
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graph-ui.js +11 -7
- fastapi_voyager-0.9.3/src/fastapi_voyager/web/index.html +405 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/vue-main.js +22 -67
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/demo.py +16 -1
- fastapi_voyager-0.9.1/src/fastapi_voyager/web/index.html +0 -437
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/.gitignore +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/.python-version +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/LICENSE +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/pyproject.toml +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/__init__.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/render.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/server.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/type.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/type_helper.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/voyager.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/__init__.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/demo_anno.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/programatic.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/service/schema.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_import.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_module.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/tests/test_type_helper.py +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/uv.lock +0 -0
- {fastapi_voyager-0.9.1 → fastapi_voyager-0.9.3}/voyager.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-voyager
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
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
|
|
@@ -27,18 +27,15 @@ Description-Content-Type: text/markdown
|
|
|
27
27
|
|
|
28
28
|
[](https://pypi.python.org/pypi/fastapi-voyager)
|
|
29
29
|

|
|
30
|
-
|
|
31
|
-
<p align="center"><img src="./voyager.jpg" alt="" /></p>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
[](https://www.youtube.com/watch?v=PGlbQq1M-n8 "FastAPI Voyager")
|
|
30
|
+
[](https://pepy.tech/projects/fastapi-voyager)
|
|
35
31
|
|
|
36
32
|
|
|
37
|
-
> This repo is still in early stage,
|
|
33
|
+
> This repo is still in early stage, it supports pydantic v2 only
|
|
38
34
|
|
|
39
|
-
Inspect your API interactively
|
|
35
|
+
Inspect your API interactively!
|
|
40
36
|
|
|
41
|
-
<
|
|
37
|
+
<p align="center"><img src="./voyager.jpg" alt="" /></p>
|
|
38
|
+
<p align="center"><a target="_blank" rel="" href="https://www.youtube.com/watch?v=PGlbQq1M-n8"><img src="http://img.youtube.com/vi/PGlbQq1M-n8/0.jpg" alt="" style="max-width: 100%;"></a></p>
|
|
42
39
|
|
|
43
40
|
## Installation
|
|
44
41
|
|
|
@@ -52,11 +49,6 @@ uv add fastapi-voyager
|
|
|
52
49
|
voyager -m path.to.your.app.module --server
|
|
53
50
|
```
|
|
54
51
|
|
|
55
|
-
## Dependencies
|
|
56
|
-
|
|
57
|
-
- FastAPI
|
|
58
|
-
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
59
|
-
|
|
60
52
|
|
|
61
53
|
## Feature
|
|
62
54
|
|
|
@@ -79,9 +71,9 @@ voyager -m tests.demo
|
|
|
79
71
|
```
|
|
80
72
|
|
|
81
73
|
### generate the graph
|
|
82
|
-
after initialization, pick tag, rotue
|
|
74
|
+
after initialization, pick tag, rotue to render graph
|
|
83
75
|
|
|
84
|
-
<img width="
|
|
76
|
+
<img width="1628" height="765" alt="image" src="https://github.com/user-attachments/assets/b4712f82-e754-453b-aa69-24c932b8f48f" />
|
|
85
77
|
|
|
86
78
|
### highlight
|
|
87
79
|
click a node to highlight it's upperstream and downstream nodes. figure out the related models of one page, or homw many pages are related with one model.
|
|
@@ -89,9 +81,9 @@ click a node to highlight it's upperstream and downstream nodes. figure out the
|
|
|
89
81
|
<img width="1485" height="616" alt="image" style="border: 1px solid #aaa" src="https://github.com/user-attachments/assets/70c4095f-86c7-45da-a6f0-fd41ac645813" />
|
|
90
82
|
|
|
91
83
|
### filter related nodes
|
|
92
|
-
`shift` click a node to check related node, pick a field to narrow the result.
|
|
84
|
+
`shift` click a node to check related node, pick a field to narrow the result, picked node is marked as red.
|
|
93
85
|
|
|
94
|
-
<img width="
|
|
86
|
+
<img width="1423" height="552" alt="image" src="https://github.com/user-attachments/assets/468a058d-afa1-4601-a7c5-c6aad6a8a557" />
|
|
95
87
|
|
|
96
88
|
### view source code
|
|
97
89
|
`alt` click a node to show source code or open file in vscode.
|
|
@@ -168,7 +160,24 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
168
160
|
|
|
169
161
|
## Plan before v1.0
|
|
170
162
|
|
|
171
|
-
|
|
163
|
+
|
|
164
|
+
### backlog
|
|
165
|
+
- [ ] user can generate nodes/edges manually and connect to generated ones
|
|
166
|
+
- [ ] add owner
|
|
167
|
+
- [ ] add extra info for schema
|
|
168
|
+
- [ ] display standard ER diagram `hard`
|
|
169
|
+
- [ ] display potential invalid links
|
|
170
|
+
- [ ] support dataclass (pending)
|
|
171
|
+
|
|
172
|
+
### in analysis
|
|
173
|
+
- [ ] click field to highlight links
|
|
174
|
+
- [ ] animation effect for edges
|
|
175
|
+
- [ ] customrized right click panel
|
|
176
|
+
- [ ] show own dependencies
|
|
177
|
+
- [ ] clean up fe code
|
|
178
|
+
|
|
179
|
+
### plan:
|
|
180
|
+
#### <0.9:
|
|
172
181
|
- [x] group schemas by module hierarchy
|
|
173
182
|
- [x] module-based coloring via Analytics(module_color={...})
|
|
174
183
|
- [x] view in web browser
|
|
@@ -196,26 +205,6 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
196
205
|
- [x] fix duplicated link from class and parent class, it also break clicking highlight
|
|
197
206
|
- [x] refactor: abstract render module
|
|
198
207
|
|
|
199
|
-
### backlog
|
|
200
|
-
- [ ] user can generate nodes/edges manually and connect to generated ones
|
|
201
|
-
- [ ] add owner
|
|
202
|
-
- [ ] add extra info for schema
|
|
203
|
-
- [ ] fixed left/right bar show field information
|
|
204
|
-
- [ ] display standard ER diagram `hard`
|
|
205
|
-
- [ ] display potential invalid links
|
|
206
|
-
|
|
207
|
-
bugs & non feature:
|
|
208
|
-
- [ ] add tests
|
|
209
|
-
- [ ] support dataclass (pending)
|
|
210
|
-
|
|
211
|
-
### in analysis
|
|
212
|
-
- [ ] click field to highlight links
|
|
213
|
-
- [ ] animation effect for edges
|
|
214
|
-
- [ ] customrized right click panel
|
|
215
|
-
- [ ] show own dependencies
|
|
216
|
-
|
|
217
|
-
### plan:
|
|
218
|
-
|
|
219
208
|
#### 0.9
|
|
220
209
|
- [x] refactor: server.py
|
|
221
210
|
- [x] rename create_app_with_fastapi -> create_voyager
|
|
@@ -223,19 +212,36 @@ bugs & non feature:
|
|
|
223
212
|
- [x] improve initialization time cost
|
|
224
213
|
- [x] query route / schema info through realtime api
|
|
225
214
|
- [x] adjust fe
|
|
215
|
+
- [x] adjust layout (0.9.3)
|
|
216
|
+
- [x] show field detail in right panel
|
|
217
|
+
- [x] show route info in bottom
|
|
226
218
|
|
|
227
219
|
#### 0.10
|
|
228
|
-
- [ ]
|
|
229
|
-
- [ ] open route in swagger
|
|
220
|
+
- [ ] support opening route in swagger
|
|
230
221
|
- config docs path
|
|
231
222
|
- [ ] add http method for route
|
|
232
223
|
- [ ] enable/disable module cluster (may save space)
|
|
224
|
+
- [ ] logging information
|
|
225
|
+
- [ ] add tests
|
|
226
|
+
- [ ] hide brief mode if not configured
|
|
227
|
+
- [ ] optimize static resource
|
|
228
|
+
- [ ] show route count in tag expansion item
|
|
229
|
+
- [ ] route list show have a max height to trigger scrollable
|
|
230
|
+
- [ ] fix layout issue when rendering huge graph
|
|
233
231
|
|
|
234
232
|
#### 0.11
|
|
233
|
+
- [ ] improve user experience
|
|
234
|
+
- double click to show detail
|
|
235
|
+
- improve search dialog
|
|
236
|
+
|
|
237
|
+
#### 0.12
|
|
235
238
|
- [ ] integration with pydantic-resolve
|
|
236
239
|
- [ ] show hint for resolve, post fields
|
|
237
240
|
- [ ] display loader as edges
|
|
238
241
|
|
|
242
|
+
#### 0.13
|
|
243
|
+
- [ ] config release pipeline
|
|
244
|
+
- [ ]
|
|
239
245
|
|
|
240
246
|
## Using with pydantic-resolve
|
|
241
247
|
|
|
@@ -247,13 +253,25 @@ pydantic-resolve's @ensure_subset decorator is helpful to pick fields from `sour
|
|
|
247
253
|
|
|
248
254
|
## Credits
|
|
249
255
|
|
|
250
|
-
- https://apis.guru/graphql-voyager/, for inspiration.
|
|
251
|
-
- https://github.com/tintinweb/vscode-interactive-graphviz, for web visualization.
|
|
256
|
+
- https://apis.guru/graphql-voyager/, thanks for inspiration.
|
|
257
|
+
- https://github.com/tintinweb/vscode-interactive-graphviz, thanks for web visualization.
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
## Dependencies
|
|
261
|
+
|
|
262
|
+
- FastAPI
|
|
263
|
+
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
264
|
+
- Quasar
|
|
252
265
|
|
|
253
266
|
|
|
254
267
|
## Changelog
|
|
255
268
|
|
|
256
269
|
- 0.9:
|
|
270
|
+
- 0.9.3:
|
|
271
|
+
- enhancement: better UI
|
|
272
|
+
- 0.9.2:
|
|
273
|
+
- fix: missing fields in schema detail panel
|
|
274
|
+
- optimization: clean up fe codes.
|
|
257
275
|
- 0.9.1:
|
|
258
276
|
- api change: from `create_app_with_fastapi` to `create_voyager`, and expose as `from fastapi_voyager import create_voyager`
|
|
259
277
|
- optimization: lazy load vscode link and source code, speed up the initialization.
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
[](https://pypi.python.org/pypi/fastapi-voyager)
|
|
2
2
|

|
|
3
|
-
|
|
4
|
-
<p align="center"><img src="./voyager.jpg" alt="" /></p>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://www.youtube.com/watch?v=PGlbQq1M-n8 "FastAPI Voyager")
|
|
3
|
+
[](https://pepy.tech/projects/fastapi-voyager)
|
|
8
4
|
|
|
9
5
|
|
|
10
|
-
> This repo is still in early stage,
|
|
6
|
+
> This repo is still in early stage, it supports pydantic v2 only
|
|
11
7
|
|
|
12
|
-
Inspect your API interactively
|
|
8
|
+
Inspect your API interactively!
|
|
13
9
|
|
|
14
|
-
<
|
|
10
|
+
<p align="center"><img src="./voyager.jpg" alt="" /></p>
|
|
11
|
+
<p align="center"><a target="_blank" rel="" href="https://www.youtube.com/watch?v=PGlbQq1M-n8"><img src="http://img.youtube.com/vi/PGlbQq1M-n8/0.jpg" alt="" style="max-width: 100%;"></a></p>
|
|
15
12
|
|
|
16
13
|
## Installation
|
|
17
14
|
|
|
@@ -25,11 +22,6 @@ uv add fastapi-voyager
|
|
|
25
22
|
voyager -m path.to.your.app.module --server
|
|
26
23
|
```
|
|
27
24
|
|
|
28
|
-
## Dependencies
|
|
29
|
-
|
|
30
|
-
- FastAPI
|
|
31
|
-
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
32
|
-
|
|
33
25
|
|
|
34
26
|
## Feature
|
|
35
27
|
|
|
@@ -52,9 +44,9 @@ voyager -m tests.demo
|
|
|
52
44
|
```
|
|
53
45
|
|
|
54
46
|
### generate the graph
|
|
55
|
-
after initialization, pick tag, rotue
|
|
47
|
+
after initialization, pick tag, rotue to render graph
|
|
56
48
|
|
|
57
|
-
<img width="
|
|
49
|
+
<img width="1628" height="765" alt="image" src="https://github.com/user-attachments/assets/b4712f82-e754-453b-aa69-24c932b8f48f" />
|
|
58
50
|
|
|
59
51
|
### highlight
|
|
60
52
|
click a node to highlight it's upperstream and downstream nodes. figure out the related models of one page, or homw many pages are related with one model.
|
|
@@ -62,9 +54,9 @@ click a node to highlight it's upperstream and downstream nodes. figure out the
|
|
|
62
54
|
<img width="1485" height="616" alt="image" style="border: 1px solid #aaa" src="https://github.com/user-attachments/assets/70c4095f-86c7-45da-a6f0-fd41ac645813" />
|
|
63
55
|
|
|
64
56
|
### filter related nodes
|
|
65
|
-
`shift` click a node to check related node, pick a field to narrow the result.
|
|
57
|
+
`shift` click a node to check related node, pick a field to narrow the result, picked node is marked as red.
|
|
66
58
|
|
|
67
|
-
<img width="
|
|
59
|
+
<img width="1423" height="552" alt="image" src="https://github.com/user-attachments/assets/468a058d-afa1-4601-a7c5-c6aad6a8a557" />
|
|
68
60
|
|
|
69
61
|
### view source code
|
|
70
62
|
`alt` click a node to show source code or open file in vscode.
|
|
@@ -141,7 +133,24 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
141
133
|
|
|
142
134
|
## Plan before v1.0
|
|
143
135
|
|
|
144
|
-
|
|
136
|
+
|
|
137
|
+
### backlog
|
|
138
|
+
- [ ] user can generate nodes/edges manually and connect to generated ones
|
|
139
|
+
- [ ] add owner
|
|
140
|
+
- [ ] add extra info for schema
|
|
141
|
+
- [ ] display standard ER diagram `hard`
|
|
142
|
+
- [ ] display potential invalid links
|
|
143
|
+
- [ ] support dataclass (pending)
|
|
144
|
+
|
|
145
|
+
### in analysis
|
|
146
|
+
- [ ] click field to highlight links
|
|
147
|
+
- [ ] animation effect for edges
|
|
148
|
+
- [ ] customrized right click panel
|
|
149
|
+
- [ ] show own dependencies
|
|
150
|
+
- [ ] clean up fe code
|
|
151
|
+
|
|
152
|
+
### plan:
|
|
153
|
+
#### <0.9:
|
|
145
154
|
- [x] group schemas by module hierarchy
|
|
146
155
|
- [x] module-based coloring via Analytics(module_color={...})
|
|
147
156
|
- [x] view in web browser
|
|
@@ -169,26 +178,6 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
169
178
|
- [x] fix duplicated link from class and parent class, it also break clicking highlight
|
|
170
179
|
- [x] refactor: abstract render module
|
|
171
180
|
|
|
172
|
-
### backlog
|
|
173
|
-
- [ ] user can generate nodes/edges manually and connect to generated ones
|
|
174
|
-
- [ ] add owner
|
|
175
|
-
- [ ] add extra info for schema
|
|
176
|
-
- [ ] fixed left/right bar show field information
|
|
177
|
-
- [ ] display standard ER diagram `hard`
|
|
178
|
-
- [ ] display potential invalid links
|
|
179
|
-
|
|
180
|
-
bugs & non feature:
|
|
181
|
-
- [ ] add tests
|
|
182
|
-
- [ ] support dataclass (pending)
|
|
183
|
-
|
|
184
|
-
### in analysis
|
|
185
|
-
- [ ] click field to highlight links
|
|
186
|
-
- [ ] animation effect for edges
|
|
187
|
-
- [ ] customrized right click panel
|
|
188
|
-
- [ ] show own dependencies
|
|
189
|
-
|
|
190
|
-
### plan:
|
|
191
|
-
|
|
192
181
|
#### 0.9
|
|
193
182
|
- [x] refactor: server.py
|
|
194
183
|
- [x] rename create_app_with_fastapi -> create_voyager
|
|
@@ -196,19 +185,36 @@ bugs & non feature:
|
|
|
196
185
|
- [x] improve initialization time cost
|
|
197
186
|
- [x] query route / schema info through realtime api
|
|
198
187
|
- [x] adjust fe
|
|
188
|
+
- [x] adjust layout (0.9.3)
|
|
189
|
+
- [x] show field detail in right panel
|
|
190
|
+
- [x] show route info in bottom
|
|
199
191
|
|
|
200
192
|
#### 0.10
|
|
201
|
-
- [ ]
|
|
202
|
-
- [ ] open route in swagger
|
|
193
|
+
- [ ] support opening route in swagger
|
|
203
194
|
- config docs path
|
|
204
195
|
- [ ] add http method for route
|
|
205
196
|
- [ ] enable/disable module cluster (may save space)
|
|
197
|
+
- [ ] logging information
|
|
198
|
+
- [ ] add tests
|
|
199
|
+
- [ ] hide brief mode if not configured
|
|
200
|
+
- [ ] optimize static resource
|
|
201
|
+
- [ ] show route count in tag expansion item
|
|
202
|
+
- [ ] route list show have a max height to trigger scrollable
|
|
203
|
+
- [ ] fix layout issue when rendering huge graph
|
|
206
204
|
|
|
207
205
|
#### 0.11
|
|
206
|
+
- [ ] improve user experience
|
|
207
|
+
- double click to show detail
|
|
208
|
+
- improve search dialog
|
|
209
|
+
|
|
210
|
+
#### 0.12
|
|
208
211
|
- [ ] integration with pydantic-resolve
|
|
209
212
|
- [ ] show hint for resolve, post fields
|
|
210
213
|
- [ ] display loader as edges
|
|
211
214
|
|
|
215
|
+
#### 0.13
|
|
216
|
+
- [ ] config release pipeline
|
|
217
|
+
- [ ]
|
|
212
218
|
|
|
213
219
|
## Using with pydantic-resolve
|
|
214
220
|
|
|
@@ -220,13 +226,25 @@ pydantic-resolve's @ensure_subset decorator is helpful to pick fields from `sour
|
|
|
220
226
|
|
|
221
227
|
## Credits
|
|
222
228
|
|
|
223
|
-
- https://apis.guru/graphql-voyager/, for inspiration.
|
|
224
|
-
- https://github.com/tintinweb/vscode-interactive-graphviz, for web visualization.
|
|
229
|
+
- https://apis.guru/graphql-voyager/, thanks for inspiration.
|
|
230
|
+
- https://github.com/tintinweb/vscode-interactive-graphviz, thanks for web visualization.
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
## Dependencies
|
|
234
|
+
|
|
235
|
+
- FastAPI
|
|
236
|
+
- [pydantic-resolve](https://github.com/allmonday/pydantic-resolve)
|
|
237
|
+
- Quasar
|
|
225
238
|
|
|
226
239
|
|
|
227
240
|
## Changelog
|
|
228
241
|
|
|
229
242
|
- 0.9:
|
|
243
|
+
- 0.9.3:
|
|
244
|
+
- enhancement: better UI
|
|
245
|
+
- 0.9.2:
|
|
246
|
+
- fix: missing fields in schema detail panel
|
|
247
|
+
- optimization: clean up fe codes.
|
|
230
248
|
- 0.9.1:
|
|
231
249
|
- api change: from `create_app_with_fastapi` to `create_voyager`, and expose as `from fastapi_voyager import create_voyager`
|
|
232
250
|
- optimization: lazy load vscode link and source code, speed up the initialization.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "0.9.
|
|
2
|
+
__version__ = "0.9.3"
|
|
@@ -3,14 +3,10 @@ const { defineComponent, ref, watch, onMounted } = window.Vue;
|
|
|
3
3
|
// Component: RouteCodeDisplay
|
|
4
4
|
// Props:
|
|
5
5
|
// routeId: route id key in routeItems
|
|
6
|
-
// modelValue: dialog visibility
|
|
7
|
-
// routes: object map { id: { id, name, source_code } }
|
|
8
6
|
export default defineComponent({
|
|
9
7
|
name: "RouteCodeDisplay",
|
|
10
8
|
props: {
|
|
11
9
|
routeId: { type: String, required: true },
|
|
12
|
-
modelValue: { type: Boolean, default: false },
|
|
13
|
-
routes: { type: Object, default: () => ({}) },
|
|
14
10
|
},
|
|
15
11
|
emits: ["close"],
|
|
16
12
|
setup(props, { emit }) {
|
|
@@ -101,32 +97,26 @@ export default defineComponent({
|
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
|
|
104
|
-
watch(
|
|
105
|
-
() => props.modelValue,
|
|
106
|
-
(v) => {
|
|
107
|
-
if (v) load();
|
|
108
|
-
}
|
|
109
|
-
);
|
|
110
100
|
watch(
|
|
111
101
|
() => props.routeId,
|
|
112
102
|
() => {
|
|
113
|
-
|
|
103
|
+
load();
|
|
114
104
|
}
|
|
115
105
|
);
|
|
116
106
|
|
|
117
107
|
onMounted(() => {
|
|
118
|
-
|
|
108
|
+
load();
|
|
119
109
|
});
|
|
120
110
|
|
|
121
111
|
return { loading, code, error, close, link };
|
|
122
112
|
},
|
|
123
113
|
template: `
|
|
124
|
-
<div class="frv-route-code-display" style="border:1px solid #ccc; position:relative;
|
|
114
|
+
<div class="frv-route-code-display" style="border:1px solid #ccc; position:relative; background:#fff;">
|
|
125
115
|
<q-btn dense flat round icon="close" @click="close" aria-label="Close" style="position:absolute; top:6px; right:6px; z-index:10; background:rgba(255,255,255,0.85)" />
|
|
126
116
|
<div v-if="link" class="q-ml-md q-mt-md" style="padding-top:4px;">
|
|
127
117
|
<a :href="link" target="_blank" rel="noopener" style="font-size:12px; color:#3b82f6;">Open in VSCode</a>
|
|
128
118
|
</div>
|
|
129
|
-
<div style="padding:40px 16px 16px 16px;
|
|
119
|
+
<div style="padding:40px 16px 16px 16px; box-sizing:border-box; overflow:auto;">
|
|
130
120
|
<div v-if="loading" style="font-family:Menlo, monospace; font-size:12px;">Loading source...</div>
|
|
131
121
|
<div v-else-if="error" style="color:#c10015; font-family:Menlo, monospace; font-size:12px;">{{ error }}</div>
|
|
132
122
|
<pre v-else style="margin:0;"><code class="language-python">{{ code }}</code></pre>
|
|
@@ -13,23 +13,17 @@ export default defineComponent({
|
|
|
13
13
|
name: "SchemaCodeDisplay",
|
|
14
14
|
props: {
|
|
15
15
|
schemaName: { type: String, required: true },
|
|
16
|
-
|
|
17
|
-
schemas: { type: Array, default: () => [] },
|
|
16
|
+
schemas: { type: Object, default: () => ({}) },
|
|
18
17
|
},
|
|
19
|
-
emits: ["close"],
|
|
20
18
|
setup(props, { emit }) {
|
|
21
|
-
const loading = ref(false);
|
|
22
19
|
const code = ref("");
|
|
23
20
|
const link = ref("");
|
|
24
21
|
const error = ref("");
|
|
25
22
|
const fields = ref([]); // schema fields list
|
|
26
23
|
const tab = ref("source");
|
|
27
24
|
|
|
28
|
-
function close() {
|
|
29
|
-
emit("close");
|
|
30
|
-
}
|
|
31
25
|
|
|
32
|
-
function highlightLater() {
|
|
26
|
+
async function highlightLater() {
|
|
33
27
|
// wait a tick for DOM update
|
|
34
28
|
requestAnimationFrame(() => {
|
|
35
29
|
try {
|
|
@@ -38,6 +32,10 @@ export default defineComponent({
|
|
|
38
32
|
".frv-code-display pre code.language-python"
|
|
39
33
|
);
|
|
40
34
|
if (block) {
|
|
35
|
+
// If already highlighted by highlight.js, remove the flag so it can be highlighted again
|
|
36
|
+
if (block.dataset && block.dataset.highlighted) {
|
|
37
|
+
block.removeAttribute("data-highlighted");
|
|
38
|
+
}
|
|
41
39
|
window.hljs.highlightElement(block);
|
|
42
40
|
}
|
|
43
41
|
}
|
|
@@ -50,7 +48,6 @@ export default defineComponent({
|
|
|
50
48
|
async function loadSource() {
|
|
51
49
|
if (!props.schemaName) return;
|
|
52
50
|
|
|
53
|
-
loading.value = true;
|
|
54
51
|
error.value = null;
|
|
55
52
|
code.value = "";
|
|
56
53
|
link.value = "";
|
|
@@ -77,7 +74,6 @@ export default defineComponent({
|
|
|
77
74
|
} catch (e) {
|
|
78
75
|
error.value = "Failed to load source";
|
|
79
76
|
} finally {
|
|
80
|
-
loading.value = false;
|
|
81
77
|
}
|
|
82
78
|
|
|
83
79
|
try {
|
|
@@ -99,10 +95,12 @@ export default defineComponent({
|
|
|
99
95
|
} catch (e) {
|
|
100
96
|
error.value = "Failed to load source";
|
|
101
97
|
} finally {
|
|
102
|
-
loading.value = false;
|
|
103
98
|
}
|
|
104
99
|
|
|
105
|
-
|
|
100
|
+
const schema = props.schemas && props.schemas[props.schemaName];
|
|
101
|
+
fields.value = Array.isArray(schema?.fields) ? schema.fields : [];
|
|
102
|
+
|
|
103
|
+
if (tab.value === "source") {
|
|
106
104
|
highlightLater();
|
|
107
105
|
}
|
|
108
106
|
}
|
|
@@ -118,25 +116,21 @@ export default defineComponent({
|
|
|
118
116
|
);
|
|
119
117
|
|
|
120
118
|
watch(
|
|
121
|
-
() => props.
|
|
122
|
-
(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
}
|
|
119
|
+
() => props.schemaName,
|
|
120
|
+
() => {
|
|
121
|
+
loadSource();
|
|
122
|
+
},
|
|
127
123
|
);
|
|
128
124
|
|
|
129
125
|
onMounted(() => {
|
|
130
|
-
|
|
126
|
+
loadSource();
|
|
131
127
|
});
|
|
132
128
|
|
|
133
|
-
return {
|
|
129
|
+
return { link, code, error, fields, tab };
|
|
134
130
|
},
|
|
135
131
|
template: `
|
|
136
|
-
<div class="frv-code-display" style="border: 1px solid #ccc; border-left: none; position:relative;
|
|
137
|
-
|
|
138
|
-
style="position:absolute; top:6px; right:6px; z-index:10; background:rgba(255,255,255,0.85)" />
|
|
139
|
-
<div v-if="link" class="q-ml-md q-mt-md">
|
|
132
|
+
<div class="frv-code-display" style="border: 1px solid #ccc; border-left: none; position:relative; height:100%; background:#fff;">
|
|
133
|
+
<div class="q-ml-lg q-mt-md">
|
|
140
134
|
<a :href="link" target="_blank" rel="noopener" style="font-size:12px; color:#3b82f6;">
|
|
141
135
|
Open in VSCode
|
|
142
136
|
</a>
|
|
@@ -150,8 +144,7 @@ export default defineComponent({
|
|
|
150
144
|
</div>
|
|
151
145
|
<q-separator />
|
|
152
146
|
<div style="padding:8px 16px 16px 16px; height:75%; box-sizing:border-box; overflow:auto;">
|
|
153
|
-
<div v-if="
|
|
154
|
-
<div v-else-if="error" style="color:#c10015; font-family:Menlo, monospace; font-size:12px;">{{ error }}</div>
|
|
147
|
+
<div v-if="error" style="color:#c10015; font-family:Menlo, monospace; font-size:12px;">{{ error }}</div>
|
|
155
148
|
<template v-else>
|
|
156
149
|
<div v-show="tab === 'source'">
|
|
157
150
|
<pre style="margin:0;"><code class="language-python">{{ code }}</code></pre>
|
|
@@ -14,7 +14,8 @@ export default defineComponent({
|
|
|
14
14
|
name: "SchemaFieldFilter",
|
|
15
15
|
props: {
|
|
16
16
|
schemaName: { type: String, default: null }, // external injection triggers auto-query
|
|
17
|
-
|
|
17
|
+
// externally provided schemas dict (state.rawSchemasFull): { [id]: schema }
|
|
18
|
+
schemas: { type: Object, default: () => ({}) },
|
|
18
19
|
},
|
|
19
20
|
emits: ["queried", "close"],
|
|
20
21
|
setup(props, { emit }) {
|
|
@@ -39,9 +40,11 @@ export default defineComponent({
|
|
|
39
40
|
let lastAppliedExternal = null;
|
|
40
41
|
|
|
41
42
|
async function loadSchemas() {
|
|
42
|
-
//
|
|
43
|
+
// Use externally provided props.schemas dict directly; no network call.
|
|
43
44
|
state.error = null;
|
|
44
|
-
|
|
45
|
+
const dict = props.schemas && typeof props.schemas === "object" ? props.schemas : {};
|
|
46
|
+
// Flatten to array for local operations
|
|
47
|
+
state.schemas = Object.values(dict);
|
|
45
48
|
state.schemaOptions = state.schemas.map((s) => ({
|
|
46
49
|
label: `${s.name} (${s.id})`,
|
|
47
50
|
value: s.id,
|
|
@@ -69,23 +69,27 @@ export class GraphUI {
|
|
|
69
69
|
const set = $();
|
|
70
70
|
set.push(this);
|
|
71
71
|
const obj = { set, direction: "bidirectional" };
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
const schemaName = event.currentTarget.dataset.name;
|
|
73
74
|
if (event.shiftKey && self.options.onSchemaClick) {
|
|
74
75
|
// try data-name or title text
|
|
75
|
-
const schemaName = event.currentTarget.dataset.name;
|
|
76
76
|
if (schemaName) {
|
|
77
77
|
try {
|
|
78
|
-
self.options.
|
|
78
|
+
self.options.onSchemaShiftClick(schemaName);
|
|
79
79
|
} catch (e) {
|
|
80
|
-
console.warn("
|
|
80
|
+
console.warn("onSchemaShiftClick callback failed", e);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
} else if (event.altKey && self.options.onSchemaAltClick) {
|
|
84
|
-
const schemaName = event.currentTarget.dataset.name;
|
|
85
|
-
self.options.onSchemaAltClick(schemaName);
|
|
86
83
|
} else {
|
|
87
84
|
self.currentSelection = [obj];
|
|
88
85
|
self._highlight();
|
|
86
|
+
if (schemaName) {
|
|
87
|
+
try {
|
|
88
|
+
self.options.onSchemaClick(schemaName);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.warn("onSchemaClick callback failed", e);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
89
93
|
}
|
|
90
94
|
});
|
|
91
95
|
|