cadwyn 3.15.3a2__py3-none-any.whl → 3.15.5__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,5 @@
1
+ import dataclasses
2
+ import datetime
1
3
  from collections.abc import Callable, Coroutine, Sequence
2
4
  from datetime import date
3
5
  from logging import getLogger
@@ -24,7 +26,6 @@ from starlette.routing import BaseRoute, Route
24
26
  from starlette.types import Lifespan
25
27
  from typing_extensions import Self, deprecated
26
28
 
27
- from cadwyn._utils import same_definition_as_in
28
29
  from cadwyn.middleware import HeaderVersioningMiddleware, _get_api_version_dependency
29
30
  from cadwyn.route_generation import generate_versioned_routers
30
31
  from cadwyn.routing import _RootHeaderAPIRouter
@@ -34,6 +35,11 @@ CURR_DIR = Path(__file__).resolve()
34
35
  logger = getLogger(__name__)
35
36
 
36
37
 
38
+ @dataclasses.dataclass(slots=True)
39
+ class FakeDependencyOverridesProvider:
40
+ dependency_overrides: dict[Callable[..., Any], Callable[..., Any]]
41
+
42
+
37
43
  class Cadwyn(FastAPI):
38
44
  _templates = Jinja2Templates(directory=CURR_DIR.parent / "static")
39
45
 
@@ -81,20 +87,18 @@ class Cadwyn(FastAPI):
81
87
  deprecated: bool | None = None,
82
88
  include_in_schema: bool = True,
83
89
  swagger_ui_parameters: dict[str, Any] | None = None,
84
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
90
+ generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( # noqa: B008
85
91
  generate_unique_id
86
- ), # noqa: B008
92
+ ),
87
93
  separate_input_output_schemas: bool = True,
88
94
  **extra: Any,
89
95
  ) -> None:
90
96
  self.versions = versions
91
97
  # 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
- )
98
+ latest_schemas_package = extra.pop("latest_schemas_package", None) or self.versions.head_schemas_package
96
99
  self.versions.head_schemas_package = latest_schemas_package
97
100
  self._latest_schemas_package = cast(ModuleType, latest_schemas_package)
101
+ self._dependency_overrides_provider = FakeDependencyOverridesProvider({})
98
102
 
99
103
  super().__init__(
100
104
  debug=debug,
@@ -148,23 +152,20 @@ class Cadwyn(FastAPI):
148
152
  "responses": responses,
149
153
  "generate_unique_id_function": generate_unique_id_function,
150
154
  }
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
- )
155
+ self.router: _RootHeaderAPIRouter = _RootHeaderAPIRouter( # pyright: ignore[reportIncompatibleVariableOverride]
156
+ **self._kwargs_to_router,
157
+ api_version_header_name=api_version_header_name,
158
+ api_version_var=self.versions.api_version_var,
157
159
  )
158
160
 
159
161
  self.docs_url = docs_url
160
162
  self.redoc_url = redoc_url
161
163
  self.openapi_url = openapi_url
162
164
  self.redoc_url = redoc_url
163
- self.swaggers = {}
164
165
 
165
166
  unversioned_router = APIRouter(**self._kwargs_to_router)
166
167
  self._add_openapi_endpoints(unversioned_router)
167
- self.add_unversioned_routers(unversioned_router)
168
+ self.include_router(unversioned_router)
168
169
  self.add_middleware(
169
170
  HeaderVersioningMiddleware,
170
171
  api_version_header_name=self.router.api_version_header_name,
@@ -172,17 +173,27 @@ class Cadwyn(FastAPI):
172
173
  default_response_class=default_response_class,
173
174
  )
174
175
 
176
+ @property
177
+ def dependency_overrides(self) -> dict[Callable[..., Any], Callable[..., Any]]:
178
+ # This is only necessary because we cannot send self to versioned router generator
179
+ # because it takes a deepcopy of the router and self.versions.head_schemas_package is a module
180
+ # which cannot be copied.
181
+ return self._dependency_overrides_provider.dependency_overrides
182
+
183
+ @dependency_overrides.setter
184
+ def dependency_overrides( # pyright: ignore[reportIncompatibleVariableOverride]
185
+ self,
186
+ value: dict[Callable[..., Any], Callable[..., Any]],
187
+ ) -> None:
188
+ self._dependency_overrides_provider.dependency_overrides = value
189
+
175
190
  @property # pragma: no cover
