cadwyn 3.15.10__py3-none-any.whl → 4.1.0__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.

@@ -6,7 +6,6 @@ from .data import (
6
6
  )
7
7
  from .endpoints import endpoint
8
8
  from .enums import enum
9
- from .modules import module
10
9
  from .schemas import schema
11
10
  from .versions import (
12
11
  HeadVersion,
@@ -25,7 +24,6 @@ __all__ = [
25
24
  "endpoint",
26
25
  "schema",
27
26
  "enum",
28
- "module",
29
27
  "convert_response_to_previous_version_for",
30
28
  "convert_request_to_next_version_for",
31
29
  "RequestInfo",
@@ -1,16 +1,13 @@
1
- import ast
2
- import inspect
3
- import textwrap
4
1
  from collections.abc import Callable
5
- from dataclasses import dataclass, field
6
- from typing import TYPE_CHECKING, Any, Literal
2
+ from dataclasses import dataclass
3
+ from typing import TYPE_CHECKING, Any, Literal, cast
7
4
 
5
+ from issubclass import issubclass as lenient_issubclass
8
6
  from pydantic import BaseModel, Field
7
+ from pydantic._internal._decorators import PydanticDescriptorProxy, unwrap_wrapped_function
9
8
  from pydantic.fields import FieldInfo
10
9
 
11
- from cadwyn._asts import _ValidatorWrapper, get_validator_info_or_none
12
- from cadwyn._compat import PYDANTIC_V2
13
- from cadwyn._utils import Sentinel
10
+ from cadwyn._utils import Sentinel, fully_unwrap_decorator
14
11
  from cadwyn.exceptions import CadwynStructureError
15
12
 
16
13
  if TYPE_CHECKING:
@@ -105,7 +102,6 @@ class FieldDidntExistInstruction:
105
102
  class FieldExistedAsInstruction:
106
103
  schema: type[BaseModel]
107
104
  name: str
108
- type: type
109
105
  field: FieldInfo
110
106
 
111
107
 
@@ -148,23 +144,19 @@ class AlterFieldInstructionFactory:
148
144
  discriminator: str = Sentinel,
149
145
  repr: bool = Sentinel,
150
146
  ) -> FieldHadInstruction:
151
- if PYDANTIC_V2:
152
- if regex is not Sentinel:
153
- raise CadwynStructureError("`regex` was removed in Pydantic 2. Use `pattern` instead")
154
- if include is not Sentinel:
155
- raise CadwynStructureError("`include` was removed in Pydantic 2. Use `exclude` instead")
156
- if min_items is not Sentinel:
157
- raise CadwynStructureError("`min_items` was removed in Pydantic 2. Use `min_length` instead")
158
- if max_items is not Sentinel:
159
- raise CadwynStructureError("`max_items` was removed in Pydantic 2. Use `max_length` instead")
160
- if unique_items is not Sentinel:
161
- raise CadwynStructureError(
162
- "`unique_items` was removed in Pydantic 2. Use `Set` type annotation instead"
163
- "(this feature is discussed in https://github.com/pydantic/pydantic-core/issues/296)",
164
- )
165
- else:
166
- if pattern is not Sentinel:
167
- raise CadwynStructureError("`pattern` is only available in Pydantic 2. use `regex` instead")
147
+ if regex is not Sentinel:
148
+ raise CadwynStructureError("`regex` was removed in Pydantic 2. Use `pattern` instead")
149
+ if include is not Sentinel:
150
+ raise CadwynStructureError("`include` was removed in Pydantic 2. Use `exclude` instead")
151
+ if min_items is not Sentinel:
152
+ raise CadwynStructureError("`min_items` was removed in Pydantic 2. Use `min_length` instead")
153
+ if max_items is not Sentinel:
154
+ raise CadwynStructureError("`max_items` was removed in Pydantic 2. Use `max_length` instead")
155
+ if unique_items is not Sentinel:
156
+ raise CadwynStructureError(
157
+ "`unique_items` was removed in Pydantic 2. Use `Set` type annotation instead"
158
+ "(this feature is discussed in https://github.com/pydantic/pydantic-core/issues/296)",
159
+ )
168
160
  return FieldHadInstruction(
169
161
  schema=self.schema,
170
162
  name=self.name,
@@ -219,30 +211,28 @@ class AlterFieldInstructionFactory:
219
211
  type: Any,
220
212
  info: FieldInfo | None = None,
221
213
  ) -> FieldExistedAsInstruction:
222
- return FieldExistedAsInstruction(
223
- self.schema,
224
- name=self.name,
225
- type=type,
226
- field=info or Field(),
227
- )
214
+ if info is None:
215
+ info = cast(FieldInfo, Field())
216
+ info.annotation = type
217
+ return FieldExistedAsInstruction(self.schema, name=self.name, field=info)
218
+
219
+
220
+ def _get_model_decorators(model: type[BaseModel]):
221
+ return [
222
+ *model.__pydantic_decorators__.validators.values(),
223
+ *model.__pydantic_decorators__.field_validators.values(),
224
+ *model.__pydantic_decorators__.root_validators.values(),
225
+ *model.__pydantic_decorators__.field_serializers.values(),
226
+ *model.__pydantic_decorators__.model_serializers.values(),
227
+ *model.__pydantic_decorators__.model_validators.values(),
228
+ *model.__pydantic_decorators__.computed_fields.values(),
229
+ ]
228
230
 
229
231
 
230
232
  @dataclass(slots=True)
231
233
  class ValidatorExistedInstruction:
232
234
  schema: type[BaseModel]
233
- validator: Callable[..., Any]
234
- validator_info: "_ValidatorWrapper" = field(init=False)
235
-
236
- def __post_init__(self):
237
- source = textwrap.dedent(inspect.getsource(self.validator))
238
- validator_ast = ast.parse(source).body[0]
239
- if not isinstance(validator_ast, ast.FunctionDef):
240
- raise CadwynStructureError("The passed validator must be a function")
241
-
242
- validator_info = get_validator_info_or_none(validator_ast)
243
- if validator_info is None:
244
- raise CadwynStructureError("The passed function must be a pydantic validator")
245
- self.validator_info = validator_info
235
+ validator: Callable[..., Any] | PydanticDescriptorProxy
246
236
 
247
237
 
248
238
  @dataclass(slots=True)
@@ -254,7 +244,7 @@ class ValidatorDidntExistInstruction:
254
244
  @dataclass(slots=True)
255
245
  class AlterValidatorInstructionFactory:
256
246
  schema: type[BaseModel]
257
- func: Callable[..., Any]
247
+ func: Callable[..., Any] | PydanticDescriptorProxy
258
248
 
259
249
  @property
260
250
  def existed(self) -> ValidatorExistedInstruction:
@@ -288,9 +278,20 @@ class AlterSchemaInstructionFactory:
288
278
  def field(self, name: str, /) -> AlterFieldInstructionFactory:
289
279
  return AlterFieldInstructionFactory(self.schema, name)
290
280
 
291
- def validator(self, func: "Callable[..., Any] | classmethod[Any, Any, Any]", /) -> AlterValidatorInstructionFactory:
292
- if isinstance(func, classmethod):
293
- func = func.__wrapped__
281
+ def validator(
282
+ self, func: "Callable[..., Any] | classmethod[Any, Any, Any] | PydanticDescriptorProxy", /
283
+ ) -> AlterValidatorInstructionFactory:
284
+ func = cast(Callable | PydanticDescriptorProxy, unwrap_wrapped_function(func))
285
+
286
+ if not isinstance(func, PydanticDescriptorProxy):
287
+ if hasattr(func, "__self__"):
288
+ owner = func.__self__
289
+ if lenient_issubclass(owner, BaseModel) and any( # pragma: no branch
290
+ fully_unwrap_decorator(decorator.func, decorator.shim) == func
291
+ for decorator in _get_model_decorators(owner)
292
+ ):
293
+ return AlterValidatorInstructionFactory(self.schema, func)
294
+ raise CadwynStructureError("The passed function must be a pydantic validator")
294
295
  return AlterValidatorInstructionFactory(self.schema, func)
295
296
 
296
297
  def had(self, *, name: str) -> SchemaHadInstruction:
@@ -2,20 +2,18 @@ import email.message
2
2
  import functools
3
3
  import inspect
4
4
  import json
5
- import warnings
6
5
  from collections import defaultdict
7
6
  from collections.abc import Callable, Iterator, Sequence
8
7
  from contextlib import AsyncExitStack
9
8
  from contextvars import ContextVar
9
+ from datetime import date
10
10
  from enum import Enum
11
- from pathlib import Path
12
- from types import ModuleType
13
- from typing import Any, ClassVar, ParamSpec, TypeAlias, TypeVar, cast, overload
11
+ from typing import Any, ClassVar, ParamSpec, TypeAlias, TypeVar
14
12
 
15
13
  from fastapi import HTTPException, params
16
14
  from fastapi import Request as FastapiRequest
17
15
  from fastapi import Response as FastapiResponse
18
- from fastapi._compat import _normalize_errors
16
+ from fastapi._compat import ModelField, _normalize_errors
19
17
  from fastapi.concurrency import run_in_threadpool
20
18
  from fastapi.dependencies.models import Dependant
21
19
  from fastapi.dependencies.utils import solve_dependencies
@@ -23,18 +21,16 @@ from fastapi.exceptions import RequestValidationError
23
21
  from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
24
22
  from fastapi.routing import APIRoute, _prepare_response_content
25
23
  from pydantic import BaseModel
24
+ from pydantic_core import PydanticUndefined
26
25
  from starlette._utils import is_async_callable
27
- from typing_extensions import assert_never, deprecated
28
-
29
- from cadwyn._compat import PYDANTIC_V2, ModelField, PydanticUndefined, model_dump
30
- from cadwyn._package_utils import (
31
- IdentifierPythonPath,
32
- get_cls_pythonpath,
33
- get_package_path_from_module,
34
- get_version_dir_path,
26
+ from typing_extensions import assert_never
27
+
28
+ from cadwyn._utils import classproperty
29
+ from cadwyn.exceptions import (
30
+ CadwynError,
31
+ CadwynHeadRequestValidationError,
32
+ CadwynStructureError,
35
33
  )
36
- from cadwyn._utils import classproperty, get_another_version_of_cls
37
- from cadwyn.exceptions import CadwynError, CadwynHeadRequestValidationError, CadwynStructureError
38
34
 
39
35
  from .._utils import Sentinel
40
36
  from .common import Endpoint, VersionDate, VersionedModel
@@ -49,7 +45,6 @@ from .data import (
49
45
  )
50
46
  from .endpoints import AlterEndpointSubInstruction
51
47
  from .enums import AlterEnumSubInstruction
52
- from .modules import AlterModuleInstruction
53
48
  from .schemas import AlterSchemaSubInstruction, SchemaHadInstruction
54
49
 
55
50
  _CADWYN_REQUEST_PARAM_NAME = "cadwyn_request_param"
@@ -61,10 +56,10 @@ PossibleInstructions: TypeAlias = (
61
56
  | AlterEndpointSubInstruction
62
57
  | AlterEnumSubInstruction
63
58
  | SchemaHadInstruction
64
- | AlterModuleInstruction
65
59
  | staticmethod
66
60
  )
67
61
  APIVersionVarType: TypeAlias = ContextVar[VersionDate | None] | ContextVar[VersionDate]
62
+ IdentifierPythonPath = str
68
63
 
69
64
 
70
65
  class VersionChange:
@@ -72,7 +67,6 @@ class VersionChange:
72
67
  instructions_to_migrate_to_previous_version: ClassVar[Sequence[PossibleInstructions]] = Sentinel
73
68
  alter_schema_instructions: ClassVar[list[AlterSchemaSubInstruction | SchemaHadInstruction]] = Sentinel
74
69
  alter_enum_instructions: ClassVar[list[AlterEnumSubInstruction]] = Sentinel
75
- alter_module_instructions: ClassVar[list[AlterModuleInstruction]] = Sentinel
76
70
  alter_endpoint_instructions: ClassVar[list[AlterEndpointSubInstruction]] = Sentinel
77
71
  alter_request_by_schema_instructions: ClassVar[dict[type[BaseModel], list[_AlterRequestBySchemaInstruction]]] = (
78
72
  Sentinel
@@ -111,7 +105,6 @@ class VersionChange:
111
105
  def _extract_list_instructions_into_correct_containers(cls):
112
106
  cls.alter_schema_instructions = []
113
107
  cls.alter_enum_instructions = []
114
- cls.alter_module_instructions = []
115
108
  cls.alter_endpoint_instructions = []
116
109
  cls.alter_request_by_schema_instructions = defaultdict(list)
117
110
  cls.alter_request_by_path_instructions = defaultdict(list)
@@ -122,8 +115,6 @@ class VersionChange:
122
115
  cls.alter_schema_instructions.append(alter_instruction)
123
116
  elif isinstance(alter_instruction, AlterEnumSubInstruction):
124
117
  cls.alter_enum_instructions.append(alter_instruction)
125
- elif isinstance(alter_instruction, AlterModuleInstruction):
126
- cls.alter_module_instructions.append(alter_instruction)
127
118
  elif isinstance(alter_instruction, AlterEndpointSubInstruction):
128
119
  cls.alter_endpoint_instructions.append(alter_instruction)
129
120
  elif isinstance(alter_instruction, staticmethod): # pragma: no cover
@@ -207,9 +198,11 @@ class VersionChangeWithSideEffects(VersionChange, _abstract=True):
207
198
 
208
199
 
209
200
  class Version:
210
- def __init__(self, value: VersionDate, *version_changes: type[VersionChange]) -> None:
201
+ def __init__(self, value: VersionDate | str, *version_changes: type[VersionChange]) -> None:
211
202
  super().__init__()
212
203
 
204
+ if isinstance(value, str):
205
+ value = date.fromisoformat(value)
213
206
  self.value = value
214
207
  self.version_changes = version_changes
215
208
 
@@ -236,36 +229,17 @@ class HeadVersion:
236
229
  )
237
230
 
238
231
 
239
- class VersionBundle:
240
- @overload
241
- def __init__(
242
- self,
243
- latest_version_or_head_version: Version | HeadVersion,
244
- /,
245
- *other_versions: Version,
246
- api_version_var: APIVersionVarType | None = None,
247
- head_schemas_package: ModuleType | None = None,
248
- ) -> None: ...
232
+ def get_cls_pythonpath(cls: type) -> IdentifierPythonPath:
233
+ return f"{cls.__module__}.{cls.__name__}"
249
234
 
250
- @overload
251
- @deprecated("Pass head_version_package instead of latest_schemas_package.")
252
- def __init__(
253
- self,
254
- latest_version_or_head_version: Version | HeadVersion,
255
- /,
256
- *other_versions: Version,
257
- api_version_var: APIVersionVarType | None = None,
258
- latest_schemas_package: ModuleType | None = None,
259
- ) -> None: ...
260
235
 
236
+ class VersionBundle:
261
237
  def __init__(
262
238
  self,
263
239
  latest_version_or_head_version: Version | HeadVersion,
264
240
  /,
265
241
  *other_versions: Version,
266
242
  api_version_var: APIVersionVarType | None = None,
267
- head_schemas_package: ModuleType | None = None,
268
- latest_schemas_package: ModuleType | None = None,
269
243
  ) -> None:
270
244
  super().__init__()
271
245
 
@@ -276,7 +250,6 @@ class VersionBundle:
276
250
  self.head_version = HeadVersion()
277
251
  self.versions = (latest_version_or_head_version, *other_versions)
278
252
 
279
- self.head_schemas_package = head_schemas_package or latest_schemas_package
280
253
  self.version_dates = tuple(version.value for version in self.versions)
281
254
  if api_version_var is None:
282
255
  api_version_var = ContextVar("cadwyn_api_version")
@@ -310,39 +283,9 @@ class VersionBundle:
310
283
  )
311
284
  version_change._bound_version_bundle = self
312
285
 
313
- @property # pragma: no cover
314
- @deprecated("Use head_version_package instead.")
315
- def latest_schemas_package(self):
316
- return self.head_schemas_package
317
-
318
286
  def __iter__(self) -> Iterator[Version]:
319
287
  yield from self.versions
320
288
 
321
- def _validate_head_schemas_package_structure(self):
322
- # This entire function won't be necessary once we start raising an exception
323
- # upon receiving `latest`.
324
-
325
- head_schemas_package = cast(ModuleType, self.head_schemas_package)
326
- if not hasattr(head_schemas_package, "__path__"):
327
- raise CadwynStructureError(
328
- f'The head schemas package must be a package. "{head_schemas_package.__name__}" is not a package.',
329
- )
330
- elif head_schemas_package.__name__.endswith(".head") or head_schemas_package.__name__ == "head":
331
- return "head"
332
- elif head_schemas_package.__name__.endswith(".latest"):
333
- warnings.warn(
334
- 'The name of the head schemas module must be "head". '
335
- f'Received "{head_schemas_package.__name__}" instead.',
336
- DeprecationWarning,
337
- stacklevel=4,
338
- )
339
- return "latest"
340
- else:
341
- raise CadwynStructureError(
342
- 'The name of the head schemas module must be "head". '
343
- f'Received "{head_schemas_package.__name__}" instead.',
344
- )
345
-
346
289
  @functools.cached_property
347
290
  def _all_versions(self):
348
291
  return (self.head_version, *self.versions)
@@ -374,56 +317,6 @@ class VersionBundle:
374
317
  for instruction in version_change.alter_enum_instructions
375
318
  }
