# Flask-Marshmallow: Flask + marshmallow for beautiful APIs

changelog // github // pypi // issues

## Flask + marshmallow for beautiful APIs

Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmallow (an object serialization/deserialization library) that adds additional features to marshmallow, including URL and Hyperlinks fields for HATEOAS-ready APIs. It also (optionally) integrates with Flask-SQLAlchemy.

### Get it now

    pip install flask-marshmallow

Create your app.

    from flask import Flask
    from flask_marshmallow import Marshmallow

    app = Flask(__name__)
    ma = Marshmallow(app)

Write your models.

    from your_orm import Model, Column, Integer, String, DateTime

    class User(Model):
        email = Column(String)
        password = Column(String)
        date_created = Column(DateTime, auto_now_add=True)

Define your output format with marshmallow.

    class UserSchema(ma.Schema):
        class Meta:
            # Fields to expose
            fields = ("email", "date_created", "_links")

        # Smart hyperlinking
        _links = ma.Hyperlinks(
            {
                "self": ma.URLFor("user_detail", values=dict(id="<id>")),
                "collection": ma.URLFor("users"),
            }
        )

    user_schema = UserSchema()
    users_schema = UserSchema(many=True)

Output the data in your views.

    @app.route("/api/users/")
    def users():
        all_users = User.all()
        return users_schema.dump(all_users)

    @app.route("/api/users/<id>")
    def user_detail(id):
        user = User.get(id)
        return user_schema.dump(user)

    # {
    #     "email": "fred@queen.com",
    #     "date_created": "Fri, 25 Apr 2014 06:02:56 -0000",
    #     "_links": {
    #         "self": "/api/users/42",
    #         "collection": "/api/users/"
    #     }
    # }

### Optional Flask-SQLAlchemy Integration

Flask-Marshmallow includes useful extras for integrating with Flask-SQLAlchemy and marshmallow-sqlalchemy.

To enable SQLAlchemy integration, make sure that both Flask-SQLAlchemy and marshmallow-sqlalchemy are installed.

    pip install -U flask-sqlalchemy marshmallow-sqlalchemy

Next, initialize the `SQLAlchemy` and `Marshmallow` extensions, in that order.

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from flask_marshmallow import Marshmallow

    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"

    # Order matters: Initialize SQLAlchemy before Marshmallow
    db = SQLAlchemy(app)
    ma = Marshmallow(app)

Note on initialization order

Flask-SQLAlchemy must be initialized before Flask-Marshmallow.

Declare your models like normal.

    class Author(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(255))

    class Book(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String(255))
        author_id = db.Column(db.Integer, db.ForeignKey("author.id"))
        author = db.relationship("Author", backref="books")

Generate marshmallow `Schemas` from your models using `SQLAlchemySchema` or `SQLAlchemyAutoSchema`.

    class AuthorSchema(ma.SQLAlchemySchema):
        class Meta:
            model = Author

        id = ma.auto_field()
        name = ma.auto_field()
        books = ma.auto_field()

    class BookSchema(ma.SQLAlchemyAutoSchema):
        class Meta:
            model = Book
            include_fk = True

You can now use your schema to dump and load your ORM objects.

    db.create_all()
    author_schema = AuthorSchema()
    book_schema = BookSchema()
    author = Author(name="Chuck Paluhniuk")
    book = Book(title="Fight Club", author=author)
    db.session.add(author)
    db.session.add(book)
    db.session.commit()
    author_schema.dump(author)
    # {'id': 1, 'name': 'Chuck Paluhniuk', 'books': [1]}

`SQLAlchemySchema` is nearly identical in API to `marshmallow_sqlalchemy.SQLAlchemySchema` with the following exceptions:

- By default, `SQLAlchemySchema` uses the scoped session created by Flask-SQLAlchemy.

- `SQLAlchemySchema` subclasses `flask_marshmallow.Schema`, so it includes the `jsonify` method.

Note: By default, Flask’s `jsonify` method sorts the list of keys and returns consistent results to ensure that external HTTP caches aren’t trashed. As a side effect, this will override ordered=True in the SQLAlchemySchema’s `class Meta` (if you set it). To disable this, set `JSON_SORT_KEYS=False` in your Flask app config. In production it’s recommended to let `jsonify` sort the keys and not set `ordered=True` in your `SQLAlchemySchema` in order to minimize generation time and maximize cacheability of the results.

You can also use `ma.HyperlinkRelated` fields if you want relationships to be represented by hyperlinks rather than primary keys.

    class BookSchema(ma.SQLAlchemyAutoSchema):
        class Meta:
            model = Book

        author = ma.HyperlinkRelated("author_detail")

    with app.test_request_context():
        print(book_schema.dump(book))
    # {'id': 1, 'title': 'Fight Club', 'author': '/authors/1'}

The first argument to the `HyperlinkRelated` constructor is the name of the view used to generate the URL, just as you would pass it to the `url_for` function. If your models and views use the `id` attribute as a primary key, you’re done; otherwise, you must specify the name of the attribute used as the primary key.

