fastapi-voyager 0.11.1__py3-none-any.whl → 0.11.3__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/render.py CHANGED
@@ -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", dir="back", arrowtail="odot", minlen=3];"""
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, mods: list[ModuleNode]) -> str:
68
- module_color_flag = set(self.module_color.keys())
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
- return '\n'.join(render_module_schema(m) for m in mods)
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 render_module_route(self, mod: ModuleRoute) -> str:
104
- # Inner route nodes, same style as flat route_str
105
- inner_nodes = [
106
- f'''
107
- "{r.id}" [
108
- label = " {r.name} | {r.response_schema} "
109
- margin="0.5,0.1"
110
- shape = "record"
111
- ];''' for r in mod.routes
112
- ]
113
- inner_nodes_str = '\n'.join(inner_nodes)
114
- child_str = '\n'.join(self.render_module_route(m) for m in mod.modules)
115
- return f'''
116
- subgraph cluster_route_module_{mod.fullname.replace('.', '_')} {{
117
- tooltip="{mod.fullname}"
118
- color = "#666"
119
- style="rounded"
120
- label = " {mod.name}"
121
- labeljust = "l"
122
- {inner_nodes_str}
123
- {child_str}
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(module_schemas)
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'''
fastapi_voyager/server.py CHANGED
@@ -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(
@@ -40,6 +41,7 @@ def create_route(
40
41
  module_color: dict[str, str] | None = None,
41
42
  swagger_url: Optional[str] = None,
42
43
  module_prefix: Optional[str] = None,
44
+ online_repo_url: Optional[str] = None,
43
45
  ):
44
46
  """
45
47
  module_color: dict mapping module name to color string, e.g. {'models': 'lightblue'}
@@ -77,6 +79,7 @@ def create_route(
77
79
  module_color=module_color,
78
80
  route_name=payload.route_name,
79
81
  hide_primitive_route=payload.hide_primitive_route,
82
+ show_module=payload.show_module,
80
83
  )
81
84
  voyager.analysis(target_app)
82
85
  if payload.brief:
@@ -181,7 +184,7 @@ def create_route(
181
184
 
182
185
  mod = __import__(module_name, fromlist=[class_name])
183
186
  obj = getattr(mod, class_name)
184
- link = get_vscode_link(obj)
187
+ link = get_vscode_link(obj, online_repo_url=online_repo_url)
185
188
 
186
189
  return JSONResponse(content={"link": link})
187
190
  except ImportError as e:
@@ -209,8 +212,14 @@ def create_voyager(
209
212
  gzip_minimum_size: int | None = 500,
210
213
  module_prefix: Optional[str] = None,
211
214
  swagger_url: Optional[str] = None,
215
+ online_repo_url: Optional[str] = None,
212
216
  ) -> FastAPI:
213
- router = create_route(target_app, module_color=module_color, module_prefix=module_prefix, swagger_url=swagger_url)
217
+ router = create_route(
218
+ target_app,
219
+ module_color=module_color,
220
+ module_prefix=module_prefix,
221
+ swagger_url=swagger_url,
222
+ online_repo_url=online_repo_url)
214
223
 
215
224
  app = FastAPI(title="fastapi-voyager demo server")
216
225
  if gzip_minimum_size is not None and gzip_minimum_size >= 0:
@@ -1,7 +1,7 @@
1
1
  import inspect
2
2
  import os
3
3
  from pydantic import BaseModel
4
- from typing import get_origin, get_args, Union, Annotated, Any, Type, Generic
4
+ from typing import get_origin, get_args, Union, Annotated, Any, Type, Generic, Optional
5
5
  from fastapi_voyager.type import FieldInfo
6
6
  from types import UnionType
7
7
  import pydantic_resolve.constant as const
@@ -182,7 +182,7 @@ def get_pydantic_fields(schema: type[BaseModel], bases_fields: set[str]) -> list
182
182
  return fields
183
183
 
184
184
 
185
- def get_vscode_link(kls):
185
+ def get_vscode_link(kls, online_repo_url: Optional[str] = None) -> str:
186
186
  """Build a VSCode deep link to the class definition.
187
187
 
188
188
  Priority:
@@ -197,6 +197,10 @@ def get_vscode_link(kls):
197
197
  _lines, start_line = inspect.getsourcelines(kls)
198
198
 
199
199
  distro = os.environ.get("WSL_DISTRO_NAME")
200
+ if online_repo_url:
201
+ cwd = os.getcwd()
202
+ relative_path = os.path.relpath(source_file, cwd)
203
+ return f"{online_repo_url}/{relative_path}#L{start_line}"
200
204
  if distro:
201
205
  # Ensure absolute path (it should already be under /) and build remote link
202
206
  return f"vscode://vscode-remote/wsl+{distro}{source_file}:{start_line}"
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.11.1"
2
+ __version__ = "0.11.3"
@@ -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
  });
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-voyager
3
- Version: 0.11.1
3
+ Version: 0.11.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
@@ -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
- Inspect your API interactively!
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,14 @@ 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
- - [ ] enable/disable module cluster (to save space)
271
+ - [x] enable/disable module cluster (to save space)
272
+ - 0.11.3
273
+ - [x] support online repo url
274
+ - 0.11.4
275
+ - [ ] add loading for field detail panel
261
276
  - [ ] logging information
