flask-marshmallow: marshmallow schemas wired into a Flask application
Flask + marshmallow for beautiful APIs
At a glance
- What is it?
- flask-marshmallow is a thin integration layer between Flask and marshmallow that adds URL and Hyperlinks fields so an API can emit HATEOAS-style links, and it optionally bridges to Flask-SQLAlchemy. The package metadata says version 1.5.0 and requires marshmallow 4, while the newest GitHub release tag is 0.15.0 from 2023, so the two version numbers do not agree.
- Who is it for?
- flask-marshmallow suits a Flask project that already uses marshmallow and wants its schemas to produce API payloads, especially one that wants self and collection links in the response without hand-writing them per view. It does not add much beyond that, and the author says so, calling it a thin integration layer.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A thin layer whose only real addition is hyperlinks
The description is precise about the scope: flask-marshmallow is a thin integration layer for Flask, a Python web framework, and marshmallow, an object serialization and deserialization library, and it adds features to marshmallow including URL and Hyperlinks fields for HATEOAS-ready APIs. It also optionally integrates with Flask-SQLAlchemy. That word thin is doing real work, and it is the right way to think about the package. Almost everything you use comes from marshmallow itself, which is the mature part, and what the integration layer contributes is the Flask specific fields and the ability to resolve endpoint names into URLs. The documentation lives at a readthedocs site, the changelog is published alongside it, and the project is MIT licensed with the file in the repository. The last push was on 2026-10-06 and the default branch is dev, which is worth noting if you are following the repository for changes.
Installing it is one pip command
The install is the standard pip invocation, and the package is on PyPI under the name flask-marshmallow:
pip install flask-marshmallowThe dependency list in the package metadata is short: Flask at 2.2 or newer and marshmallow at 4.0.0 or newer, with requires-python of 3.10 or newer and classifiers for Python 3.10 through 3.14. The compatibility badge records that the current line works with marshmallow 3 and 4, and the marshmallow documentation link in the badge points at the upgrading page, which is where the differences between the two live. The optional SQLAlchemy support is an extra rather than a core dependency, and it pulls in flask-sqlalchemy at 3.0.0 or newer together with marshmallow-sqlalchemy at 1.4.0 or newer, so a project that does not use an ORM does not pay for it.
Marshmallow is instantiated with the app, which is the whole setup
There is one piece of setup and it is short. You create the Flask application and then hand it to the Marshmallow object, so the integration layer knows about the app and can resolve endpoints:
from flask import Flask
from flask_marshmallow import Marshmallow
app = Flask(__name__)
ma = Marshmallow(app)The Marshmallow object is the handle through which everything else is defined, and it is what gives the schemas access to the Flask application context. Everything after this is ordinary marshmallow. The important detail is that the app is passed in at construction rather than registered later, because the URL fields need the app's endpoint map to exist before they can be used. If you are adding this to an existing application factory setup, the Marshmallow instance is created inside the factory alongside the app, not at module level.
Hyperlinks turn endpoint names into URLs in the payload
The feature that distinguishes this from plain marshmallow is the Hyperlinks field, which takes a mapping of names to URL definitions. The schema in the documentation declares a _links attribute with a self entry pointing at a user_detail endpoint with an id value, and a collection entry pointing at the users endpoint:
class UserSchema(ma.Schema):
email = ma.Email()
date_created = ma.DateTime()
# Smart hyperlinking
_links = ma.Hyperlinks(
{
"self": ma.URLFor("user_detail", values=dict(id="<id>")),
"collection": ma.URLFor("users"),
}
)The endpoint names are strings, so the schema refers to the routes rather than hard-coding URL paths, and the values argument fills the variable part of the URL. That is the HATEOAS part: a client reading a user sees both the canonical link to that user and the link to the collection, without needing to know the route pattern. The two schema instances follow, one for a single object and one with many set for a collection.
The views just dump, and the links come out on their own
The view code stays trivial, which is the point of doing the work in the schema. A collection route dumps a list with the many schema, and a detail route dumps one object with the single schema:
@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)The result for a single user is documented in the README as a JSON object with the email, the date_created and a _links object holding the self and collection URLs, with the id substituted into the self link. The deserialisation side of marshmallow is what you use on input, and the integration layer does not change it. What it does change is that the link fields are resolved at dump time, so they always reflect the routes as they are registered when the app starts.
Two version numbers, and the one that tells you what is published
The version picture is confusing enough to be worth laying out, because it decides what you actually get from PyPI. The package metadata declares version 1.5.0, with the description Flask plus marshmallow for beautiful APIs, and it lists two maintainers. The GitHub release list shows a single tag, 0.15.0, dated 2023-04-05. So the metadata version and the release tag are two different numbering lines, and the metadata is the one that reflects the current state of the source, since it also carries the marshmallow 4 dependency and the Python 3.14 classifier, neither of which could exist in a 2023 release. The practical reading is that the project moved to a 1.x line without a matching set of GitHub release tags, so if you want the published artefact, trust the metadata and the package index rather than the releases page. The repository also has a RELEASING.md file, which is where the release process is described, and a CHANGELOG.rst for the history.
A modern build on flit, uv and ruff
The build configuration is current, and it tells you the toolchain the maintainers use. The build backend is flit_core, with flit as the sdist including the docs, tests, changelog and tox configuration, and the backend itself pinned below version 5. Dependency management is uv, with a uv.lock file in the repository and a default group of dev, and the tool is configured to exclude new releases from the last week, which is the usual way to avoid picking up a fresh dependency release in the same change. Development is split into dependency groups: tests with pytest, lint with pre-commit, docs with Sphinx and sphinx-issues, and a dev group that includes the others plus tox and tox-uv. Linting and formatting are ruff, configured with the source directory set to src, with fix and show-fixes enabled, with docstring code formatting turned on, and a rule selection that starts from flake8-bugbear, pycodestyle, pyflakes, isort and pyupgrade. Automated dependency updates come from renovate, and there is a pre-commit configuration file at the root.
Editorial conclusion
flask-marshmallow suits a Flask project that already uses marshmallow and wants its schemas to produce API payloads, especially one that wants self and collection links in the response without hand-writing them per view. It does not add much beyond that, and the author says so, calling it a thin integration layer. Before you depend on it, check which version is actually published, because the package metadata claims 1.5.0 with marshmallow 4 support while the newest tagged release is 0.15.0 from 2023, and read the compatibility note, since the marshmallow 3 and 4 upgrade path is where the breakage lives.
Frequently asked questions
What does flask-marshmallow add to marshmallow?
It is a thin integration layer for Flask and marshmallow that adds URL and Hyperlinks fields for HATEOAS-ready APIs, and it optionally integrates with Flask-SQLAlchemy. The Marshmallow object is constructed with the Flask app so schemas can resolve endpoint names into URLs.
How do I install flask-marshmallow and set it up?
Run pip install flask-marshmallow, then create the Marshmallow object with your app, for example ma = Marshmallow(app) after app = Flask(__name__). The SQLAlchemy integration is optional and comes as an extra that pulls in flask-sqlalchemy and marshmallow-sqlalchemy.
How do I add self and collection links to a marshmallow schema?
Declare a _links attribute with ma.Hyperlinks, mapping names to ma.URLFor calls that name your Flask endpoints. The self entry passes the variable part of the URL through the values argument, as in ma.URLFor("user_detail", values=dict(id="<id>")), and the links are resolved when the schema is dumped.
Which version of flask-marshmallow should I depend on?
The package metadata declares version 1.5.0 with marshmallow 4.0.0 or newer and Python 3.10 or newer, while the newest GitHub release tag is 0.15.0 from 2023. The compatibility badge records support for marshmallow 3 and 4, and the marshmallow upgrading page linked from the badge is where the differences between those two are described.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/marshmallow-code-flask-marshmallow)Was this useful?