API Bundle

class flask_unchained.bundles.api.ApiBundle[source]
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
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
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 Serializers on them.

process_objects(app, objects)[source]

Implement to do stuff with discovered objects (eg, registering them with the app instance).

type_check(obj)[source]

Implement to determine which objects in a module should be processed by this hook.

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

Registers serializers.

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

Implement to do stuff with discovered objects (eg, registering them with the app instance).

type_check(obj: Any) → bool[source]

Implement to determine which objects in a module should be processed by this hook.

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

Implement to add objects to the CLI shell context.

ModelResource

class flask_unchained.bundles.api.model_resource.ModelResource(session_manager: flask_unchained.bundles.sqlalchemy.services.session_manager.SessionManager = 'INJECTABLE_PARAMETER')[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 database 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, data, **kwargs)[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