cadwyn 3.12.0__py3-none-any.whl → 3.15.10__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/structure/data.py CHANGED
@@ -8,6 +8,7 @@ from fastapi import Request, Response
8
8
  from starlette.datastructures import MutableHeaders
9
9
 
10
10
  from cadwyn._utils import same_definition_as_in
11
+ from cadwyn.structure.endpoints import _validate_that_strings_are_valid_http_methods
11
12
 
12
13
  _P = ParamSpec("_P")
13
14
 
@@ -96,26 +97,25 @@ class _BaseAlterRequestInstruction(_AlterDataInstruction):
96
97
 
97
98
 
98
99
  @dataclass
99
- class AlterRequestBySchemaInstruction(_BaseAlterRequestInstruction):
100
+ class _AlterRequestBySchemaInstruction(_BaseAlterRequestInstruction):
100
101
  schemas: tuple[Any, ...]
101
102
 
102
103
 
103
104
  @dataclass
104
- class AlterRequestByPathInstruction(_BaseAlterRequestInstruction):
105
+ class _AlterRequestByPathInstruction(_BaseAlterRequestInstruction):
105
106
  path: str
106
107
  methods: set[str]
108
+ repr_name = "Request by path converter"
107
109
 
108
110
 
109
111
  @overload
110
112
  def convert_request_to_next_version_for(
111
113
  first_schema: type, /, *additional_schemas: type
112
- ) -> "type[staticmethod[_P, None]]":
113
- ...
114
+ ) -> "type[staticmethod[_P, None]]": ...
114
115
 
115
116
 
116
117
  @overload
117
- def convert_request_to_next_version_for(path: str, methods: list[str], /) -> "type[staticmethod[_P, None]]":
118
- ...
118
+ def convert_request_to_next_version_for(path: str, methods: list[str], /) -> "type[staticmethod[_P, None]]": ...
119
119
 
120
120
 
