fastapi-voyager 0.11.5__py3-none-any.whl → 0.11.7__py3-none-any.whl

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/server.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import Optional
2
+ from typing import Optional, Literal
3
3
  from fastapi import FastAPI, APIRouter
4
4
  from starlette.middleware.gzip import GZipMiddleware
5
5
  from pydantic import BaseModel
@@ -15,6 +15,7 @@ from fastapi_voyager.version import __version__
15
15
  WEB_DIR = Path(__file__).parent / "web"
16
16
  WEB_DIR.mkdir(exist_ok=True)
17
17
 
18
+ INITIAL_PAGE_POLICY = Literal['first', 'full', 'empty']
18
19
 
19
20
  class OptionParam(BaseModel):
20
21
  tags: list[Tag]
@@ -22,6 +23,7 @@ class OptionParam(BaseModel):
22
23
  dot: str
23
24
  enable_brief_mode: bool
24
25
  version: str
26
+ initial_page_policy: INITIAL_PAGE_POLICY
25
27
  swagger_url: Optional[str] = None
26
28
 
27
29
  class Payload(BaseModel):
@@ -42,6 +44,7 @@ def create_route(
42
44
  swagger_url: Optional[str] = None,
43
45
  module_prefix: Optional[str] = None,
44
46
  online_repo_url: Optional[str] = None,
47
+ initial_page_policy: INITIAL_PAGE_POLICY = 'first',
45
48
  ):
