Flask-Marshmallow
Flask-Marshmallow is a thin integration layer for Flask, a Python web framework, and Marshmallow, an object serialization/deserialization library. It enhances Marshmallow with features like URL and Hyperlinks fields for HATEOAS-ready APIs and offers optional integration with Flask-SQLAlchemy. The current version is 1.4.0, and it follows a release cadence tied to Flask and Marshmallow updates.
Warnings
- breaking The `ModelSchema` and `TableSchema` classes were removed in `flask-marshmallow` v0.12.0. You must migrate to `SQLAlchemySchema` or `SQLAlchemyAutoSchema`.
- breaking The syntax for defining `Hyperlinks` fields changed in `flask-marshmallow` v0.14.0. The `id="<id>"` argument is no longer supported; `values=dict(id="<id>")` should be used instead.
- gotcha When integrating with Flask-SQLAlchemy, the `SQLAlchemy` extension must be initialized before the `Marshmallow` extension.
- gotcha Flask's `jsonify` method sorts keys by default, which can override `ordered=True` in your Marshmallow schemas. This can lead to unexpected key ordering in your JSON responses.
- deprecated Accessing `flask_marshmallow.__version__` and `flask_marshmallow.__version_info__` attributes is deprecated.
- gotcha Marshmallow 3.x (a dependency of flask-marshmallow) removed implicit field creation. Schemas no longer infer fields automatically from data introspection.
Install
-
pip install flask-marshmallow
Imports
- Marshmallow
from flask_marshmallow import Marshmallow
- SQLAlchemyAutoSchema
from flask_marshmallow.sqla import SQLAlchemyAutoSchema
Quickstart
from flask import Flask
from flask_marshmallow import Marshmallow
app = Flask(__name__)
ma = Marshmallow(app)
class User:
def __init__(self, id, name, email):
self.id = id
self.name = name
self.email = email
@classmethod
def get(cls, id):
# Simulate fetching a user from a DB
if id == 1:
return cls(1, 'Alice', 'alice@example.com')
return None
@classmethod
def all(cls):
# Simulate fetching all users
return [cls(1, 'Alice', 'alice@example.com'), cls(2, 'Bob', 'bob@example.com')]
class UserSchema(ma.Schema):
id = ma.Int(dump_only=True)
name = ma.Str(required=True)
email = ma.Email(required=True)
_links = ma.Hyperlinks({
"self": ma.URLFor("user_detail", values=dict(id="<id>")),
"collection": ma.URLFor("users")
})
user_schema = UserSchema()
users_schema = UserSchema(many=True)
@app.route("/api/users/")
def users():
all_users = User.all()
return users_schema.dump(all_users)
@app.route("/api/users/<int:id>")
def user_detail(id):
user = User.get(id)
if user:
return user_schema.dump(user)
return {"message": "User not found"}, 404
if __name__ == "__main__":
with app.test_request_context():
# Example usage in a test context
print(users())
print(user_detail(1))
print(user_detail(99))