API Bundle

class flask_unchained.bundles.api.ApiBundle[source]

The API Bundle.

name = 'api_bundle'

The name of the API Bundle.

resources_by_model = None

Lookup of resource classes by class name.

serializers = None

Lookup of serializer classes by class name.

serializers_by_model = None

Lookup of serializer classes by model class name

create_by_model = None

Lookup of serializer classes by model class name, as set by @ma.serializer(create=True) (see serializer())

many_by_model = None

Lookup of serializer classes by model class name, as set by @ma.serializer(many=True) (see serializer())

after_init_app(app: flask_unchained.flask_unchained.FlaskUnchained)[source]

Configure the JSON encoder for Flask to be able to serialize Enums, LocalProxy objects, and SQLAlchemy models.

Decorators

flask_unchained.bundles.api.decorators.list_loader(*decorator_args, model)[source]

Decorator to automatically query the database for all records of a model.

Parameters

model – The model class to query

flask_unchained.bundles.api.decorators.patch_loader(*decorator_args, serializer)[source]

Decorator to automatically load and (partially) update a model from json request data

Parameters

serializer – The ModelSerializer to use to load data from the request

flask_unchained.bundles.api.decorators.put_loader(*decorator_args, serializer)[source]

Decorator to automatically load and update a model from json request data

Parameters

serializer – The ModelSerializer to use to load data from the request

flask_unchained.bundles.api.decorators.post_loader(*decorator_args, serializer)[source]

Decorator to automatically instantiate a model from json request data

Parameters

serializer – The ModelSerializer to use to load data from the request

Extensions

class flask_unchained.bundles.api.extensions.Api[source]

The Api extension:

from flask_unchained.bundles.api import api

Allows interfacing with apispec.

register_serializer(serializer, name=None, **kwargs)[source]

Method to manually register a Serializer with APISpec.

Parameters
  • serializer

  • name

  • kwargs

register_model_resource(resource: flask_unchained.bundles.api.model_resource.ModelResource)[source]

Method to manually register a ModelResource with APISpec.

Parameters

resource

register_converter(converter, conv_type, conv_format=None, *, name=None)[source]

Register custom path parameter converter.

Parameters
  • converter (BaseConverter) – Converter Subclass of werkzeug’s BaseConverter

  • conv_type (str) – Parameter type

  • conv_format (str) – Parameter format (optional)

  • name (str) –

    Name of the converter. If not None, this name is used to register the converter in the Flask app. Example:

    api.register_converter(
        UUIDConverter, 'string', 'UUID', name='uuid')
    @blp.route('/pets/{uuid:pet_id}')
        # ...
    api.register_blueprint(blp)
    

This registers the converter in the Flask app and in the internal APISpec instance.

Once the converter is registered, all paths using it will have corresponding path parameter documented with the right type and format. The name parameter need not be passed if the converter is already registered in the app, for instance if it belongs to a Flask extension that already registers it in the app.

register_field(field, *args)[source]

Register custom Marshmallow field.

Registering the Field class allows the Schema parser to set the proper type and format when documenting parameters from Schema fields.

Parameters

field (Field) – Marshmallow Field class

Param

args: - a pair of the form (type, format) to map to - a core marshmallow field type (then that type’s mapping is used)

Examples:

# Map to ('string', 'UUID')
api.register_field(UUIDField, 'string', 'UUID')
# Map to ('string')
api.register_field(URLField, 'string', None)
# Map to ('integer, 'int32')
api.register_field(CustomIntegerField, ma.fields.Integer)
class flask_unchained.bundles.api.extensions.Marshmallow[source]

The Marshmallow extension:

from flask_unchained.bundles.api import ma

Allows decorating a ModelSerializer with serializer() to specify it should be used for creating objects, listing them, or as the fallback.

Also provides aliases from the following modules:

flask_unchained.bundles.api

marshmallow.decorators

marshmallow.exceptions

marshmallow.fields

flask_marshmallow.fields

flask_marshmallow.sqla

serializer(create=False, many=False)[source]

Decorator to mark a Serializer subclass for a specific purpose, ie, to be used during object creation or for serializing lists of objects.

Parameters
  • create – Whether or not this serializer is for object creation.

  • many – Whether or not this serializer is for lists of objects.

Hooks

class flask_unchained.bundles.api.hooks.RegisterModelResourcesHook(unchained: flask_unchained.unchained.Unchained, bundle: Optional[flask_unchained.bundles.Bundle] = None)[source]

Registers ModelResources and configures ModelSerializers on them.

name = 'model_resources'

The name of this hook.

bundle_module_names = ['views']

The default module this hook loads from.

Override by setting the model_resources_module_names attribute on your bundle class.

process_objects(app, objects)[source]

Configures ModelSerializers on ModelResources.

type_check(obj)[source]

Returns True if obj is a subclass of ModelResource.

