fastapi-voyager 0.12.10__tar.gz → 0.12.11__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 (58) hide show
  1. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/PKG-INFO +2 -3
  2. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/README.md +1 -2
  3. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/docs/changelog.md +5 -1
  4. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/render.py +1 -1
  5. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/version.py +1 -1
  6. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/graph-ui.js +11 -4
  7. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/index.html +10 -2
  8. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/store.js +6 -0
  9. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/vue-main.js +32 -10
  10. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/programatic.py +2 -2
  11. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  12. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  13. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/.github/workflows/publish.yml +0 -0
  14. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/.gitignore +0 -0
  15. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/.python-version +0 -0
  16. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/CONTRIBUTING.md +0 -0
  17. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/LICENSE +0 -0
  18. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/docs/idea.md +0 -0
  19. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/pyproject.toml +0 -0
  20. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/release.md +0 -0
  21. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/__init__.py +0 -0
  22. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/cli.py +0 -0
  23. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/filter.py +0 -0
  24. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/module.py +0 -0
  25. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/server.py +0 -0
  26. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/type.py +0 -0
  27. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/type_helper.py +0 -0
  28. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/voyager.py +0 -0
  29. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/component/demo.js +0 -0
  30. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/component/render-graph.js +0 -0
  31. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
  32. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
  33. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
  34. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
  35. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
  36. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
  37. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
  38. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
  39. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
  40. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
  41. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
  42. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/quasar.min.css +0 -0
  43. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/src/fastapi_voyager/web/quasar.min.js +0 -0
  44. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/__init__.py +0 -0
  45. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/demo.py +0 -0
  46. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/demo_anno.py +0 -0
  47. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/service/__init__.py +0 -0
  48. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/service/schema/__init__.py +0 -0
  49. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/service/schema/extra.py +0 -0
  50. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/service/schema/schema.py +0 -0
  51. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_analysis.py +0 -0
  52. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_filter.py +0 -0
  53. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_generic.py +0 -0
  54. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_import.py +0 -0
  55. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_module.py +0 -0
  56. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/tests/test_type_helper.py +0 -0
  57. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/uv.lock +0 -0
  58. {fastapi_voyager-0.12.10 → fastapi_voyager-0.12.11}/voyager.jpg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-voyager
