cadwyn 3.15.3a1__py3-none-any.whl → 3.15.4__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.

Potentially problematic release.


This version of cadwyn might be problematic. Click here for more details.

cadwyn/applications.py CHANGED
@@ -1,3 +1,4 @@
1
+ import datetime
1
2
  from collections.abc import Callable, Coroutine, Sequence
2
3
  from datetime import date
3
4
  from logging import getLogger
@@ -24,7 +25,6 @@ from starlette.routing import BaseRoute, Route
24
25
  from starlette.types import Lifespan
25
26
  from typing_extensions import Self, deprecated
26
27
 
27
- from cadwyn._utils import same_definition_as_in
28
28
  from cadwyn.middleware import HeaderVersioningMiddleware, _get_api_version_dependency
29
29
  from cadwyn.route_generation import generate_versioned_routers
30
30
  from cadwyn.routing import _RootHeaderAPIRouter
@@ -81,18 +81,15 @@ class Cadwyn(FastAPI):
81
81
  deprecated: bool | None = None,
82
82
  include_in_schema: bool = True,
83
83
  swagger_ui_parameters: dict[str, Any] | None = None,
84
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
84
+ generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( # noqa: B008
85
85
  generate_unique_id
86
- ), # noqa: B008
86
+ ),
87
87
  separate_input_output_schemas: bool = True,
88
88
  **extra: Any,
89
89
  ) -> None:
90
90
  self.versions = versions
91
91
  # TODO: Remove argument entirely in any major version.
92
- latest_schemas_package = (
93
- extra.pop("latest_schemas_package", None)
94
- or self.versions.head_schemas_package
95
- )
92
+ latest_schemas_package = extra.pop("latest_schemas_package", None) or self.versions.head_schemas_package
96
93
  self.versions.head_schemas_package = latest_schemas_package
97
94
  self._latest_schemas_package = cast(ModuleType, latest_schemas_package)
98
95
 
@@ -148,23 +145,20 @@ class Cadwyn(FastAPI):
148
145
  "responses": responses,
149
146
  "generate_unique_id_function": generate_unique_id_function,
150
147
  }
