fastapi-voyager 0.11.1__tar.gz → 0.11.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.11.1 → fastapi_voyager-0.11.2}/PKG-INFO +30 -19
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/README.md +27 -18
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/pyproject.toml +2 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/render.py +54 -40
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/server.py +2 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/version.py +1 -1
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/voyager.py +5 -3
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/index.html +16 -3
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/vue-main.js +8 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/.gitignore +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/.python-version +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/LICENSE +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/__init__.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/type.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/type_helper.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/component/schema-field-filter.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/graph-ui.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/__init__.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/demo.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/demo_anno.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/programatic.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/service/schema.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_import.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_module.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/tests/test_type_helper.py +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/uv.lock +0 -0
- {fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/voyager.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-voyager
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.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
|
|
@@ -16,6 +16,8 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
21
|
Requires-Python: >=3.10
|
|
20
22
|
Requires-Dist: fastapi>=0.110
|
|
21
23
|
Requires-Dist: pydantic-resolve>=1.13.2
|
|
@@ -32,7 +34,14 @@ Description-Content-Type: text/markdown
|
|
|
32
34
|
|
|
33
35
|
> This repo is still in early stage, it supports pydantic v2 only
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
FastAPI can help you:
|
|
38
|
+
|
|
39
|
+
- design your API
|
|
40
|
+
- inspect your API
|
|
41
|
+
- refactor your API
|
|
42
|
+
|
|
43
|
+
interactively !!
|
|
44
|
+
|
|
36
45
|
|
|
37
46
|
[visit online demo](https://www.newsyeah.fun/voyager/) of project: [composition oriented development pattern](https://github.com/allmonday/composition-oriented-development-pattern)
|
|
38
47
|
|
|
@@ -51,6 +60,22 @@ uv add fastapi-voyager
|
|
|
51
60
|
voyager -m path.to.your.app.module --server
|
|
52
61
|
```
|
|
53
62
|
|
|
63
|
+
## Mount into project
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from fastapi import FastAPI
|
|
67
|
+
from fastapi_voyager import create_voyager
|
|
68
|
+
from tests.demo import app
|
|
69
|
+
|
|
70
|
+
app.mount('/voyager', create_voyager(
|
|
71
|
+
app,
|
|
72
|
+
module_color={"tests.service": "red"},
|
|
73
|
+
module_prefix="tests.service"),
|
|
74
|
+
swagger_url="/docs")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
78
|
+
|
|
54
79
|
|
|
55
80
|
## Feature
|
|
56
81
|
|
|
@@ -99,20 +124,6 @@ click a node to highlight it's upperstream and downstream nodes. figure out the
|
|
|
99
124
|
<img width="882" height="445" alt="image" src="https://github.com/user-attachments/assets/158560ef-63ca-4991-9b7d-587be4fa04e4" />
|
|
100
125
|
|
|
101
126
|
|
|
102
|
-
## Mount to target project
|
|
103
|
-
|
|
104
|
-
```python
|
|
105
|
-
from fastapi import FastAPI
|
|
106
|
-
from fastapi_voyager import create_voyager
|
|
107
|
-
from tests.demo import app
|
|
108
|
-
|
|
109
|
-
app.mount('/voyager', create_voyager(
|
|
110
|
-
app,
|
|
111
|
-
module_color={"tests.service": "red"},
|
|
112
|
-
module_prefix="tests.service"))
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
116
127
|
|
|
117
128
|
|
|
118
129
|
## Command Line Usage
|
|
@@ -257,12 +268,12 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
257
268
|
- [x] config docs path
|
|
258
269
|
- [x] provide option to hide routes in brief mode (auto hide in full graph mode)
|
|
259
270
|
- 0.11.2
|
|
260
|
-
- [
|
|
271
|
+
- [x] enable/disable module cluster (to save space)
|
|
272
|
+
- 0.11.3
|
|
273
|
+
- [ ] add loading for field detail panel
|
|
261
274
|
- [ ] logging information
|
|
262
275
|
- [ ] sort field name
|
|
263
276
|
- [ ] set max limit for fields
|
|
264
|
-
- [ ] add info icon alone with schema node
|
|
265
|
-
- [ ] add loading for field detail panel
|
|
266
277
|
|
|
267
278
|
#### 0.12
|
|
268
279
|
- [ ] add tests
|
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
> This repo is still in early stage, it supports pydantic v2 only
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
FastAPI can help you:
|
|
9
|
+
|
|
10
|
+
- design your API
|
|
11
|
+
- inspect your API
|
|
12
|
+
- refactor your API
|
|
13
|
+
|
|
14
|
+
interactively !!
|
|
15
|
+
|
|
9
16
|
|
|
10
17
|
[visit online demo](https://www.newsyeah.fun/voyager/) of project: [composition oriented development pattern](https://github.com/allmonday/composition-oriented-development-pattern)
|
|
11
18
|
|
|
@@ -24,6 +31,22 @@ uv add fastapi-voyager
|
|
|
24
31
|
voyager -m path.to.your.app.module --server
|
|
25
32
|
```
|
|
26
33
|
|
|
34
|
+
## Mount into project
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from fastapi import FastAPI
|
|
38
|
+
from fastapi_voyager import create_voyager
|
|
39
|
+
from tests.demo import app
|
|
40
|
+
|
|
41
|
+
app.mount('/voyager', create_voyager(
|
|
42
|
+
app,
|
|
43
|
+
module_color={"tests.service": "red"},
|
|
44
|
+
module_prefix="tests.service"),
|
|
45
|
+
swagger_url="/docs")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
49
|
+
|
|
27
50
|
|
|
28
51
|
## Feature
|
|
29
52
|
|
|
@@ -72,20 +95,6 @@ click a node to highlight it's upperstream and downstream nodes. figure out the
|
|
|
72
95
|
<img width="882" height="445" alt="image" src="https://github.com/user-attachments/assets/158560ef-63ca-4991-9b7d-587be4fa04e4" />
|
|
73
96
|
|
|
74
97
|
|
|
75
|
-
## Mount to target project
|
|
76
|
-
|
|
77
|
-
```python
|
|
78
|
-
from fastapi import FastAPI
|
|
79
|
-
from fastapi_voyager import create_voyager
|
|
80
|
-
from tests.demo import app
|
|
81
|
-
|
|
82
|
-
app.mount('/voyager', create_voyager(
|
|
83
|
-
app,
|
|
84
|
-
module_color={"tests.service": "red"},
|
|
85
|
-
module_prefix="tests.service"))
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
more about [sub application](https://fastapi.tiangolo.com/advanced/sub-applications/?h=sub)
|
|
89
98
|
|
|
90
99
|
|
|
91
100
|
## Command Line Usage
|
|
@@ -230,12 +239,12 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
|
|
|
230
239
|
- [x] config docs path
|
|
231
240
|
- [x] provide option to hide routes in brief mode (auto hide in full graph mode)
|
|
232
241
|
- 0.11.2
|
|
233
|
-
- [
|
|
242
|
+
- [x] enable/disable module cluster (to save space)
|
|
243
|
+
- 0.11.3
|
|
244
|
+
- [ ] add loading for field detail panel
|
|
234
245
|
- [ ] logging information
|
|
235
246
|
- [ ] sort field name
|
|
236
247
|
- [ ] set max limit for fields
|
|
237
|
-
- [ ] add info icon alone with schema node
|
|
238
|
-
- [ ] add loading for field detail panel
|
|
239
248
|
|
|
240
249
|
#### 0.12
|
|
241
250
|
- [ ] add tests
|
|
@@ -17,6 +17,8 @@ classifiers = [
|
|
|
17
17
|
"Programming Language :: Python :: 3.10",
|
|
18
18
|
"Programming Language :: Python :: 3.11",
|
|
19
19
|
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
20
22
|
"Framework :: FastAPI",
|
|
21
23
|
"Intended Audience :: Developers",
|
|
22
24
|
"License :: OSI Approved :: MIT License"
|
|
@@ -10,10 +10,12 @@ class Renderer:
|
|
|
10
10
|
show_fields: FieldType = 'single',
|
|
11
11
|
module_color: dict[str, str] | None = None,
|
|
12
12
|
schema: str | None = None,
|
|
13
|
+
show_module: bool = True
|
|
13
14
|
) -> None:
|
|
14
15
|
self.show_fields = show_fields if show_fields in ('single', 'object', 'all') else 'single'
|
|
15
16
|
self.module_color = module_color or {}
|
|
16
17
|
self.schema = schema
|
|
18
|
+
self.show_module = show_module
|
|
17
19
|
|
|
18
20
|
def render_schema_label(self, node: SchemaNode) -> str:
|
|
19
21
|
has_base_fields = any(f.from_base for f in node.fields)
|
|
@@ -60,13 +62,18 @@ class Renderer:
|
|
|
60
62
|
elif link.type == 'subset':
|
|
61
63
|
return f"""{h(link.source)}:e -> {h(link.target)}:w [style = "solid, dashed", dir="back", minlen=3, taillabel = "< subset >", color = "orange", tailport="n"];"""
|
|
62
64
|
elif link.type == 'tag_to_schema':
|
|
63
|
-
return f"""{h(link.source)}:e -> {h(link.target)}:w [style = "solid",
|
|
65
|
+
return f"""{h(link.source)}:e -> {h(link.target)}:w [style = "solid", minlen=3];"""
|
|
64
66
|
else:
|
|
65
67
|
raise ValueError(f'Unknown link type: {link.type}')
|
|
66
68
|
|
|
67
|
-
def render_module_schema_content(self,
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
def render_module_schema_content(self, nodes: list[SchemaNode]) -> str:
|
|
70
|
+
def render_node(node: SchemaNode) -> str:
|
|
71
|
+
return f'''
|
|
72
|
+
"{node.id}" [
|
|
73
|
+
label = {self.render_schema_label(node)}
|
|
74
|
+
shape = "plain"
|
|
75
|
+
margin="0.5,0.1"
|
|
76
|
+
];'''
|
|
70
77
|
def render_module_schema(mod: ModuleNode) -> str:
|
|
71
78
|
color: Optional[str] = None
|
|
72
79
|
|
|
@@ -76,14 +83,7 @@ class Renderer:
|
|
|
76
83
|
color = self.module_color[k]
|
|
77
84
|
break
|
|
78
85
|
|
|
79
|
-
inner_nodes = [
|
|
80
|
-
f'''
|
|
81
|
-
"{node.id}" [
|
|
82
|
-
label = {self.render_schema_label(node)}
|
|
83
|
-
shape = "plain"
|
|
84
|
-
margin="0.5,0.1"
|
|
85
|
-
];''' for node in mod.schema_nodes
|
|
86
|
-
]
|
|
86
|
+
inner_nodes = [ render_node(node) for node in mod.schema_nodes ]
|
|
87
87
|
inner_nodes_str = '\n'.join(inner_nodes)
|
|
88
88
|
child_str = '\n'.join(render_module_schema(m) for m in mod.modules)
|
|
89
89
|
return f'''
|
|
@@ -98,34 +98,49 @@ class Renderer:
|
|
|
98
98
|
{inner_nodes_str}
|
|
99
99
|
{child_str}
|
|
100
100
|
}}'''
|
|
101
|
-
|
|
101
|
+
if self.show_module:
|
|
102
|
+
module_schemas = build_module_schema_tree(nodes)
|
|
103
|
+
module_color_flag = set(self.module_color.keys())
|
|
104
|
+
return '\n'.join(render_module_schema(m) for m in module_schemas)
|
|
105
|
+
else:
|
|
106
|
+
return '\n'.join(render_node(n) for n in nodes)
|
|
102
107
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
f'''
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
108
|
+
def render_module_route_content(self, routes: list[Route]) -> str:
|
|
109
|
+
def render_route(route: Route) -> str:
|
|
110
|
+
response_schema = route.response_schema[:25] + '..' if len(route.response_schema) > 25 else route.response_schema
|
|
111
|
+
return f'''
|
|
112
|
+
"{route.id}" [
|
|
113
|
+
label = " {route.name} | {response_schema} "
|
|
114
|
+
margin="0.5,0.1"
|
|
115
|
+
shape = "record"
|
|
116
|
+
];'''
|
|
117
|
+
|
|
118
|
+
def render_module_route(mod: ModuleRoute) -> str:
|
|
119
|
+
# Inner route nodes, same style as flat route_str
|
|
120
|
+
inner_nodes = [
|
|
121
|
+
render_route(r) for r in mod.routes
|
|
122
|
+
]
|
|
123
|
+
inner_nodes_str = '\n'.join(inner_nodes)
|
|
124
|
+
child_str = '\n'.join(render_module_route(m) for m in mod.modules)
|
|
125
|
+
return f'''
|
|
126
|
+
subgraph cluster_route_module_{mod.fullname.replace('.', '_')} {{
|
|
127
|
+
tooltip="{mod.fullname}"
|
|
128
|
+
color = "#666"
|
|
129
|
+
style="rounded"
|
|
130
|
+
label = " {mod.name}"
|
|
131
|
+
labeljust = "l"
|
|
132
|
+
{inner_nodes_str}
|
|
133
|
+
{child_str}
|
|
134
|
+
}}'''
|
|
135
|
+
if self.show_module:
|
|
136
|
+
module_routes = build_module_route_tree(routes)
|
|
137
|
+
module_routes_str = '\n'.join(render_module_route(m) for m in module_routes)
|
|
138
|
+
return module_routes_str
|
|
139
|
+
else:
|
|
140
|
+
return '\n'.join(render_route(r) for r in routes)
|
|
141
|
+
|
|
125
142
|
|
|
126
143
|
def render_dot(self, tags: list[Tag], routes: list[Route], nodes: list[SchemaNode], links: list[Link], spline_line=False) -> str:
|
|
127
|
-
module_schemas = build_module_schema_tree(nodes)
|
|
128
|
-
module_routes = build_module_route_tree(routes)
|
|
129
144
|
|
|
130
145
|
tag_str = '\n'.join([
|
|
131
146
|
f'''
|
|
@@ -136,9 +151,8 @@ class Renderer:
|
|
|
136
151
|
];''' for t in tags
|
|
137
152
|
])
|
|
138
153
|
|
|
139
|
-
|
|
140
|
-
module_schemas_str = self.render_module_schema_content(
|
|
141
|
-
module_routes_str = '\n'.join(self.render_module_route(m) for m in module_routes)
|
|
154
|
+
module_routes_str = self.render_module_route_content(routes)
|
|
155
|
+
module_schemas_str = self.render_module_schema_content(nodes)
|
|
142
156
|
link_str = '\n'.join(self.render_link(link) for link in links)
|
|
143
157
|
|
|
144
158
|
dot_str = f'''
|
|
@@ -33,6 +33,7 @@ class Payload(BaseModel):
|
|
|
33
33
|
show_meta: bool = False
|
|
34
34
|
brief: bool = False
|
|
35
35
|
hide_primitive_route: bool = False
|
|
36
|
+
show_module: bool = True
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def create_route(
|
|
@@ -77,6 +78,7 @@ def create_route(
|
|
|
77
78
|
module_color=module_color,
|
|
78
79
|
route_name=payload.route_name,
|
|
79
80
|
hide_primitive_route=payload.hide_primitive_route,
|
|
81
|
+
show_module=payload.show_module,
|
|
80
82
|
)
|
|
81
83
|
voyager.analysis(target_app)
|
|
82
84
|
if payload.brief:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "0.11.
|
|
2
|
+
__version__ = "0.11.2"
|
|
@@ -27,6 +27,7 @@ class Voyager:
|
|
|
27
27
|
module_color: dict[str, str] | None = None,
|
|
28
28
|
route_name: str | None = None,
|
|
29
29
|
hide_primitive_route: bool = False,
|
|
30
|
+
show_module: bool = True
|
|
30
31
|
):
|
|
31
32
|
|
|
32
33
|
self.routes: list[Route] = []
|
|
@@ -48,6 +49,7 @@ class Voyager:
|
|
|
48
49
|
self.module_color = module_color or {}
|
|
49
50
|
self.route_name = route_name
|
|
50
51
|
self.hide_primitive_route = hide_primitive_route
|
|
52
|
+
self.show_module = show_module
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def _get_available_route(self, app: FastAPI):
|
|
@@ -301,7 +303,7 @@ class Voyager:
|
|
|
301
303
|
node_set=self.node_set,
|
|
302
304
|
)
|
|
303
305
|
|
|
304
|
-
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema)
|
|
306
|
+
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema, show_module=self.show_module)
|
|
305
307
|
|
|
306
308
|
_tags, _routes, _links = self.handle_hide(_tags, _routes, _links)
|
|
307
309
|
return renderer.render_dot(_tags, _routes, _nodes, _links)
|
|
@@ -326,7 +328,7 @@ class Voyager:
|
|
|
326
328
|
links=_links,
|
|
327
329
|
)
|
|
328
330
|
|
|
329
|
-
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema)
|
|
331
|
+
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema, show_module=self.show_module)
|
|
330
332
|
|
|
331
333
|
_tags, _routes, _links = self.handle_hide(_tags, _routes, _links)
|
|
332
334
|
return renderer.render_dot(_tags, _routes, _nodes, _links, True)
|
|
@@ -350,7 +352,7 @@ class Voyager:
|
|
|
350
352
|
links=_links,
|
|
351
353
|
)
|
|
352
354
|
|
|
353
|
-
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema)
|
|
355
|
+
renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema, show_module=self.show_module)
|
|
354
356
|
|
|
355
357
|
_tags, _routes, _links = self.handle_hide(_tags, _routes, _links)
|
|
356
358
|
return renderer.render_dot(_tags, _routes, _nodes, _links, True)
|
|
@@ -148,6 +148,7 @@
|
|
|
148
148
|
side="right"
|
|
149
149
|
style="border-left: 1px solid #888;"
|
|
150
150
|
bordered
|
|
151
|
+
overlay
|
|
151
152
|
>
|
|
152
153
|
<!-- 可拖拽的调整栏 -->
|
|
153
154
|
<div
|
|
@@ -265,32 +266,44 @@
|
|
|
265
266
|
<div style="position: relative; width: 100%; height: 100%;">
|
|
266
267
|
<div id="graph" class="adjust-fit"></div>
|
|
267
268
|
<div style="position: absolute; left: 8px; bottom: 8px; z-index: 10; background: rgba(255,255,255,0.85); border-radius: 4px; padding: 2px 8px;">
|
|
268
|
-
<div>
|
|
269
|
+
<div class="q-mt-sm">
|
|
269
270
|
<q-toggle
|
|
270
271
|
v-model="state.focus"
|
|
271
272
|
v-show="schemaCodeName"
|
|
272
273
|
@update:model-value="val => onFocusChange(val)"
|
|
273
274
|
label="Focus"
|
|
275
|
+
dense
|
|
274
276
|
title="pick a schema and toggle focus on to display related nodes only"
|
|
275
277
|
/>
|
|
276
278
|
</div>
|
|
277
|
-
<div>
|
|
279
|
+
<div class="q-mt-sm">
|
|
278
280
|
<q-toggle
|
|
279
281
|
v-if="state.enableBriefMode"
|
|
282
|
+
dense
|
|
280
283
|
v-model="state.brief"
|
|
281
284
|
label="Brief Mode"
|
|
282
285
|
@update:model-value="(val) => toggleBrief(val)"
|
|
283
286
|
title="skip middle classes, config module_prefix to enable it"
|
|
284
287
|
/>
|
|
285
288
|
</div>
|
|
286
|
-
<div>
|
|
289
|
+
<div class="q-mt-sm">
|
|
287
290
|
<q-toggle
|
|
288
291
|
v-model="state.hidePrimitiveRoute"
|
|
289
292
|
@update:model-value="(val) => toggleHidePrimitiveRoute(val)"
|
|
290
293
|
label="Hide Primitive"
|
|
294
|
+
dense
|
|
291
295
|
title="hide routes return primitive"
|
|
292
296
|
/>
|
|
293
297
|
</div>
|
|
298
|
+
<div class="q-mt-sm">
|
|
299
|
+
<q-toggle
|
|
300
|
+
v-model="state.showModule"
|
|
301
|
+
@update:model-value="(val) => toggleShowModule(val)"
|
|
302
|
+
label="Show Module Cluster"
|
|
303
|
+
dense
|
|
304
|
+
title="show module cluster"
|
|
305
|
+
/>
|
|
306
|
+
</div>
|
|
294
307
|
</div>
|
|
295
308
|
</div>
|
|
296
309
|
</template>
|
|
@@ -34,6 +34,7 @@ const app = createApp({
|
|
|
34
34
|
detailDrawer: false,
|
|
35
35
|
drawerWidth: 300, // drawer 宽度
|
|
36
36
|
version: "", // version from backend
|
|
37
|
+
showModule: true
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
const showDetail = ref(false);
|
|
@@ -112,6 +113,7 @@ const app = createApp({
|
|
|
112
113
|
show_fields: state.showFields,
|
|
113
114
|
brief: state.brief,
|
|
114
115
|
hide_primitive_route: state.hidePrimitiveRoute,
|
|
116
|
+
show_module: state.showModule,
|
|
115
117
|
};
|
|
116
118
|
const res = await fetch("dot", {
|
|
117
119
|
method: "POST",
|
|
@@ -261,6 +263,11 @@ const app = createApp({
|
|
|
261
263
|
onGenerate();
|
|
262
264
|
}
|
|
263
265
|
|
|
266
|
+
function toggleShowModule(val) {
|
|
267
|
+
state.showModule = val;
|
|
268
|
+
onGenerate()
|
|
269
|
+
}
|
|
270
|
+
|
|
264
271
|
function toggleShowField(field) {
|
|
265
272
|
state.showFields = field;
|
|
266
273
|
onGenerate(false);
|
|
@@ -337,6 +344,7 @@ const app = createApp({
|
|
|
337
344
|
toggleShowField,
|
|
338
345
|
startDragDrawer,
|
|
339
346
|
onFocusChange,
|
|
347
|
+
toggleShowModule
|
|
340
348
|
};
|
|
341
349
|
},
|
|
342
350
|
});
|
|
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.11.1 → fastapi_voyager-0.11.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.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/apple-touch-icon.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/favicon-16x16.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.11.1 → fastapi_voyager-0.11.2}/src/fastapi_voyager/web/icon/favicon-32x32.png
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.11.1 → fastapi_voyager-0.11.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
|
|
File without changes
|
|
File without changes
|