46
49
  """
47
50
  module_color: dict mapping module name to color string, e.g. {'models': 'lightblue'}
@@ -67,7 +70,8 @@ def create_route(
67
70
  dot=dot,
68
71
  enable_brief_mode=bool(module_prefix),
69
72
  version=__version__,
70
- swagger_url=swagger_url)
73
+ swagger_url=swagger_url,
74
+ initial_page_policy=initial_page_policy)
71
75
 
72
76
  @router.post("/dot", response_class=PlainTextResponse)
73
77
  def get_filtered_dot(payload: Payload) -> str:
@@ -213,13 +217,16 @@ def create_voyager(
213
217
  module_prefix: Optional[str] = None,
214
218
  swagger_url: Optional[str] = None,
215
219
  online_repo_url: Optional[str] = None,
220
+ initial_page_policy: INITIAL_PAGE_POLICY = 'first',
216
221
  ) -> FastAPI:
217
222
  router = create_route(
218
223
  target_app,
219
224
  module_color=module_color,
220
225
  module_prefix=module_prefix,
221
226
  swagger_url=swagger_url,
222
- online_repo_url=online_repo_url)
227
+ online_repo_url=online_repo_url,
228
+ initial_page_policy=initial_page_policy,
229
+ )
223
230
 
224
231
  app = FastAPI(title="fastapi-voyager demo server")
225
232
  if gzip_minimum_size is not None and gzip_minimum_size >= 0:
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.11.5"
2
+ __version__ = "0.11.7"
@@ -1,5 +1,6 @@
1
1
  from pydantic import BaseModel
2
2
  from fastapi import FastAPI, routing
3
+ from typing import Callable
3
4
  from fastapi_voyager.type_helper import (
4
5
  get_core_types,
5
6
  full_class_name,
@@ -27,7 +28,8 @@ class Voyager:
27
28
  module_color: dict[str, str] | None = None,
28
29
  route_name: str | None = None,
29
30
  hide_primitive_route: bool = False,
30
- show_module: bool = True
31
+ show_module: bool = True,
32
+ route_name_fn: Callable | None = None
31
33
  ):
32
34
 
33
35
  self.routes: list[Route] = []
@@ -50,6 +52,7 @@ class Voyager:
50
52
  self.route_name = route_name
51
53
  self.hide_primitive_route = hide_primitive_route
52
54
  self.show_module = show_module
55
+ self.route_name_fn = route_name_fn
53
56
 
54
57
 
55
58
  def _get_available_route(self, app: FastAPI):
@@ -123,7 +126,7 @@ class Voyager:
123
126
  id=route_id,
124
127
  name=route_name,
125
128
  module=route_module,
126
- unique_id=route.unique_id,
129
+ unique_id=self.route_name_fn(route) if self.route_name_fn else route.unique_id,
127
130
  response_schema=get_type_name(route.response_model),
128
131
  is_primitive=is_primitive_response
129
132
  )
@@ -59,8 +59,39 @@
59
59
  .adjust-fit {
60
60
  height: calc(100vh - 54px);
61
61
  }
62
+ /* App boot loading overlay & gating */
63
+ #app-loading-overlay {
64
+ position: fixed;
65
+ inset: 0;
66
+ display: none;
67
+ align-items: center;
68
+ justify-content: center;
69
+ gap: 12px;
70
+ background: #ffffff;
71
+ z-index: 9999;
72
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
73
+ color: #009485;
74
+ }
75
+ .loading-text { font-size: 14px; }
76
+ .spinner {
77
+ width: 20px;
78
+ height: 20px;
79
+ border: 2px solid rgba(0, 148, 133, 0.2);
80
+ border-top-color: #009485;
81
+ border-radius: 50%;
82
+ animation: frv-spin 0.8s linear infinite;
83
+ }
84
+ @keyframes frv-spin { to { transform: rotate(360deg); } }
85
+ /* While JS not ready: hide app, show overlay */
86
+ body.app-loading #q-app { visibility: hidden; }
87
+ body.app-loading #app-loading-overlay { display: flex; }
62
88
  </style>
63
- <body>
89
+ <body class="app-loading">
90
+ <!-- App boot loading overlay: shown until JS initializes -->
91
+ <div id="app-loading-overlay" aria-busy="true" aria-live="polite">
92
+ <div class="spinner" aria-hidden="true"></div>
93
+ <div class="loading-text">Loading…</div>
94
+ </div>
64
95
  <div id="q-app">
65
96
  <q-layout view="hHh lpR fff">
66
97
  <q-header bordered class="bg-primary text-white">
@@ -75,7 +106,7 @@
75
106
  </div>
76
107
  <div class="col-auto" style="font-size: 16px">
77
108
  <q-option-group
78
- style="margin-left: 140px"
109
+ style="margin-left: 80px"
79
110
  v-model="state.showFields"
80
111
  :options="state.fieldOptions"
81
112
  @update:model-value="(val) => toggleShowField(val)"
@@ -410,7 +441,8 @@
410
441
  />
411
442
  </q-dialog>
412
443
  </div>
413
-
444
+ <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
445
+ <script src="fastapi-voyager-static/quasar.min.js"></script>
414
446
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" integrity="sha512-egJ/Y+22P9NQ9aIyVCh0VCOsfydyn8eNmqBy+y2CnJG+fpRIxXMS6jbWP8tVKp0jp+NO5n8WtMUAnNnGoJKi4w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
415
447
  <script
416
448
  src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"
@@ -422,15 +454,6 @@
422
454
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-graphviz/5.6.0/d3-graphviz.min.js" integrity="sha512-Le8HpIpS2Tc7SDHLM6AOgAKq6ZR4uDwLhjPSR20DtXE5dFb9xECHRwgpc1nxxnU0Dv+j6FNMoSddky5gyvI3lQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
423
455
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
424
456
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script>
425
-
426
- <!-- Add the following at the end of your body tag -->
427
- <script
428
- src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.22/vue.global.prod.min.js"
429
- integrity="sha512-Y9sKU0AwzWRxKSLd2i35LuDpUdHY/E9tJrKG0mxw0qYQ75VVgGYazIUQPwKhFK9vGO3jIgAtxLiSq8GQ7PDfUg=="
430
- crossorigin="anonymous"
431
- referrerpolicy="no-referrer"
432
- ></script>
433
- <script src="fastapi-voyager-static/quasar.min.js"></script>
434
457
  <script src="fastapi-voyager-static/graphviz.svg.js"></script>
435
458
  <!-- highlight.js minimal ES module load (python only) -->
436
459
  <link
@@ -438,10 +461,18 @@
438
461
  href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css"
439
462
  />
440
463
  <script type="module">
441
- import hljs from "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/highlight.min.js";
442
- import python from "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/languages/python.min.js";
443
- hljs.registerLanguage("python", python);
444
- window.hljs = hljs;
464
+ window.addEventListener('DOMContentLoaded', async () => {
465
+ if (!window.hljs) {
466
+ try {
467
+ const { default: hljs } = await import('https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/highlight.min.js');
468
+ const { default: python } = await import('https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/languages/python.min.js');
469
+ hljs.registerLanguage("python", python);
470
+ window.hljs = hljs;
471
+ } catch (e) {
472
+ console.warn("Failed to preload highlight.js", e);
473
+ }
474
+ }
475
+ });
445
476
  </script>
446
477
  <script type="module" src="fastapi-voyager-static/vue-main.js"></script>
447
478
  </body>
@@ -34,7 +34,7 @@ const app = createApp({
34
34
  detailDrawer: false,
35
35
  drawerWidth: 300, // drawer 宽度
36
36
  version: "", // version from backend
37
- showModule: true
37
+ showModule: true,
38
38
  });
39
39
 
40
40
  const showDetail = ref(false);
@@ -82,6 +82,19 @@ const app = createApp({
82
82
  state.version = data.version || "";
83
83
  state.swaggerUrl = data.swagger_url || null
84
84
 
85
+ switch (data.initial_page_policy) {
86
+ case "full":
87
+ onGenerate()
88
+ return
89
+ case "empty":
90
+ return
91
+ case "first":
92
+ state.tag = state.rawTags.length > 0 ? state.rawTags[0].name : null;
93
+ state._tag = state.tag;
94
+ onGenerate();
95
+ return
96
+ }
97
+
85
98
  // default route options placeholder
86
99
  } catch (e) {
87
100
  console.error("Initial load failed", e);
@@ -226,6 +239,7 @@ const app = createApp({
226
239
 
227
240
  async function onReset() {
228
241
  state.tag = null;
242
+ state._tag = null;
229
243
  state.routeId = "";
230
244
  state.schemaId = null;
231
245
  // state.showFields = "object";
@@ -308,7 +322,9 @@ const app = createApp({
308
322
  }
309
323
 
310
324
  onMounted(async () => {
325
+ document.body.classList.remove("app-loading")
311
326
  await loadInitial();
327
+ // Reveal app content only after initial JS/data is ready
312
328
  });
313
329
 
314
330
  return {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-voyager
3
- Version: 0.11.5
3
+ Version: 0.11.7
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
@@ -183,6 +183,9 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
183
183
  - [ ] animation effect for edges
184
184
  - [ ] customrized right click panel
185
185
  - [ ] show own dependencies
186
+ - [ ] sort field name
187
+ - [ ] set max limit for fields
188
+ - [ ] logging information
186
189
 
187
190
  ### plan:
188
191
  #### <0.9:
@@ -269,10 +272,10 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
269
272
  - [x] optimize open in swagger link
270
273
  - [x] change jquery cdn
271
274
  - 0.11.6
272
- - [ ] flag of loading full graph in first render or not
273
- - [ ] logging information
274
- - [ ] sort field name
275
- - [ ] set max limit for fields
275
+ - [x] flag of loading full graph in first render or not
276
+ - [x] optimize loading static resource
277
+ - 0.11.7
278
+ - [x] fix swagger link
276
279
 
277
280
  #### 0.12
278
281
  - [ ] add tests
@@ -3,18 +3,18 @@ fastapi_voyager/cli.py,sha256=kQb4g6JEGZR99e5r8LyFFEeb_-uT-n_gp_sDoYG3R7k,11118
3
3
  fastapi_voyager/filter.py,sha256=GY2J9Vfsf_wbFwC-0t74-Lf-OlO77PnhEXD_rmgkfSw,11574
4
4
  fastapi_voyager/module.py,sha256=Z2QHNmiLk6ZAJlm2nSmO875Q33TweSg8UxZSzIpU9zY,3499
5
5
  fastapi_voyager/render.py,sha256=vdwqIync2wsP8gMPY0v_XjRhdPBtbKyRT8yTBa_Ep3Y,8744
6
- fastapi_voyager/server.py,sha256=cRTUQik4rvrdZgfkFabCs6LBZnC1FVU4z3lwd1r8GNk,6839
6
+ fastapi_voyager/server.py,sha256=upc38XFWr3UqAxbst-EAqf3_uaA9eS0Q_pzn3gE59jk,7143
7
7
  fastapi_voyager/type.py,sha256=VmcTB1G-LOT70EWCzi4LU_FUkSGWUIBJX15T_J5HnOo,1764
8
8
  fastapi_voyager/type_helper.py,sha256=QqP4c642vEkoWTZAtl_Vvt-kys3MkVDp4BNkLrw5mHQ,9477
9
- fastapi_voyager/version.py,sha256=jjZSCgkES3-8Fj88lWI3Bp418XjCkMi4KhC0Rc564i8,49
10
- fastapi_voyager/voyager.py,sha256=hNal25S5Hi_ZRe-gnmdUKt8tnRd-BRCrzaybAEJ_1HI,13498
9
+ fastapi_voyager/version.py,sha256=FDsWNAszzeAI5uYptGQNcnHKwUJ5yQ8avSPu41kgadI,49
10
+ fastapi_voyager/voyager.py,sha256=Ocj4gKK8S3QMBlJYUmqRzSEKjGLV1lBuNsljEKYLV5M,13673
11
11
  fastapi_voyager/web/graph-ui.js,sha256=DTedkpZNbtufexONVkJ8mOwF_-VnvxoReYHtox6IKR4,5842
12
12
  fastapi_voyager/web/graphviz.svg.css,sha256=zDCjjpT0Idufu5YOiZI76PL70-avP3vTyzGPh9M85Do,1563
13
13
  fastapi_voyager/web/graphviz.svg.js,sha256=lvAdbjHc-lMSk4GQp-iqYA2PCFX4RKnW7dFaoe0LUHs,16005
14
- fastapi_voyager/web/index.html,sha256=ys5zhYNO-smzb1_EgrQ3cWSbhzgMSpk32d1AupX6EP8,18293
14
+ fastapi_voyager/web/index.html,sha256=FJtx1_SiNq7tTMRXMKIx7zMInhEMCusw6VFTYBPtpak,19444
15
15
  fastapi_voyager/web/quasar.min.css,sha256=F5jQe7X2XT54VlvAaa2V3GsBFdVD-vxDZeaPLf6U9CU,203145
16
16
  fastapi_voyager/web/quasar.min.js,sha256=h0ftyPMW_CRiyzeVfQqiup0vrVt4_QWojpqmpnpn07E,502974
17
- fastapi_voyager/web/vue-main.js,sha256=sUjLmn06jYy1guwxAcouHwkcjxGD2UgZgkiiIEDbk04,10663
17
+ fastapi_voyager/web/vue-main.js,sha256=D1H6UhwAlQta73shjZLmQAKbss7X2Y471fjC1H58p9g,11156
18
18
  fastapi_voyager/web/component/render-graph.js,sha256=e8Xgh2Kl-nYU0P1gstEmAepCgFnk2J6UdxW8TlMafGs,2322
19
19
  fastapi_voyager/web/component/route-code-display.js,sha256=8NJPPjNRUC21gjpY8XYEQs4RBbhX1pCiqEhJp39ku6k,3678
20
20
  fastapi_voyager/web/component/schema-code-display.js,sha256=FjoD3CLl967VMfbZNQMdbiEnS0z-doLJDJIeDCmKGew,6983
@@ -26,8 +26,8 @@ fastapi_voyager/web/icon/favicon-16x16.png,sha256=JC07jEzfIYxBIoQn_FHXvyHuxESdhW
26
26
  fastapi_voyager/web/icon/favicon-32x32.png,sha256=C7v1h58cfWOsiLp9yOIZtlx-dLasBcq3NqpHVGRmpt4,1859
27
27
  fastapi_voyager/web/icon/favicon.ico,sha256=tZolYIXkkBcFiYl1A8ksaXN2VjGamzcSdes838dLvNc,15406
28
28
  fastapi_voyager/web/icon/site.webmanifest,sha256=ep4Hzh9zhmiZF2At3Fp1dQrYQuYF_3ZPZxc1KcGBvwQ,263
29
- fastapi_voyager-0.11.5.dist-info/METADATA,sha256=-9xjzPJFY0WqW_SM9AGHLHI6tRrE3sqsy8iiKThQmvM,9712
30
- fastapi_voyager-0.11.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- fastapi_voyager-0.11.5.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
- fastapi_voyager-0.11.5.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
- fastapi_voyager-0.11.5.dist-info/RECORD,,
29
+ fastapi_voyager-0.11.7.dist-info/METADATA,sha256=M0F4nnUPt_wY5cot9IIf_fpFieR80iMDwN8nBmwblfk,9780
30
+ fastapi_voyager-0.11.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
+ fastapi_voyager-0.11.7.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
+ fastapi_voyager-0.11.7.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
+ fastapi_voyager-0.11.7.dist-info/RECORD,,