fastapi-voyager 0.9.2__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.
Files changed (49) hide show
  1. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/PKG-INFO +11 -2
  2. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/README.md +10 -1
  3. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/version.py +1 -1
  4. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/route-code-display.js +4 -12
  5. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/schema-code-display.js +17 -26
  6. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graph-ui.js +11 -7
  7. fastapi_voyager-0.9.3/src/fastapi_voyager/web/index.html +405 -0
  8. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/vue-main.js +8 -11
  9. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/demo.py +16 -1
  10. fastapi_voyager-0.9.2/src/fastapi_voyager/web/index.html +0 -436
  11. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/.gitignore +0 -0
  12. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/.python-version +0 -0
  13. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/LICENSE +0 -0
  14. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/pyproject.toml +0 -0
  15. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/__init__.py +0 -0
  16. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/cli.py +0 -0
  17. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/filter.py +0 -0
  18. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/module.py +0 -0
  19. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/render.py +0 -0
  20. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/server.py +0 -0
  21. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/type.py +0 -0
  22. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/type_helper.py +0 -0
  23. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/voyager.py +0 -0
  24. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/render-graph.js +0 -0
  25. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/component/schema-field-filter.js +0 -0
  26. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
  27. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
  28. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
  29. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
  30. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
  31. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
  32. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
  33. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
  34. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
  35. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/quasar.min.css +0 -0
  36. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/src/fastapi_voyager/web/quasar.min.js +0 -0
  37. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/__init__.py +0 -0
  38. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/demo_anno.py +0 -0
  39. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/programatic.py +0 -0
  40. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/service/__init__.py +0 -0
  41. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/service/schema.py +0 -0
  42. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_analysis.py +0 -0
  43. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_filter.py +0 -0
  44. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_generic.py +0 -0
  45. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_import.py +0 -0
  46. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_module.py +0 -0
  47. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/tests/test_type_helper.py +0 -0
  48. {fastapi_voyager-0.9.2 → fastapi_voyager-0.9.3}/uv.lock +0 -0
  49. {fastapi_voyager-0.9.2 → 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.2
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,6 +27,8 @@ Description-Content-Type: text/markdown
27
27
 
28
28
  [![pypi](https://img.shields.io/pypi/v/fastapi-voyager.svg)](https://pypi.python.org/pypi/fastapi-voyager)
29
29
  ![Python Versions](https://img.shields.io/pypi/pyversions/fastapi-voyager)
30
+ [![PyPI Downloads](https://static.pepy.tech/badge/fastapi-voyager/month)](https://pepy.tech/projects/fastapi-voyager)
31
+
30
32
 
31
33
  > This repo is still in early stage, it supports pydantic v2 only
32
34
 
@@ -163,7 +165,6 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
163
165
  - [ ] user can generate nodes/edges manually and connect to generated ones
164
166
  - [ ] add owner
165
167
  - [ ] add extra info for schema
166
- - [ ] fixed left/right bar show field information
167
168
  - [ ] display standard ER diagram `hard`
168
169
  - [ ] display potential invalid links
169
170
  - [ ] support dataclass (pending)
@@ -211,6 +212,9 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
211
212
  - [x] improve initialization time cost
212
213
  - [x] query route / schema info through realtime api
213
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
214
218
 
215
219
  #### 0.10
216
220
  - [ ] support opening route in swagger
@@ -235,6 +239,9 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
235
239
  - [ ] show hint for resolve, post fields
236
240
  - [ ] display loader as edges
237
241
 
242
+ #### 0.13
243
+ - [ ] config release pipeline
244
+ - [ ]
238
245
 
239
246
  ## Using with pydantic-resolve
240
247
 
@@ -260,6 +267,8 @@ pydantic-resolve's @ensure_subset decorator is helpful to pick fields from `sour
260
267
  ## Changelog
261
268
 
262
269
  - 0.9:
270
+ - 0.9.3:
271
+ - enhancement: better UI
263
272
  - 0.9.2:
264
273
  - fix: missing fields in schema detail panel
265
274
  - optimization: clean up fe codes.
@@ -1,5 +1,7 @@
1
1
  [![pypi](https://img.shields.io/pypi/v/fastapi-voyager.svg)](https://pypi.python.org/pypi/fastapi-voyager)
2
2
  ![Python Versions](https://img.shields.io/pypi/pyversions/fastapi-voyager)
3
+ [![PyPI Downloads](https://static.pepy.tech/badge/fastapi-voyager/month)](https://pepy.tech/projects/fastapi-voyager)
4
+
3
5
 
4
6
  > This repo is still in early stage, it supports pydantic v2 only
5
7
 
@@ -136,7 +138,6 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
136
138
  - [ ] user can generate nodes/edges manually and connect to generated ones
137
139
  - [ ] add owner
138
140
  - [ ] add extra info for schema
139
- - [ ] fixed left/right bar show field information
140
141
  - [ ] display standard ER diagram `hard`
141
142
  - [ ] display potential invalid links
142
143
  - [ ] support dataclass (pending)
@@ -184,6 +185,9 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
184
185
  - [x] improve initialization time cost
185
186
  - [x] query route / schema info through realtime api
186
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
187
191
 
188
192
  #### 0.10
189
193
  - [ ] support opening route in swagger
@@ -208,6 +212,9 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
208
212
  - [ ] show hint for resolve, post fields
209
213
  - [ ] display loader as edges
210
214
 
215
+ #### 0.13
216
+ - [ ] config release pipeline
217
+ - [ ]
211
218
 
212
219
  ## Using with pydantic-resolve
213
220
 
@@ -233,6 +240,8 @@ pydantic-resolve's @ensure_subset decorator is helpful to pick fields from `sour
233
240
  ## Changelog
234
241
 
235
242
  - 0.9:
243
+ - 0.9.3:
244
+ - enhancement: better UI
236
245
  - 0.9.2:
237
246
  - fix: missing fields in schema detail panel
238
247
  - optimization: clean up fe codes.
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.9.2"
2
+ __version__ = "0.9.3"
@@ -3,12 +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
6
  export default defineComponent({
8
7
  name: "RouteCodeDisplay",
9
8
  props: {
10
9
  routeId: { type: String, required: true },
11
- modelValue: { type: Boolean, default: false },
12
10
  },
13
11
  emits: ["close"],
14
12
  setup(props, { emit }) {
@@ -99,32 +97,26 @@ export default defineComponent({
99
97
  }
100
98
  }
101
99
 
102
- watch(
103
- () => props.modelValue,
104
- (v) => {
105
- if (v) load();
106
- }
107
- );
108
100
  watch(
109
101
  () => props.routeId,
110
102
  () => {
111
- if (props.modelValue) load();
103
+ load();
112
104
  }
113
105
  );
114
106
 
115
107
  onMounted(() => {
116
- if (props.modelValue) load();
108
+ load();
117
109
  });
118
110
 
119
111
  return { loading, code, error, close, link };
120
112
  },
121
113
  template: `
122
- <div class="frv-route-code-display" style="border:1px solid #ccc; position:relative; width:50vw; max-width:50vw; height:100%; background:#fff;">
114
+ <div class="frv-route-code-display" style="border:1px solid #ccc; position:relative; background:#fff;">
123
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)" />
124
116
  <div v-if="link" class="q-ml-md q-mt-md" style="padding-top:4px;">
125
117
  <a :href="link" target="_blank" rel="noopener" style="font-size:12px; color:#3b82f6;">Open in VSCode</a>
126
118
  </div>
127
- <div style="padding:40px 16px 16px 16px; height:100%; box-sizing:border-box; overflow:auto;">
119
+ <div style="padding:40px 16px 16px 16px; box-sizing:border-box; overflow:auto;">
128
120
  <div v-if="loading" style="font-family:Menlo, monospace; font-size:12px;">Loading source...</div>
129
121
  <div v-else-if="error" style="color:#c10015; font-family:Menlo, monospace; font-size:12px;">{{ error }}</div>
130
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
- modelValue: { type: Boolean, default: false },
17
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,12 +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
- fields.value = props.schemas[props.schemaName].fields || []
100
+ const schema = props.schemas && props.schemas[props.schemaName];
101
+ fields.value = Array.isArray(schema?.fields) ? schema.fields : [];
106
102
 
107
- if (!error.value && tab.value === "source") {
103
+ if (tab.value === "source") {
108
104
  highlightLater();
109
105
  }
110
106
  }
@@ -120,25 +116,21 @@ export default defineComponent({
120
116
  );
121
117
 
122
118
  watch(
123
- () => props.modelValue,
124
- (val) => {
125
- if (val) {
126
- loadSource();
127
- }
128
- }
119
+ () => props.schemaName,
120
+ () => {
121
+ loadSource();
122
+ },
129
123
  );
130
124
 
131
125
  onMounted(() => {
132
- if (props.modelValue) loadSource();
126
+ loadSource();
133
127
  });
134
128
 
135
- return { loading, link, code, error, close, fields, tab };
129
+ return { link, code, error, fields, tab };
136
130
  },
137
131
  template: `
138
- <div class="frv-code-display" style="border: 1px solid #ccc; border-left: none; position:relative; width:40vw; max-width:40vw; height:100%; background:#fff;">
139
- <q-btn dense flat round icon="close" @click="close" aria-label="Close"
140
- style="position:absolute; top:6px; right:6px; z-index:10; background:rgba(255,255,255,0.85)" />
141
- <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">
142
134
  <a :href="link" target="_blank" rel="noopener" style="font-size:12px; color:#3b82f6;">
143
135
  Open in VSCode
144
136
  </a>
@@ -152,8 +144,7 @@ export default defineComponent({
152
144
  </div>
153
145
  <q-separator />
154
146
  <div style="padding:8px 16px 16px 16px; height:75%; box-sizing:border-box; overflow:auto;">
155
- <div v-if="loading" style="font-family:Menlo, monospace; font-size:12px;">Loading source...</div>
156
- <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>
157
148
  <template v-else>
158
149
  <div v-show="tab === 'source'">
159
150
  <pre style="margin:0;"><code class="language-python">{{ code }}</code></pre>
@@ -69,23 +69,27 @@ export class GraphUI {
69
69
  const set = $();
70
70
  set.push(this);
71
71
  const obj = { set, direction: "bidirectional" };
72
- // Shift+Click to trigger schema detail callback (if provided)
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.onSchemaClick(schemaName);
78
+ self.options.onSchemaShiftClick(schemaName);
79
79
  } catch (e) {
80
- console.warn("onSchemaClick callback failed", e);
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