fastapi-voyager 0.7.6__tar.gz → 0.8.2__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.7.6 → fastapi_voyager-0.8.2}/PKG-INFO +12 -2
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/README.md +11 -1
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/render.py +1 -1
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/server.py +3 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/type.py +2 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/type_helper.py +6 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/version.py +1 -1
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/voyager.py +22 -11
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/index.html +7 -6
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/vue-main.js +16 -1
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/demo.py +5 -1
- fastapi_voyager-0.8.2/tests/programatic.py +4 -0
- fastapi_voyager-0.7.6/tests/programatic.py +0 -8
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/.gitignore +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/.python-version +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/LICENSE +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/pyproject.toml +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/__init__.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/component/schema-field-filter.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/graph-ui.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/__init__.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/demo_anno.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/service/schema.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_import.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_module.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/tests/test_type_helper.py +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/uv.lock +0 -0
- {fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/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.8.2
|
|
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
|
|
@@ -108,7 +108,10 @@ from fastapi import FastAPI
|
|
|
108
108
|
from fastapi_voyager.server import create_app_with_fastapi
|
|
109
109
|
from tests.demo import app
|
|
110
110
|
|
|
111
|
-
app.mount('/voyager', create_app_with_fastapi(
|
|
111
|
+
app.mount('/voyager', create_app_with_fastapi(
|
|
112
|
+
app,
|
|
113
|
+
module_color={"tests.service": "red"},
|
|
114
|
+
module_prefix="tests.service"))
|
|
112
115
|
```
|
|
113
116
|
|
|
114
117
|
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
@@ -198,6 +201,8 @@ features:
|
|
|
198
201
|
- [x] export voyager core data into json (for better debugging)
|
|
199
202
|
- [x] add api to rebuild core data from json, and render it
|
|
200
203
|
- [x] fix Generic case `test_generic.py`
|
|
204
|
+
- [ ] show tips for routes not return pydantic type.
|
|
205
|
+
- [ ] add http method for route
|
|
201
206
|
|
|
202
207
|
bugs & non feature:
|
|
203
208
|
- [x] fix duplicated link from class and parent class, it also break clicking highlight
|
|
@@ -220,6 +225,11 @@ TODO: ...
|
|
|
220
225
|
|
|
221
226
|
## Changelog
|
|
222
227
|
|
|
228
|
+
- 0.8:
|
|
229
|
+
- 0.8.2
|
|
230
|
+
- fix silly typo.
|
|
231
|
+
- 0.8.1
|
|
232
|
+
- add feature: hide primitive routes
|
|
223
233
|
- 0.7:
|
|
224
234
|
- 0.7.5
|
|
225
235
|
- fix show all display issue
|
|
@@ -81,7 +81,10 @@ from fastapi import FastAPI
|
|
|
81
81
|
from fastapi_voyager.server import create_app_with_fastapi
|
|
82
82
|
from tests.demo import app
|
|
83
83
|
|
|
84
|
-
app.mount('/voyager', create_app_with_fastapi(
|
|
84
|
+
app.mount('/voyager', create_app_with_fastapi(
|
|
85
|
+
app,
|
|
86
|
+
module_color={"tests.service": "red"},
|
|
87
|
+
module_prefix="tests.service"))
|
|
85
88
|
```
|
|
86
89
|
|
|
87
90
|
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
@@ -171,6 +174,8 @@ features:
|
|
|
171
174
|
- [x] export voyager core data into json (for better debugging)
|
|
172
175
|
- [x] add api to rebuild core data from json, and render it
|
|
173
176
|
- [x] fix Generic case `test_generic.py`
|
|
177
|
+
- [ ] show tips for routes not return pydantic type.
|
|
178
|
+
- [ ] add http method for route
|
|
174
179
|
|
|
175
180
|
bugs & non feature:
|
|
176
181
|
- [x] fix duplicated link from class and parent class, it also break clicking highlight
|
|
@@ -193,6 +198,11 @@ TODO: ...
|
|
|
193
198
|
|
|
194
199
|
## Changelog
|
|
195
200
|
|
|
201
|
+
- 0.8:
|
|
202
|
+
- 0.8.2
|
|
203
|
+
- fix silly typo.
|
|
204
|
+
- 0.8.1
|
|
205
|
+
- add feature: hide primitive routes
|
|
196
206
|
- 0.7:
|
|
197
207
|
- 0.7.5
|
|
198
208
|
- fix show all display issue
|
|
@@ -33,6 +33,7 @@ class Payload(BaseModel):
|
|
|
33
33
|
show_fields: str = 'object'
|
|
34
34
|
show_meta: bool = False
|
|
35
35
|
brief: bool = False
|
|
36
|
+
hide_primitive_route: bool = False
|
|
36
37
|
|
|
37
38
|
def create_route(
|
|
38
39
|
target_app: FastAPI,
|
|
@@ -65,6 +66,7 @@ def create_route(
|
|
|
65
66
|
|
|
66
67
|
@router.post("/dot", response_class=PlainTextResponse)
|
|
67
68
|
def get_filtered_dot(payload: Payload) -> str:
|
|
69
|
+
print(payload)
|
|
68
70
|
voyager = Voyager(
|
|
69
71
|
include_tags=payload.tags,
|
|
70
72
|
schema=payload.schema_name,
|
|
@@ -73,6 +75,7 @@ def create_route(
|
|
|
73
75
|
module_color=module_color,
|
|
74
76
|
route_name=payload.route_name,
|
|
75
77
|
load_meta=False,
|
|
78
|
+
hide_primitive_route=payload.hide_primitive_route,
|
|
76
79
|
)
|
|
77
80
|
voyager.analysis(target_app)
|
|
78
81
|
if payload.brief:
|
|
@@ -276,6 +276,12 @@ def is_generic_container(cls):
|
|
|
276
276
|
return (hasattr(cls, '__bases__') and Generic in cls.__bases__ and (hasattr(cls, '__parameters__') and bool(cls.__parameters__)))
|
|
277
277
|
except (TypeError, AttributeError):
|
|
278
278
|
return False
|
|
279
|
+
|
|
280
|
+
def is_non_pydantic_type(tp):
|
|
281
|
+
for schema in get_core_types(tp):
|
|
282
|
+
if schema and issubclass(schema, BaseModel):
|
|
283
|
+
return False
|
|
284
|
+
return True
|
|
279
285
|
|
|
280
286
|
if __name__ == "__main__":
|
|
281
287
|
from tests.demo_anno import PageSprint, PageOverall
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.8.2"
|
|
@@ -8,7 +8,9 @@ from fastapi_voyager.type_helper import (
|
|
|
8
8
|
get_pydantic_fields,
|
|
9
9
|
get_vscode_link,
|
|
10
10
|
get_source,
|
|
11
|
-
|
|
11
|
+
get_type_name,
|
|
12
|
+
update_forward_refs,
|
|
13
|
+
is_non_pydantic_type
|
|
12
14
|
)
|
|
13
15
|
from pydantic import BaseModel
|
|
14
16
|
from fastapi_voyager.type import Route, SchemaNode, Link, Tag, LinkType, FieldType, PK, CoreData
|
|
@@ -26,6 +28,7 @@ class Voyager:
|
|
|
26
28
|
include_tags: list[str] | None = None,
|
|
27
29
|
module_color: dict[str, str] | None = None,
|
|
28
30
|
route_name: str | None = None,
|
|
31
|
+
hide_primitive_route: bool = False,
|
|
29
32
|
load_meta: bool = False
|
|
30
33
|
):
|
|
31
34
|
|
|
@@ -48,6 +51,7 @@ class Voyager:
|
|
|
48
51
|
self.module_color = module_color or {}
|
|
49
52
|
self.route_name = route_name
|
|
50
53
|
self.load_meta = load_meta
|
|
54
|
+
self.hide_primitive_route = hide_primitive_route
|
|
51
55
|
|
|
52
56
|
|
|
53
57
|
def _get_available_route(self, app: FastAPI):
|
|
@@ -89,28 +93,36 @@ class Voyager:
|
|
|
89
93
|
if self.route_name is not None and route_id != self.route_name:
|
|
90
94
|
continue
|
|
91
95
|
|
|
96
|
+
is_primitive_response = is_non_pydantic_type(route.response_model)
|
|
97
|
+
# filter primitive route if needed
|
|
98
|
+
if self.hide_primitive_route and is_primitive_response:
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
self.links.append(Link(
|
|
102
|
+
source=tag_id,
|
|
103
|
+
source_origin=tag_id,
|
|
104
|
+
target=route_id,
|
|
105
|
+
target_origin=route_id,
|
|
106
|
+
type='tag_route'
|
|
107
|
+
))
|
|
108
|
+
|
|
92
109
|
route_obj = Route(
|
|
93
110
|
id=route_id,
|
|
94
111
|
name=route_name,
|
|
95
112
|
module=route_module,
|
|
96
113
|
vscode_link=get_vscode_link(route.endpoint) if self.load_meta else '',
|
|
97
|
-
source_code=inspect.getsource(route.endpoint) if self.load_meta else ''
|
|
114
|
+
source_code=inspect.getsource(route.endpoint) if self.load_meta else '',
|
|
115
|
+
response_schema=get_type_name(route.response_model),
|
|
116
|
+
is_primitive=is_primitive_response
|
|
98
117
|
)
|
|
99
|
-
|
|
100
118
|
self.routes.append(route_obj)
|
|
101
119
|
# add route into current tag
|
|
102
120
|
self.tag_set[tag_id].routes.append(route_obj)
|
|
103
|
-
self.links.append(Link(
|
|
104
|
-
source=tag_id,
|
|
105
|
-
source_origin=tag_id,
|
|
106
|
-
target=route_id,
|
|
107
|
-
target_origin=route_id,
|
|
108
|
-
type='tag_route'
|
|
109
|
-
))
|
|
110
121
|
|
|
111
122
|
# add response_models and create links from route -> response_model
|
|
112
123
|
for schema in get_core_types(route.response_model):
|
|
113
124
|
if schema and issubclass(schema, BaseModel):
|
|
125
|
+
is_primitive_response = False
|
|
114
126
|
target_name = full_class_name(schema)
|
|
115
127
|
self.links.append(Link(
|
|
116
128
|
source=route_id,
|
|
@@ -274,7 +286,6 @@ class Voyager:
|
|
|
274
286
|
return renderer.render_dot(_tags, _routes, _nodes, _links)
|
|
275
287
|
|
|
276
288
|
def render_brief_dot(self, module_prefix: str | None = None):
|
|
277
|
-
print(module_prefix)
|
|
278
289
|
_tags, _routes, _nodes, _links = filter_subgraph(
|
|
279
290
|
module_prefix=module_prefix,
|
|
280
291
|
tags=self.tags,
|
|
@@ -104,9 +104,6 @@
|
|
|
104
104
|
</div>
|
|
105
105
|
</div>
|
|
106
106
|
|
|
107
|
-
<div class="col-auto">
|
|
108
|
-
<q-toggle class="q-ml-md" v-model="state.brief" label="Brief Mode" title="config module_prefix to enable it" dense />
|
|
109
|
-
</div>
|
|
110
107
|
|
|
111
108
|
<!-- <div class="col-auto">
|
|
112
109
|
<q-btn-dropdown
|
|
@@ -129,6 +126,10 @@
|
|
|
129
126
|
</div> -->
|
|
130
127
|
|
|
131
128
|
<div class="col-auto q-ml-auto">
|
|
129
|
+
<q-toggle class="q-ml-md" v-model="state.brief" label="Brief Mode" title="config module_prefix to enable it" dense />
|
|
130
|
+
<q-toggle class="q-ml-md" v-model="state.hidePrimitiveRoute" label="Hide Primitive Routes" title="" dense />
|
|
131
|
+
</div>
|
|
132
|
+
<div class="col-auto">
|
|
132
133
|
<q-btn outline @click="onReset" title="may be very slow" label="Show All" />
|
|
133
134
|
</div>
|
|
134
135
|
<div class="col-auto">
|
|
@@ -200,7 +201,7 @@
|
|
|
200
201
|
|
|
201
202
|
<q-list separator>
|
|
202
203
|
<q-item
|
|
203
|
-
v-for="route in (tag.routes || [])"
|
|
204
|
+
v-for="route in (state.hidePrimitiveRoute ? tag.routes.filter(r => !r.is_primitive) :tag.routes || [])"
|
|
204
205
|
:key="route.id"
|
|
205
206
|
clickable
|
|
206
207
|
v-ripple
|
|
@@ -209,8 +210,8 @@
|
|
|
209
210
|
@click="selectRoute(route.id)"
|
|
210
211
|
>
|
|
211
212
|
<q-item-section>
|
|
212
|
-
<span class="q-ml-sm"> {{ route.name }}
|
|
213
|
-
|
|
213
|
+
<span class="q-ml-sm"> <span style="font-weight: bold;">⋅</span> {{ route.name }}</span>
|
|
214
|
+
</q-item-section>
|
|
214
215
|
</q-item>
|
|
215
216
|
<q-item v-if="!tag.routes || tag.routes.length === 0" dense>
|
|
216
217
|
<q-item-section class="text-grey-6">No routes</q-item-section>
|
|
@@ -23,6 +23,7 @@ const app = createApp({
|
|
|
23
23
|
{ label: "All fields", value: "all" },
|
|
24
24
|
],
|
|
25
25
|
brief: false,
|
|
26
|
+
hidePrimitiveRoute: false,
|
|
26
27
|
generating: false,
|
|
27
28
|
rawTags: [], // [{ name, routes: [{ id, name }] }]
|
|
28
29
|
rawSchemas: [], // [{ name, fullname }]
|
|
@@ -123,6 +124,7 @@ const app = createApp({
|
|
|
123
124
|
route_name: state.routeId || null,
|
|
124
125
|
show_fields: state.showFields,
|
|
125
126
|
brief: state.brief,
|
|
127
|
+
hide_primitive_route: state.hidePrimitiveRoute
|
|
126
128
|
};
|
|
127
129
|
|
|
128
130
|
const res = await fetch("dot", {
|
|
@@ -243,7 +245,11 @@ const app = createApp({
|
|
|
243
245
|
}
|
|
244
246
|
|
|
245
247
|
function selectRoute(routeId) {
|
|
246
|
-
state.routeId
|
|
248
|
+
if (state.routeId === routeId) {
|
|
249
|
+
state.routeId = ''
|
|
250
|
+
} else {
|
|
251
|
+
state.routeId = routeId
|
|
252
|
+
}
|
|
247
253
|
onGenerate()
|
|
248
254
|
}
|
|
249
255
|
|
|
@@ -276,6 +282,15 @@ const app = createApp({
|
|
|
276
282
|
}
|
|
277
283
|
);
|
|
278
284
|
|
|
285
|
+
watch(
|
|
286
|
+
() => state.hidePrimitiveRoute,
|
|
287
|
+
() => {
|
|
288
|
+
if (!state.initializing) {
|
|
289
|
+
onGenerate();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
);
|
|
293
|
+
|
|
279
294
|
onMounted(async () => {
|
|
280
295
|
await loadInitial();
|
|
281
296
|
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/component/render-graph.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/apple-touch-icon.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/favicon-16x16.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/favicon-32x32.png
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.7.6 → fastapi_voyager-0.8.2}/src/fastapi_voyager/web/icon/site.webmanifest
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|