262
277
  - [ ] sort field name
263
278
  - [ ] set max limit for fields
264
- - [ ] add info icon alone with schema node
265
- - [ ] add loading for field detail panel
266
279
 
267
280
  #### 0.12
268
281
  - [ ] add tests
@@ -2,19 +2,19 @@ fastapi_voyager/__init__.py,sha256=tZy0Nkj8kTaMgbvHy-mGxVcFGVX0Km-36dnzsAIG2uk,2
2
2
  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
- fastapi_voyager/render.py,sha256=EtSkQWb3k3g6T6pnDW2GF9BM-NkDkbDjhlsnF0u-IG0,7970
6
- fastapi_voyager/server.py,sha256=UkTeMFduq4Ebt6eNisfPVUiy04XzHmOaZkBuwEk5mus,6617
5
+ fastapi_voyager/render.py,sha256=vdwqIync2wsP8gMPY0v_XjRhdPBtbKyRT8yTBa_Ep3Y,8744
6
+ fastapi_voyager/server.py,sha256=cRTUQik4rvrdZgfkFabCs6LBZnC1FVU4z3lwd1r8GNk,6839
7
7
  fastapi_voyager/type.py,sha256=VmcTB1G-LOT70EWCzi4LU_FUkSGWUIBJX15T_J5HnOo,1764
8
- fastapi_voyager/type_helper.py,sha256=hjBC4E0tgBpQDlYxGg74uK07SXjsrAgictEETJfIpYM,9231
9
- fastapi_voyager/version.py,sha256=mqCYzIn6okf6Z1_ZJPQL0K0ySha6En_onGIReGtmFxM,49
10
- fastapi_voyager/voyager.py,sha256=etSIrqJJQXArxYLp_45wa0kKdqSebYy9TBYbuyK0iC4,13332
8
+ fastapi_voyager/type_helper.py,sha256=QqP4c642vEkoWTZAtl_Vvt-kys3MkVDp4BNkLrw5mHQ,9477
9
+ fastapi_voyager/version.py,sha256=lbhVTyfJZpsKCnUAXtQjVxbGBg1jjoqiyaCQRf2W6hk,49
10
+ fastapi_voyager/voyager.py,sha256=hNal25S5Hi_ZRe-gnmdUKt8tnRd-BRCrzaybAEJ_1HI,13498
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=1WkNQ_xuS-oy4WkRChk53b9mZjATC5XZbIhPZ_pVBJQ,17317
14
+ fastapi_voyager/web/index.html,sha256=9zp6id31DB_cWdAoCkO5NkeHCMTnNaz2VOdJO24__eM,17837
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=ZM1BmFcA9hz6FmP5W-J1xxNE8mE_Rsj-5-dlh43zfcQ,10483
17
+ fastapi_voyager/web/vue-main.js,sha256=sUjLmn06jYy1guwxAcouHwkcjxGD2UgZgkiiIEDbk04,10663
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=UgFotzvqSuhnPXNOr6w_r1fV2_savRiCdokEvferutE,6244
@@ -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.1.dist-info/METADATA,sha256=K47oTptR1SQCs7hgvlhJSX9FeDO0knh-QFtgjjfe8mY,9767
30
- fastapi_voyager-0.11.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- fastapi_voyager-0.11.1.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
- fastapi_voyager-0.11.1.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
- fastapi_voyager-0.11.1.dist-info/RECORD,,
29
+ fastapi_voyager-0.11.3.dist-info/METADATA,sha256=2yD09_89vwgOEDQuiGN48d98XWowh8wTr4rnNNu7mVU,9960
30
+ fastapi_voyager-0.11.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
+ fastapi_voyager-0.11.3.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
+ fastapi_voyager-0.11.3.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
+ fastapi_voyager-0.11.3.dist-info/RECORD,,