To represent a one-to-many relationship, wrap the `HyperlinkRelated` instance in a `marshmallow.fields.List` field, like this:

    class AuthorSchema(ma.SQLAlchemyAutoSchema):
        class Meta:
            model = Author

        books = ma.List(ma.HyperlinkRelated("book_detail"))

    with app.test_request_context():
        print(author_schema.dump(author))
    # {'id': 1, 'name': 'Chuck Paluhniuk', 'books': ['/books/1']}

## API

### flask_marshmallow

Integrates the marshmallow serialization/deserialization library with your Flask application.

class flask_marshmallow.Marshmallow(app: Flask | None = None)

  Wrapper class that integrates Marshmallow with a Flask application.

  To use it, instantiate with an application:

      from flask import Flask

      app = Flask(__name__)
      ma = Marshmallow(app)

  The object provides access to the `Schema` class, all fields in `marshmallow.fields`, as well as the Flask-specific fields in `flask_marshmallow.fields`.

  You can declare schema like so:

      class BookSchema(ma.Schema):
          class Meta:
              fields = ('id', 'title', 'author', 'links')

          author = ma.Nested(AuthorSchema)

          links = ma.Hyperlinks({
              'self': ma.URLFor('book_detail', values=dict(id='<id>')),
              'collection': ma.URLFor('book_list')
          })

  In order to integrate with Flask-SQLAlchemy, this extension must be initialized after `flask_sqlalchemy.SQLAlchemy`.

      db = SQLAlchemy(app)
      ma = Marshmallow(app)

  This gives you access to `ma.SQLAlchemySchema` and `ma.SQLAlchemyAutoSchema`, which generate marshmallow `Schema` classes based on the passed in model or table.

      class AuthorSchema(ma.SQLAlchemyAutoSchema):
          class Meta:
              model = Author

  Parameters:

    app (Flask) – The Flask application object.

  init_app(app: Flask)

    Initializes the application with the extension.

    Parameters:

      app (Flask) – The Flask application object.

class flask_marshmallow.Schema(*, only: Sequence[str] | AbstractSet[str] | None = None, exclude: Sequence[str] | AbstractSet[str] = (), many: bool = False, context: dict | None = None, load_only: Sequence[str] | AbstractSet[str] = (), dump_only: Sequence[str] | AbstractSet[str] = (), partial: bool | Sequence[str] | AbstractSet[str] | None = None, unknown: str | None = None)

  Base serializer with which to define custom serializers.

  See `marshmallow.Schema` for more details about the `Schema` API.

  jsonify(obj: Any, many: bool | None = None, *args, **kwargs) → Response

    Return a JSON response containing the serialized data.

    Parameters:

      - obj – Object to serialize.

      - many (bool) – Whether `obj` should be serialized as an instance or as a collection. If None, defaults to the value of the `many` attribute on this Schema.

      - kwargs – Additional keyword arguments passed to `flask.jsonify`.

    Changed in version 0.6.0: Takes the same arguments as `marshmallow.Schema.dump`. Additional keyword arguments are passed to `flask.jsonify`.

    Changed in version 0.6.3: The `many` argument for this method defaults to the value of the `many` attribute on the Schema. Previously, the `many` argument of this method defaulted to False, regardless of the value of `Schema.many`.

flask_marshmallow.pprint(obj, *args, **kwargs) → None

  Pretty-printing function that can pretty-print OrderedDicts like regular dictionaries. Useful for printing the output of `marshmallow.Schema.dump()`.

  Deprecated since version 3.7.0: marshmallow.pprint will be removed in marshmallow 4.

### flask_marshmallow.fields

Custom, Flask-specific fields.

See the `marshmallow.fields` module for the list of all fields available from the marshmallow library.

class flask_marshmallow.fields.AbsoluteURLFor(endpoint: str, values: Dict[str, Any] | None = None, **kwargs)

  Field that outputs the absolute URL for an endpoint.

flask_marshmallow.fields.AbsoluteUrlFor

  alias of `AbsoluteURLFor`

class flask_marshmallow.fields.Config(key: str, **kwargs)

  A field for Flask configuration values.

  Examples:

      from flask import Flask

      app = Flask(__name__)
      app.config['API_TITLE'] = 'Pet API'

      class FooSchema(Schema):
          user = String()
          title = Config('API_TITLE')

  This field should only be used in an output schema. A `ValueError` will be raised if the config key is not found in the app config.

  Parameters:

    key (str) – The key of the configuration value.

class flask_marshmallow.fields.File(*args, **kwargs)

  A binary file field for uploaded files.

  Examples:

      class ImageSchema(Schema):
          image = File(required=True)

  default_error_messages = {'invalid': 'Not a valid file.'}

    Default error messages for various kinds of errors. The keys in this dictionary are passed to `Field.make_error`. The values are error messages passed to `marshmallow.exceptions.ValidationError`.

class flask_marshmallow.fields.Hyperlinks(schema: Dict[str, URLFor | str], **kwargs)

  Field that outputs a dictionary of hyperlinks, given a dictionary schema with `URLFor` objects as values.

  Example:

      _links = Hyperlinks({
          'self': URLFor('author', values=dict(id='<id>')),
          'collection': URLFor('author_list'),
      })

  `URLFor` objects can be nested within the dictionary.

      _links = Hyperlinks({
          'self': {
              'href': URLFor('book', values=dict(id='<id>')),
              'title': 'book detail'
          }
      })

  Parameters:

    schema (dict) – A dict that maps names to `URLFor` fields.

