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,
SQLAlchemySchemauses the scoped session created by Flask-SQLAlchemy.SQLAlchemySchemasubclassesflask_marshmallow.Schema, so it includes thejsonifymethod.
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=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
Schemaclass, all fields inmarshmallow.fields, as well as the Flask-specific fields inflask_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.SQLAlchemySchemaandma.SQLAlchemyAutoSchema, which generate marshmallowSchemaclasses 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)¶
Initializes the application with the extension.
- Parameters:
app (Flask) – The Flask application object.
- class flask_marshmallow.Schema(*, only: Optional[Union[Sequence[str], Set[str]]] = None, exclude: Union[Sequence[str], Set[str]] = (), many: bool = False, context: dict | None = None, load_only: Union[Sequence[str], Set[str]] = (), dump_only: Union[Sequence[str], Set[str]] = (), partial: Union[bool, Sequence[str], Set[str]] = False, unknown: str | None = None)¶
Base serializer with which to define custom serializers.
See
marshmallow.Schemafor more details about theSchemaAPI.- jsonify(obj, many=<object object>, *args, **kwargs)¶
Return a JSON response containing the serialized data.
- Parameters:
obj – Object to serialize.
many (bool) – Whether
objshould be serialized as an instance or as a collection. If unset, defaults to the value of themanyattribute 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 toflask.jsonify.Changed in version 0.6.3: The
manyargument for this method defaults to the value of themanyattribute on the Schema. Previously, themanyargument of this method defaulted to False, regardless of the value ofSchema.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, values=None, **kwargs)¶
Field that outputs the absolute URL for an endpoint.
- flask_marshmallow.fields.AbsoluteUrlFor¶
alias of
AbsoluteURLFor
- class flask_marshmallow.fields.Hyperlinks(schema, **kwargs)¶
Field that outputs a dictionary of hyperlinks, given a dictionary schema with
URLForobjects as values.Example:
_links = Hyperlinks({ 'self': URLFor('author', values=dict(id='<id>')), 'collection': URLFor('author_list'), })
URLForobjects can be nested within the dictionary._links = Hyperlinks({ 'self': { 'href': URLFor('book', values=dict(id='<id>')), 'title': 'book detail' } })
- class flask_marshmallow.fields.URLFor(endpoint, values=None, id=None, **kwargs)¶
Field that outputs the URL for an endpoint. Acts identically to Flask’s
url_forfunction, except that arguments can be pulled from the object to be serialized, and**valuesshould be passed to thevaluesparameter.Usage:
url = URLFor('author_get', values=dict(id='<id>')) https_url = URLFor('author_get', values=dict(id='<id>', _scheme='https', _external=True))
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, url_key='id', external=False, **kwargs)¶
Field that generates hyperlinks to indicate references between models, rather than primary keys.
- 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.SQLAlchemyAutoSchemafor more details on theSQLAlchemyAutoSchemaAPI.- 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
modelclass Meta option, which should be adb.Modelclass fromflask_sqlalchemy. Uses the scoped session from Flask-SQLAlchemy by default.See
marshmallow_sqlalchemy.SQLAlchemySchemafor more details on theSQLAlchemySchemaAPI.- OPTIONS_CLASS¶
alias of
SQLAlchemySchemaOpts
- opts: SchemaOpts = <flask_marshmallow.sqla.SQLAlchemySchemaOpts object>¶
- class flask_marshmallow.sqla.SQLAlchemySchemaOpts(meta, **kwargs)¶