151
- self.router: _RootHeaderAPIRouter = (
152
- _RootHeaderAPIRouter( # pyright: ignore[reportIncompatibleVariableOverride]
153
- **self._kwargs_to_router,
154
- api_version_header_name=api_version_header_name,
155
- api_version_var=self.versions.api_version_var,
156
- )
148
+ self.router: _RootHeaderAPIRouter = _RootHeaderAPIRouter( # pyright: ignore[reportIncompatibleVariableOverride]
149
+ **self._kwargs_to_router,
150
+ api_version_header_name=api_version_header_name,
151
+ api_version_var=self.versions.api_version_var,
157
152
  )
158
153
 
159
154
  self.docs_url = docs_url
160
155
  self.redoc_url = redoc_url
161
156
  self.openapi_url = openapi_url
162
157
  self.redoc_url = redoc_url
163
- self.swaggers = {}
164
158
 
165
159
  unversioned_router = APIRouter(**self._kwargs_to_router)
166
160
  self._add_openapi_endpoints(unversioned_router)
167
- self.add_unversioned_routers(unversioned_router)
161
+ self.include_router(unversioned_router)
168
162
  self.add_middleware(
169
163
  HeaderVersioningMiddleware,
170
164
  api_version_header_name=self.router.api_version_header_name,
@@ -173,16 +167,12 @@ class Cadwyn(FastAPI):
173
167
  )
174
168
 
175
169
  @property # pragma: no cover
176
- @deprecated(
177
- "It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead"
178
- )
170
+ @deprecated("It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead")
179
171
  def latest_schemas_package(self):
180
172
  return self._latest_schemas_package
181
173
 
182
174
  @latest_schemas_package.setter # pragma: no cover
183
- @deprecated(
184
- "It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead"
185
- )
175
+ @deprecated("It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead")
186
176
  def latest_schemas_package(self, value: ModuleType | None):
187
177
  self._latest_schemas_package = value
188
178
 
@@ -229,57 +219,45 @@ class Cadwyn(FastAPI):
229
219
  for version, router in router_versions.items():
230
220
  self.add_header_versioned_routers(router, header_value=version.isoformat())
231
221
 
232
- def enrich_swagger(self):
233
- """
234
- This method goes through all header-based apps and collect a dict[openapi_version, openapi_json]
235
-
236
- For each route a `X-API-VERSION` header with value is added
237
-
238
- """
239
- unversioned_routes_openapi = get_openapi(
240
- title=self.title,
241
- version=self.version,
242
- openapi_version=self.openapi_version,
243
- description=self.description,
244
- terms_of_service=self.terms_of_service,
245
- contact=self.contact,
246
- license_info=self.license_info,
247
- routes=self.router.unversioned_routes,
248
- tags=self.openapi_tags,
249
- servers=self.servers,
222
+ async def openapi_jsons(self, req: Request) -> JSONResponse:
223
+ raw_version = req.query_params.get("version") or req.headers.get(self.router.api_version_header_name)
224
+ not_found_error = HTTPException(
225
+ status_code=404,
226
+ detail=f"OpenApi file of with version `{raw_version}` not found",
250
227
  )
251
- if unversioned_routes_openapi["paths"]:
252
- self.swaggers["unversioned"] = unversioned_routes_openapi
253
-
254
- for header_value, router in self.router.versioned_routers.items():
255
- header_value_str = header_value.isoformat()
256
- openapi = get_openapi(
228
+ try:
229
+ version = datetime.date.fromisoformat(raw_version) # pyright: ignore[reportArgumentType]
230
+ # TypeError when raw_version is None
231
+ # ValueError when raw_version is of the non-iso format
232
+ except (ValueError, TypeError):
233
+ version = raw_version
234
+
235
+ if version in self.router.versioned_routers:
236
+ routes = self.router.versioned_routers[version].routes
237
+ formatted_version = version.isoformat()
238
+ elif version == "unversioned" and self._there_are_public_unversioned_routes():
239
+ routes = self.router.unversioned_routes
240
+ formatted_version = "unversioned"
241
+ else:
242
+ raise not_found_error
243
+
244
+ return JSONResponse(
245
+ get_openapi(
257
246
  title=self.title,
258
- version=header_value.isoformat(),
247
+ version=formatted_version,
259
248
  openapi_version=self.openapi_version,
260
249
  description=self.description,
261
250
  terms_of_service=self.terms_of_service,
262
251
  contact=self.contact,
263
252
  license_info=self.license_info,
264
- routes=router.routes,
253
+ routes=routes,
265
254
  tags=self.openapi_tags,
266
255
  servers=self.servers,
267
256
  )
268
- # in current implementation we expect header_value to be a date
269
- self.swaggers[header_value_str] = openapi
270
-
271
- async def openapi_jsons(self, req: Request) -> JSONResponse:
272
- version = req.query_params.get("version") or req.headers.get(
273
- self.router.api_version_header_name
274
257
  )
275
- openapi_of_a_version = self.swaggers.get(version)
276
- if not openapi_of_a_version:
277
- raise HTTPException(
278
- status_code=404,
279
- detail=f"OpenApi file of with version `{version}` not found",
280
- )
281
258
 
282
- return JSONResponse(openapi_of_a_version)
259
+ def _there_are_public_unversioned_routes(self):
260
+ return any(isinstance(route, Route) and route.include_in_schema for route in self.router.unversioned_routes)
283
261
 
284
262
  async def swagger_dashboard(self, req: Request) -> Response:
285
263
  version = req.query_params.get("version")
@@ -305,9 +283,7 @@ class Cadwyn(FastAPI):
305
283
  if version:
306
284
  root_path = self._extract_root_path(req)
307
285
  openapi_url = root_path + f"{self.openapi_url}?version={version}"
308
- return get_redoc_html(
309
- openapi_url=openapi_url, title=f"{self.title} - ReDoc"
310
- )
286
+ return get_redoc_html(openapi_url=openapi_url, title=f"{self.title} - ReDoc")
311
287
 
312
288
  return self._render_docs_dashboard(req, docs_url=cast(str, self.redoc_url))
313
289
 
@@ -316,15 +292,12 @@ class Cadwyn(FastAPI):
316
292
 
317
293
  def _render_docs_dashboard(self, req: Request, docs_url: str):
318
294
  base_url = str(req.base_url).rstrip("/")
295
+ table = {version: f"{base_url}{docs_url}?version={version}" for version in self.router.sorted_versions}
296
+ if self._there_are_public_unversioned_routes():
297
+ table |= {"unversioned": f"{base_url}{docs_url}?version=unversioned"}
319
298
  return self._templates.TemplateResponse(
320
299
  "docs.html",
321
- {
322
- "request": req,
323
- "table": {
324
- version: f"{base_url}{docs_url}?version={version}"
325
- for version in sorted(self.swaggers)
326
- },
327
- },
300
+ {"request": req, "table": table},
328
301
  )
329
302
 
330
303
  def add_header_versioned_routers(
@@ -339,126 +312,41 @@ class Cadwyn(FastAPI):
339
312
  except ValueError as e:
340
313
  raise ValueError("header_value should be in ISO 8601 format") from e
341
314
 
315
+ added_routes: list[BaseRoute] = []
342
316
  if header_value_as_dt not in self.router.versioned_routers: # pragma: no branch
343
- self.router.versioned_routers[header_value_as_dt] = APIRouter(
344
- **self._kwargs_to_router
317
+ self.router.versioned_routers[header_value_as_dt] = APIRouter(**self._kwargs_to_router)
318
+
319
+ versioned_router = self.router.versioned_routers[header_value_as_dt]
320
+ if self.openapi_url is not None: # pragma: no branch
321
+ versioned_router.add_route(
322
+ path=self.openapi_url,
323
+ endpoint=self.openapi_jsons,
324
+ include_in_schema=False,
345
325
  )
346
- if self.openapi_url is not None: # pragma: no branch
347
- self.router.versioned_routers[header_value_as_dt].add_route(
348
- path=self.openapi_url,
349
- endpoint=self.openapi_jsons,
350
- include_in_schema=False,
351
- )
326
+ added_routes.append(versioned_router.routes[-1])
352
327
 
353
- version_router = self.router.versioned_routers[header_value_as_dt]
354
- added_routes: list[BaseRoute] = []
355
328
  added_route_count = 0
356
329
  for router in (first_router, *other_routers):
357
330
  self.router.versioned_routers[header_value_as_dt].include_router(
358
331
  router,
359
- dependencies=[
360
- Depends(
361
- _get_api_version_dependency(
362
- self.router.api_version_header_name, header_value
363
- )
364
- )
365
- ],
332
+ dependencies=[Depends(_get_api_version_dependency(self.router.api_version_header_name, header_value))],
366
333
  )
367
334
  added_route_count += len(router.routes)
368
335
 
369
- added_routes = (
370
- version_router.routes[-added_route_count :]
371
- )
336
+ added_routes.extend(versioned_router.routes[-added_route_count:])
372
337
  self.router.routes.extend(added_routes)
373
338
 
374
- self.enrich_swagger()
375
339
  return added_routes
376
340
 
341
+ @deprecated("Use builtin FastAPI methods such as include_router instead")
377
342
  def add_unversioned_routers(self, *routers: APIRouter):
378
343
  for router in routers:
379
- self.router.include_router(router)
380
- self.enrich_swagger()
344
+ self.include_router(router)
381
345
 
382
- @deprecated("Use add add_unversioned_routers instead")
346
+ @deprecated("Use builtin FastAPI methods such as add_api_route instead")
383
347
  def add_unversioned_routes(self, *routes: Route):
384
348
  router = APIRouter(routes=list(routes))
385
349
  self.include_router(router)
386
- self.enrich_swagger()
387
-
388
- @same_definition_as_in(FastAPI.include_router)
389
- def include_router(self, *args: Any, **kwargs: Any):
390
- route = super().include_router(*args, **kwargs)
391
- self.enrich_swagger()
392
- return route
393
-
394
- @same_definition_as_in(FastAPI.post)
395
- def post(self, *args: Any, **kwargs: Any):
396
- route = super().post(*args, **kwargs)
397
- self.enrich_swagger()
398
- return route
399
-
400
- @same_definition_as_in(FastAPI.get)
401
- def get(self, *args: Any, **kwargs: Any):
402
- route = super().get(*args, **kwargs)
403
- self.enrich_swagger()
404
- return route
405
-
406
- @same_definition_as_in(FastAPI.patch)
407
- def patch(self, *args: Any, **kwargs: Any):
408
- route = super().patch(*args, **kwargs)
409
- self.enrich_swagger()
410
- return route
411
-
412
- @same_definition_as_in(FastAPI.delete)
413
- def delete(self, *args: Any, **kwargs: Any):
414
- route = super().delete(*args, **kwargs)
415
- self.enrich_swagger()
416
- return route
417
-
418
- @same_definition_as_in(FastAPI.put)
419
- def put(self, *args: Any, **kwargs: Any):
420
- route = super().put(*args, **kwargs)
421
- self.enrich_swagger()
422
- return route
423
-
424
- @same_definition_as_in(FastAPI.trace)
425
- def trace(self, *args: Any, **kwargs: Any): # pragma: no cover
426
- route = super().trace(*args, **kwargs)
427
- self.enrich_swagger()
428
- return route
429
-
430
- @same_definition_as_in(FastAPI.options)
431
- def options(self, *args: Any, **kwargs: Any):
432
- route = super().options(*args, **kwargs)
433
- self.enrich_swagger()
434
- return route
435
-
436
- @same_definition_as_in(FastAPI.head)
437
- def head(self, *args: Any, **kwargs: Any):
438
- route = super().head(*args, **kwargs)
439
- self.enrich_swagger()
440
- return route
441
-
442
- @same_definition_as_in(FastAPI.add_api_route)
443
- def add_api_route(self, *args: Any, **kwargs: Any):
444
- route = super().add_api_route(*args, **kwargs)
445
- self.enrich_swagger()
446
- return route
447
-
448
- @same_definition_as_in(FastAPI.api_route)
449
- def api_route(self, *args: Any, **kwargs: Any):
450
- route = super().api_route(*args, **kwargs)
451
- self.enrich_swagger()
452
- return route
453
-
454
- @same_definition_as_in(FastAPI.add_api_websocket_route)
455
- def add_api_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
456
- route = super().add_api_websocket_route(*args, **kwargs)
457
- self.enrich_swagger()
458
- return route
459
-
460
- @same_definition_as_in(FastAPI.websocket)
461
- def websocket(self, *args: Any, **kwargs: Any): # pragma: no cover
462
- route = super().websocket(*args, **kwargs)
463
- self.enrich_swagger()
464
- return route
350
+
351
+ @deprecated("It no longer does anything")
352
+ def enrich_swagger(self): ...
cadwyn/routing.py CHANGED
@@ -9,10 +9,15 @@ from typing import Any
9
9
  from fastapi.routing import APIRouter
10
10
  from starlette.datastructures import URL
11
11
  from starlette.responses import RedirectResponse
12
- from starlette.routing import BaseRoute, Match, Route
12
+ from starlette.routing import BaseRoute, Match
13
13
  from starlette.types import Receive, Scope, Send
14
14
 
15
- from .route_generation import InternalRepresentationOf, generate_versioned_routers # pyright: ignore[reportDeprecated]
15
+ from cadwyn._utils import same_definition_as_in
16
+
17
+ from .route_generation import (
18
+ InternalRepresentationOf, # pyright: ignore[reportDeprecated]
19
+ generate_versioned_routers,
20
+ )
16
21
 
17
22
  # TODO: Remove this in a major version. This is only here for backwards compatibility
18
23
  __all__ = ["InternalRepresentationOf", "generate_versioned_routers"]
@@ -46,7 +51,7 @@ class _RootHeaderAPIRouter(APIRouter):
46
51
  self.versioned_routers: dict[date, APIRouter] = {}
47
52
  self.api_version_header_name = api_version_header_name.lower()
48
53
  self.api_version_var = api_version_var
49
- self.unversioned_routes: list[Route] = []
54
+ self.unversioned_routes: list[BaseRoute] = []
50
55
 
51
56
  @cached_property
52
57
  def sorted_versions(self):
@@ -69,13 +74,19 @@ class _RootHeaderAPIRouter(APIRouter):
69
74
  # then the request version is older that the oldest route we have
70
75
  _logger.info(
71
76
  "Request version is older than the oldest version. No route can match this version",
72
- extra={"oldest_version": self.min_routes_version.isoformat(), "request_version": request_version},
77
+ extra={
78
+ "oldest_version": self.min_routes_version.isoformat(),
79
+ "request_version": request_version,
80
+ },
73
81
  )
74
82
  return []
75
83
  version_chosen = self.find_closest_date_but_not_new(request_header_value)
76
84
  _logger.info(
77
85
  "Partial match. The endpoint with a lower version was selected for the API call",
78
- extra={"version_chosen": version_chosen, "request_version": request_version},
86
+ extra={
87
+ "version_chosen": version_chosen,
88
+ "request_version": request_version,
89
+ },
79
90
  )
80
91
  return self.versioned_routers[version_chosen].routes
81
92
 
@@ -102,10 +113,26 @@ class _RootHeaderAPIRouter(APIRouter):
102
113
  routes = self.pick_version(request_header_value=header_value)
103
114
  await self.process_request(scope=scope, receive=receive, send=send, routes=routes)
104
115
 
105
- def add_api_route(self, *args, **kwargs):
116
+ @same_definition_as_in(APIRouter.add_api_route)
117
+ def add_api_route(self, *args: Any, **kwargs: Any):
106
118
  super().add_api_route(*args, **kwargs)
107
119
  self.unversioned_routes.append(self.routes[-1])
108
120
 
121
+ @same_definition_as_in(APIRouter.add_route)
122
+ def add_route(self, *args: Any, **kwargs: Any):
123
+ super().add_route(*args, **kwargs)
124
+ self.unversioned_routes.append(self.routes[-1])
125
+
126
+ @same_definition_as_in(APIRouter.add_api_websocket_route)
127
+ def add_api_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
128
+ super().add_api_websocket_route(*args, **kwargs)
129
+ self.unversioned_routes.append(self.routes[-1])
130
+
131
+ @same_definition_as_in(APIRouter.add_websocket_route)
132
+ def add_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
133
+ super().add_websocket_route(*args, **kwargs)
134
+ self.unversioned_routes.append(self.routes[-1])
135
+
109
136
  async def process_request(self, scope: Scope, receive: Receive, send: Send, routes: Sequence[BaseRoute]) -> None:
110
137
  """
111
138
  its a copy-paste from starlette.routing.Router
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cadwyn
3
- Version: 3.15.3a1
3
+ Version: 3.15.4
4
4
  Summary: Production-ready community-driven modern Stripe-like API versioning in FastAPI
5
5
  Home-page: https://github.com/zmievsa/cadwyn
6
6
  License: MIT
@@ -4,7 +4,7 @@ cadwyn/_asts.py,sha256=OF1qQKPqTbgYhH1tYF-MB8CCU0r6YITZpMFegzmk0Ic,10118
4
4
  cadwyn/_compat.py,sha256=yAPmfGl2vVEYXlNHHPMoa2JkEJCVPjbP_Uz0WOIVOp4,5494
5
5
  cadwyn/_package_utils.py,sha256=trxTYLmppv-10SKhScfyDQJh21rsQGFoLaOtHycKKR0,1443
6
6
  cadwyn/_utils.py,sha256=BFsfZBpdoL5RMAaT1V1cXJVpTZCmwksQ-Le2MTHivGI,4841
7
- cadwyn/applications.py,sha256=nreLcBP8CSc22JLfRWjPP1Ngt4xawTwgl0qTil4d_Hc,17983
7
+ cadwyn/applications.py,sha256=vb6nDJnZGgQcC8a8ei6543DQ6KK-jhVXo31GdUC-3yo,14755
8
8
  cadwyn/codegen/README.md,sha256=hc7AE87LsEsvbh-wX1H10JEWh-8bLHoe-1CkY3h00FI,879
9
9
  cadwyn/codegen/__init__.py,sha256=JgddDjxMTjSfVrMXHwNu1ODgdn2QfPWpccrRKquBV6k,355
10
10
  cadwyn/codegen/_common.py,sha256=FTI4fqpUFGBMACVlPiDMHTWhqwW_-zQNa_4Qh7m-hCA,5877
@@ -20,7 +20,7 @@ cadwyn/main.py,sha256=kt2Vn7TIA4ZnD_xrgz57TOjUk-4zVP8SV8nuTZBEaaU,218
20
20
  cadwyn/middleware.py,sha256=8cuBri_yRkl0goe6G0MLwtL04WGbW9Infah3wy9hUVM,3372
21
21
  cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  cadwyn/route_generation.py,sha256=nn_PWDa2WQOF-z3IOYBfG9K8po0tHm2C_Q0sRJRr5Ck,39843
23
- cadwyn/routing.py,sha256=38-NhKXGQkUlz3zKnfwIIw9QSYz2h2nXEaSMlBkXzoU,6507
23
+ cadwyn/routing.py,sha256=o6IMjxTxARPa5BxFfsXqOP3bVw9Ya6OBAEbUwH9lMVM,7445
24
24
  cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
26
26
  cadwyn/structure/__init__.py,sha256=HjaNd6H4m4Cia42-dCO7A7sLWuVII7oldjaCabhbs_o,697
@@ -31,8 +31,8 @@ cadwyn/structure/enums.py,sha256=iMokxA2QYJ61SzyB-Pmuq3y7KL7-e6TsnjLVUaVZQnw,954
31
31
  cadwyn/structure/modules.py,sha256=1FK-lLm-zOTXEvn-QtyBH38aDRht5PDQiZrOPCsBlM4,1268
32
32
  cadwyn/structure/schemas.py,sha256=0ylArAkUw626VkUOJSulOwJs7CS6lrGBRECEG5HFD4Q,8897
33
33
  cadwyn/structure/versions.py,sha256=PuXYze89tWvLsOOiuAQtYRi-p1ue2FPfBWWR2bl8hLg,37236
34
- cadwyn-3.15.3a1.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
- cadwyn-3.15.3a1.dist-info/METADATA,sha256=aaXSojcoje-vXvK6fGtFVPOJIlDkqjrMWozw2J9md28,4399
36
- cadwyn-3.15.3a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
37
- cadwyn-3.15.3a1.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
- cadwyn-3.15.3a1.dist-info/RECORD,,
34
+ cadwyn-3.15.4.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
+ cadwyn-3.15.4.dist-info/METADATA,sha256=Hp9cctE2SIKT41gA-az7uLKyoeuGZhTe0h2PAYWnMuA,4397
36
+ cadwyn-3.15.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
37
+ cadwyn-3.15.4.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
+ cadwyn-3.15.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 1.8.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any