176
- @deprecated(
177
- "It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead"
178
- )
191
+ @deprecated("It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead")
179
192
  def latest_schemas_package(self):
180
193
  return self._latest_schemas_package
181
194
 
182
195
  @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
- )
196
+ @deprecated("It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead")
186
197
  def latest_schemas_package(self, value: ModuleType | None):
187
198
  self._latest_schemas_package = value
188
199
 
@@ -219,7 +230,7 @@ class Cadwyn(FastAPI):
219
230
  )
220
231
 
221
232
  def generate_and_include_versioned_routers(self, *routers: APIRouter) -> None:
222
- root_router = APIRouter()
233
+ root_router = APIRouter(dependency_overrides_provider=self._dependency_overrides_provider)
223
234
  for router in routers:
224
235
  root_router.include_router(router)
225
236
  router_versions = generate_versioned_routers(
@@ -229,57 +240,45 @@ class Cadwyn(FastAPI):
229
240
  for version, router in router_versions.items():
230
241
  self.add_header_versioned_routers(router, header_value=version.isoformat())
231
242
 
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,
243
+ async def openapi_jsons(self, req: Request) -> JSONResponse:
244
+ raw_version = req.query_params.get("version") or req.headers.get(self.router.api_version_header_name)
245
+ not_found_error = HTTPException(
246
+ status_code=404,
247
+ detail=f"OpenApi file of with version `{raw_version}` not found",
250
248
  )
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(
249
+ try:
250
+ version = datetime.date.fromisoformat(raw_version) # pyright: ignore[reportArgumentType]
251
+ # TypeError when raw_version is None
252
+ # ValueError when raw_version is of the non-iso format
253
+ except (ValueError, TypeError):
254
+ version = raw_version
255
+
256
+ if version in self.router.versioned_routers:
257
+ routes = self.router.versioned_routers[version].routes
258
+ formatted_version = version.isoformat()
259
+ elif version == "unversioned" and self._there_are_public_unversioned_routes():
260
+ routes = self.router.unversioned_routes
261
+ formatted_version = "unversioned"
262
+ else:
263
+ raise not_found_error
264
+
265
+ return JSONResponse(
266
+ get_openapi(
257
267
  title=self.title,
258
- version=header_value.isoformat(),
268
+ version=formatted_version,
259
269
  openapi_version=self.openapi_version,
260
270
  description=self.description,
261
271
  terms_of_service=self.terms_of_service,
262
272
  contact=self.contact,
263
273
  license_info=self.license_info,
264
- routes=router.routes,
274
+ routes=routes,
265
275
  tags=self.openapi_tags,
266
276
  servers=self.servers,
267
277
  )
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
278
  )
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
279
 
282
- return JSONResponse(openapi_of_a_version)
280
+ def _there_are_public_unversioned_routes(self):
281
+ return any(isinstance(route, Route) and route.include_in_schema for route in self.router.unversioned_routes)
283
282
 
284
283
  async def swagger_dashboard(self, req: Request) -> Response:
285
284
  version = req.query_params.get("version")
@@ -305,9 +304,7 @@ class Cadwyn(FastAPI):
305
304
  if version:
306
305
  root_path = self._extract_root_path(req)
307
306
  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
- )
307
+ return get_redoc_html(openapi_url=openapi_url, title=f"{self.title} - ReDoc")
311
308
 
312
309
  return self._render_docs_dashboard(req, docs_url=cast(str, self.redoc_url))
313
310
 
@@ -316,15 +313,12 @@ class Cadwyn(FastAPI):
316
313
 
317
314
  def _render_docs_dashboard(self, req: Request, docs_url: str):
318
315
  base_url = str(req.base_url).rstrip("/")
316
+ table = {version: f"{base_url}{docs_url}?version={version}" for version in self.router.sorted_versions}
317
+ if self._there_are_public_unversioned_routes():
318
+ table |= {"unversioned": f"{base_url}{docs_url}?version=unversioned"}
319
319
  return self._templates.TemplateResponse(
320
320
  "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
- },
321
+ {"request": req, "table": table},
328
322
  )
329
323
 