121
121
  def convert_request_to_next_version_for(
@@ -128,7 +128,7 @@ def convert_request_to_next_version_for(
128
128
 
129
129
  def decorator(transformer: Callable[[RequestInfo], None]) -> Any:
130
130
  if isinstance(schema_or_path, str):
131
- return AlterRequestByPathInstruction(
131
+ return _AlterRequestByPathInstruction(
132
132
  path=schema_or_path,
133
133
  methods=set(cast(list, methods_or_second_schema)),
134
134
  transformer=transformer,
@@ -138,7 +138,7 @@ def convert_request_to_next_version_for(
138
138
  schemas = (schema_or_path,)
139
139
  else:
140
140
  schemas = (schema_or_path, methods_or_second_schema, *additional_schemas)
141
- return AlterRequestBySchemaInstruction(
141
+ return _AlterRequestBySchemaInstruction(
142
142
  schemas=schemas,
143
143
  transformer=transformer,
144
144
  )
@@ -158,14 +158,15 @@ class _BaseAlterResponseInstruction(_AlterDataInstruction):
158
158
 
159
159
 
160
160
  @dataclass
161
- class AlterResponseBySchemaInstruction(_BaseAlterResponseInstruction):
161
+ class _AlterResponseBySchemaInstruction(_BaseAlterResponseInstruction):
162
162
  schemas: tuple[Any, ...]
163
163
 
164
164
 
165
165
  @dataclass
166
- class AlterResponseByPathInstruction(_BaseAlterResponseInstruction):
166
+ class _AlterResponseByPathInstruction(_BaseAlterResponseInstruction):
167
167
  path: str
168
168
  methods: set[str]
169
+ repr_name = "Response by path converter"
169
170
 
170
171
 
171
172
  @overload
@@ -174,8 +175,7 @@ def convert_response_to_previous_version_for(
174
175
  /,
175
176
  *schemas: type,
176
177
  migrate_http_errors: bool = False,
177
- ) -> "type[staticmethod[_P, None]]":
178
- ...
178
+ ) -> "type[staticmethod[_P, None]]": ...
179
179
 
180
180
 
181
181
  @overload
@@ -185,8 +185,7 @@ def convert_response_to_previous_version_for(
185
185
  /,
186
186
  *,
187
187
  migrate_http_errors: bool = False,
188
- ) -> "type[staticmethod[_P, None]]":
189
- ...
188
+ ) -> "type[staticmethod[_P, None]]": ...
190
189
 
191
190
 
192
191
  def convert_response_to_previous_version_for(
@@ -201,7 +200,7 @@ def convert_response_to_previous_version_for(
201
200
  def decorator(transformer: Callable[[ResponseInfo], None]) -> Any:
202
201
  if isinstance(schema_or_path, str):
203
202
  # The validation above checks that methods is not None
204
- return AlterResponseByPathInstruction(
203
+ return _AlterResponseByPathInstruction(
205
204
  path=schema_or_path,
206
205
  methods=set(cast(list, methods_or_second_schema)),
207
206
  transformer=transformer,
@@ -212,7 +211,7 @@ def convert_response_to_previous_version_for(
212
211
  schemas = (schema_or_path,)
213
212
  else:
214
213
  schemas = (schema_or_path, methods_or_second_schema, *additional_schemas)
215
- return AlterResponseBySchemaInstruction(
214
+ return _AlterResponseBySchemaInstruction(
216
215
  schemas=schemas,
217
216
  transformer=transformer,
218
217
  migrate_http_errors=migrate_http_errors,
@@ -223,10 +222,11 @@ def convert_response_to_previous_version_for(
223
222
 
224
223
  def _validate_decorator_args(
225
224
  schema_or_path: type | str, methods_or_second_schema: list[str] | type | None, additional_schemas: tuple[type, ...]
226
- ):
225
+ ) -> None:
227
226
  if isinstance(schema_or_path, str):
228
227
  if not isinstance(methods_or_second_schema, list):
229
228
  raise TypeError("If path was provided as a first argument, methods must be provided as a second argument")
229
+ _validate_that_strings_are_valid_http_methods(methods_or_second_schema)
230
230
  if additional_schemas:
231
231
  raise TypeError("If path was provided as a first argument, then additional schemas cannot be added")
232
232
 
@@ -1,4 +1,4 @@
1
- from collections.abc import Callable, Sequence
1
+ from collections.abc import Callable, Collection, Sequence
2
2
  from dataclasses import dataclass
3
3
  from enum import Enum
4
4
  from typing import Any
@@ -148,6 +148,12 @@ class EndpointInstructionFactory:
148
148
 
149
149
 
150
150
  def endpoint(path: str, methods: list[str], /, *, func_name: str | None = None) -> EndpointInstructionFactory:
151
+ _validate_that_strings_are_valid_http_methods(methods)
152
+
153
+ return EndpointInstructionFactory(path, set(methods), func_name)
154
+
155
+
156
+ def _validate_that_strings_are_valid_http_methods(methods: Collection[str]):
151
157
  invalid_methods = set(methods) - HTTP_METHODS
152
158
  if invalid_methods:
153
159
  invalid_methods = ", ".join(sorted(invalid_methods))
@@ -156,7 +162,5 @@ def endpoint(path: str, methods: list[str], /, *, func_name: str | None = None)
156
162
  "Please use valid HTTP methods such as GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD.",
157
163
  )
158
164
 
159
- return EndpointInstructionFactory(path, set(methods), func_name)
160
-
161
165
 
162
166
  AlterEndpointSubInstruction = EndpointDidntExistInstruction | EndpointExistedInstruction | EndpointHadInstruction
@@ -1,5 +1,6 @@
1
1
  import ast
2
2
  import dataclasses
3
+ import textwrap
3
4
  from dataclasses import InitVar, dataclass
4
5
  from types import ModuleType
5
6
 
@@ -13,7 +14,7 @@ class AlterModuleInstruction:
13
14
  import_: ast.Import | ast.ImportFrom = dataclasses.field(init=False)
14
15
 
15
16
  def __post_init__(self, raw_import: str):
16
- parsed_body = ast.parse(raw_import).body
17
+ parsed_body = ast.parse(textwrap.dedent(raw_import)).body
17
18
  if len(parsed_body) > 1:
18
19
  raise CadwynStructureError(
19
20
  f"You have specified more than just a single import. This is prohibited. "
@@ -20,7 +20,7 @@ from fastapi.concurrency import run_in_threadpool
20
20
  from fastapi.dependencies.models import Dependant
21
21
  from fastapi.dependencies.utils import solve_dependencies
22
22
  from fastapi.exceptions import RequestValidationError
23
- from fastapi.responses import FileResponse, StreamingResponse
23
+ from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
24
24
  from fastapi.routing import APIRoute, _prepare_response_content
25
25
  from pydantic import BaseModel
26
26
  from starlette._utils import is_async_callable
@@ -39,12 +39,12 @@ from cadwyn.exceptions import CadwynError, CadwynHeadRequestValidationError, Cad
39
39
  from .._utils import Sentinel
40
40
  from .common import Endpoint, VersionDate, VersionedModel
41
41
  from .data import (
42
- AlterRequestByPathInstruction,
43
- AlterRequestBySchemaInstruction,
44
- AlterResponseByPathInstruction,
45
- AlterResponseBySchemaInstruction,
46
42
  RequestInfo,
47
43
  ResponseInfo,
44
+ _AlterRequestByPathInstruction,
45
+ _AlterRequestBySchemaInstruction,
46
+ _AlterResponseByPathInstruction,
47
+ _AlterResponseBySchemaInstruction,
48
48
  _BaseAlterResponseInstruction,
49
49
  )
50
50
  from .endpoints import AlterEndpointSubInstruction
@@ -74,12 +74,12 @@ class VersionChange:
74
74
  alter_enum_instructions: ClassVar[list[AlterEnumSubInstruction]] = Sentinel
75
75
  alter_module_instructions: ClassVar[list[AlterModuleInstruction]] = Sentinel
76
76
  alter_endpoint_instructions: ClassVar[list[AlterEndpointSubInstruction]] = Sentinel
77
- alter_request_by_schema_instructions: ClassVar[
78
- dict[type[BaseModel], list[AlterRequestBySchemaInstruction]]
79
- ] = Sentinel
80
- alter_request_by_path_instructions: ClassVar[dict[str, list[AlterRequestByPathInstruction]]] = Sentinel
81
- alter_response_by_schema_instructions: ClassVar[dict[type, list[AlterResponseBySchemaInstruction]]] = Sentinel
82
- alter_response_by_path_instructions: ClassVar[dict[str, list[AlterResponseByPathInstruction]]] = Sentinel
77
+ alter_request_by_schema_instructions: ClassVar[dict[type[BaseModel], list[_AlterRequestBySchemaInstruction]]] = (
78
+ Sentinel
79
+ )
80
+ alter_request_by_path_instructions: ClassVar[dict[str, list[_AlterRequestByPathInstruction]]] = Sentinel
81
+ alter_response_by_schema_instructions: ClassVar[dict[type, list[_AlterResponseBySchemaInstruction]]] = Sentinel
82
+ alter_response_by_path_instructions: ClassVar[dict[str, list[_AlterResponseByPathInstruction]]] = Sentinel
83
83
  _bound_version_bundle: "VersionBundle | None"
84
84
 
85
85
  def __init_subclass__(cls, _abstract: bool = False) -> None:
@@ -96,15 +96,15 @@ class VersionChange:
96
96
  @classmethod
97
97
  def _extract_body_instructions_into_correct_containers(cls):
98
98
  for instruction in cls.__dict__.values():
99
- if isinstance(instruction, AlterRequestBySchemaInstruction):
99
+ if isinstance(instruction, _AlterRequestBySchemaInstruction):
100
100
  for schema in instruction.schemas:
101
101
  cls.alter_request_by_schema_instructions[schema].append(instruction)
102
- elif isinstance(instruction, AlterRequestByPathInstruction):
102
+ elif isinstance(instruction, _AlterRequestByPathInstruction):
103
103
  cls.alter_request_by_path_instructions[instruction.path].append(instruction)
104
- elif isinstance(instruction, AlterResponseBySchemaInstruction):
104
+ elif isinstance(instruction, _AlterResponseBySchemaInstruction):
105
105
  for schema in instruction.schemas:
106
106
  cls.alter_response_by_schema_instructions[schema].append(instruction)
107
- elif isinstance(instruction, AlterResponseByPathInstruction):
107
+ elif isinstance(instruction, _AlterResponseByPathInstruction):
108
108
  cls.alter_response_by_path_instructions[instruction.path].append(instruction)
109
109
 
110
110
  @classmethod
@@ -154,10 +154,10 @@ class VersionChange:
154
154
  for attr_name, attr_value in cls.__dict__.items():
155
155
  if not isinstance(
156
156
  attr_value,
157
- AlterRequestBySchemaInstruction
158
- | AlterRequestByPathInstruction
159
- | AlterResponseBySchemaInstruction
160
- | AlterResponseByPathInstruction,
157
+ _AlterRequestBySchemaInstruction
158
+ | _AlterRequestByPathInstruction
159
+ | _AlterResponseBySchemaInstruction
160
+ | _AlterResponseByPathInstruction,
161
161
  ) and attr_name not in {
162
162
  "description",
163
163
  "side_effects",
@@ -245,8 +245,7 @@ class VersionBundle:
245
245
  *other_versions: Version,
246
246
  api_version_var: APIVersionVarType | None = None,
247
247
  head_schemas_package: ModuleType | None = None,
248
- ) -> None:
249
- ...
248
+ ) -> None: ...
250
249
 
251
250
  @overload
252
251
  @deprecated("Pass head_version_package instead of latest_schemas_package.")
@@ -257,8 +256,7 @@ class VersionBundle:
257
256
  *other_versions: Version,
258
257
  api_version_var: APIVersionVarType | None = None,
259
258
  latest_schemas_package: ModuleType | None = None,
260
- ) -> None:
261
- ...
259
+ ) -> None: ...
262
260
 
263
261
  def __init__(
264
262
  self,
@@ -287,6 +285,8 @@ class VersionBundle:
287
285
  raise CadwynStructureError(
288
286
  "Versions are not sorted correctly. Please sort them in descending order.",
289
287
  )
288
+ if not self.versions:
289
+ raise CadwynStructureError("You must define at least one non-head version in a VersionBundle.")
290
290
  if self.versions[-1].version_changes:
291
291
  raise CadwynStructureError(
292
292
  f'The first version "{self.versions[-1].value}" cannot have any version changes. '
@@ -327,7 +327,7 @@ class VersionBundle:
327
327
  raise CadwynStructureError(
328
328
  f'The head schemas package must be a package. "{head_schemas_package.__name__}" is not a package.',
329
329
  )
330
- elif head_schemas_package.__name__.endswith(".head"):
330
+ elif head_schemas_package.__name__.endswith(".head") or head_schemas_package.__name__ == "head":
331
331
  return "head"
332
332
  elif head_schemas_package.__name__.endswith(".latest"):
333
333
  warnings.warn(
@@ -387,7 +387,7 @@ class VersionBundle:
387
387
  }
388
388
 
389
389
  @functools.cached_property
390
- def versioned_directories(self) -> tuple[Path, ...]:
390
+ def versioned_directories_with_head(self) -> tuple[Path, ...]:
391
391
  if self.head_schemas_package is None:
392
392
  raise CadwynError(
393
393
  f"You cannot call 'VersionBundle.{self.migrate_response_body.__name__}' because it has no access to "
@@ -399,6 +399,10 @@ class VersionBundle:
399
399
  + [get_version_dir_path(self.head_schemas_package, version.value) for version in self]
400
400
  )
401
401
 
402
+ @functools.cached_property
403
+ def versioned_directories_without_head(self) -> tuple[Path, ...]:
404
+ return self.versioned_directories_with_head[1:]
405
+
402
406
  def migrate_response_body(self, latest_response_model: type[BaseModel], *, latest_body: Any, version: VersionDate):
403
407
  """Convert the data to a specific version by applying all version changes from latest until that version
404
408
  in reverse order and wrapping the result in the correct version of latest_response_model.
@@ -413,13 +417,12 @@ class VersionBundle:
413
417
  )
414
418
 
415
419
  version = self._get_closest_lesser_version(version)
416
- # + 1 comes from latest also being in the versioned_directories list
417
- version_dir = self.versioned_directories[self.version_dates.index(version) + 1]
420
+ version_dir = self.versioned_directories_without_head[self.version_dates.index(version)]
418
421
 
419
422
  versioned_response_model: type[BaseModel] = get_another_version_of_cls(
420
- latest_response_model, version_dir, self.versioned_directories
423
+ latest_response_model, version_dir, self.versioned_directories_with_head
421
424
  )
422
- return versioned_response_model.parse_obj(migrated_response.body)
425
+ return versioned_response_model.parse_obj(migrated_response.body) # pyright: ignore[reportDeprecated]
423
426
 
424
427
  def _get_closest_lesser_version(self, version: VersionDate):
425
428
  for defined_version in self.version_dates:
@@ -446,6 +449,8 @@ class VersionBundle:
446
449
  current_version: VersionDate,
447
450
  head_route: APIRoute,
448
451
  exit_stack: AsyncExitStack,
452
+ *,
453
+ embed_body_fields: bool,
449
454
  ) -> dict[str, Any]:
450
455
  method = request.method
451
456
  for v in reversed(self.versions):
@@ -457,25 +462,25 @@ class VersionBundle:
457
462
  instruction(request_info)
458
463
  if path in version_change.alter_request_by_path_instructions:
459
464
  for instruction in version_change.alter_request_by_path_instructions[path]:
460
- if method in instruction.methods:
465
+ if method in instruction.methods: # pragma: no branch # safe branch to skip
461
466
  instruction(request_info)
462
467
  request.scope["headers"] = tuple((key.encode(), value.encode()) for key, value in request_info.headers.items())
463
468
  del request._headers
464
469
  # Remember this: if len(body_params) == 1, then route.body_schema == route.dependant.body_params[0]
465
-
466
- dependencies, errors, _, _, _ = await solve_dependencies(
470
+ result = await solve_dependencies(
467
471
  request=request,
468
472
  response=response,
469
473
  dependant=head_dependant,
470
474
  body=request_info.body,
471
475
  dependency_overrides_provider=head_route.dependency_overrides_provider,
472
476
  async_exit_stack=exit_stack,
477
+ embed_body_fields=embed_body_fields,
473
478
  )
474
- if errors:
479
+ if result.errors:
475
480
  raise CadwynHeadRequestValidationError(
476
- _normalize_errors(errors), body=request_info.body, version=current_version
481
+ _normalize_errors(result.errors), body=request_info.body, version=current_version
477
482
  )
478
- return dependencies
483
+ return result.values
479
484
 
480
485
  def _migrate_response(
481
486
  self,
@@ -509,7 +514,7 @@ class VersionBundle:
509
514
 
510
515
  if path in version_change.alter_response_by_path_instructions:
511
516
  for instruction in version_change.alter_response_by_path_instructions[path]:
512
- if method in instruction.methods:
517
+ if method in instruction.methods: # pragma: no branch # Safe branch to skip
513
518
  migrations_to_apply.append(instruction)
514
519
 
515
520
  for migration in migrations_to_apply:
@@ -620,7 +625,10 @@ class VersionBundle:
620
625
  if isinstance(response_or_response_body, StreamingResponse | FileResponse):
621
626
  body = None
622
627
  elif response_or_response_body.body:
623
- body = json.loads(response_or_response_body.body)
628
+ if isinstance(response_or_response_body, JSONResponse) or raised_exception is not None:
629
+ body = json.loads(response_or_response_body.body)
630
+ else:
631
+ body = response_or_response_body.body.decode(response_or_response_body.charset)
624
632
  else:
625
633
  body = None
626
634
  # TODO (https://github.com/zmievsa/cadwyn/issues/51): Only do this if there are migrations
@@ -666,16 +674,28 @@ class VersionBundle:
666
674
  # that do not have it. We don't support it too.
667
675
  if response_info.body is not None and hasattr(response_info._response, "body"):
668
676
  # TODO (https://github.com/zmievsa/cadwyn/issues/51): Only do this if there are migrations
669
- response_info._response.body = json.dumps(response_info.body).encode()
677
+ if (
678
+ isinstance(response_info.body, str)
679
+ and response_info._response.headers.get("content-type") != "application/json"
680
+ ):
681
+ response_info._response.body = response_info.body.encode(response_info._response.charset)
682
+ else:
683
+ response_info._response.body = json.dumps(
684
+ response_info.body,
685
+ ensure_ascii=False,
686
+ allow_nan=False,
687
+ indent=None,
688
+ separators=(",", ":"),
689
+ ).encode("utf-8")
690
+ # It makes sense to re-calculate content length because the previously calculated one
691
+ # might slightly differ. If it differs -- uvicorn will break.
692
+ response_info.headers["content-length"] = str(len(response_info._response.body))
670
693
 
671
694
  if raised_exception is not None and response_info.status_code >= 400:
672
695
  if isinstance(response_info.body, dict) and "detail" in response_info.body:
673
696
  detail = response_info.body["detail"]
674
697
  else:
675
698
  detail = response_info.body
676
- # It makes more sense to re-calculate content length because the previously calculated one
677
- # might slightly differ.
678
- del response_info.headers["content-length"]
679
699
 
680
700
  raise HTTPException(
681
701
  status_code=response_info.status_code,
@@ -713,7 +733,7 @@ class VersionBundle:
713
733
  and body_field_alias in kwargs
714
734
  ):
715
735
  raw_body: BaseModel | None = kwargs.get(body_field_alias)
716
- if raw_body is None:
736
+ if raw_body is None: # pragma: no cover # This is likely an impossible case but we would like to be safe
717
737
  body = None
718
738
  # It means we have a dict or a list instead of a full model.
719
739
  # This covers the following use case in the endpoint definition: "payload: dict = Body(None)"
@@ -738,6 +758,7 @@ class VersionBundle:
738
758
  api_version,
739
759
  head_route,
740
760
  exit_stack=exit_stack,
761
+ embed_body_fields=route._embed_body_fields,
741
762
  )
742
763
  # Because we re-added it into our kwargs when we did solve_dependencies
743
764
  if _CADWYN_REQUEST_PARAM_NAME in new_kwargs:
@@ -790,7 +811,7 @@ async def _get_body(
790
811
  ) from e
791
812
  except HTTPException:
792
813
  raise
793
- except Exception as e: # noqa: BLE001
814
+ except Exception as e:
794
815
  raise HTTPException(status_code=400, detail="There was an error parsing the body") from e
795
816
  return body
796
817
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cadwyn
3
- Version: 3.12.0
3
+ Version: 3.15.10
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
@@ -33,7 +33,8 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
33
  Classifier: Typing :: Typed
34
34
  Provides-Extra: cli
35
35
  Requires-Dist: better-ast-comments (>=1.2.1,<1.3.0)
36
- Requires-Dist: fastapi (>=0.110.0)
36
+ Requires-Dist: fastapi (>=0.115.2)
37
+ Requires-Dist: issubclass (>=0.1.2,<0.2.0)
37
38
  Requires-Dist: jinja2 (>=3.1.2)
38
39
  Requires-Dist: pydantic (>=1.0.0)
39
40
  Requires-Dist: starlette (>=0.36.3)
@@ -53,8 +54,8 @@ Production-ready community-driven modern [Stripe-like](https://stripe.com/blog/a
53
54
  <a href="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml?branch=main&event=push" target="_blank">
54
55
  <img src="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml/badge.svg?branch=main&event=push" alt="Test">
55
56
  </a>
56
- <a href="https://codecov.io/gh/ovsyanka83/cadwyn" target="_blank">
57
- <img src="https://img.shields.io/codecov/c/github/ovsyanka83/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
57
+ <a href="https://codecov.io/gh/zmievsa/cadwyn" target="_blank">
58
+ <img src="https://img.shields.io/codecov/c/github/zmievsa/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
58
59
  </a>
59
60
  <a href="https://pypi.org/project/cadwyn/" target="_blank">
60
61
  <img alt="PyPI" src="https://img.shields.io/pypi/v/cadwyn?color=%2334D058&logo=pypi&label=PyPI package" alt="Package version">
@@ -0,0 +1,38 @@
1
+ cadwyn/__init__.py,sha256=Wh_CtNgodacy8plxyDXCDb52CDftbql4jGXQ2pldX4s,605
2
+ cadwyn/__main__.py,sha256=cc-5iYItjxRnB09uxuxlEbjrLm1AEhXI2KrI5iakEOw,4376
3
+ cadwyn/_asts.py,sha256=0OcYNZPFm65CFb-oZMwbx191Bai0asqDA4y_IKzh6_w,10147
4
+ cadwyn/_compat.py,sha256=yAPmfGl2vVEYXlNHHPMoa2JkEJCVPjbP_Uz0WOIVOp4,5494
5
+ cadwyn/_package_utils.py,sha256=trxTYLmppv-10SKhScfyDQJh21rsQGFoLaOtHycKKR0,1443
6
+ cadwyn/_utils.py,sha256=BFsfZBpdoL5RMAaT1V1cXJVpTZCmwksQ-Le2MTHivGI,4841
7
+ cadwyn/applications.py,sha256=MkZ_vMs6YfnfuWPUzBjNBmrxtDa97etsV0zcnlv-iS0,15749
8
+ cadwyn/codegen/README.md,sha256=hc7AE87LsEsvbh-wX1H10JEWh-8bLHoe-1CkY3h00FI,879
9
+ cadwyn/codegen/__init__.py,sha256=JgddDjxMTjSfVrMXHwNu1ODgdn2QfPWpccrRKquBV6k,355
10
+ cadwyn/codegen/_common.py,sha256=fnz9Q-C7oZ3JKypPC_Xi6_CssF803XAUHL661IYY1hM,5910
11
+ cadwyn/codegen/_main.py,sha256=KT362MCSeb_CYBJrCHej-E15dtmCYgykwE9Jz43B17g,10546
12
+ cadwyn/codegen/_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ cadwyn/codegen/_plugins/class_migrations.py,sha256=kHZ-RMRTARZ4l70fxHMtul_204Ute2_yQmEej7wMwwo,20119
14
+ cadwyn/codegen/_plugins/class_rebuilding.py,sha256=_gjQsx_kU36tf8HT3mKhSv7V9RXfawFdbKTtYLP2IMk,3698
15
+ cadwyn/codegen/_plugins/class_renaming.py,sha256=oc9Ms6YnpJKaq1iOehcBfA_OFUFL-CAAZJiaQPlkKHs,1773
16
+ cadwyn/codegen/_plugins/import_auto_adding.py,sha256=krAVzsmsW-CbKP-W9oCkQsL7aPfhHzRq4STgai6Tm5s,2543
17
+ cadwyn/codegen/_plugins/module_migrations.py,sha256=TeWJk4Iu4SRQ9K2iI3v3sCs1110jrltKlPdfU9mXIsQ,722
18
+ cadwyn/exceptions.py,sha256=aJKx1qgzZqShL4MX3COjS780qzNJcdZFeGzYYa5gbzw,1726
19
+ cadwyn/main.py,sha256=kt2Vn7TIA4ZnD_xrgz57TOjUk-4zVP8SV8nuTZBEaaU,218
20
+ cadwyn/middleware.py,sha256=kUZK2dmoricMbv6knPCIHpXEInX2670XIwAj0v_XQxk,3408
21
+ cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ cadwyn/route_generation.py,sha256=80LmEodZ5SgscnhVL4A3ck0t8RJK5d5Acnefyo4CfIc,41607
23
+ cadwyn/routing.py,sha256=o6IMjxTxARPa5BxFfsXqOP3bVw9Ya6OBAEbUwH9lMVM,7445
24
+ cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
26
+ cadwyn/structure/__init__.py,sha256=HjaNd6H4m4Cia42-dCO7A7sLWuVII7oldjaCabhbs_o,697
27
+ cadwyn/structure/common.py,sha256=6Z4nI97XPWTCinn6np73m-rLPyYNrz2fWXKJlqjsiaQ,269
28
+ cadwyn/structure/data.py,sha256=1ALPhBBCE_t4GrxM0Fa3hQ-jkORJgeWNySnZ42bsi0g,7382
29
+ cadwyn/structure/endpoints.py,sha256=JhTgVrqLjm5LkE9thjvU1UuWcSCmDgW2bMdqznsZb2Y,5777
30
+ cadwyn/structure/enums.py,sha256=iMokxA2QYJ61SzyB-Pmuq3y7KL7-e6TsnjLVUaVZQnw,954
31
+ cadwyn/structure/modules.py,sha256=v3hA_KiqKwwo-ur0Z84WvqD0rTTe4fBTkMUK8SxUj7s,1301
32
+ cadwyn/structure/schemas.py,sha256=0ylArAkUw626VkUOJSulOwJs7CS6lrGBRECEG5HFD4Q,8897
33
+ cadwyn/structure/versions.py,sha256=Vlp-H1K36NRztHRkNhagmNKgQbIP6bc0gAgm7egHCTs,37679
34
+ cadwyn-3.15.10.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
+ cadwyn-3.15.10.dist-info/METADATA,sha256=HVnWPABfADEa4aUPJvW_1PEmDmfbUu9waeKNXwnLW-I,4398
36
+ cadwyn-3.15.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
37
+ cadwyn-3.15.10.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
+ cadwyn-3.15.10.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,38 +0,0 @@
1
- cadwyn/__init__.py,sha256=XgF-CtZo-fPk5730sKlY2fAmPsTQRIsFbrfNFeUZyFY,495
2
- cadwyn/__main__.py,sha256=TMxAEvgN1MFc1TkkKmsS-jFMBAW8lVos4wUZ9stp6WU,4343
3
- cadwyn/_asts.py,sha256=S-x9fVKTENZZxwWfabm0PbztcHyX2MJkI6Cwv5XgVrI,10138
4
- cadwyn/_compat.py,sha256=6QwtzbXn53mIhEFfEizmFjd-f894oLsM6ITxqq2rCpc,5408
5
- cadwyn/_package_utils.py,sha256=trxTYLmppv-10SKhScfyDQJh21rsQGFoLaOtHycKKR0,1443
6
- cadwyn/_utils.py,sha256=BFsfZBpdoL5RMAaT1V1cXJVpTZCmwksQ-Le2MTHivGI,4841
7
- cadwyn/applications.py,sha256=MAVsgYojgQO4PrUETVMAsp49k6baW4h4LtS6z12gTZs,15767
8
- cadwyn/codegen/README.md,sha256=hc7AE87LsEsvbh-wX1H10JEWh-8bLHoe-1CkY3h00FI,879
9
- cadwyn/codegen/__init__.py,sha256=JgddDjxMTjSfVrMXHwNu1ODgdn2QfPWpccrRKquBV6k,355
10
- cadwyn/codegen/_common.py,sha256=FTI4fqpUFGBMACVlPiDMHTWhqwW_-zQNa_4Qh7m-hCA,5877
11
- cadwyn/codegen/_main.py,sha256=8VdMhbQyNDyeZaxKV-2sUW_Sl5X-Lu92rHdINAHaTn0,10491
12
- cadwyn/codegen/_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- cadwyn/codegen/_plugins/class_migrations.py,sha256=kHZ-RMRTARZ4l70fxHMtul_204Ute2_yQmEej7wMwwo,20119
14
- cadwyn/codegen/_plugins/class_rebuilding.py,sha256=zNlB_VxoEAtdC5Ydiqa7pu6Ka-pKnpPQk_dvovaK0QI,3623
15
- cadwyn/codegen/_plugins/class_renaming.py,sha256=oc9Ms6YnpJKaq1iOehcBfA_OFUFL-CAAZJiaQPlkKHs,1773
16
- cadwyn/codegen/_plugins/import_auto_adding.py,sha256=krAVzsmsW-CbKP-W9oCkQsL7aPfhHzRq4STgai6Tm5s,2543
17
- cadwyn/codegen/_plugins/module_migrations.py,sha256=TeWJk4Iu4SRQ9K2iI3v3sCs1110jrltKlPdfU9mXIsQ,722
18
- cadwyn/exceptions.py,sha256=gsb1vszQ2VsnfTBM5B8AYmXwCW0yvA8pJ1GhNkGzgyE,1440
19
- cadwyn/main.py,sha256=kt2Vn7TIA4ZnD_xrgz57TOjUk-4zVP8SV8nuTZBEaaU,218
20
- cadwyn/middleware.py,sha256=8cuBri_yRkl0goe6G0MLwtL04WGbW9Infah3wy9hUVM,3372
21
- cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- cadwyn/route_generation.py,sha256=7nHe_IP7Uz1rXmnItJsQ2yIuqe3lRgtOr8_MP_6Vg8c,35704
23
- cadwyn/routing.py,sha256=s_-PxzDq0GT0pW-JtRLQrcR51tDQfd420oyWBP9S-sg,6158
24
- cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
26
- cadwyn/structure/__init__.py,sha256=HjaNd6H4m4Cia42-dCO7A7sLWuVII7oldjaCabhbs_o,697
27
- cadwyn/structure/common.py,sha256=6Z4nI97XPWTCinn6np73m-rLPyYNrz2fWXKJlqjsiaQ,269
28
- cadwyn/structure/data.py,sha256=F7jqlRohpLJrgJxkxs2gTkO77q6BJ6pCbt6wJIo3TRk,7128
29
- cadwyn/structure/endpoints.py,sha256=VngfAydGBwekhV2tBOtNDPVgl3X1IgYxUCw--VZ5cQY,5627
30
- cadwyn/structure/enums.py,sha256=iMokxA2QYJ61SzyB-Pmuq3y7KL7-e6TsnjLVUaVZQnw,954
31
- cadwyn/structure/modules.py,sha256=1FK-lLm-zOTXEvn-QtyBH38aDRht5PDQiZrOPCsBlM4,1268
32
- cadwyn/structure/schemas.py,sha256=0ylArAkUw626VkUOJSulOwJs7CS6lrGBRECEG5HFD4Q,8897
33
- cadwyn/structure/versions.py,sha256=SjrVqwWFIgUQEazaIW8xXjwMhgJSdSNakbAyfHSArwA,36188
34
- cadwyn-3.12.0.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
35
- cadwyn-3.12.0.dist-info/METADATA,sha256=YWd0MSdFsQe6ZedoasOrtI_8J-RKlRL8TkSylw8XuYk,4360
36
- cadwyn-3.12.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
37
- cadwyn-3.12.0.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
38
- cadwyn-3.12.0.dist-info/RECORD,,