376
319
 
377
- @functools.cached_property
378
- def versioned_modules(self) -> dict[IdentifierPythonPath, ModuleType]:
379
- return {
380
- # We do this because when users import their modules, they might import
381
- # the __init__.py file directly instead of the package itself
382
- # which results in this extra `.__init__` suffix in the name
383
- instruction.module.__name__.removesuffix(".__init__"): instruction.module
384
- for version in self._all_versions
385
- for version_change in version.version_changes
386
- for instruction in version_change.alter_module_instructions
387
- }
388
-
389
- @functools.cached_property
390
- def versioned_directories_with_head(self) -> tuple[Path, ...]:
391
- if self.head_schemas_package is None:
392
- raise CadwynError(
393
- f"You cannot call 'VersionBundle.{self.migrate_response_body.__name__}' because it has no access to "
394
- "'head_schemas_package'. It likely means that it was not attached "
395
- "to any Cadwyn application which attaches 'head_schemas_package' during initialization."
396
- )
397
- return tuple(
398
- [get_package_path_from_module(self.head_schemas_package)]
399
- + [get_version_dir_path(self.head_schemas_package, version.value) for version in self]
400
- )
401
-
402
- @functools.cached_property
403
- def versioned_directories_without_head(self) -> tuple[Path, ...]:
404
- return self.versioned_directories_with_head[1:]
405
-
406
- def migrate_response_body(self, latest_response_model: type[BaseModel], *, latest_body: Any, version: VersionDate):
407
- """Convert the data to a specific version by applying all version changes from latest until that version
408
- in reverse order and wrapping the result in the correct version of latest_response_model.
409
- """
410
- response = ResponseInfo(FastapiResponse(status_code=200), body=latest_body)
411
- migrated_response = self._migrate_response(
412
- response,
413
- current_version=version,
414
- head_response_model=latest_response_model,
415
- path="\0\0\0",
416
- method="GET",
417
- )
418
-
419
- version = self._get_closest_lesser_version(version)
420
- version_dir = self.versioned_directories_without_head[self.version_dates.index(version)]
421
-
422
- versioned_response_model: type[BaseModel] = get_another_version_of_cls(
423
- latest_response_model, version_dir, self.versioned_directories_with_head
424
- )
425
- return versioned_response_model.parse_obj(migrated_response.body) # pyright: ignore[reportDeprecated]
426
-
427
320
  def _get_closest_lesser_version(self, version: VersionDate):