class flask_unchained.bundles.api.hooks.RegisterModelSerializersHook(unchained: flask_unchained.unchained.Unchained, bundle: Optional[flask_unchained.bundles.Bundle] = None)[source]

Registers ModelSerializers.

name = 'model_serializers'

The name of this hook.

bundle_module_names = ['serializers']

The default module this hook loads from.

Override by setting the model_serializers_module_names attribute on your bundle class.

process_objects(app: flask_unchained.flask_unchained.FlaskUnchained, serializers: Dict[str, Type[flask_unchained.bundles.api.model_serializer.ModelSerializer]]) → None[source]

Registers model serializers onto the API Bundle instance.

type_check(obj: Any) → bool[source]

Returns True if obj is a subclass of ModelSerializer.

update_shell_context(ctx: Dict[str, Any]) → None[source]

Adds model serializers to the CLI shell context.

ModelResource

class flask_unchained.bundles.api.model_resource.ModelResource[source]

Base class for model resources. This is intended for building RESTful APIs with SQLAlchemy models and Marshmallow serializers.

list(instances)[source]

List model instances.

Parameters

instances – The list of model instances.

Returns

The list of model instances.

create(instance, errors)[source]

Create an instance of a model.

Parameters
  • instance – The created model instance.

  • errors – Any errors.

Returns

The created model instance, or a dictionary of errors.

get(instance)[source]

Get an instance of a model.

Parameters

instance – The model instance.

Returns

The model instance.

patch(instance, errors)[source]

Partially update a model instance.

Parameters
  • instance – The model instance.

  • errors – Any errors.

Returns

The updated model instance, or a dictionary of errors.

put(instance, errors)[source]

Update a model instance.

Parameters
  • instance – The model instance.

  • errors – Any errors.

Returns

The updated model instance, or a dictionary of errors.

delete(instance)[source]

Delete a model instance.

Parameters

instance – The model instance.

Returns

HTTPStatus.NO_CONTENT

created(instance, commit=True)[source]

Convenience method for saving a model (automatically commits it to the database and returns the object with an HTTP 201 status code)

deleted(instance)[source]

Convenience method for deleting a model (automatically commits the delete to the database and returns with an HTTP 204 status code)

updated(instance)[source]

Convenience method for updating a model (automatically commits it to the database and returns the object with with an HTTP 200 status code)

ModelSerializer

class flask_unchained.bundles.api.model_serializer.ModelSerializer(*args, **kwargs)[source]

Base class for SQLAlchemy model serializers. This is pretty much a stock flask_marshmallow.sqla.ModelSchema, except:

  • dependency injection is set up automatically on ModelSerializer

  • when loading to update an existing instance, validate the primary keys are the same

  • automatically make fields named slug, model.Meta.created_at, and model.Meta.updated_at dump-only

For example:

from flask_unchained.bundles.api import ModelSerializer
from flask_unchained.bundles.security.models import Role

class RoleSerializer(ModelSerializer):
    class Meta:
        model = Role

Is roughly equivalent to:

from marshmallow import Schema, fields

class RoleSerializer(Schema):
    id = fields.Integer(dump_only=True)
    name = fields.String()
    description = fields.String()
    created_at = fields.DateTime(dump_only=True)
    updated_at = fields.DateTime(dump_only=True)
OPTIONS_CLASS

alias of _ModelSerializerOptionsClass

is_create()[source]

Check if we’re creating a new object. Note that this context flag must be set from the outside, ie when the class gets instantiated.

load(data: Mapping, *, many: bool = None, partial: Union[bool, Sequence[str], Set[str]] = None, unknown: str = None, **kwargs)[source]

Deserialize a dict to an object defined by this ModelSerializer’s fields.

A ValidationError is raised if invalid data is passed.

Parameters
  • data – The data to deserialize.

  • many – Whether to deserialize data as a collection. If None, the value for self.many is used.

  • partial – Whether to ignore missing fields and not require any fields declared. Propagates down to Nested fields as well. If its value is an iterable, only missing fields listed in that iterable will be ignored. Use dot delimiters to specify nested fields.

  • unknown – Whether to exclude, include, or raise an error for unknown fields in the data. Use EXCLUDE, INCLUDE or RAISE. If None, the value for self.unknown is used.

Returns

Deserialized data

dump(obj, *, many: bool = None)[source]

Serialize an object to native Python data types according to this ModelSerializer’s fields.

Parameters
  • obj – The object to serialize.

  • many – Whether to serialize obj as a collection. If None, the value for self.many is used.

Returns

A dict of serialized data

Return type

dict

handle_error(error: marshmallow.exceptions.ValidationError, data: Any, **kwargs) → None[source]

Customize the error messages for required/not-null validators with dynamically generated field names. This is definitely a little hacky (it mutates state, uses hardcoded strings), but unsure how better to do it