330
324
  def add_header_versioned_routers(
@@ -339,126 +333,41 @@ class Cadwyn(FastAPI):
339
333
  except ValueError as e:
340
334
  raise ValueError("header_value should be in ISO 8601 format") from e
341
335
 
336
+ added_routes: list[BaseRoute] = []
342
337
  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
338
+ self.router.versioned_routers[header_value_as_dt] = APIRouter(**self._kwargs_to_router)
339
+
340
+ versioned_router = self.router.versioned_routers[header_value_as_dt]
341
+ if self.openapi_url is not None: # pragma: no branch
342
+ versioned_router.add_route(
343
+ path=self.openapi_url,
344
+ endpoint=self.openapi_jsons,
345
+ include_in_schema=False,
345
346
  )
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
- )
347
+ added_routes.append(versioned_router.routes[-1])
352
348
 
353
- version_router = self.router.versioned_routers[header_value_as_dt]
354
- added_routes: list[BaseRoute] = []
355
349
  added_route_count = 0
356
350
  for router in (first_router, *other_routers):
357
351
  self.router.versioned_routers[header_value_as_dt].include_router(
358
352
  router,
359
- dependencies=[
360
- Depends(
361
- _get_api_version_dependency(
362
- self.router.api_version_header_name, header_value
363
- )
364
- )
365
- ],
353
+ dependencies=[Depends(_get_api_version_dependency(self.router.api_version_header_name, header_value))],
366
354
  )
367
355
  added_route_count += len(router.routes)
368
356
 
369
- added_routes = (
370
- version_router.routes[-added_route_count :]
371
- )
357
+ added_routes.extend(versioned_router.routes[-added_route_count:])
372
358
  self.router.routes.extend(added_routes)
373
359
 
374
- self.enrich_swagger()
375
360
  return added_routes
376
361
 
362
+ @deprecated("Use builtin FastAPI methods such as include_router instead")
377
363
  def add_unversioned_routers(self, *routers: APIRouter):
378
364
  for router in routers:
379
- self.router.include_router(router)
380
- self.enrich_swagger()
365
+ self.include_router(router)
381
366
 
382
- @deprecated("Use add add_unversioned_routers instead")
367
+ @deprecated("Use builtin FastAPI methods such as add_api_route instead")
383
368
  def add_unversioned_routes(self, *routes: Route):
384
369
  router = APIRouter(routes=list(routes))
385
370
  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
371
+
372
+ @deprecated("It no longer does anything")
373
+ 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,19 +113,23 @@ 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
 
109
- def add_route(self, *args, **kwargs):
121
+ @same_definition_as_in(APIRouter.add_route)
122
+ def add_route(self, *args: Any, **kwargs: Any):
110
123
  super().add_route(*args, **kwargs)
111
124
  self.unversioned_routes.append(self.routes[-1])
112
125
 
113
- def add_api_websocket_route(self, *args, **kwargs):
126
+ @same_definition_as_in(APIRouter.add_api_websocket_route)
127
+ def add_api_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
114
128
  super().add_api_websocket_route(*args, **kwargs)
115
129
  self.unversioned_routes.append(self.routes[-1])
116
130
 
117
- def add_websocket_route(self, *args, **kwargs):
131
+ @same_definition_as_in(APIRouter.add_websocket_route)
132
+ def add_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
118
133
  super().add_websocket_route(*args, **kwargs)
119
134
  self.unversioned_routes.append(self.routes[-1])
120
135
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cadwyn
3
- Version: 3.15.3a2
3
+ Version: 3.15.5
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=MkZ_vMs6YfnfuWPUzBjNBmrxtDa97etsV0zcnlv-iS0,15749
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=O61Srr7G_mT6NPJO5fnVVh-FK-MBHSNfaYrCn2vAQZs,6984
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.3a2.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
- cadwyn-3.15.3a2.dist-info/METADATA,sha256=HIo2WiBgNZRUliiEjAjP6b1bMWk6JCWWBOgg2_xMSGE,4399
36
- cadwyn-3.15.3a2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
37
- cadwyn-3.15.3a2.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
- cadwyn-3.15.3a2.dist-info/RECORD,,
34
+ cadwyn-3.15.5.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
+ cadwyn-3.15.5.dist-info/METADATA,sha256=tMGbnU7byw_9yGiPDo-rM0V5gHCKVcVcSRiccCnwJsA,4397
36
+ cadwyn-3.15.5.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
37
+ cadwyn-3.15.5.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
+ cadwyn-3.15.5.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