starmallow 0.7.0__py3-none-any.whl → 0.8.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.
starmallow/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.7.0"
1
+ __version__ = "0.8.0"
2
2
 
3
3
  from .applications import StarMallow
4
4
  from .exceptions import RequestValidationError
starmallow/endpoint.py CHANGED
@@ -20,6 +20,7 @@ from typing import (
20
20
  import marshmallow as ma
21
21
  import marshmallow.fields as mf
22
22
  from marshmallow.utils import missing as missing_
23
+ from marshmallow_dataclass2 import class_schema, is_generic_alias_of_dataclass
23
24
  from starlette.background import BackgroundTasks
24
25
  from starlette.requests import HTTPConnection, Request
25
26
  from starlette.responses import Response
@@ -243,6 +244,9 @@ class EndpointMixin:
243
244
  if is_marshmallow_dataclass(model):
244
245
  model = model.Schema
245
246
 
247
+ if is_generic_alias_of_dataclass(model):
248
+ model = class_schema(model)
249
+
246
250
  if isinstance(model, NewType) and getattr(model, '_marshmallow_field', None):
247
251
  return model._marshmallow_field(**kwargs)
248
252
  elif is_marshmallow_schema(model):
@@ -2,7 +2,7 @@ from typing import Any
2
2
 
3
3
  import marshmallow as ma
4
4
  import marshmallow.fields as mf
5
- import marshmallow_dataclass.collection_field as collection_field
5
+ import marshmallow_dataclass2.collection_field as collection_field
6
6
  from apispec import APISpec
7
7
  from apispec.ext.marshmallow.common import get_fields
8
8
  from apispec.ext.marshmallow.field_converter import (
@@ -12,9 +12,9 @@ from apispec.ext.marshmallow.field_converter import (
12
12
  )
13
13
  from apispec.ext.marshmallow.openapi import OpenAPIConverter as ApiSpecOpenAPIConverter
14
14
  from marshmallow.utils import is_collection
15
+ from marshmallow_dataclass2.union_field import Union as UnionField
15
16
  from packaging.version import Version
16
17
 
17
- from starmallow.union_field import Union as UnionField
18
18
  from starmallow.utils import MARSHMALLOW_ITERABLES
19
19
 
20
20
  # marshmallow field => (JSON Schema type, format)
@@ -1,7 +1,7 @@
1
1
  from enum import Enum
2
2
  from typing import ClassVar, Optional
3
3
 
4
- from marshmallow_dataclass import dataclass as ma_dataclass
4
+ from marshmallow_dataclass2 import dataclass as ma_dataclass
5
5
  from starlette.requests import Request
6
6
  from starlette.status import HTTP_403_FORBIDDEN
7
7
 
@@ -2,7 +2,7 @@ from enum import Enum
2
2
  from typing import Any, ClassVar, Dict, Optional
3
3
 
4
4
  import marshmallow as ma
5
- from marshmallow_dataclass import dataclass as ma_dataclass
5
+ from marshmallow_dataclass2 import dataclass as ma_dataclass
6
6
 
7
7
 
8
8
  # Provided by: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#security-scheme-object
@@ -2,7 +2,7 @@ import binascii
2
2
  from base64 import b64decode
3
3
  from typing import ClassVar, Optional
4
4
 
5
- from marshmallow_dataclass import dataclass as ma_dataclass
5
+ from marshmallow_dataclass2 import dataclass as ma_dataclass
6
6
  from starlette.requests import Request
7
7
  from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
8
8
 
@@ -1,7 +1,7 @@
1
1
  from typing import Any, Dict, List, Optional, Union
2
2
 
3
3
  import marshmallow as ma
4
- from marshmallow_dataclass import dataclass as ma_dataclass
4
+ from marshmallow_dataclass2 import dataclass as ma_dataclass
5
5
  from starlette.requests import Request
6
6
  from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
7
7
 
@@ -1,6 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
- from marshmallow_dataclass import dataclass as ma_dataclass
3
+ from marshmallow_dataclass2 import dataclass as ma_dataclass
4
4
  from starlette.exceptions import HTTPException
5
5
  from starlette.requests import Request
6
6
  from starlette.status import HTTP_403_FORBIDDEN
starmallow/types.py CHANGED
@@ -2,7 +2,7 @@ import uuid
2
2
  from typing import Any, Callable, List, TypeVar, Union
3
3
 
4
4
  import marshmallow.fields as mf
5
- from marshmallow_dataclass import NewType
5
+ from marshmallow_dataclass2 import NewType
6
6
 
7
7
  import starmallow.fields as sf
8
8
  from starmallow.endpoints import APIHTTPEndpoint
starmallow/utils.py CHANGED
@@ -33,15 +33,16 @@ from typing import (
33
33
  import dpath.util
34
34
  import marshmallow as ma
35
35
  import marshmallow.fields as mf
36
- import marshmallow_dataclass.collection_field as collection_field
36
+ import marshmallow_dataclass2.collection_field as collection_field
37
37
  import typing_inspect
38
38
  from marshmallow.validate import Equal, OneOf
39
+ from marshmallow_dataclass2 import class_schema, is_generic_alias_of_dataclass
40
+ from marshmallow_dataclass2.union_field import Union as UnionField
39
41
  from starlette.responses import Response
40
42
  from typing_inspect import is_final_type, is_generic_type, is_literal_type
41
43
 
42
44
  from starmallow.concurrency import contextmanager_in_threadpool
43
45
  from starmallow.datastructures import DefaultPlaceholder, DefaultType
44
- from starmallow.union_field import Union as UnionField
45
46
 
46
47
  if TYPE_CHECKING: # pragma: nocover
47
48
  from starmallow.routing import APIRoute
@@ -105,6 +106,9 @@ def get_model_field(model: Any, **kwargs) -> mf.Field:
105
106
  if is_marshmallow_dataclass(model):
106
107
  model = model.Schema
107
108
 
109
+ if is_generic_alias_of_dataclass(model):
110
+ model = class_schema(model)
111
+
108
112
  if is_marshmallow_schema(model):
109
113
  return mf.Nested(model if isinstance(model, ma.Schema) else model())
110
114
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: starmallow
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: StarMallow framework
5
5
  Project-URL: Homepage, https://github.com/mvanderlee/starmallow
6
6
  Author-email: Michiel Vanderlee <jmt.vanderlee@gmail.com>
@@ -28,7 +28,7 @@ Classifier: Typing :: Typed
28
28
  Requires-Python: >=3.10
29
29
  Requires-Dist: apispec[marshmallow]<7,>=6
30
30
  Requires-Dist: dpath<3,>=2.1.0
31
- Requires-Dist: marshmallow-dataclass<9,>=8.5.1
31
+ Requires-Dist: marshmallow-dataclass2<9,>=8.8.1
32
32
  Requires-Dist: marshmallow<4,>=3.18.0
33
33
  Requires-Dist: python-multipart<0.0.7,>=0.0.5
34
34
  Requires-Dist: pyyaml>=5.4.1
@@ -68,7 +68,7 @@ Create a file `main.py` with:
68
68
 
69
69
  ```python
70
70
  from typing import Annotated
71
- from marshmallow_dataclass import dataclass
71
+ from marshmallow_dataclass2 import dataclass
72
72
  from starmallow import Body, Path, StarMallow
73
73
 
74
74
  app = StarMallow()
@@ -131,7 +131,7 @@ INFO: Application startup complete.
131
131
  You can also use class-based views. This can make it easier to organize your code and gives you an easy migration path if you use [flask-smorest](https://flask-smorest.readthedocs.io/)
132
132
 
133
133
  ```python
134
- from marshmallow_dataclass import dataclass
134
+ from marshmallow_dataclass2 import dataclass
135
135
  from starmallow import StarMallow
136
136
  from starmallow.decorators import route
137
137
  from starmallow.endpoints import APIHTTPEndpoint
@@ -1,4 +1,4 @@
1
- starmallow/__init__.py,sha256=9E5AxUkYZG-q-eDh8OMP4YBFBCKro7Lp7hn2VFQe5E8,322
1
+ starmallow/__init__.py,sha256=_rVQsLfQ3QzRRXvJYKcuR9Ki79d7xvWU1Mhk7E4y2KY,322
2
2
  starmallow/applications.py,sha256=mSL4YDozP8n6v22g4NX7EAMXmGhzzhtjtZd68YHcFvw,31720
3
3
  starmallow/background.py,sha256=qxT6-9SfnkcGZzvecNOpIsCOMW0TPwDtpQ81GHI28P0,995
4
4
  starmallow/concurrency.py,sha256=MVRjo4Vqss_yqhaoeVt3xb7rLaSuAq_q9uYgTwbsojE,1375
@@ -8,7 +8,7 @@ starmallow/datastructures.py,sha256=iH_KJuJ6kBCWEsnHFLdA3iyb6ZxhfdMHYrJlhiEZtDU,
8
8
  starmallow/decorators.py,sha256=MYk3WEFRSfQTN0Y3JoL3Y_Cz47gatMrVEPtNDw42XwU,4105
9
9
  starmallow/delimited_field.py,sha256=gonWgYg6G5xH2yXAyfDgkePmQ8dUaRSp2hdJ3mCfOBw,3466
10
10
  starmallow/docs.py,sha256=eA39LunVMEoPU5ge4qxm2eiJbrFTUSUu5EhG1L_LKxk,6268
11
- starmallow/endpoint.py,sha256=aNsbN0mdcVvIIcdgqICRgoGjIYJAeSVFXcpDlAji0Oc,16017
11
+ starmallow/endpoint.py,sha256=WChgjb47lYUrbyeaQiyUbuyHFCREYPiZJMNLqnz_iuA,16186
12
12
  starmallow/endpoints.py,sha256=UrwVZCxbmWI20iNtJ0oXxo4d3-y12TjsOGs_jnStTiU,939
13
13
  starmallow/exception_handlers.py,sha256=gr2qLYWEtsIEH28n7OreEiiLVz6Y7b6osRyS9esJbBk,891
14
14
  starmallow/exceptions.py,sha256=vabtPJkTmtCdC8_2OPBE8Osz0v0KxaSOX6IWf1jgNkc,872
@@ -20,23 +20,22 @@ starmallow/responses.py,sha256=k2pf_m21ykf_FECdODUz400pMucMJJf_Zm8TXFujvaU,2012
20
20
  starmallow/routing.py,sha256=VSotmrEerVzuUfn20mpmSbuRVS4XiHrPtNRvBP8KJ4M,45397
21
21
  starmallow/schema_generator.py,sha256=yi368FwF9B50ZHSNOG0rvYVirVUeMFq2kXkUDeJUz4w,17961
22
22
  starmallow/serializers.py,sha256=rBEKMNgONgz_bai12uDvAEMCI_aEFGsqMSeIoWtlrOI,12514
23
- starmallow/types.py,sha256=8GXWjvzXQhF5NMHf14fbid6uErxVd1Xk_w2I4FoUgZ4,717
24
- starmallow/union_field.py,sha256=psc5GPWDGVeu4vxFf2ItgtHEK8tT62IZHrxoRZidyxc,3113
25
- starmallow/utils.py,sha256=ilJyQHXZq1o6XRaDdninTNTt4u4KzIPQwImbhNQeZUs,12285
23
+ starmallow/types.py,sha256=xp4eitWenXRZCPlsopTfG4aMs86kOrvioDTCVLg-MXU,718
24
+ starmallow/utils.py,sha256=lI6qWalsBsEaJLSiGsCC_vBN6Sw-r5aDTl9hWuHCW-Q,12459
26
25
  starmallow/websockets.py,sha256=yIz3LzTBMNclpEoG7oTMbQwxbcdKNU6M8XcqZMyBTuA,2223
27
26
  starmallow/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
27
  starmallow/ext/marshmallow/__init__.py,sha256=33jENGdfPq4-CDG0LOmN3KOGW1pXTy7a2oMwy4hrYzM,208
29
- starmallow/ext/marshmallow/openapi.py,sha256=BOPgTmolpZxQaPvyg0VcHLTjWSlvEj2L1OOHGFKfWik,10189
28
+ starmallow/ext/marshmallow/openapi.py,sha256=LHFcdw8ISpPsS2drefL2h8AiKk_B_I7UffloEH3-xXI,10202
30
29
  starmallow/middleware/__init__.py,sha256=vtNm85Z9pUPjJd-9giJGg3YL1wO7Jm5ooXBm31pDOK8,53
31
30
  starmallow/middleware/asyncexitstack.py,sha256=0GPhQSxqSVmAiVIqBIN5slueWYZ8bwh9f2bBPy7AbP0,1191
32
31
  starmallow/security/__init__.py,sha256=1rQFBIGnEbE51XDZSSi9NgPjXLScFq3RoLu4vk0KVYw,191
33
- starmallow/security/api_key.py,sha256=E326Sxb_qhWbfN70vHuq4KEJcToW1Fxw0qGL0pHmQjc,3144
34
- starmallow/security/base.py,sha256=_7PR7tepr0CHJxg6uTc_cBAeY90jBS5gu8z5598yEM0,1144
35
- starmallow/security/http.py,sha256=cpGjM1kFDq3i_bOY96kMkf4cspBUxFkkET9lTK3NA-0,6607
36
- starmallow/security/oauth2.py,sha256=1nv1580PY4cwgu5gzpQCf2MfMNv2Cfv05753AUHPOhQ,10005
37
- starmallow/security/open_id_connect_url.py,sha256=IPsL2YzWc2mPwJbrUn6oFRTi7uRAG6mR62CGwmzBs1k,1399
32
+ starmallow/security/api_key.py,sha256=OWogzuwqPC3H0xf4jzx_RQjC8UoM8WDVtOhjq1lQ5ik,3145
33
+ starmallow/security/base.py,sha256=PtTsBViTUEtNUT9q_zFFydnOqIvGLfKggtgyCYeYRZk,1145
34
+ starmallow/security/http.py,sha256=O4mUrBHp6JTJNewOvcG_dgsx0IwjMonL8usswOqGdOY,6608
35
+ starmallow/security/oauth2.py,sha256=wlc5K6rURqOrMLwSYeOcd_2ZtFcvMqG3OwbiAwpft3E,10006
36
+ starmallow/security/open_id_connect_url.py,sha256=NONotu-uAWJUps06wdyVCJSRrK71Bl23z8gWWi7ymmw,1400
38
37
  starmallow/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293
39
- starmallow-0.7.0.dist-info/METADATA,sha256=nfu-fi46UGqJcsgp88z9WTm_D1qepTVczqHGdkb-a_w,5615
40
- starmallow-0.7.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
41
- starmallow-0.7.0.dist-info/licenses/LICENSE.md,sha256=QelyGgOzch8CXzy6HrYwHh7nmj0rlWkDA0YzmZ3CPaY,1084
42
- starmallow-0.7.0.dist-info/RECORD,,
38
+ starmallow-0.8.0.dist-info/METADATA,sha256=w3SFqGhVi71VdQQZBQyQsM0Kk7dPvrGRAte3GpVAH5M,5618
39
+ starmallow-0.8.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
40
+ starmallow-0.8.0.dist-info/licenses/LICENSE.md,sha256=QelyGgOzch8CXzy6HrYwHh7nmj0rlWkDA0YzmZ3CPaY,1084
41
+ starmallow-0.8.0.dist-info/RECORD,,
starmallow/union_field.py DELETED
@@ -1,86 +0,0 @@
1
- '''Copied from marshmallow_dataclass, https://github.com/lovasoa/marshmallow_dataclass/blob/master/marshmallow_dataclass/union_field.py
2
- Didn't want to add the dependency to this project1
3
- '''
4
-
5
- import copy
6
- import inspect
7
- from typing import Any, List, Optional, Tuple
8
-
9
- import typeguard
10
- from marshmallow import Schema, ValidationError, fields
11
-
12
- try:
13
- from typeguard import TypeCheckError # type: ignore[attr-defined]
14
- except ImportError:
15
- # typeguard < 3
16
- TypeCheckError = TypeError # type: ignore[misc, assignment]
17
-
18
- if "argname" not in inspect.signature(typeguard.check_type).parameters:
19
-
20
- def _check_type(value, expected_type, argname: str):
21
- return typeguard.check_type(value=value, expected_type=expected_type)
22
-
23
- else:
24
- # typeguard < 3.0.0rc2
25
- def _check_type(value, expected_type, argname: str):
26
- return typeguard.check_type( # type: ignore[call-overload]
27
- value=value, expected_type=expected_type, argname=argname,
28
- )
29
-
30
-
31
- class Union(fields.Field):
32
- """A union field, composed other `Field` classes or instances.
33
- This field serializes elements based on their type, with one of its child fields.
34
-
35
- Example: ::
36
-
37
- number_or_string = UnionField([
38
- (float, fields.Float()),
39
- (str, fields.Str())
40
- ])
41
-
42
- :param union_fields: A list of types and their associated field instance.
43
- :param kwargs: The same keyword arguments that :class:`Field` receives.
44
- """
45
-
46
- def __init__(self, union_fields: List[Tuple[type, fields.Field]], **kwargs):
47
- super().__init__(**kwargs)
48
- self.union_fields = union_fields
49
-
50
- def _bind_to_schema(self, field_name: str, schema: Schema) -> None:
51
- super()._bind_to_schema(field_name, schema)
52
- new_union_fields = []
53
- for typ, field in self.union_fields:
54
- field = copy.deepcopy(field)
55
- field._bind_to_schema(field_name, self)
56
- new_union_fields.append((typ, field))
57
-
58
- self.union_fields = new_union_fields
59
-
60
- def _serialize(self, value: Any, attr: Optional[str], obj, **kwargs) -> Any:
61
- errors = []
62
- if value is None:
63
- return value
64
- for typ, field in self.union_fields:
65
- try:
66
- _check_type(value=value, expected_type=typ, argname=attr or "anonymous")
67
- return field._serialize(value, attr, obj, **kwargs)
68
- except TypeCheckError as e:
69
- errors.append(e)
70
- raise TypeError(
71
- f"Unable to serialize value with any of the fields in the union: {errors}",
72
- )
73
-
74
- def _deserialize(self, value: Any, attr: Optional[str], data, **kwargs) -> Any:
75
- errors = []
76
- for typ, field in self.union_fields:
77
- try:
78
- result = field.deserialize(value, **kwargs)
79
- _check_type(
80
- value=result, expected_type=typ, argname=attr or "anonymous",
81
- )
82
- return result
83
- except (TypeCheckError, ValidationError) as e:
84
- errors.append(e)
85
-
86
- raise ValidationError(errors)