class flask_marshmallow.fields.URLFor(endpoint: str, values: Dict[str, Any] | None = None, **kwargs)

  Field that outputs the URL for an endpoint. Acts identically to Flask’s `url_for` function, except that arguments can be pulled from the object to be serialized, and `**values` should be passed to the `values` parameter.

  Usage:

      url = URLFor('author_get', values=dict(id='<id>'))
      https_url = URLFor(
          'author_get',
          values=dict(id='<id>', _scheme='https', _external=True),
      )

  Parameters:

    - endpoint (str) – Flask endpoint name.

    - values (dict) – Same keyword arguments as Flask’s url_for, except string arguments enclosed in `< >` will be interpreted as attributes to pull from the object.

    - kwargs – keyword arguments to pass to marshmallow field (e.g. `required`).

flask_marshmallow.fields.UrlFor

  alias of `URLFor`

### flask_marshmallow.validate

Custom validation classes for various types of data.

class flask_marshmallow.validate.FileSize(min: str | None = None, max: str | None = None, min_inclusive: bool = True, max_inclusive: bool = True, error: str | None = None)

  Validator which succeeds if the file passed to it is within the specified size range. If `min` is not specified, or is specified as `None`, no lower bound exists. If `max` is not specified, or is specified as `None`, no upper bound exists. The inclusivity of the bounds (if they exist) is configurable. If `min_inclusive` is not specified, or is specified as `True`, then the `min` bound is included in the range. If `max_inclusive` is not specified, or is specified as `True`, then the `max` bound is included in the range.

  Example:

      class ImageSchema(Schema):
          image = File(required=True, validate=FileSize(min='1 MiB', max='2 MiB'))

  Parameters:

    - min – The minimum size (lower bound). If not provided, minimum size will not be checked.

    - max – The maximum size (upper bound). If not provided, maximum size will not be checked.

    - min_inclusive – Whether the `min` bound is included in the range.

    - max_inclusive – Whether the `max` bound is included in the range.

    - error – Error message to raise in case of a validation error. Can be interpolated with `{input}`, `{min}` and `{max}`.

class flask_marshmallow.validate.FileType(accept: Iterable[str], error: str | None = None)
  Validator which succeeds if the uploaded file is allowed by a given list

    of extensions.

  Example: ::
    class ImageSchema(Schema):

      image = File(required=True, validate=FileType([‘.png’]))

  Parameters:

    - accept – A sequence of allowed extensions.

    - error – Error message to raise in case of a validation error. Can be interpolated with `{input}` and `{extensions}`.

### flask_marshmallow.sqla

Integration with Flask-SQLAlchemy and marshmallow-sqlalchemy. Provides `SQLAlchemySchema` and `SQLAlchemyAutoSchema` classes that use the scoped session from Flask-SQLAlchemy.

class flask_marshmallow.sqla.DummySession

  Placeholder session object.

class flask_marshmallow.sqla.HyperlinkRelated(endpoint: str, url_key: str = 'id', external: bool = False, **kwargs)

  Field that generates hyperlinks to indicate references between models, rather than primary keys.

  Parameters:

    - endpoint (str) – Flask endpoint name for generated hyperlink.

    - url_key (str) – The attribute containing the reference’s primary key. Defaults to “id”.

    - external (bool) – Set to `True` if absolute URLs should be used, instead of relative URLs.

class flask_marshmallow.sqla.SQLAlchemyAutoSchema(*args, **kwargs)

  SQLAlchemyAutoSchema that automatically generates marshmallow fields from a SQLAlchemy model’s or table’s column. Uses the scoped session from Flask-SQLAlchemy by default.

  See `marshmallow_sqlalchemy.SQLAlchemyAutoSchema` for more details on the `SQLAlchemyAutoSchema` API.

  OPTIONS_CLASS

    alias of `SQLAlchemyAutoSchemaOpts`

  opts: SchemaOpts = <flask_marshmallow.sqla.SQLAlchemyAutoSchemaOpts object>

class flask_marshmallow.sqla.SQLAlchemyAutoSchemaOpts(meta, **kwargs)

class flask_marshmallow.sqla.SQLAlchemySchema(*args, **kwargs)

  SQLAlchemySchema that associates a schema with a model via the `model` class Meta option, which should be a `db.Model` class from `flask_sqlalchemy`. Uses the scoped session from Flask-SQLAlchemy by default.

  See `marshmallow_sqlalchemy.SQLAlchemySchema` for more details on the `SQLAlchemySchema` API.

  OPTIONS_CLASS

    alias of `SQLAlchemySchemaOpts`

  opts: SchemaOpts = <flask_marshmallow.sqla.SQLAlchemySchemaOpts object>

class flask_marshmallow.sqla.SQLAlchemySchemaOpts(meta, **kwargs)

## Useful Links

- Flask docs

- marshmallow docs

## Project Info

- License
- Changelog