Skip to content

Commit

Permalink
Use msgpec JSON conversion if Pydantic isn't installed
Browse files Browse the repository at this point in the history
This ensures the extension does in fact work with msgspec without
pydantic present.
  • Loading branch information
pgjones committed Feb 13, 2024
1 parent dea4312 commit d6ac41d
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/quart_schema/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@
try:
from pydantic_core import to_jsonable_python
except ImportError:
from msgspec import to_builtins as to_jsonable_python # type: ignore
to_jsonable_python = None

try:
from msgspec import to_builtins
except ImportError:
to_builtins = None


SecurityScheme = Union[
Expand Down Expand Up @@ -125,13 +130,23 @@
"""


class JSONProvider(DefaultJSONProvider):
@staticmethod
def default(object_: Any) -> Any:
try:
return super().default(object_)
except TypeError:
return to_jsonable_python(object_)
def create_json_provider(app: Quart) -> DefaultJSONProvider:
preference = app.config["QUART_SCHEMA_CONVERSION_PREFERENCE"]

class JSONProvider(DefaultJSONProvider):
@staticmethod
def default(object_: Any) -> Any:
try:
return super().default(object_)
except TypeError:
if to_jsonable_python is not None and preference != "msgspec":
return to_jsonable_python(object_)
elif to_builtins is not None and preference != "pydantic":
return to_builtins(object_)
else:
raise

return JSONProvider(app)


def hide(func: Callable) -> Callable:
Expand Down Expand Up @@ -262,7 +277,6 @@ def init_app(self, app: Quart) -> None:
if self.info is None:
self.info = Info(title=app.name, version="0.1.0")

app.json = JSONProvider(app)
app.test_client_class = new_class("TestClient", (TestClientMixin, app.test_client_class))
app.websocket_class = new_class( # type: ignore
"Websocket", (WebsocketMixin, app.websocket_class)
Expand All @@ -288,6 +302,8 @@ def init_app(self, app: Quart) -> None:
app.config.setdefault("QUART_SCHEMA_BY_ALIAS", False)
app.config.setdefault("QUART_SCHEMA_CONVERT_CASING", self.convert_casing)
app.config.setdefault("QUART_SCHEMA_CONVERSION_PREFERENCE", self.conversion_preference)
app.json = create_json_provider(app)

if self.openapi_path is not None:
hide(app.send_static_file.__func__) # type: ignore
app.add_url_rule(self.openapi_path, "openapi", self.openapi)
Expand Down

0 comments on commit d6ac41d

Please sign in to comment.