Source code for flask_unchained.bundles.api
import enum
from flask_unchained import Bundle, FlaskUnchained, unchained
from flask_unchained._compat import is_local_proxy
from speaklater import _LazyString
from .extensions import Api, Marshmallow, api, ma
from .model_resource import ModelResource
from .model_serializer import ModelSerializer
from .views import OpenAPIController
[docs]class ApiBundle(Bundle):
"""The API Bundle."""
name = 'api_bundle'
"""
The name of the API Bundle.
"""
def __init__(self):
self.resources_by_model = {}
"""
Lookup of resource classes by class name.
"""
self.serializers = {}
"""
Lookup of serializer classes by class name.
"""
self.serializers_by_model = {}
"""
Lookup of serializer classes by model class name
"""
self.create_by_model = {}
"""
Lookup of serializer classes by model class name, as set by
``@ma.serializer(create=True)`` (see
:meth:`~flask_unchained.bundles.api.extensions.Marshmallow.serializer`)
"""
self.many_by_model = {}
"""
Lookup of serializer classes by model class name, as set by
``@ma.serializer(many=True)`` (see
:meth:`~flask_unchained.bundles.api.extensions.Marshmallow.serializer`)
"""
[docs] def after_init_app(self, app: FlaskUnchained):
"""
Configure the JSON encoder for Flask to be able to serialize Enums,
LocalProxy objects, and SQLAlchemy models.
"""
from flask_unchained.bundles.sqlalchemy import BaseModel
class JSONEncoder(app.json_encoder):
def default(self, obj):
if is_local_proxy(obj):
obj = obj._get_current_object()
if isinstance(obj, enum.Enum):
return obj.name
elif isinstance(obj, _LazyString):
return str(obj)
api_bundle = unchained.api_bundle
if isinstance(obj, BaseModel):
model_name = obj.__class__.__name__
serializer_cls = api_bundle.serializers_by_model.get(model_name)
if serializer_cls:
return serializer_cls().dump(obj)
elif (obj and isinstance(obj, (list, tuple))
and isinstance(obj[0], BaseModel)):
model_name = obj[0].__class__.__name__
serializer_cls = api_bundle.many_by_model.get(
model_name,
api_bundle.serializers_by_model.get(model_name))
if serializer_cls:
return serializer_cls(many=True).dump(obj)
return super().default(obj)
app.json_encoder = JSONEncoder