marshmallow-jsonapi¶
Release v0.24.0. (Changelog)
JSON API 1.0 (https://jsonapi.org) formatting with marshmallow.
marshmallow-jsonapi provides a simple way to produce JSON API-compliant data in any Python web framework.
from marshmallow_jsonapi import Schema, fields
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
author = fields.Relationship(
related_url="/authors/{author_id}",
related_url_kwargs={"author_id": "<author.id>"},
)
comments = fields.Relationship(
related_url="/posts/{post_id}/comments",
related_url_kwargs={"post_id": "<id>"},
# Include resource linkage
many=True,
include_resource_linkage=True,
type_="comments",
)
class Meta:
type_ = "posts"
strict = True
post_schema = PostSchema()
post_schema.dump(post)
# {
# "data": {
# "id": "1",
# "type": "posts"
# "attributes": {
# "title": "JSON API paints my bikeshed!"
# },
# "relationships": {
# "author": {
# "links": {
# "related": "/authors/9"
# }
# },
# "comments": {
# "data": [
# {"id": 5, "type": "comments"},
# {"id": 12, "type": "comments"}
# ],
# "links": {
# "related": "/posts/1/comments/"
# }
# }
# },
# }
# }
Installation¶
pip install marshmallow-jsonapi
Guide¶
Quickstart¶
Note
The following guide assumes some familiarity with the marshmallow API. To learn more about marshmallow, see its official documentation at https://marshmallow.readthedocs.io.
Declaring schemas¶
Let’s start with a basic post “model”.
class Post:
def __init__(self, id, title):
self.id = id
self.title = title
Declare your schemas as you would with marshmallow.
A Schema
MUST define:
An
id
fieldThe
type_
class Meta option
It is RECOMMENDED to set strict mode to True
.
Automatic self-linking is supported through these Meta options:
self_url
specifies the URL to the resource itselfself_url_kwargs
specifies replacement fields forself_url
self_url_many
specifies the URL the resource when a collection (many) are serialized
from marshmallow_jsonapi import Schema, fields
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
class Meta:
type_ = "posts"
self_url = "/posts/{id}"
self_url_kwargs = {"id": "<id>"}
self_url_many = "/posts/"
These URLs can be auto-generated by specifying self_view
, self_view_kwargs
and self_view_many
instead when using the Flask integration.
Serialization¶
Objects will be serialized to JSON API documents with primary data.
post = Post(id="1", title="Django is Omakase")
PostSchema().dump(post)
# {
# 'data': {
# 'id': '1',
# 'type': 'posts',
# 'attributes': {'title': 'Django is Omakase'},
# 'links': {'self': '/posts/1'}
# },
# 'links': {'self': '/posts/1'}
# }
Relationships¶
The Relationship
field is used to serialize relationship objects. For example, a Post may have an author and comments associated with it.
class User:
def __init__(self, id, name):
self.id = id
self.name = name
class Comment:
def __init__(self, id, body, author):
self.id = id
self.body = body
self.author = author
class Post:
def __init__(self, id, title, author, comments=None):
self.id = id
self.title = title
self.author = author # User object
self.comments = [] if comments is None else comments # Comment objects
To serialize links, pass a URL format string and a dictionary of keyword arguments. String arguments enclosed in < >
will be interpreted as attributes to pull from the object being serialized. The relationship links can automatically be generated from Flask view names when using the Flask integration.
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
author = fields.Relationship(
self_url="/posts/{post_id}/relationships/author",
self_url_kwargs={"post_id": "<id>"},
related_url="/authors/{author_id}",
related_url_kwargs={"author_id": "<author.id>"},
)
class Meta:
type_ = "posts"
user = User(id="94", name="Laura")
post = Post(id="1", title="Django is Omakase", author=user)
PostSchema().dump(post)
# {
# 'data': {
# 'id': '1',
# 'type': 'posts',
# 'attributes': {'title': 'Django is Omakase'},
# 'relationships': {
# 'author': {
# 'links': {
# 'self': '/posts/1/relationships/author',
# 'related': '/authors/94'
# }
# }
# }
# }
# }
Resource linkages¶
You can serialize resource linkages by passing include_resource_linkage=True
and the resource type_
argument.
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
author = fields.Relationship(
self_url="/posts/{post_id}/relationships/author",
self_url_kwargs={"post_id": "<id>"},
related_url="/authors/{author_id}",
related_url_kwargs={"author_id": "<author.id>"},
# Include resource linkage
include_resource_linkage=True,
type_="users",
)
class Meta:
type_ = "posts"
PostSchema().dump(post)
# {
# 'data': {
# 'id': '1',
# 'type': 'posts',
# 'attributes': {'title': 'Django is Omakase'},
# 'relationships': {
# 'author': {
# 'data': {'type': 'users', 'id': '94'},
# 'links': {
# 'self': '/posts/1/relationships/author',
# 'related': '/authors/94'
# }
# }
# }
# }
# }
Compound documents¶
Compound documents allow to include related resources into the request with the primary resource. In order to include objects, you have to define a Schema
for the respective relationship, which will be used to render those objects.
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
comments = fields.Relationship(
related_url="/posts/{post_id}/comments",
related_url_kwargs={"post_id": "<id>"},
many=True,
include_resource_linkage=True,
type_="comments",
# define a schema for rendering included data
schema="CommentSchema",
)
author = fields.Relationship(
self_url="/posts/{post_id}/relationships/author",
self_url_kwargs={"post_id": "<id>"},
related_url="/authors/{author_id}",
related_url_kwargs={"author_id": "<author.id>"},
include_resource_linkage=True,
type_="users",
)
class Meta:
type_ = "posts"
class CommentSchema(Schema):
id = fields.Str(dump_only=True)
body = fields.Str()
author = fields.Relationship(
self_url="/comments/{comment_id}/relationships/author",
self_url_kwargs={"comment_id": "<id>"},
related_url="/comments/{author_id}",
related_url_kwargs={"author_id": "<author.id>"},
type_="users",
# define a schema for rendering included data
schema="UserSchema",
)
class Meta:
type_ = "comments"
class UserSchema(Schema):
id = fields.Str(dump_only=True)
name = fields.Str()
class Meta:
type_ = "users"
Just as with nested fields the schema
can be a class or a string with a simple or fully qualified class name. Make sure to import the schema beforehand.
Now you can include some data in a dump by specifying the include_data
argument (also supports nested relations via the dot syntax).
armin = User(id="101", name="Armin")
laura = User(id="94", name="Laura")
steven = User(id="23", name="Steven")
comments = [
Comment(id="5", body="Marshmallow is sweet like sugar!", author=steven),
Comment(id="12", body="Flask is Fun!", author=armin),
]
post = Post(id="1", title="Django is Omakase", author=laura, comments=comments)
PostSchema(include_data=("comments", "comments.author")).dump(post)
# {
# 'data': {
# 'id': '1',
# 'type': 'posts',
# 'attributes': {'title': 'Django is Omakase'},
# 'relationships': {
# 'author': {
# 'data': {'type': 'users', 'id': '94'},
# 'links': {
# 'self': '/posts/1/relationships/author',
# 'related': '/authors/94'
# }
# },
# 'comments': {
# 'data': [
# {'type': 'comments', 'id': '5'},
# {'type': 'comments', 'id': '12'}
# ],
# 'links': {
# 'related': '/posts/1/comments'
# }
# }
# }
# },
# 'included': [
# {
# 'id': '5',
# 'type': 'comments',
# 'attributes': {'body': 'Marshmallow is sweet like sugar!'},
# 'relationships': {
# 'author': {
# 'data': {'type': 'users', 'id': '23'},
# 'links': {
# 'self': '/comments/5/relationships/author',
# 'related': '/comments/23'
# }
# }
# }
# },
# {
# 'id': '12',
# 'type': 'comments',
# 'attributes': {'body': 'Flask is Fun!'},
# 'relationships': {
# 'author': {
# 'data': {'type': 'users', 'id': '101'},
# 'links': {
# 'self': '/comments/12/relationships/author',
# 'related': '/comments/101'
# }
# }
# },
#
# },
# {
# 'id': '23',
# 'type': 'users',
# 'attributes': {'name': 'Steven'}
# },
# {
# 'id': '101',
# 'type': 'users',
# 'attributes': {'name': 'Armin'}
# }
# ]
# }
Meta Information¶
The DocumentMeta
field is used to serialize
the meta object within a document’s “top level”.
from marshmallow_jsonapi import Schema, fields
class UserSchema(Schema):
id = fields.Str(dump_only=True)
name = fields.Str()
document_meta = fields.DocumentMeta()
class Meta:
type_ = "users"
user = {"name": "Alice", "document_meta": {"page": {"offset": 10}}}
UserSchema().dump(user)
# {
# "meta": {
# "page": {
# "offset": 10
# }
# },
# "data": {
# "id": "1",
# "type": "users"
# "attributes": {"name": "Alice"},
# }
# }
The ResourceMeta
field is used to serialize the meta object within a resource object.
from marshmallow_jsonapi import Schema, fields
class UserSchema(Schema):
id = fields.Str(dump_only=True)
name = fields.Str()
resource_meta = fields.ResourceMeta()
class Meta:
type_ = "users"
user = {"name": "Alice", "resource_meta": {"active": True}}
UserSchema().dump(user)
# {
# "data": {
# "type": "users",
# "attributes": {"name": "Alice"},
# "meta": {
# "active": true
# }
# }
# }
Errors¶
Schema.load()
and Schema.validate()
will return JSON API-formatted Error objects.
from marshmallow_jsonapi import Schema, fields
from marshmallow import validate, ValidationError
class AuthorSchema(Schema):
id = fields.Str(dump_only=True)
first_name = fields.Str(required=True)
last_name = fields.Str(required=True)
password = fields.Str(load_only=True, validate=validate.Length(6))
twitter = fields.Str()
class Meta:
type_ = "authors"
author_data = {
"data": {"type": "users", "attributes": {"first_name": "Dan", "password": "short"}}
}
AuthorSchema().validate(author_data)
# {
# 'errors': [
# {
# 'detail': 'Missing data for required field.',
# 'source': {
# 'pointer': '/data/attributes/last_name'
# }
# },
# {
# 'detail': 'Shorter than minimum length 6.',
# 'source': {
# 'pointer': '/data/attributes/password'
# }
# }
# ]
# }
If an invalid “type” is passed in the input data, an IncorrectTypeError
is raised.
from marshmallow_jsonapi.exceptions import IncorrectTypeError
author_data = {
"data": {
"type": "invalid-type",
"attributes": {
"first_name": "Dan",
"last_name": "Gebhardt",
"password": "verysecure",
},
}
}
try:
AuthorSchema().validate(author_data)
except IncorrectTypeError as err:
pprint(err.messages)
# {
# 'errors': [
# {
# 'detail': 'Invalid type. Expected "users".',
# 'source': {
# 'pointer': '/data/type'
# }
# }
# ]
# }
Inflection¶
You can optionally specify a function to transform attribute names. For example, you may decide to follow JSON API’s recommendation to use “dasherized” names.
from marshmallow_jsonapi import Schema, fields
def dasherize(text):
return text.replace("_", "-")
class UserSchema(Schema):
id = fields.Str(dump_only=True)
first_name = fields.Str(required=True)
last_name = fields.Str(required=True)
class Meta:
type_ = "users"
inflect = dasherize
UserSchema().dump(user)
# {
# 'data': {
# 'id': '9',
# 'type': 'users',
# 'attributes': {
# 'first-name': 'Dan',
# 'last-name': 'Gebhardt'
# }
# }
# }
Flask integration¶
marshmallow-jsonapi includes optional utilities to integrate with Flask.
A Flask-specific schema in marshmallow_jsonapi.flask
can be used to
auto-generate self-links based on view names instead of hard-coding URLs.
Additionally, the Relationship
field in the marshmallow_jsonapi.flask
module allows you to pass view names instead of path templates to generate
relationship links.
from marshmallow_jsonapi import fields
from marshmallow_jsonapi.flask import Relationship, Schema
class PostSchema(Schema):
id = fields.Str(dump_only=True)
title = fields.Str()
author = fields.Relationship(
self_view="post_author",
self_url_kwargs={"post_id": "<id>"},
related_view="author_detail",
related_view_kwargs={"author_id": "<author.id>"},
)
comments = Relationship(
related_view="post_comments",
related_view_kwargs={"post_id": "<id>"},
many=True,
include_resource_linkage=True,
type_="comments",
)
class Meta:
type_ = "posts"
self_view = "post_detail"
self_view_kwargs = {"post_detail": "<id>"}
self_view_many = "posts_list"
See here for a full example.
API Reference¶
API Reference¶
Core¶
-
class
marshmallow_jsonapi.
Schema
(*args, **kwargs)[source]¶ Schema class that formats data according to JSON API 1.0. Must define the
type_
class Meta
option.Example:
from marshmallow_jsonapi import Schema, fields def dasherize(text): return text.replace('_', '-') class PostSchema(Schema): id = fields.Str(dump_only=True) # Required title = fields.Str() author = fields.HyperlinkRelated( '/authors/{author_id}', url_kwargs={'author_id': '<author.id>'}, ) comments = fields.HyperlinkRelated( '/posts/{post_id}/comments', url_kwargs={'post_id': '<id>'}, # Include resource linkage many=True, include_resource_linkage=True, type_='comments' ) class Meta: type_ = 'posts' # Required inflect = dasherize
-
class
Meta
[source]¶ Options object for
Schema
. Takes the same options asmarshmallow.Schema.Meta
with the addition of:type_
- required, the JSON API resource type as a string.inflect
- optional, an inflection function to modify attribute names.self_url
- optional, URL to use toself
in linksself_url_kwargs
- optional, replacement fields forself_url
. String arguments enclosed in< >
will be interpreted as attributes to pull from the schema data.self_url_many
- optional, URL to use toself
in top-levellinks
when a collection of resources is returned.
-
OPTIONS_CLASS
¶ alias of
marshmallow_jsonapi.schema.SchemaOpts
-
format_error
(field_name, message, index=None)[source]¶ Override-able hook to format a single error message as an Error object.
-
format_json_api_response
(data, many, **kwargs)[source]¶ Post-dump hook that formats serialized data as a top-level JSON API object.
-
inflect
(text)[source]¶ Inflect
text
if theinflect
class Meta option is defined, otherwise do nothing.
-
class
Fields¶
Includes all the fields classes from marshmallow.fields
as well as
fields for serializing JSON API-formatted hyperlinks.
-
class
marshmallow_jsonapi.fields.
BaseRelationship
(*, load_default: Any = <marshmallow.missing>, missing: Any = <marshmallow.missing>, dump_default: Any = <marshmallow.missing>, default: Any = <marshmallow.missing>, data_key: Optional[str] = None, attribute: Optional[str] = None, validate: Optional[Union[Callable[[Any], Any], Iterable[Callable[[Any], Any]]]] = None, required: bool = False, allow_none: Optional[bool] = None, load_only: bool = False, dump_only: bool = False, error_messages: Optional[Dict[str, str]] = None, metadata: Optional[Mapping[str, Any]] = None, **additional_metadata)[source]¶ Base relationship field.
This is used by
marshmallow_jsonapi.Schema
to determine which fields should be formatted as relationship objects.See: http://jsonapi.org/format/#document-resource-object-relationships
-
class
marshmallow_jsonapi.fields.
DocumentMeta
(**kwargs)[source]¶ Field which serializes to a “meta object” within a document’s “top level”.
Examples:
from marshmallow_jsonapi import Schema, fields class UserSchema(Schema): id = fields.String() metadata = fields.DocumentMeta() class Meta: type_ = 'product'
-
class
marshmallow_jsonapi.fields.
Relationship
(related_url='', related_url_kwargs=None, *, self_url='', self_url_kwargs=None, include_resource_linkage=False, schema=None, many=False, type_=None, id_field=None, **kwargs)[source]¶ Framework-independent field which serializes to a “relationship object”.
See: http://jsonapi.org/format/#document-resource-object-relationships
Examples:
author = Relationship( related_url='/authors/{author_id}', related_url_kwargs={'author_id': '<author.id>'}, ) comments = Relationship( related_url='/posts/{post_id}/comments/', related_url_kwargs={'post_id': '<id>'}, many=True, include_resource_linkage=True, type_='comments' )
This field is read-only by default.
- Parameters
related_url (str) – Format string for related resource links.
related_url_kwargs (dict) – Replacement fields for
related_url
. String arguments enclosed in< >
will be interpreted as attributes to pull from the target object.self_url (str) – Format string for self relationship links.
self_url_kwargs (dict) – Replacement fields for
self_url
. String arguments enclosed in< >
will be interpreted as attributes to pull from the target object.include_resource_linkage (bool) – Whether to include a resource linkage (http://jsonapi.org/format/#document-resource-object-linkage) in the serialized result.
schema (marshmallow_jsonapi.Schema) – The schema to render the included data with.
many (bool) – Whether the relationship represents a many-to-one or many-to-many relationship. Only affects serialization of the resource linkage.
type (str) – The type of resource.
id_field (str) – Attribute name to pull ids from if a resource linkage is included.
-
deserialize
(value, attr=None, data=None, **kwargs)[source]¶ Deserialize
value
.- Raises
ValidationError – If the value is not type
dict
, if the value does not contain adata
key, and if the value is required but unspecified.
-
serialize
(attr, obj, accessor=None)[source]¶ Pulls the value for the given key from the object, applies the field’s formatting and returns the result.
- Parameters
attr – The attribute/key to get from the object.
obj – The object to access the attribute/key from.
accessor – Function used to access values from
obj
.kwargs – Field-specific keyword arguments.
-
class
marshmallow_jsonapi.fields.
ResourceMeta
(**kwargs)[source]¶ Field which serializes to a “meta object” within a “resource object”.
Examples:
from marshmallow_jsonapi import Schema, fields class UserSchema(Schema): id = fields.String() meta_resource = fields.ResourceMeta() class Meta: type_ = 'product'
Flask¶
Flask integration that avoids the need to hard-code URLs for links.
This includes a Flask-specific schema with custom Meta options and a relationship field for linking to related resources.
-
class
marshmallow_jsonapi.flask.
Relationship
(related_view=None, related_view_kwargs=None, *, self_view=None, self_view_kwargs=None, **kwargs)[source]¶ Field which serializes to a “relationship object” with a “related resource link”.
See: http://jsonapi.org/format/#document-resource-object-relationships
Examples:
author = Relationship( related_view='author_detail', related_view_kwargs={'author_id': '<author.id>'}, ) comments = Relationship( related_view='posts_comments', related_view_kwargs={'post_id': '<id>'}, many=True, include_resource_linkage=True, type_='comments' )
This field is read-only by default.
- Parameters
related_view (str) – View name for related resource link.
related_view_kwargs (dict) – Path kwargs fields for
related_view
. String arguments enclosed in< >
will be interpreted as attributes to pull from the target object.self_view (str) – View name for self relationship link.
self_view_kwargs (dict) – Path kwargs for
self_view
. String arguments enclosed in< >
will be interpreted as attributes to pull from the target object.**kwargs – Same keyword arguments as
marshmallow_jsonapi.fields.Relationship
.
-
class
marshmallow_jsonapi.flask.
Schema
(*args, **kwargs)[source]¶ A Flask specific schema that resolves self URLs from view names.
-
class
Meta
[source]¶ Options object that takes the same options as
marshmallow-jsonapi.Schema
, but instead ofself_url
,self_url_kwargs
andself_url_many
has the following options to resolve the URLs from Flask views:self_view
- View name to resolve the self URL link from.self_view_kwargs
- Replacement fields forself_view
. String attributes enclosed in< >
will be interpreted as attributes to pull from the schema data.self_view_many
- View name to resolve the self URL link when a collection of resources is returned.
-
self_url
= None¶
-
self_url_kwargs
= None¶
-
self_url_many
= None¶
-
OPTIONS_CLASS
¶ alias of
marshmallow_jsonapi.flask.SchemaOpts
-
class
Exceptions¶
Exception classes.
Utilities¶
Utility functions.
This module should be considered private API.
Project info¶
Changelog¶
0.24.0 (2020-12-27)¶
Deprecations/Removals:
Drop support for marshmallow 2, which is now EOL (#332).
Bug fixes:
Other changes:
Test against Python 3.8 and 3.9 (#332).
0.23.2 (2020-07-20)¶
Bug fixes:
Import from
collections.abc
for forward-compatibility with Python 3.10 (#318). Thanks @tirkarthi.
0.23.1 (2020-03-22)¶
Bug fixes:
0.23.0 (2020-02-02)¶
Improve performance of link generation from
Relationship
(#277). Thanks @iamareebjamal for reporting and fixing.
0.22.0 (2019-09-15)¶
Deprecation/Removals:
Drop support for Python 2.7 and 3.5. Only Python>=3.6 is supported (#251).
Drop support for marshmallow 3 pre-releases. Only stable versions >=2.15.2 are supported.
Remove
fields.Meta
.
Bug fixes:
Address
DeprecationWarning
raised byField.fail
on marshmallow 3.
0.21.2 (2019-07-01)¶
Bug fixes:
marshmallow 3.0.0rc7 compatibility (#233).
Other changes:
0.21.1 (2019-05-05)¶
Bug fixes:
marshmallow 3.0.0rc6 cmpatibility (#221).
0.21.0 (2018-12-16)¶
Bug fixes:
Backwards-incompatible: Revert URL quoting introduced in 0.20.2 (#184). If you need quoting, override
Schema.generate_url
.
from marshmallow_jsonapi import Schema
from werkzeug.urls import url_fix
class MySchema(Schema):
def generate_url(self, link, **kwargs):
url = super().generate_url(link, **kwargs)
return url_fix(url)
Thanks @kgutwin for reporting the issue.
Fix
Relationship
deserialization behavior whenrequired=False
(#177). Thanks @aberres for reporting and @scottwernervt for the fix.
Other changes:
Test against Python 3.7.
0.20.5 (2018-10-27)¶
Bug fixes:
0.20.4 (2018-10-04)¶
Bug fixes:
0.20.3 (2018-09-13)¶
Bug fixes:
Fix missing load validation when data is not a collection but many=True (#161). Thanks @grantHarris.
0.20.2 (2018-08-15)¶
Bug fixes:
Fix issues where generated URLs are unquoted (#147). Thanks @grantHarris.
Other changes:
Fix tests against marshmallow 3.0.0b13.
0.20.1 (2018-07-15)¶
Bug fixes:
0.20.0 (2018-06-10)¶
Bug fixes:
Fix serialization of
id
forRelationship
fields whenattribute
is set (#69). Thanks @jordal for reporting and thanks @scottwernervt for the fix.
Note: The above fix could break some code that set
Relationship.id_field
before instantiating it.
Set Relationship.default_id_field
instead.
# before
fields.Relationship.id_field = "item_id"
# after
fields.Relationship.default_id_field = "item_id"
Support:
0.19.0 (2018-05-27)¶
Features:
Schemas passed to
fields.Relationship
will inherit context from the parent schema (#84). Thanks @asteinlein and @scottwernervt for the PRs.
0.18.0 (2018-05-19)¶
Features:
Add
fields.ResourceMeta
for serializing a resource-level meta object (#107). Thanks @scottwernervt.
Other changes:
Backwards-incompatible: Drop official support for Python 3.4.
0.17.0 (2018-04-29)¶
Features:
Thanks @mdodsworth for helping with #101.
Move meta information object to document top level (#95). Thanks @scottwernervt.
0.16.0 (2017-11-08)¶
Features:
Add support for exluding or including nested fields on relationships (#94). Thanks @scottwernervt for the PR.
Other changes:
Backwards-incompatible: Drop support for marshmallow<2.8.0
0.15.1 (2017-08-23)¶
Bug fixes:
0.15.0 (2017-06-27)¶
Features:
Relationship
field supports deserializing included data (#83). Thanks @anuragagarwal561994 for the suggestion and thanks @asteinlein for the PR.
0.14.0 (2017-04-30)¶
Features:
0.13.0 (2017-04-18)¶
Features:
Add support for including deeply nested relationships in compount documents (#61). Thanks @mrhanky17 for the PR.
0.12.0 (2017-04-16)¶
Features:
Use default attribute value instead of raising exception if relationship is
None
onRelationship
field (#75). Thanks @akira-dev.
0.11.1 (2017-04-06)¶
Bug fixes:
Fix formatting JSON pointer when serializing an invalid object at index 0 (#77). Thanks @danpoland for the catch and patch.
0.11.0 (2017-03-12)¶
Bug fixes:
Fix compatibility with marshmallow 3.x.
Other changes:
Backwards-incompatible: Remove unused
utils.get_value_or_raise
function.
0.10.2 (2017-03-08)¶
Bug fixes:
Fix format of error object returned when
data
key is not included in input (#66). Thanks @RazerM.Fix serializing compound documents when
Relationship
is passed a schema class andmany=True
(#67). Thanks @danpoland for the catch and patch.
0.10.1 (2017-02-05)¶
Bug fixes:
0.10.0 (2017-01-05)¶
Features:
Add
fields.Meta
for (de)serializingmeta
data on resource objects (#28). Thanks @rubdos for the suggestion and initial work. Thanks @RazerM for the PR.
Other changes:
Test against Python 3.6.
0.9.0 (2016-10-08)¶
Features:
Add Flask-specific schema with class Meta options for self link generation:
self_view
,self_view_kwargs
, andself_view_many
(#51). Thanks @asteinlein.
Bug fixes:
Fix formatting of validation error messages on newer versions of marshmallow.
Other changes:
Drop official support for Python 3.3.
0.8.0 (2016-06-20)¶
Features:
Add support for compound documents (#11). Thanks @Tim-Erwin and @woodb for implementing this.
Backwards-incompatible: Remove
include_data
parameter fromRelationship
. Useinclude_resource_linkage
instead.
0.7.1 (2016-05-08)¶
Bug fixes:
0.7.0 (2016-04-03)¶
Features:
Correctly format
messages
attribute ofValidationError
raised whentype
key is missing in input (#43). Thanks @ZeeD26 for the catch and patch.JSON pointers for error objects for relationships will point to the
data
key (#41). Thanks @cmanallen for the PR.
0.6.0 (2016-03-24)¶
Features:
Relationship
deserialization improvements: properly validate to-one and to-many relatinoships and validate the presense of thedata
key (#37). Thanks @cmanallen for the PR.attributes
is no longer a required key in thedata
object (#39, #42). Thanks @ZeeD26 for reporting and @cmanallen for the PR.Added
id
serialization (#39). Thanks again @cmanallen.
0.5.0 (2016-02-08)¶
Features:
Add relationship deserialization (#15).
Allow serialization of foreign key attributes (#32).
Relationship IDs serialize to strings, as is required by JSON-API (#31).
Relationship
field respectsdump_to
parameter (#33).
Thanks @cmanallen for all of these changes.
Other changes:
The minimum supported marshmallow version is 2.3.0.
0.4.2 (2015-12-21)¶
Bug fixes:
Relationship names are inflected when appropriate (#22). Thanks @angelosarto for reporting.
0.4.1 (2015-12-19)¶
Bug fixes:
0.4.0 (2015-12-06)¶
Correctly serialize null and empty relationships (#10). Thanks @jo-tham for the PR.
Add
self_url
,self_url_kwargs
, andself_url_many
class Meta options for addingself
links. Thanks @asteinlein for the PR.
0.3.0 (2015-10-18)¶
Backwards-incompatible: Replace
HyperlinkRelated
withRelationship
field. Supports related links (related
), relationship links (self
), and resource linkages.Backwards-incompatible: Validate and deserialize JSON API-formatted request payloads.
Fix error formatting when
many=True
.Fix error formatting in strict mode.
0.2.2 (2015-09-26)¶
Fix for marshmallow 2.0.0 compat.
0.2.1 (2015-09-16)¶
Compatibility with marshmallow>=2.0.0rc2.
0.2.0 (2015-09-13)¶
Features:
Add framework-independent
HyperlinkRelated
field.Support inflection of attribute names via the
inflect
class Meta option.
Bug fixes:
Fix for making
HyperlinkRelated
read-only by defualt.
Support:
Docs updates.
Tested on Python 3.5.
0.1.0 (2015-09-12)¶
First PyPI release.
Include Schema that serializes objects to resource objects.
Flask-compatible HyperlinkRelate field for serializing relationships.
Errors are formatted as JSON API errror objects.
Contributing Guidelines¶
Questions, Feature Requests, Bug Reports, and Feedback…¶
…should all be reported on the Github Issue Tracker .
Setting Up for Local Development¶
Fork marshmallow-jsonapi on Github.
$ git clone https://github.com/marshmallow-code/marshmallow-jsonapi.git
$ cd marshmallow-jsonapi
Install development requirements. It is highly recommended that you use a virtualenv. Use the following command to install an editable version of marshmallow-jsonapi along with its development requirements.
# After activating your virtualenv
$ pip install -e '.[dev]'
Install the pre-commit hooks, which will format and lint your git staged files.
# The pre-commit CLI was installed above
$ pre-commit install
Git Branch Structure¶
Marshmallow abides by the following branching model:
dev
Current development branch. New features should branch off here.
X.Y-line
Maintenance branch for release
X.Y
. Bug fixes should be sent to the most recent release branch. The maintainer will forward-port the fix todev
. Note: exceptions may be made for bug fixes that introduce large code changes.
Always make a new branch for your work, no matter how small. Also, do not put unrelated changes in the same branch or pull request. This makes it more difficult to merge your changes.
Pull Requests¶
1. Create a new local branch.
$ git checkout -b name-of-feature dev
2. Commit your changes. Write good commit messages.
$ git commit -m "Detailed commit message"
$ git push origin name-of-feature
Before submitting a pull request, check the following:
If the pull request adds functionality, it is tested and the docs are updated.
You’ve added yourself to
AUTHORS.rst
.
Submit a pull request to
marshmallow-code:dev
or the appropriate maintenance branch. The CI build must be passing before your pull request is merged.
Running tests¶
To run all To run all tests:
$ pytest
To run syntax checks:
$ tox -e lint
(Optional) To run tests in all supported Python versions in their own virtual environments (must have each interpreter installed):
$ tox
Documentation¶
Contributions to the documentation are welcome. Documentation is written in reStructuredText (rST). A quick rST reference can be found here. Builds are powered by Sphinx.
To build the docs in “watch” mode:
$ tox -e watch-docs
Changes in the docs/
directory will automatically trigger a rebuild.
License¶
Copyright 2015-2020 Steven Loria and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.