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 +1 -1
- starmallow/endpoint.py +4 -0
- starmallow/ext/marshmallow/openapi.py +2 -2
- starmallow/security/api_key.py +1 -1
- starmallow/security/base.py +1 -1
- starmallow/security/http.py +1 -1
- starmallow/security/oauth2.py +1 -1
- starmallow/security/open_id_connect_url.py +1 -1
- starmallow/types.py +1 -1
- starmallow/utils.py +6 -2
- {starmallow-0.7.0.dist-info → starmallow-0.8.0.dist-info}/METADATA +4 -4
- {starmallow-0.7.0.dist-info → starmallow-0.8.0.dist-info}/RECORD +14 -15
- starmallow/union_field.py +0 -86
- {starmallow-0.7.0.dist-info → starmallow-0.8.0.dist-info}/WHEEL +0 -0
- {starmallow-0.7.0.dist-info → starmallow-0.8.0.dist-info}/licenses/LICENSE.md +0 -0
starmallow/__init__.py
CHANGED
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
|
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)
|
starmallow/security/api_key.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
from typing import ClassVar, Optional
|
3
3
|
|
4
|
-
from
|
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
|
|
starmallow/security/base.py
CHANGED
@@ -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
|
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
|
starmallow/security/http.py
CHANGED
@@ -2,7 +2,7 @@ import binascii
|
|
2
2
|
from base64 import b64decode
|
3
3
|
from typing import ClassVar, Optional
|
4
4
|
|
5
|
-
from
|
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
|
|
starmallow/security/oauth2.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import Any, Dict, List, Optional, Union
|
2
2
|
|
3
3
|
import marshmallow as ma
|
4
|
-
from
|
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
|
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
|
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
|
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.
|
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-
|
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
|
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
|
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=
|
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=
|
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=
|
24
|
-
starmallow/
|
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=
|
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=
|
34
|
-
starmallow/security/base.py,sha256=
|
35
|
-
starmallow/security/http.py,sha256=
|
36
|
-
starmallow/security/oauth2.py,sha256=
|
37
|
-
starmallow/security/open_id_connect_url.py,sha256=
|
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.
|
40
|
-
starmallow-0.
|
41
|
-
starmallow-0.
|
42
|
-
starmallow-0.
|
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)
|
File without changes
|
File without changes
|