fastapi-voyager 0.13.1__tar.gz → 0.13.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.13.1 → fastapi_voyager-0.13.3}/PKG-INFO +64 -27
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/README.md +63 -26
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/docs/changelog.md +5 -1
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/er_diagram.py +10 -4
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/type.py +2 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/type_helper.py +2 -1
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/version.py +1 -1
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/component/schema-code-display.js +2 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/service/schema/schema.py +4 -4
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/.github/workflows/publish.yml +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/.gitignore +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/.python-version +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/CONTRIBUTING.md +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/LICENSE +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/docs/idea.md +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/pyproject.toml +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/release.md +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/__init__.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/render.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/server.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/voyager.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/component/demo.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/graph-ui.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/index.html +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/store.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/vue-main.js +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/__init__.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/demo.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/demo_anno.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/programatic.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/service/schema/__init__.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/service/schema/base_entity.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/service/schema/extra.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_import.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_module.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/tests/test_type_helper.py +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/uv.lock +0 -0
- {fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/voyager.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-voyager
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.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
|
|
@@ -35,11 +35,12 @@ Visualize your FastAPI endpoints, and explore them interactively.
|
|
|
35
35
|
|
|
36
36
|
> This repo is still in early stage, it supports pydantic v2 only
|
|
37
37
|
|
|
38
|
-
[live demo](https://www.newsyeah.fun/voyager/)
|
|
38
|
+
visit [live demo](https://www.newsyeah.fun/voyager/)
|
|
39
|
+
source code:[composition oriented development pattern](https://github.com/allmonday/composition-oriented-development-pattern)
|
|
39
40
|
|
|
40
|
-
<img width="
|
|
41
|
+
<img width="1597" height="933" alt="image" src="https://github.com/user-attachments/assets/020bf5b2-6c69-44bf-ba1f-39389d388d27" />
|
|
41
42
|
|
|
42
|
-
with configuration
|
|
43
|
+
with simple configuration it can be embedded into FastAPI.
|
|
43
44
|
|
|
44
45
|
```python
|
|
45
46
|
app.mount('/voyager',
|
|
@@ -67,6 +68,8 @@ pip install fastapi-voyager
|
|
|
67
68
|
uv add fastapi-voyager
|
|
68
69
|
```
|
|
69
70
|
|
|
71
|
+
run with cli:
|
|
72
|
+
|
|
70
73
|
```shell
|
|
71
74
|
voyager -m path.to.your.app.module --server
|
|
72
75
|
```
|
|
@@ -77,47 +80,81 @@ voyager -m path.to.your.app.module --server
|
|
|
77
80
|
voyager -m path.to.your.app.module --server --app api
|
|
78
81
|
```
|
|
79
82
|
|
|
80
|
-
## Mount into project
|
|
81
|
-
|
|
82
|
-
```python
|
|
83
|
-
from fastapi import FastAPI
|
|
84
|
-
from fastapi_voyager import create_voyager
|
|
85
|
-
from tests.demo import app
|
|
86
|
-
|
|
87
|
-
app.mount('/voyager', create_voyager(
|
|
88
|
-
app,
|
|
89
|
-
module_color={"tests.service": "red"},
|
|
90
|
-
module_prefix="tests.service"),
|
|
91
|
-
swagger_url="/docs")
|
|
92
|
-
```
|
|
93
83
|
|
|
94
84
|
## Features
|
|
95
85
|
|
|
96
86
|
For scenarios of using FastAPI as internal API integration endpoints, `fastapi-voyager` helps to visualize the dependencies.
|
|
97
87
|
|
|
98
|
-
It is also an architecture
|
|
88
|
+
It is also an architecture tool that can identify issues inside implementation, finding out wrong relationships, overfetchs, or anything else.
|
|
89
|
+
|
|
90
|
+
**If the process of building the view model follows the ER model**, the full potential of fastapi-voyager can be realized. It allows for quick identification of APIs that use entities, as well as which entities are used by a specific API
|
|
99
91
|
|
|
100
|
-
|
|
92
|
+
Given ErDiagram defined by pydantic-resolve, application level entity relationship diagram can be visualized too.
|
|
101
93
|
|
|
102
94
|
### highlight nodes and links
|
|
103
95
|
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.
|
|
104
96
|
|
|
105
|
-
|
|
106
97
|
<img width="1100" height="700" alt="image" src="https://github.com/user-attachments/assets/3e0369ea-5fa4-469a-82c1-ed57d407e53d" />
|
|
107
98
|
|
|
108
|
-
### focus on nodes
|
|
109
|
-
|
|
110
|
-
Double click a node, and then toggle focus to hide irrelevant nodes.
|
|
111
|
-
|
|
112
|
-
<img width="1061" height="937" alt="image" src="https://github.com/user-attachments/assets/79709b02-7571-43fc-abc9-17a287a97515" />
|
|
113
|
-
|
|
114
99
|
### view source code
|
|
115
100
|
|
|
116
101
|
double click a node or route to show source code or open file in vscode.
|
|
117
102
|
|
|
118
103
|
<img width="1297" height="940" alt="image" src="https://github.com/user-attachments/assets/c8bb2e7d-b727-42a6-8c9e-64dce297d2d8" />
|
|
119
104
|
|
|
120
|
-
|
|
105
|
+
### quick search
|
|
106
|
+
|
|
107
|
+
seach schemas by name and dispaly it's upstream and downstreams.
|
|
108
|
+
|
|
109
|
+
shift + click can quickly search current one
|
|
110
|
+
|
|
111
|
+
<img width="1587" height="873" alt="image" src="https://github.com/user-attachments/assets/ee4716f3-233d-418f-bc0e-3b214d1498f7" />
|
|
112
|
+
|
|
113
|
+
### display ER diagram
|
|
114
|
+
|
|
115
|
+
ER diagram is a new feature from pydantic-resolve which provide a solid expression for business descritpions.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
diagram = ErDiagram(
|
|
119
|
+
configs=[
|
|
120
|
+
Entity(
|
|
121
|
+
kls=Team,
|
|
122
|
+
relationships=[
|
|
123
|
+
Relationship( field='id', target_kls=list[Sprint], loader=sprint_loader.team_to_sprint_loader),
|
|
124
|
+
Relationship( field='id', target_kls=list[User], loader=user_loader.team_to_user_loader)
|
|
125
|
+
]
|
|
126
|
+
),
|
|
127
|
+
Entity(
|
|
128
|
+
kls=Sprint,
|
|
129
|
+
relationships=[
|
|
130
|
+
Relationship( field='id', target_kls=list[Story], loader=story_loader.sprint_to_story_loader)
|
|
131
|
+
]
|
|
132
|
+
),
|
|
133
|
+
Entity(
|
|
134
|
+
kls=Story,
|
|
135
|
+
relationships=[
|
|
136
|
+
Relationship( field='id', target_kls=list[Task], loader=task_loader.story_to_task_loader),
|
|
137
|
+
Relationship( field='owner_id', target_kls=User, loader=user_loader.user_batch_loader)
|
|
138
|
+
]
|
|
139
|
+
),
|
|
140
|
+
Entity(
|
|
141
|
+
kls=Task,
|
|
142
|
+
relationships=[
|
|
143
|
+
Relationship( field='owner_id', target_kls=User, loader=user_loader.user_batch_loader)
|
|
144
|
+
]
|
|
145
|
+
)
|
|
146
|
+
]
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# display in voyager
|
|
150
|
+
app.mount('/voyager',
|
|
151
|
+
create_voyager(
|
|
152
|
+
app,
|
|
153
|
+
er_diagram=diagram)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
<img width="1276" height="613" alt="image" src="https://github.com/user-attachments/assets/ea0091bb-ee11-4f71-8be3-7129d956c910" />
|
|
157
|
+
|
|
121
158
|
|
|
122
159
|
|
|
123
160
|
## Command Line Usage
|
|
@@ -7,11 +7,12 @@ Visualize your FastAPI endpoints, and explore them interactively.
|
|
|
7
7
|
|
|
8
8
|
> This repo is still in early stage, it supports pydantic v2 only
|
|
9
9
|
|
|
10
|
-
[live demo](https://www.newsyeah.fun/voyager/)
|
|
10
|
+
visit [live demo](https://www.newsyeah.fun/voyager/)
|
|
11
|
+
source code:[composition oriented development pattern](https://github.com/allmonday/composition-oriented-development-pattern)
|
|
11
12
|
|
|
12
|
-
<img width="
|
|
13
|
+
<img width="1597" height="933" alt="image" src="https://github.com/user-attachments/assets/020bf5b2-6c69-44bf-ba1f-39389d388d27" />
|
|
13
14
|
|
|
14
|
-
with configuration
|
|
15
|
+
with simple configuration it can be embedded into FastAPI.
|
|
15
16
|
|
|
16
17
|
```python
|
|
17
18
|
app.mount('/voyager',
|
|
@@ -39,6 +40,8 @@ pip install fastapi-voyager
|
|
|
39
40
|
uv add fastapi-voyager
|
|
40
41
|
```
|
|
41
42
|
|
|
43
|
+
run with cli:
|
|
44
|
+
|
|
42
45
|
```shell
|
|
43
46
|
voyager -m path.to.your.app.module --server
|
|
44
47
|
```
|
|
@@ -49,47 +52,81 @@ voyager -m path.to.your.app.module --server
|
|
|
49
52
|
voyager -m path.to.your.app.module --server --app api
|
|
50
53
|
```
|
|
51
54
|
|
|
52
|
-
## Mount into project
|
|
53
|
-
|
|
54
|
-
```python
|
|
55
|
-
from fastapi import FastAPI
|
|
56
|
-
from fastapi_voyager import create_voyager
|
|
57
|
-
from tests.demo import app
|
|
58
|
-
|
|
59
|
-
app.mount('/voyager', create_voyager(
|
|
60
|
-
app,
|
|
61
|
-
module_color={"tests.service": "red"},
|
|
62
|
-
module_prefix="tests.service"),
|
|
63
|
-
swagger_url="/docs")
|
|
64
|
-
```
|
|
65
55
|
|
|
66
56
|
## Features
|
|
67
57
|
|
|
68
58
|
For scenarios of using FastAPI as internal API integration endpoints, `fastapi-voyager` helps to visualize the dependencies.
|
|
69
59
|
|
|
70
|
-
It is also an architecture
|
|
60
|
+
It is also an architecture tool that can identify issues inside implementation, finding out wrong relationships, overfetchs, or anything else.
|
|
61
|
+
|
|
62
|
+
**If the process of building the view model follows the ER model**, the full potential of fastapi-voyager can be realized. It allows for quick identification of APIs that use entities, as well as which entities are used by a specific API
|
|
71
63
|
|
|
72
|
-
|
|
64
|
+
Given ErDiagram defined by pydantic-resolve, application level entity relationship diagram can be visualized too.
|
|
73
65
|
|
|
74
66
|
### highlight nodes and links
|
|
75
67
|
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.
|
|
76
68
|
|
|
77
|
-
|
|
78
69
|
<img width="1100" height="700" alt="image" src="https://github.com/user-attachments/assets/3e0369ea-5fa4-469a-82c1-ed57d407e53d" />
|
|
79
70
|
|
|
80
|
-
### focus on nodes
|
|
81
|
-
|
|
82
|
-
Double click a node, and then toggle focus to hide irrelevant nodes.
|
|
83
|
-
|
|
84
|
-
<img width="1061" height="937" alt="image" src="https://github.com/user-attachments/assets/79709b02-7571-43fc-abc9-17a287a97515" />
|
|
85
|
-
|
|
86
71
|
### view source code
|
|
87
72
|
|
|
88
73
|
double click a node or route to show source code or open file in vscode.
|
|
89
74
|
|
|
90
75
|
<img width="1297" height="940" alt="image" src="https://github.com/user-attachments/assets/c8bb2e7d-b727-42a6-8c9e-64dce297d2d8" />
|
|
91
76
|
|
|
92
|
-
|
|
77
|
+
### quick search
|
|
78
|
+
|
|
79
|
+
seach schemas by name and dispaly it's upstream and downstreams.
|
|
80
|
+
|
|
81
|
+
shift + click can quickly search current one
|
|
82
|
+
|
|
83
|
+
<img width="1587" height="873" alt="image" src="https://github.com/user-attachments/assets/ee4716f3-233d-418f-bc0e-3b214d1498f7" />
|
|
84
|
+
|
|
85
|
+
### display ER diagram
|
|
86
|
+
|
|
87
|
+
ER diagram is a new feature from pydantic-resolve which provide a solid expression for business descritpions.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
diagram = ErDiagram(
|
|
91
|
+
configs=[
|
|
92
|
+
Entity(
|
|
93
|
+
kls=Team,
|
|
94
|
+
relationships=[
|
|
95
|
+
Relationship( field='id', target_kls=list[Sprint], loader=sprint_loader.team_to_sprint_loader),
|
|
96
|
+
Relationship( field='id', target_kls=list[User], loader=user_loader.team_to_user_loader)
|
|
97
|
+
]
|
|
98
|
+
),
|
|
99
|
+
Entity(
|
|
100
|
+
kls=Sprint,
|
|
101
|
+
relationships=[
|
|
102
|
+
Relationship( field='id', target_kls=list[Story], loader=story_loader.sprint_to_story_loader)
|
|
103
|
+
]
|
|
104
|
+
),
|
|
105
|
+
Entity(
|
|
106
|
+
kls=Story,
|
|
107
|
+
relationships=[
|
|
108
|
+
Relationship( field='id', target_kls=list[Task], loader=task_loader.story_to_task_loader),
|
|
109
|
+
Relationship( field='owner_id', target_kls=User, loader=user_loader.user_batch_loader)
|
|
110
|
+
]
|
|
111
|
+
),
|
|
112
|
+
Entity(
|
|
113
|
+
kls=Task,
|
|
114
|
+
relationships=[
|
|
115
|
+
Relationship( field='owner_id', target_kls=User, loader=user_loader.user_batch_loader)
|
|
116
|
+
]
|
|
117
|
+
)
|
|
118
|
+
]
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# display in voyager
|
|
122
|
+
app.mount('/voyager',
|
|
123
|
+
create_voyager(
|
|
124
|
+
app,
|
|
125
|
+
er_diagram=diagram)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
<img width="1276" height="613" alt="image" src="https://github.com/user-attachments/assets/ea0091bb-ee11-4f71-8be3-7129d956c910" />
|
|
129
|
+
|
|
93
130
|
|
|
94
131
|
|
|
95
132
|
## Command Line Usage
|
|
@@ -141,11 +141,15 @@
|
|
|
141
141
|
- 0.13.1
|
|
142
142
|
- [x] show more details in er diagram
|
|
143
143
|
- 0.13.2
|
|
144
|
+
- [x] show dashed line for link without dataloader
|
|
145
|
+
- 0.13.3
|
|
146
|
+
- [x] show field description
|
|
147
|
+
- 0.13.4
|
|
144
148
|
- [ ] integration with pydantic-resolve
|
|
145
149
|
- [ ] show hint for resolve, post fields
|
|
146
150
|
- [ ] display loader as edges
|
|
147
151
|
- [ ] add tests
|
|
148
|
-
- 0.13.
|
|
152
|
+
- 0.13.5
|
|
149
153
|
- [ ] refactor vue-main.js, move methods to store
|
|
150
154
|
- [ ] refactor render.py
|
|
151
155
|
|
|
@@ -70,7 +70,7 @@ class DiagramRenderer:
|
|
|
70
70
|
def render_link(self, link: Link) -> str:
|
|
71
71
|
h = self._handle_schema_anchor
|
|
72
72
|
if link.type == 'schema':
|
|
73
|
-
return f"""{h(link.source)}:e -> {h(link.target)}:w [style = "
|
|
73
|
+
return f"""{h(link.source)}:e -> {h(link.target)}:w [style = "{link.style}", label = "{link.label}", minlen=3];"""
|
|
74
74
|
else:
|
|
75
75
|
raise ValueError(f'Unknown link type: {link.type}')
|
|
76
76
|
|
|
@@ -154,6 +154,7 @@ class VoyagerErDiagram:
|
|
|
154
154
|
er_diagram: ErDiagram,
|
|
155
155
|
show_fields: FieldType = 'single',
|
|
156
156
|
show_module: bool = False):
|
|
157
|
+
|
|
157
158
|
self.er_diagram = er_diagram
|
|
158
159
|
self.nodes: list[SchemaNode] = []
|
|
159
160
|
self.node_set: dict[str, SchemaNode] = {}
|
|
@@ -186,7 +187,9 @@ class VoyagerErDiagram:
|
|
|
186
187
|
target=self.generate_node_head(full_class_name(anno)),
|
|
187
188
|
target_origin=full_class_name(anno),
|
|
188
189
|
type='schema',
|
|
189
|
-
label=get_type_name(relationship.target_kls)
|
|
190
|
+
label=get_type_name(relationship.target_kls),
|
|
191
|
+
style='solid' if relationship.loader else 'solid, dashed'
|
|
192
|
+
)
|
|
190
193
|
|
|
191
194
|
elif isinstance(relationship, MultipleRelationship):
|
|
192
195
|
for link in relationship.links:
|
|
@@ -197,7 +200,8 @@ class VoyagerErDiagram:
|
|
|
197
200
|
target_origin=full_class_name(anno),
|
|
198
201
|
type='schema',
|
|
199
202
|
biz=link.biz,
|
|
200
|
-
label=f'{get_type_name(relationship.target_kls)} / {link.biz} '
|
|
203
|
+
label=f'{get_type_name(relationship.target_kls)} / {link.biz} ',
|
|
204
|
+
style='solid' if link.loader else 'solid, dashed'
|
|
201
205
|
)
|
|
202
206
|
|
|
203
207
|
def add_to_node_set(self, schema, fk_set: set[str] | None = None) -> str:
|
|
@@ -226,6 +230,7 @@ class VoyagerErDiagram:
|
|
|
226
230
|
target_origin: str,
|
|
227
231
|
type: LinkType,
|
|
228
232
|
label: str,
|
|
233
|
+
style: str,
|
|
229
234
|
biz: str | None = None
|
|
230
235
|
) -> bool:
|
|
231
236
|
"""
|
|
@@ -241,7 +246,8 @@ class VoyagerErDiagram:
|
|
|
241
246
|
target=target,
|
|
242
247
|
target_origin=target_origin,
|
|
243
248
|
type=type,
|
|
244
|
-
label=label
|
|
249
|
+
label=label,
|
|
250
|
+
style=style
|
|
245
251
|
))
|
|
246
252
|
return result
|
|
247
253
|
|
|
@@ -16,6 +16,7 @@ class FieldInfo:
|
|
|
16
16
|
from_base: bool = False
|
|
17
17
|
is_object: bool = False
|
|
18
18
|
is_exclude: bool = False
|
|
19
|
+
desc: str = ''
|
|
19
20
|
|
|
20
21
|
@dataclass
|
|
21
22
|
class Tag(NodeBase):
|
|
@@ -68,6 +69,7 @@ class Link:
|
|
|
68
69
|
target_origin: str
|
|
69
70
|
type: LinkType
|
|
70
71
|
label: str | None = None
|
|
72
|
+
style: str | None = None
|
|
71
73
|
|
|
72
74
|
FieldType = Literal['single', 'object', 'all']
|
|
73
75
|
PK = "PK"
|
|
@@ -182,7 +182,8 @@ def get_pydantic_fields(schema: type[BaseModel], bases_fields: set[str]) -> list
|
|
|
182
182
|
name=k,
|
|
183
183
|
from_base=k in bases_fields,
|
|
184
184
|
type_name=get_type_name(anno),
|
|
185
|
-
is_exclude=bool(v.exclude)
|
|
185
|
+
is_exclude=bool(v.exclude),
|
|
186
|
+
desc=v.description or ''
|
|
186
187
|
))
|
|
187
188
|
return fields
|
|
188
189
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "0.13.
|
|
2
|
+
__version__ = "0.13.3"
|
|
@@ -179,6 +179,7 @@ export default defineComponent({
|
|
|
179
179
|
<tr>
|
|
180
180
|
<th style="text-align:left; border-bottom:1px solid #ddd; padding:4px 6px;">Field</th>
|
|
181
181
|
<th style="text-align:left; border-bottom:1px solid #ddd; padding:4px 6px;">Type</th>
|
|
182
|
+
<th style="text-align:left; border-bottom:1px solid #ddd; padding:4px 6px;">Description</th>
|
|
182
183
|
<th style="text-align:left; border-bottom:1px solid #ddd; padding:4px 6px;">Inherited</th>
|
|
183
184
|
</tr>
|
|
184
185
|
</thead>
|
|
@@ -186,6 +187,7 @@ export default defineComponent({
|
|
|
186
187
|
<tr v-for="f in fields" :key="f.name">
|
|
187
188
|
<td style="padding:4px 6px; border-bottom:1px solid #f0f0f0;">{{ f.name }}</td>
|
|
188
189
|
<td style="padding:4px 6px; border-bottom:1px solid #f0f0f0; white-space:nowrap;">{{ f.type_name }}</td>
|
|
190
|
+
<td style="padding:4px 6px; border-bottom:1px solid #f0f0f0; max-width: 200px;">{{ f.desc }}</td>
|
|
189
191
|
<td style="padding:4px 6px; border-bottom:1px solid #f0f0f0; text-align:left;">{{ f.from_base ? '✔︎' : '' }}</td>
|
|
190
192
|
</tr>
|
|
191
193
|
<tr v-if="!fields.length">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from typing import Literal
|
|
3
|
-
from pydantic import BaseModel
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
4
|
from pydantic_resolve import Relationship, MultipleRelationship, Link
|
|
5
5
|
from .base_entity import BaseEntity
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ class Task(BaseModel, BaseEntity):
|
|
|
16
16
|
Relationship(field='owner_id', target_kls=Member),
|
|
17
17
|
Relationship(field='story_id', target_kls='Story'),
|
|
18
18
|
]
|
|
19
|
-
id: int
|
|
19
|
+
id: int = Field(description="The unique identifier of the task")
|
|
20
20
|
story_id: int
|
|
21
21
|
description: str
|
|
22
22
|
owner_id: int
|
|
@@ -35,8 +35,8 @@ class Story(BaseModel, BaseEntity):
|
|
|
35
35
|
class Sprint(BaseModel, BaseEntity):
|
|
36
36
|
__pydantic_resolve_relationships__ = [
|
|
37
37
|
MultipleRelationship(field='id', target_kls=list[Story], links=[
|
|
38
|
-
Link(biz='all'),
|
|
39
|
-
Link(biz='done'),
|
|
38
|
+
Link(biz='all', loader=lambda x: x),
|
|
39
|
+
Link(biz='done', loader=lambda x: x),
|
|
40
40
|
])
|
|
41
41
|
]
|
|
42
42
|
id: int
|
|
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
|
|
File without changes
|
{fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/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
|
{fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/apple-touch-icon.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/favicon-16x16.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/src/fastapi_voyager/web/icon/favicon-32x32.png
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.13.1 → fastapi_voyager-0.13.3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|