428
321
  for defined_version in self.version_dates:
429
322
  if defined_version <= version:
@@ -449,8 +342,6 @@ class VersionBundle:
449
342
  current_version: VersionDate,
450
343
  head_route: APIRoute,
451
344
  exit_stack: AsyncExitStack,
452
- *,
453
- embed_body_fields: bool,
454
345
  ) -> dict[str, Any]:
455
346
  method = request.method
456
347
  for v in reversed(self.versions):
@@ -467,20 +358,19 @@ class VersionBundle:
467
358
  request.scope["headers"] = tuple((key.encode(), value.encode()) for key, value in request_info.headers.items())
468
359
  del request._headers
469
360
  # Remember this: if len(body_params) == 1, then route.body_schema == route.dependant.body_params[0]
470
- result = await solve_dependencies(
361
+ dependencies, errors, _, _, _ = await solve_dependencies(
471
362
  request=request,
472
363
  response=response,
473
364
  dependant=head_dependant,
474
365
  body=request_info.body,
475
366
  dependency_overrides_provider=head_route.dependency_overrides_provider,
476
367
  async_exit_stack=exit_stack,
477
- embed_body_fields=embed_body_fields,
478
368
  )
479
- if result.errors:
369
+ if errors:
480
370
  raise CadwynHeadRequestValidationError(
481
- _normalize_errors(result.errors), body=request_info.body, version=current_version
371
+ _normalize_errors(errors), body=request_info.body, version=current_version
482
372
  )
483
- return result.values
373
+ return dependencies
484
374
 
485
375
  def _migrate_response(
486
376
  self,
@@ -580,7 +470,7 @@ class VersionBundle:
580
470
  if response_param_name == _CADWYN_RESPONSE_PARAM_NAME:
581
471
  _add_keyword_only_parameter(decorator, _CADWYN_RESPONSE_PARAM_NAME, FastapiResponse)
582
472
 
583
- return decorator # pyright: ignore[reportReturnType]
473
+ return decorator
584
474
 
585
475
  return wrapper
586
476
 
@@ -740,9 +630,7 @@ class VersionBundle:
740
630
  elif not isinstance(raw_body, BaseModel):
741
631
  body = raw_body
742
632
  else:
743
- body = model_dump(raw_body, by_alias=True, exclude_unset=True)
744
- if not PYDANTIC_V2 and raw_body.__custom_root_type__: # pyright: ignore[reportAttributeAccessIssue]
745
- body = body["__root__"]
633
+ body = raw_body.model_dump(by_alias=True, exclude_unset=True)
746
634
  else:
747
635
  # This is for requests without body or with complex body such as form or file
748
636
  body = await _get_body(request, route.body_field, exit_stack)
@@ -758,7 +646,6 @@ class VersionBundle:
758
646
  api_version,
759
647
  head_route,
760
648
  exit_stack=exit_stack,
761
- embed_body_fields=route._embed_body_fields,
762
649
  )
763
650
  # Because we re-added it into our kwargs when we did solve_dependencies
764
651
  if _CADWYN_REQUEST_PARAM_NAME in new_kwargs:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cadwyn
3
- Version: 3.15.10
3
+ Version: 4.1.0
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
@@ -32,12 +32,11 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
32
32
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
33
  Classifier: Typing :: Typed
34
34
  Provides-Extra: cli
35
- Requires-Dist: better-ast-comments (>=1.2.1,<1.3.0)
36
- Requires-Dist: fastapi (>=0.115.2)
35
+ Requires-Dist: fastapi (>=0.110.0)
37
36
  Requires-Dist: issubclass (>=0.1.2,<0.2.0)
38
37
  Requires-Dist: jinja2 (>=3.1.2)
39
- Requires-Dist: pydantic (>=1.0.0)
40
- Requires-Dist: starlette (>=0.36.3)
38
+ Requires-Dist: pydantic (>=2.0.0)
39
+ Requires-Dist: starlette (>=0.30.0)
41
40
  Requires-Dist: typer (>=0.7.0) ; extra == "cli"
42
41
  Requires-Dist: typing-extensions
43
42
  Project-URL: Documentation, https://docs.cadwyn.dev
@@ -0,0 +1,27 @@
1
+ cadwyn/__init__.py,sha256=tlQpR9prjNPCGM1-BsWksRdTAYPCGbcZpMKYC8Qxyck,990
2
+ cadwyn/__main__.py,sha256=fGoKJPNVueqqXW4rqwmRUBBMoDGeLEyATdT-rel5Pvs,2449
3
+ cadwyn/_asts.py,sha256=kNDXS0Ju0pYZyohAmJNVgJpspwKai5_a9tbekkGehUE,5130
4
+ cadwyn/_importer.py,sha256=2mZrDHlfY2heZsMBW-9RBpvKsCk9I-Wa8pxZ6f2f8gY,1074
5
+ cadwyn/_render.py,sha256=YujZIIn4O5QSF5R_0KLzsHgB_H42m1ZwHNemMvaLdy4,5480
6
+ cadwyn/_utils.py,sha256=GK9w_qzyOI_o6UaGVfwLLYhnJFMzXistoYI9fq2E9dE,1159
7
+ cadwyn/applications.py,sha256=g4VlB3SzQMjfAq5vX8u6DYj2OZei2oGBffSUTVVyaAA,14478
8
+ cadwyn/exceptions.py,sha256=VlJKRmEGfFTDtHbOWc8kXK4yMi2N172K684Y2UIV8rI,1832
9
+ cadwyn/middleware.py,sha256=8cuBri_yRkl0goe6G0MLwtL04WGbW9Infah3wy9hUVM,3372
10
+ cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ cadwyn/route_generation.py,sha256=Y1LF80-gfKnKe3UZA_ovNAFV-IMo1BVS8XDTgei5n80,22959
12
+ cadwyn/routing.py,sha256=9AHSojmuLgUAQlLMIqXz-ViZ9n-fljgOsn7oxha7PjM,7341
13
+ cadwyn/schema_generation.py,sha256=EzLly9Dign0ltZ6sJkiJZFzwdvDZL5ucReuZ7q95xCk,39377
14
+ cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
16
+ cadwyn/structure/__init__.py,sha256=vej7TdTMSOg8U8Wk7GTNdA4rc6loA9083FWaTg4jAaY,655
17
+ cadwyn/structure/common.py,sha256=6Z4nI97XPWTCinn6np73m-rLPyYNrz2fWXKJlqjsiaQ,269
18
+ cadwyn/structure/data.py,sha256=1ALPhBBCE_t4GrxM0Fa3hQ-jkORJgeWNySnZ42bsi0g,7382
19
+ cadwyn/structure/endpoints.py,sha256=JhTgVrqLjm5LkE9thjvU1UuWcSCmDgW2bMdqznsZb2Y,5777
20
+ cadwyn/structure/enums.py,sha256=iMokxA2QYJ61SzyB-Pmuq3y7KL7-e6TsnjLVUaVZQnw,954
21
+ cadwyn/structure/schemas.py,sha256=dfVeVL6R6RjcNeehbd4yPlCYCkpiHi0Ujrwkq4pCvd8,9285
22
+ cadwyn/structure/versions.py,sha256=3SXzQD9Ps3jukF6prhGTABUAik70jd7KebTApY8B3Ns,32190
23
+ cadwyn-4.1.0.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
24
+ cadwyn-4.1.0.dist-info/METADATA,sha256=UgryTNBlff2jHWpeAIU1E6EdKCkisRfRlORKfDaGbSg,4344
25
+ cadwyn-4.1.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
26
+ cadwyn-4.1.0.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
27
+ cadwyn-4.1.0.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