muffin-rest 4.4.3__py3-none-any.whl → 4.5.1__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.
muffin_rest/openapi.py CHANGED
@@ -4,8 +4,7 @@ import re
4
4
  from contextlib import suppress
5
5
  from functools import partial
6
6
  from http import HTTPStatus
7
- from types import ModuleType
8
- from typing import Callable, Dict, List, Optional, Tuple, cast
7
+ from typing import Callable, Dict, List, Tuple, cast
9
8
 
10
9
  from apispec import utils
11
10
  from apispec.core import APISpec
@@ -18,11 +17,11 @@ from muffin import Response
18
17
  from . import LIMIT_PARAM, OFFSET_PARAM, openapi
19
18
  from .options import RESTOptions
20
19
 
21
- yaml_utils: Optional[ModuleType] = None
22
-
23
20
  with suppress(ImportError):
24
21
  from apispec import yaml_utils
25
22
 
23
+ locals().setdefault("yaml_utils", None)
24
+
26
25
 
27
26
  DEFAULT_METHODS = ("get",)
28
27
  HTTP_METHODS = [
@@ -45,7 +44,8 @@ def render_openapi(api, request):
45
44
  # Setup Specs
46
45
  options = dict(api.openapi_options)
47
46
  options.setdefault(
48
- "servers", [{"url": str(request.url.with_query("").with_path(api.prefix))}],
47
+ "servers",
48
+ [{"url": str(request.url.with_query("").with_path(api.prefix))}],
49
49
  )
50
50
 
51
51
  spec = APISpec(
@@ -163,7 +163,6 @@ def return_type_to_response(fn: Callable) -> Dict:
163
163
  and issubclass(return_type, Response)
164
164
  and return_type.content_type
165
165
  ):
166
-
167
166
  responses[return_type.status_code] = {
168
167
  "description": HTTPStatus(return_type.status_code).description,
169
168
  "content": {return_type.content_type: {}},
@@ -2,8 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import TYPE_CHECKING, Optional, Tuple, Type, TypeVar, cast, overload
5
+ from typing import TYPE_CHECKING, Optional, Tuple, Type, cast, overload
6
6
 
7
+ import marshmallow as ma
7
8
  import peewee as pw
8
9
  from apispec.ext.marshmallow import MarshmallowPlugin
9
10
  from marshmallow_peewee import ForeignKey
@@ -14,16 +15,17 @@ from muffin_rest.handler import RESTBase
14
15
  from muffin_rest.peewee.openapi import PeeweeOpenAPIMixin
15
16
 
16
17
  from .options import PWRESTOptions
18
+ from .schemas import EnumField
19
+ from .types import TVModel
17
20
 
18
21
  if TYPE_CHECKING:
19
- import marshmallow as ma
20
22
  from asgi_tools.types import TJSON
21
23
  from muffin import Request
22
24
 
23
25
  # XXX: Patch apispec.MarshmallowPlugin to support ForeignKeyField
24
26
  MarshmallowPlugin.Converter.field_mapping[ForeignKey] = ("integer", None)
25
27
 
26
- TVModel = TypeVar("TVModel", bound=pw.Model)
28
+ assert issubclass(EnumField, ma.fields.Field) # just register EnumField
27
29
 
28
30
 
29
31
  class PWRESTBase(RESTBase[TVModel], PeeweeOpenAPIMixin):
@@ -0,0 +1,36 @@
1
+ import marshmallow as ma
2
+ from marshmallow_peewee import DefaultConverter
3
+ from muffin_peewee.fields import IntEnumField, StrEnumField
4
+
5
+
6
+ class EnumField(ma.fields.Field):
7
+ default_error_messages = {
8
+ "unknown": "Must be one of: {choices}.",
9
+ }
10
+
11
+ def __init__(self, enum, **kwargs):
12
+ self.enum = enum
13
+ self.choices_text = ", ".join([str(c.value) for c in enum])
14
+ super().__init__(**kwargs)
15
+
16
+ def _serialize(self, value, attr, obj, **kwargs):
17
+ if value is None:
18
+ return None
19
+
20
+ return value.value
21
+
22
+ def _deserialize(self, value, attr, data, **kwargs):
23
+ try:
24
+ return self.enum(value)
25
+ except ValueError as error:
26
+ raise self.make_error("unknown", choices=self.choices_text) from error
27
+
28
+
29
+ @DefaultConverter.register(StrEnumField)
30
+ @DefaultConverter.register(IntEnumField)
31
+ def build_field(field, opts, **params):
32
+ params.pop("validate", None)
33
+ return EnumField(field.enum, **params)
34
+
35
+
36
+ # ruff: noqa: ARG001, ARG002
@@ -1,5 +1,6 @@
1
1
  from typing import TypeVar
2
2
 
3
- from peewee import Query
3
+ from peewee import Model, Query
4
4
 
5
+ TVModel = TypeVar("TVModel", bound=Model)
5
6
  TVCollection = TypeVar("TVCollection", bound=Query)
@@ -1,14 +1,16 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: muffin-rest
3
- Version: 4.4.3
3
+ Version: 4.5.1
4
4
  Summary: The package provides enhanced support for writing REST APIs with Muffin framework
5
- Author-email: Kirill Klenov <horneds@gmail.com>
6
- License: MIT License
7
- Project-URL: homepage, https://github.com/klen/muffin-rest
8
- Project-URL: repository, https://github.com/klen/muffin-rest
9
- Project-URL: changelog, https://raw.githubusercontent.com/klen/muffin-rest/master/CHANGELOG.md
5
+ Home-page: https://github.com/klen/muffin-rest
6
+ License: MIT
10
7
  Keywords: rest,api,muffin,asgi,asyncio,trio
8
+ Author: Kirill Klenov
9
+ Author-email: horneds@gmail.com
10
+ Requires-Python: >=3.8,<4.0
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Framework :: AsyncIO
13
+ Classifier: Framework :: Trio
12
14
  Classifier: Intended Audience :: Developers
13
15
  Classifier: License :: OSI Approved :: MIT License
14
16
  Classifier: Programming Language :: Python
@@ -17,46 +19,26 @@ Classifier: Programming Language :: Python :: 3.8
17
19
  Classifier: Programming Language :: Python :: 3.9
18
20
  Classifier: Programming Language :: Python :: 3.10
19
21
  Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.8
26
+ Classifier: Programming Language :: Python :: 3.9
20
27
  Classifier: Topic :: Internet :: WWW/HTTP
21
- Classifier: Framework :: AsyncIO
22
- Classifier: Framework :: Trio
23
- Requires-Python: >=3.8
24
- Description-Content-Type: text/x-rst
25
- License-File: LICENSE
26
- Requires-Dist: apispec (>=4)
27
- Requires-Dist: marshmallow (>=3.14)
28
- Requires-Dist: muffin (>=0.92)
29
- Provides-Extra: dev
30
- Requires-Dist: pre-commit ; extra == 'dev'
31
- Requires-Dist: refurb ; extra == 'dev'
32
- Requires-Dist: bump2version ; extra == 'dev'
33
- Provides-Extra: example
34
- Requires-Dist: uvicorn ; extra == 'example'
35
- Requires-Dist: muffin-peewee-aio ; extra == 'example'
36
- Requires-Dist: marshmallow-peewee ; extra == 'example'
37
28
  Provides-Extra: peewee
38
- Requires-Dist: muffin-peewee-aio (>=0.2.2) ; extra == 'peewee'
39
- Requires-Dist: marshmallow-peewee (>=3.2.0) ; extra == 'peewee'
40
29
  Provides-Extra: sqlalchemy
41
- Requires-Dist: muffin-databases (>=0.3.2) ; extra == 'sqlalchemy'
42
- Requires-Dist: marshmallow-sqlalchemy ; extra == 'sqlalchemy'
43
- Requires-Dist: sqlalchemy ; extra == 'sqlalchemy'
44
- Provides-Extra: tests
45
- Requires-Dist: aiosqlite ; extra == 'tests'
46
- Requires-Dist: marshmallow-peewee (>=3.2.0) ; extra == 'tests'
47
- Requires-Dist: marshmallow-sqlalchemy (>=0.27.0) ; extra == 'tests'
48
- Requires-Dist: muffin-databases (>=0.3.2) ; extra == 'tests'
49
- Requires-Dist: muffin-mongo (>=0.3.1) ; extra == 'tests'
50
- Requires-Dist: muffin-peewee-aio ; extra == 'tests'
51
- Requires-Dist: pytest ; extra == 'tests'
52
- Requires-Dist: pytest-aio[curio,trio] ; extra == 'tests'
53
- Requires-Dist: pytest-mypy ; extra == 'tests'
54
- Requires-Dist: pyyaml ; extra == 'tests'
55
- Requires-Dist: types-PyYAML ; extra == 'tests'
56
- Requires-Dist: types-ujson ; extra == 'tests'
57
- Requires-Dist: ruff ; extra == 'tests'
58
30
  Provides-Extra: yaml
59
- Requires-Dist: pyyaml ; extra == 'yaml'
31
+ Requires-Dist: apispec (>=4,<5)
32
+ Requires-Dist: marshmallow (>=3.14,<4.0)
33
+ Requires-Dist: marshmallow-peewee (>=4,<5) ; extra == "peewee"
34
+ Requires-Dist: marshmallow-sqlalchemy (>=0.27.0,<0.28.0) ; extra == "sqlalchemy"
35
+ Requires-Dist: muffin (>=0.94,<0.95)
36
+ Requires-Dist: muffin-databases (>=0.5.0,<0.6.0) ; extra == "sqlalchemy"
37
+ Requires-Dist: muffin-peewee-aio (>=0.9.6,<0.10.0) ; extra == "peewee"
38
+ Requires-Dist: pyyaml ; extra == "yaml"
39
+ Requires-Dist: sqlalchemy ; extra == "sqlalchemy"
40
+ Project-URL: Repository, https://github.com/klen/muffin-rest
41
+ Description-Content-Type: text/x-rst
60
42
 
61
43
  Muffin-REST
62
44
  ###########
@@ -201,3 +183,4 @@ Licensed under a `MIT license`_.
201
183
  .. _SqlAlchemy Core: https://docs.sqlalchemy.org/en/14/core/
202
184
 
203
185
  .. _MIT license: http://opensource.org/licenses/MIT
186
+
@@ -3,32 +3,32 @@ muffin_rest/api.py,sha256=vGHBQM9JfnAX-9YCyZA7JEAnWiR1iukSS_DRfc5s0fw,3707
3
3
  muffin_rest/errors.py,sha256=sFiXZCEjCvgfuE28GM7_B5iOWGSucCKnGM6ta1efBpY,1168
4
4
  muffin_rest/filters.py,sha256=-Tea863cPCAuwzGkBu45W2AeTtOw2QNdANb_NN7cpjc,4951
5
5
  muffin_rest/handler.py,sha256=Tmp6xRvVl19P3yBf6UR0RPbq8pPIZQjOrjYwjOobWzY,10098
6
- muffin_rest/openapi.py,sha256=LFzrw8uiiYmA-x9xf3FZdmZUQ6kgEuYcfdyPA87j8dc,8825
7
- muffin_rest/options.py,sha256=PcrGY1qq3exgOdeJp8tYYC2V83c5vVMQrARgUkxrNTM,1927
8
- muffin_rest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- muffin_rest/redoc.html,sha256=GtuHIMvTuSi8Ro6bgI-G8VB94AljMyfjcZseqtBmGCY,559
10
- muffin_rest/sorting.py,sha256=cAFbeIyIGm9-aojrEVZtsppBktg6mOGmiUzLHzKHQhQ,2438
11
- muffin_rest/swagger.html,sha256=FGTD5pU9ZUNmlaaVZ1TSajNHvoZ9IiNhJ5yw6Yk_Kz4,4058
12
- muffin_rest/types.py,sha256=HvPwnmZomUFy4jW5IGHSvzYDZjaLY0kMt_unBfynq2g,388
13
- muffin_rest/utils.py,sha256=hAxgIvzf7uCGRhOv0pf-oFxdreBYxp0zpLa7DPILQHY,2036
14
6
  muffin_rest/mongo/__init__.py,sha256=aXD4yxY1pMmmGOFLyzzGdQc-ONJESU76JGMNu_WFzDg,4792
15
7
  muffin_rest/mongo/filters.py,sha256=y2FleM_BqkICKGq3PmM_StOgKlE7RoSxt2NdQfCvnOE,921
16
8
  muffin_rest/mongo/schema.py,sha256=y4OEPQnlV_COTIIQ3cKmpqDpD2r18eAWn0rijQldWm0,1205
17
9
  muffin_rest/mongo/sorting.py,sha256=iJBnaFwE7g_JMwpGpQkoqSqbQK9XULx1K3skiRRgLgY,870
18
10
  muffin_rest/mongo/types.py,sha256=Otqu_FyIVnDAUGcwtzY_B77CKNBYApQPO_LlS2aLAQk,206
19
11
  muffin_rest/mongo/utils.py,sha256=RZdAiKaTsgaFz8WbIPI_sjjVDsF_VmPu5Agzp5mpbvY,3946
20
- muffin_rest/peewee/__init__.py,sha256=l2R_Y9e5X4gC4T9WzPcNJ2Zb8a-LLkWFu_8AF7ZWkBk,5118
12
+ muffin_rest/openapi.py,sha256=b5lq5H1-YMpp6XW6CyttRSApnxEx_QKESSYFhK0Hb4I,8793
13
+ muffin_rest/options.py,sha256=PcrGY1qq3exgOdeJp8tYYC2V83c5vVMQrARgUkxrNTM,1927
14
+ muffin_rest/peewee/__init__.py,sha256=XtKm5fY-6lPWqIhO-WbagtbM7ih7aSzoXY7cwT3ZJOU,5191
21
15
  muffin_rest/peewee/filters.py,sha256=p-BGAKhkoreJfXMeJghIwcWNK0rjv3TkUcMbIFouwP8,2923
22
16
  muffin_rest/peewee/openapi.py,sha256=ZZuh7nJVuK9cTJqtOJ_XASe9iJgter-xIjj9YJ8xszI,1111
23
17
  muffin_rest/peewee/options.py,sha256=RXbuKzlr-MVTx6uyIM1paGdpt1MnDwXm0EkUCs3-zFY,1463
18
+ muffin_rest/peewee/schemas.py,sha256=SijMn7If3keQMwc--omDAqDr7VYASeWuCt7MEZU-waY,1014
24
19
  muffin_rest/peewee/sorting.py,sha256=vQHIrzlFTrirlbXwJNNofBUeYu4HanPanasU0NeKyJ4,1562
25
- muffin_rest/peewee/types.py,sha256=TC7GBvphxqe351NQDy3YmKIJCTxx6JJLdrdak-X0g_8,106
20
+ muffin_rest/peewee/types.py,sha256=cgCXhpGHkImKwudA1lulZHz5oJswHH168AiW5MhZRCM,155
21
+ muffin_rest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ muffin_rest/redoc.html,sha256=GtuHIMvTuSi8Ro6bgI-G8VB94AljMyfjcZseqtBmGCY,559
23
+ muffin_rest/sorting.py,sha256=cAFbeIyIGm9-aojrEVZtsppBktg6mOGmiUzLHzKHQhQ,2438
26
24
  muffin_rest/sqlalchemy/__init__.py,sha256=4ufRdMvuNR8z5lSb7awDdaWurH5zqf6l30D-F78NY_4,6329
27
25
  muffin_rest/sqlalchemy/filters.py,sha256=c6Q8aCQZIzV9cRhANF2A6V2bFHQk8WgaDA6tou3P5jM,3038
28
26
  muffin_rest/sqlalchemy/sorting.py,sha256=YlFKpIet4TUy7fJ2UBLC8b9lAOwY66QBpPDDApbyh8M,1643
29
27
  muffin_rest/sqlalchemy/types.py,sha256=JnIw44XJ2ClWzOv-mTUrvFw1JPxAlvdX_jf7r4zau-s,204
30
- muffin_rest-4.4.3.dist-info/LICENSE,sha256=xHPkOZhjyKBMOwXpWn9IB_BVLjrrMxv2M9slKkHj2hM,1082
31
- muffin_rest-4.4.3.dist-info/METADATA,sha256=W6T25ow2I3KzOv9ikLAyLunsFEUiTyL9SFOLqU0cTig,5242
32
- muffin_rest-4.4.3.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
33
- muffin_rest-4.4.3.dist-info/top_level.txt,sha256=HbkvTHa4P9UnCl-7SojUzWWDsVaBOvhcan7VQpM465M,12
34
- muffin_rest-4.4.3.dist-info/RECORD,,
28
+ muffin_rest/swagger.html,sha256=FGTD5pU9ZUNmlaaVZ1TSajNHvoZ9IiNhJ5yw6Yk_Kz4,4058
29
+ muffin_rest/types.py,sha256=HvPwnmZomUFy4jW5IGHSvzYDZjaLY0kMt_unBfynq2g,388
30
+ muffin_rest/utils.py,sha256=hAxgIvzf7uCGRhOv0pf-oFxdreBYxp0zpLa7DPILQHY,2036
31
+ muffin_rest-4.5.1.dist-info/LICENSE,sha256=xHPkOZhjyKBMOwXpWn9IB_BVLjrrMxv2M9slKkHj2hM,1082
32
+ muffin_rest-4.5.1.dist-info/METADATA,sha256=63Vq5xeNlF0O42_VAIt3b8dkBxZl-PxJwpvbxPEEQbg,4406
33
+ muffin_rest-4.5.1.dist-info/WHEEL,sha256=kLuE8m1WYU0Ig0_YEGrXyTtiJvKPpLpDEiChiNyei5Y,88
34
+ muffin_rest-4.5.1.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: poetry-core 1.5.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -1 +0,0 @@
1
- muffin_rest