3
- Version: 0.12.10
3
+ Version: 0.12.11
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
@@ -31,7 +31,6 @@ Description-Content-Type: text/markdown
31
31
  [![PyPI Downloads](https://static.pepy.tech/badge/fastapi-voyager/month)](https://pepy.tech/projects/fastapi-voyager)
32
32
 
33
33
 
34
-
35
34
  Visualize your FastAPI endpoints, and explore them interactively.
36
35
 
37
36
  > This repo is still in early stage, it supports pydantic v2 only
@@ -49,7 +48,7 @@ app.mount('/voyager',
49
48
  module_color={'src.services': 'tomato'},
50
49
  module_prefix='src.services',
51
50
  swagger_url="/docs",
52
- ga_id="G-R64S7Q49VL",
51
+ ga_id="G-XXXXXXXXVL",
53
52
  initial_page_policy='first',
54
53
  online_repo_url='https://github.com/allmonday/composition-oriented-development-pattern/blob/master'))
55
54
  ```
@@ -3,7 +3,6 @@
3
3
  [![PyPI Downloads](https://static.pepy.tech/badge/fastapi-voyager/month)](https://pepy.tech/projects/fastapi-voyager)
4
4
 
5
5
 
6
-
7
6
  Visualize your FastAPI endpoints, and explore them interactively.
8
7
 
9
8
  > This repo is still in early stage, it supports pydantic v2 only
@@ -21,7 +20,7 @@ app.mount('/voyager',
21
20
  module_color={'src.services': 'tomato'},
22
21
  module_prefix='src.services',
23
22
  swagger_url="/docs",
24
- ga_id="G-R64S7Q49VL",
23
+ ga_id="G-XXXXXXXXVL",
25
24
  initial_page_policy='first',
26
25
  online_repo_url='https://github.com/allmonday/composition-oriented-development-pattern/blob/master'))
27
26
  ```
@@ -128,7 +128,11 @@
128
128
  - 0.12.10
129
129
  - [x] fix: double trigger on reset search
130
130
  - 0.12.11
131
- - [ ] fix: pick tag and then pick route directly from another tag will render nothing
131
+ - [x] better ui for schema select
132
+ - [x] fix: pick tag and then pick route directly from another tag will render nothing
133
+ - [x] feat: cancel search schema triggered by shift click will redirect back to previous tag, route selection
134
+ - [x] optimize the node style
135
+ - 0.12.12
132
136
  - [ ] refactor vue-main.js, move methods to store
133
137
  - [ ] refactor render.py
134
138
 
@@ -57,7 +57,7 @@ class Renderer:
57
57
  header_color = 'tomato' if node.id == self.schema else default_color
58
58
  header = f"""<tr><td cellpadding="6" bgcolor="{header_color}" align="center" colspan="1" port="{PK}"> <font color="white"> {node.name} </font></td> </tr>"""
59
59
  field_content = ''.join(fields_parts) if fields_parts else ''
60
- return f"""<<table border="1" cellborder="0" cellpadding="0" bgcolor="white"> {header} {field_content} </table>>"""
60
+ return f"""<<table border="0" cellborder="1" cellpadding="0" cellspacing="0" bgcolor="white"> {header} {field_content} </table>>"""
61
61
 
62
62
  def _handle_schema_anchor(self, source: str) -> str:
63
63
  if '::' in source:
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.12.10"
2
+ __version__ = "0.12.11"
@@ -91,7 +91,13 @@ export class GraphUI {
91
91
  ready: function () {
92
92
  self.gv = this;
93
93
 
94
- self.gv.nodes().dblclick(function (event) {
94
+ const nodes = self.gv.nodes();
95
+ const edges = self.gv.edges();
96
+
97
+ nodes.off(".graphui");
98
+ edges.off(".graphui");
99
+
100
+ nodes.on("dblclick.graphui", function (event) {
95
101
  event.stopPropagation();
96
102
  try {
97
103
  self.highlightSchemaBanner(this)
@@ -110,7 +116,7 @@ export class GraphUI {
110
116
  }
111
117
  });
112
118
 
113
- self.gv.edges().click(function (event) {
119
+ edges.on("click.graphui", function (event) {
114
120
  const up = $();
115
121
  const down = $();
116
122
  const edge = $();
@@ -127,13 +133,14 @@ export class GraphUI {
127
133
  self._highlightEdgeNodes();
128
134
  })
129
135
 
130
- self.gv.nodes().click(function (event) {
136
+ nodes.on("click.graphui", function (event) {
131
137
  const set = $();
132
138
  set.push(this);
133
139
  const obj = { set, direction: "bidirectional" };
134
140
 
135
141
  const schemaName = event.currentTarget.dataset.name;
136
- if (event.shiftKey && self.options.onSchemaClick) {
142
+ console.log("shift click detected");
143
+ if (event.shiftKey && self.options.onSchemaShiftClick) {
137
144
  if (schemaName) {
138
145
  try {
139
146
  self.options.onSchemaShiftClick(schemaName);
@@ -158,7 +158,16 @@
158
158
  @update:model-value="onSearchSchemaChange"
159
159
  @filter="filterSearchSchemas"
160
160
  @clear="resetSearch"
161
- ></q-select>
161
+ >
162
+ <template v-slot:option="scope">
163
+ <q-item v-bind="scope.itemProps">
164
+ <q-item-section>
165
+ <q-item-label>{{ scope.opt.label }}</q-item-label>
166
+ <q-item-label caption>{{ scope.opt.desc }}</q-item-label>
167
+ </q-item-section>
168
+ </q-item>
169
+ </template>
170
+ </q-select>
162
171
 
163
172
  <q-select
164
173
  dense
@@ -272,7 +281,6 @@
272
281
  expand-separator
273
282
  :model-value="store.state.leftPanel._tag === tag.name || store.state.search.mode"
274
283
  @update:model-value="(val) => toggleTag(tag.name, val)"
275
- @click="() => toggleTag(tag.name, true)"
276
284
  :header-class="store.state.leftPanel.tag === tag.name ? 'text-primary text-bold tag-bg' : 'tag-bg'"
277
285
  content-class="q-pa-none"
278
286
  >
@@ -9,6 +9,12 @@ const state = reactive({
9
9
  config: {
10
10
  initial_page_policy: 'first'
11
11
  },
12
+
13
+ previousTagRoute: { // for shift + click, store previous tag/route, and populate back when needed
14
+ hasValue: false,
15
+ tag: null,
16
+ routeId: null
17
+ },
12
18
 
13
19
  swagger: {
14
20
  url: ''
@@ -12,14 +12,11 @@ const app = createApp({
12
12
  let graphUI = null;
13
13
  const allSchemaOptions = ref([]);
14
14
 
15
- const NBSP = String.fromCharCode(160);
16
- const formatSchemaLabel = (name, id) =>
17
- `${name}${NBSP}${NBSP}${NBSP}-${NBSP}${NBSP}${NBSP}${id}`;
18
-
19
15
  function rebuildSchemaOptions() {
20
16
  const dict = store.state.graph.schemaMap || {};
21
17
  const opts = Object.values(dict).map((s) => ({
22
- label: formatSchemaLabel(s.name, s.id),
18
+ label: s.name,
19
+ desc: s.id,
23
20
  value: s.id,
24
21
  }));
25
22
  allSchemaOptions.value = opts;
@@ -136,9 +133,19 @@ const app = createApp({
136
133
 
137
134
  async function resetSearch() {
138
135
  store.state.search.mode = false;
139
- store.state.leftPanel.tag = null;
140
- store.state.leftPanel._tag = null;
141
- store.state.leftPanel.routeId = null;
136
+ console.log(store.state.previousTagRoute.hasValue)
137
+ console.log(store.state.previousTagRoute)
138
+ if (store.state.previousTagRoute.hasValue) {
139
+ store.state.leftPanel.tag = store.state.previousTagRoute.tag;
140
+ store.state.leftPanel._tag = store.state.previousTagRoute.tag;
141
+ store.state.leftPanel.routeId = store.state.previousTagRoute.routeId;
142
+ store.state.previousTagRoute.hasValue = false;
143
+ } else {
144
+ store.state.leftPanel.tag = null;
145
+ store.state.leftPanel._tag = null;
146
+ store.state.leftPanel.routeId = null;
147
+ }
148
+
142
149
  syncSelectionToUrl()
143
150
  await loadSearchedTags();
144
151
  renderBasedOnInitialPolicy()
@@ -274,12 +281,19 @@ const app = createApp({
274
281
  graphUI = new GraphUI("#graph", {
275
282
  onSchemaShiftClick: (id) => {
276
283
  if (store.state.graph.schemaKeys.has(id)) {
284
+
285
+ console.log(store.state.leftPanel)
286
+ store.state.previousTagRoute.tag = store.state.leftPanel.tag;
287
+ store.state.previousTagRoute.routeId = store.state.leftPanel.routeId;
288
+ store.state.previousTagRoute.hasValue = true;
289
+
277
290
  store.state.search.mode = true;
278
291
  store.state.search.schemaName = id;
279
292
  onSearch();
280
293
  }
281
294
  },
282
295
  onSchemaClick: (id) => {
296
+ console.log("schema clicked:", id);
283
297
  resetDetailPanels();
284
298
  if (store.state.graph.schemaKeys.has(id)) {
285
299
  store.state.schemaDetail.schemaCodeName = id;
@@ -318,7 +332,7 @@ const app = createApp({
318
332
  }
319
333
 
320
334
  function toggleTag(tagName, expanded = null) {
321
- if (expanded === true) {
335
+ if (expanded === true || store.state.search.mode === true) {
322
336
  store.state.leftPanel._tag = tagName;
323
337
  store.state.leftPanel.tag = tagName;
324
338
  store.state.leftPanel.routeId = "";
@@ -335,16 +349,24 @@ const app = createApp({
335
349
  }
336
350
 
337
351
  function selectRoute(routeId) {
352
+ // find belonging tag
353
+ const belongingTag = findTagByRoute(routeId);
354
+ if (belongingTag) {
355
+ store.state.leftPanel.tag = belongingTag;
356
+ store.state.leftPanel._tag = belongingTag;
357
+ }
358
+
338
359
  if (store.state.leftPanel.routeId === routeId) {
339
360
  store.state.leftPanel.routeId = "";
340
361
  } else {
341
362
  store.state.leftPanel.routeId = routeId;
342
363
  }
364
+
343
365
  store.state.rightDrawer.drawer = false;
344
366
  store.state.routeDetail.show = false;
345
367
  store.state.schemaDetail.schemaCodeName = "";
346
- onGenerate();
347
368
  syncSelectionToUrl();
369
+ onGenerate();
348
370
  }
349
371
 
350
372
  function toggleShowModule(val) {
@@ -1,6 +1,6 @@
1
1
  from fastapi_voyager import create_voyager
2
- from tests.demo_anno import app
3
- # from tests.demo import app
2
+ # from tests.demo_anno import app
3
+ from tests.demo import app
4
4
 
5
5
  app.mount(
6
6
  '/voyager',