flask-marshmallow 1.2.1__tar.gz → 1.3.0__tar.gz
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.
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/CHANGELOG.rst +8 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/PKG-INFO +12 -13
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/README.rst +5 -6
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/index.rst +2 -3
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/pyproject.toml +6 -6
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/__init__.py +13 -5
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/fields.py +9 -9
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/schema.py +4 -2
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/sqla.py +2 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/validate.py +6 -4
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/conftest.py +4 -6
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/test_sqla.py +4 -1
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tox.ini +3 -3
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/CONTRIBUTING.rst +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/LICENSE +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/Makefile +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_static/logo.png +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_templates/side-primary.html +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_templates/side-secondary.html +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/LICENSE +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/README +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask/layout.html +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask/relations.html +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask/static/flasky.css_t +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask/theme.conf +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask_small/layout.html +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask_small/static/flasky.css_t +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask_small/theme.conf +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask_theme_support.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/changelog.rst +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/conf.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/license.rst +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/make.bat +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/src/flask_marshmallow/py.typed +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/__init__.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/test_core.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/test_fields.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/test_io.py +0 -0
- {flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/tests/test_validate.py +0 -0
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: flask-marshmallow
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Flask + marshmallow for beautiful APIs
|
|
5
5
|
Maintainer-email: Steven Loria <sloria1@gmail.com>, Stephen Rosen <sirosen0@gmail.com>
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
7
|
Description-Content-Type: text/x-rst
|
|
8
8
|
Classifier: Environment :: Web Environment
|
|
9
9
|
Classifier: Intended Audience :: Developers
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Natural Language :: English
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.9
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
18
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
19
19
|
Requires-Dist: Flask>=2.2
|
|
20
20
|
Requires-Dist: marshmallow>=3.0.0
|
|
21
21
|
Requires-Dist: flask-marshmallow[tests] ; extra == "dev"
|
|
22
22
|
Requires-Dist: tox ; extra == "dev"
|
|
23
|
-
Requires-Dist: pre-commit
|
|
23
|
+
Requires-Dist: pre-commit>=3.5,<5.0 ; extra == "dev"
|
|
24
24
|
Requires-Dist: marshmallow-sqlalchemy>=0.19.0 ; extra == "docs"
|
|
25
|
-
Requires-Dist: Sphinx==
|
|
26
|
-
Requires-Dist: sphinx-issues==
|
|
25
|
+
Requires-Dist: Sphinx==8.1.3 ; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinx-issues==5.0.0 ; extra == "docs"
|
|
27
27
|
Requires-Dist: flask-sqlalchemy>=3.0.0 ; extra == "sqlalchemy"
|
|
28
28
|
Requires-Dist: marshmallow-sqlalchemy>=0.29.0 ; extra == "sqlalchemy"
|
|
29
29
|
Requires-Dist: flask-marshmallow[sqlalchemy] ; extra == "tests"
|
|
@@ -39,7 +39,7 @@ Provides-Extra: tests
|
|
|
39
39
|
Flask-Marshmallow
|
|
40
40
|
*****************
|
|
41
41
|
|
|
42
|
-
|pypi-package| |build-status| |docs| |
|
|
42
|
+
|pypi-package| |build-status| |docs| |marshmallow-support|
|
|
43
43
|
|
|
44
44
|
Flask + marshmallow for beautiful APIs
|
|
45
45
|
======================================
|
|
@@ -82,9 +82,8 @@ Define your output format with marshmallow.
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
class UserSchema(ma.Schema):
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
fields = ("email", "date_created", "_links")
|
|
85
|
+
email = ma.Email()
|
|
86
|
+
date_created = ma.DateTime()
|
|
88
87
|
|
|
89
88
|
# Smart hyperlinking
|
|
90
89
|
_links = ma.Hyperlinks(
|
|
@@ -164,7 +163,7 @@ MIT licensed. See the bundled `LICENSE <https://github.com/marshmallow-code/flas
|
|
|
164
163
|
:target: https://flask-marshmallow.readthedocs.io/
|
|
165
164
|
:alt: Documentation
|
|
166
165
|
|
|
167
|
-
.. |
|
|
166
|
+
.. |marshmallow-support| image:: https://badgen.net/badge/marshmallow/3,4?list=1
|
|
168
167
|
:target: https://marshmallow.readthedocs.io/en/latest/upgrading.html
|
|
169
|
-
:alt: marshmallow 3 compatible
|
|
168
|
+
:alt: marshmallow 3|4 compatible
|
|
170
169
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Flask-Marshmallow
|
|
3
3
|
*****************
|
|
4
4
|
|
|
5
|
-
|pypi-package| |build-status| |docs| |
|
|
5
|
+
|pypi-package| |build-status| |docs| |marshmallow-support|
|
|
6
6
|
|
|
7
7
|
Flask + marshmallow for beautiful APIs
|
|
8
8
|
======================================
|
|
@@ -45,9 +45,8 @@ Define your output format with marshmallow.
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class UserSchema(ma.Schema):
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
fields = ("email", "date_created", "_links")
|
|
48
|
+
email = ma.Email()
|
|
49
|
+
date_created = ma.DateTime()
|
|
51
50
|
|
|
52
51
|
# Smart hyperlinking
|
|
53
52
|
_links = ma.Hyperlinks(
|
|
@@ -127,6 +126,6 @@ MIT licensed. See the bundled `LICENSE <https://github.com/marshmallow-code/flas
|
|
|
127
126
|
:target: https://flask-marshmallow.readthedocs.io/
|
|
128
127
|
:alt: Documentation
|
|
129
128
|
|
|
130
|
-
.. |
|
|
129
|
+
.. |marshmallow-support| image:: https://badgen.net/badge/marshmallow/3,4?list=1
|
|
131
130
|
:target: https://marshmallow.readthedocs.io/en/latest/upgrading.html
|
|
132
|
-
:alt: marshmallow 3 compatible
|
|
131
|
+
:alt: marshmallow 3|4 compatible
|
|
@@ -49,9 +49,8 @@ Define your output format with marshmallow.
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
class UserSchema(ma.Schema):
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
fields = ("email", "date_created", "_links")
|
|
52
|
+
email = ma.Email()
|
|
53
|
+
date_created = ma.DateTime()
|
|
55
54
|
|
|
56
55
|
# Smart hyperlinking
|
|
57
56
|
_links = ma.Hyperlinks(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flask-marshmallow"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
4
4
|
description = "Flask + marshmallow for beautiful APIs"
|
|
5
5
|
readme = "README.rst"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -14,14 +14,14 @@ classifiers = [
|
|
|
14
14
|
"License :: OSI Approved :: MIT License",
|
|
15
15
|
"Natural Language :: English",
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
|
-
"Programming Language :: Python :: 3.8",
|
|
18
17
|
"Programming Language :: Python :: 3.9",
|
|
19
18
|
"Programming Language :: Python :: 3.10",
|
|
20
19
|
"Programming Language :: Python :: 3.11",
|
|
21
20
|
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
22
|
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
23
23
|
]
|
|
24
|
-
requires-python = ">=3.
|
|
24
|
+
requires-python = ">=3.9"
|
|
25
25
|
dependencies = ["Flask>=2.2", "marshmallow>=3.0.0"]
|
|
26
26
|
|
|
27
27
|
[project.urls]
|
|
@@ -31,11 +31,11 @@ Funding = "https://opencollective.com/marshmallow"
|
|
|
31
31
|
[project.optional-dependencies]
|
|
32
32
|
docs = [
|
|
33
33
|
"marshmallow-sqlalchemy>=0.19.0",
|
|
34
|
-
"Sphinx==
|
|
35
|
-
"sphinx-issues==
|
|
34
|
+
"Sphinx==8.1.3",
|
|
35
|
+
"sphinx-issues==5.0.0",
|
|
36
36
|
]
|
|
37
37
|
tests = ["flask-marshmallow[sqlalchemy]", "pytest"]
|
|
38
|
-
dev = ["flask-marshmallow[tests]", "tox", "pre-commit
|
|
38
|
+
dev = ["flask-marshmallow[tests]", "tox", "pre-commit>=3.5,<5.0"]
|
|
39
39
|
sqlalchemy = ["flask-sqlalchemy>=3.0.0", "marshmallow-sqlalchemy>=0.29.0"]
|
|
40
40
|
|
|
41
41
|
[build-system]
|
|
@@ -9,7 +9,15 @@ with your Flask application.
|
|
|
9
9
|
import typing
|
|
10
10
|
import warnings
|
|
11
11
|
|
|
12
|
-
from marshmallow import exceptions
|
|
12
|
+
from marshmallow import exceptions
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
# Available in marshmallow 3 only
|
|
16
|
+
from marshmallow import pprint # noqa: F401
|
|
17
|
+
except ImportError:
|
|
18
|
+
_has_pprint = False
|
|
19
|
+
else:
|
|
20
|
+
_has_pprint = True
|
|
13
21
|
from marshmallow import fields as base_fields
|
|
14
22
|
|
|
15
23
|
from . import fields
|
|
@@ -41,8 +49,9 @@ __all__ = [
|
|
|
41
49
|
"Schema",
|
|
42
50
|
"fields",
|
|
43
51
|
"exceptions",
|
|
44
|
-
"pprint",
|
|
45
52
|
]
|
|
53
|
+
if _has_pprint:
|
|
54
|
+
__all__.append("pprint")
|
|
46
55
|
|
|
47
56
|
EXTENSION_NAME = "flask-marshmallow"
|
|
48
57
|
|
|
@@ -75,9 +84,8 @@ class Marshmallow:
|
|
|
75
84
|
You can declare schema like so::
|
|
76
85
|
|
|
77
86
|
class BookSchema(ma.Schema):
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
id = ma.Integer(dump_only=True)
|
|
88
|
+
title = ma.String(required=True)
|
|
81
89
|
author = ma.Nested(AuthorSchema)
|
|
82
90
|
|
|
83
91
|
links = ma.Hyperlinks(
|
|
@@ -8,6 +8,8 @@ See the `marshmallow.fields` module for the list of all fields available from th
|
|
|
8
8
|
marshmallow library.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
11
13
|
import re
|
|
12
14
|
import typing
|
|
13
15
|
from collections.abc import Sequence
|
|
@@ -29,7 +31,7 @@ __all__ = [
|
|
|
29
31
|
_tpl_pattern = re.compile(r"\s*<\s*(\S*)\s*>\s*")
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
def _tpl(val: str) ->
|
|
34
|
+
def _tpl(val: str) -> str | None:
|
|
33
35
|
"""Return value within ``< >`` if possible, else return ``None``."""
|
|
34
36
|
match = _tpl_pattern.match(val)
|
|
35
37
|
if match:
|
|
@@ -95,7 +97,7 @@ class URLFor(fields.Field):
|
|
|
95
97
|
def __init__(
|
|
96
98
|
self,
|
|
97
99
|
endpoint: str,
|
|
98
|
-
values:
|
|
100
|
+
values: dict[str, typing.Any] | None = None,
|
|
99
101
|
**kwargs,
|
|
100
102
|
):
|
|
101
103
|
self.endpoint = endpoint
|
|
@@ -133,7 +135,7 @@ class AbsoluteURLFor(URLFor):
|
|
|
133
135
|
def __init__(
|
|
134
136
|
self,
|
|
135
137
|
endpoint: str,
|
|
136
|
-
values:
|
|
138
|
+
values: dict[str, typing.Any] | None = None,
|
|
137
139
|
**kwargs,
|
|
138
140
|
):
|
|
139
141
|
if values:
|
|
@@ -146,9 +148,7 @@ class AbsoluteURLFor(URLFor):
|
|
|
146
148
|
AbsoluteUrlFor = AbsoluteURLFor
|
|
147
149
|
|
|
148
150
|
|
|
149
|
-
def _rapply(
|
|
150
|
-
d: typing.Union[dict, typing.Iterable], func: typing.Callable, *args, **kwargs
|
|
151
|
-
):
|
|
151
|
+
def _rapply(d: dict | typing.Iterable, func: typing.Callable, *args, **kwargs):
|
|
152
152
|
"""Apply a function to all values in a dictionary or
|
|
153
153
|
list of dictionaries, recursively.
|
|
154
154
|
"""
|
|
@@ -201,7 +201,7 @@ class Hyperlinks(fields.Field):
|
|
|
201
201
|
|
|
202
202
|
_CHECK_ATTRIBUTE = False
|
|
203
203
|
|
|
204
|
-
def __init__(self, schema:
|
|
204
|
+
def __init__(self, schema: dict[str, URLFor | str], **kwargs):
|
|
205
205
|
self.schema = schema
|
|
206
206
|
fields.Field.__init__(self, **kwargs)
|
|
207
207
|
|
|
@@ -229,8 +229,8 @@ class File(fields.Field):
|
|
|
229
229
|
def deserialize(
|
|
230
230
|
self,
|
|
231
231
|
value: typing.Any,
|
|
232
|
-
attr:
|
|
233
|
-
data: typing.
|
|
232
|
+
attr: str | None = None,
|
|
233
|
+
data: typing.Mapping[str, typing.Any] | None = None,
|
|
234
234
|
**kwargs,
|
|
235
235
|
):
|
|
236
236
|
if isinstance(value, Sequence) and len(value) == 0:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import typing
|
|
2
4
|
|
|
3
5
|
import flask
|
|
@@ -14,8 +16,8 @@ class Schema(ma.Schema):
|
|
|
14
16
|
"""
|
|
15
17
|
|
|
16
18
|
def jsonify(
|
|
17
|
-
self, obj: typing.Any, many:
|
|
18
|
-
) ->
|
|
19
|
+
self, obj: typing.Any, many: bool | None = None, *args, **kwargs
|
|
20
|
+
) -> Response:
|
|
19
21
|
"""Return a JSON response containing the serialized data.
|
|
20
22
|
|
|
21
23
|
|
|
@@ -5,6 +5,8 @@ flask_marshmallow.validate
|
|
|
5
5
|
Custom validation classes for various types of data.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
import io
|
|
9
11
|
import os
|
|
10
12
|
import re
|
|
@@ -91,11 +93,11 @@ class FileSize(Validator):
|
|
|
91
93
|
|
|
92
94
|
def __init__(
|
|
93
95
|
self,
|
|
94
|
-
min:
|
|
95
|
-
max:
|
|
96
|
+
min: str | None = None,
|
|
97
|
+
max: str | None = None,
|
|
96
98
|
min_inclusive: bool = True,
|
|
97
99
|
max_inclusive: bool = True,
|
|
98
|
-
error:
|
|
100
|
+
error: str | None = None,
|
|
99
101
|
):
|
|
100
102
|
self.min = min
|
|
101
103
|
self.max = max
|
|
@@ -171,7 +173,7 @@ class FileType(Validator):
|
|
|
171
173
|
def __init__(
|
|
172
174
|
self,
|
|
173
175
|
accept: typing.Iterable[str],
|
|
174
|
-
error:
|
|
176
|
+
error: str | None = None,
|
|
175
177
|
):
|
|
176
178
|
self.allowed_types = {ext.lower() for ext in accept}
|
|
177
179
|
self.error = error or self.default_message
|
|
@@ -84,9 +84,8 @@ def ma(app):
|
|
|
84
84
|
@pytest.fixture
|
|
85
85
|
def schemas(ma):
|
|
86
86
|
class AuthorSchema(ma.Schema):
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
id = ma.Integer()
|
|
88
|
+
name = ma.String()
|
|
90
89
|
absolute_url = ma.AbsoluteURLFor("author", values={"id": "<id>"})
|
|
91
90
|
|
|
92
91
|
links = ma.Hyperlinks(
|
|
@@ -97,9 +96,8 @@ def schemas(ma):
|
|
|
97
96
|
)
|
|
98
97
|
|
|
99
98
|
class BookSchema(ma.Schema):
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
id = ma.Integer()
|
|
100
|
+
title = ma.String()
|
|
103
101
|
author = ma.Nested(AuthorSchema)
|
|
104
102
|
|
|
105
103
|
links = ma.Hyperlinks(
|
|
@@ -48,7 +48,10 @@ class TestSQLAlchemy:
|
|
|
48
48
|
|
|
49
49
|
@pytest.fixture
|
|
50
50
|
def db(self, extapp):
|
|
51
|
-
|
|
51
|
+
db = extapp.extensions["sqlalchemy"]
|
|
52
|
+
yield db
|
|
53
|
+
db.session.close()
|
|
54
|
+
db.engine.dispose()
|
|
52
55
|
|
|
53
56
|
@pytest.fixture
|
|
54
57
|
def extma(self, extapp):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flask_marshmallow-1.2.1 → flask_marshmallow-1.3.0}/docs/_themes/flask_small/static/flasky.css_t
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|