<commit_before>.. _quickstart:
.. module:: marshmallow

Quickstart
==========

This guide will walk you through the basics of creating an object serializer.

Declaring Serializers
---------------------

Let's start with a basic user model.

.. code-block:: python

    import datetime as dt

    class User(object):
        def __init__(self, name, email, age=None):
            self.name = name
            self.email = email
            self.created_at = dt.datetime.now()
            self.friends = []
            self.age = age

        def __repr__(self):
            return '<User(name={self.name!r})>'.format(self=self)


Create a serializer by defining a class with variables mapping attribute names to a field class object that formats the final output of the serializer.

.. code-block:: python

    from marshmallow import Serializer, fields, pprint

    class UserSerializer(Serializer):
        name = fields.String()
        email = fields.Email()
        created_at = fields.DateTime()

For a full reference on the field classes, see the :ref:`API Docs <api_fields>`.


Serializing Objects
-------------------

Serialize objects by passing them to your serializer's :meth:`dump <marshmallow.Serializer.dump>` method, which returns the serialized ``result`` as a dictionary and a dictionary of validation errors.

.. code-block:: python

    user = User(name="Monty", email="<EMAIL>")
    serializer = UserSerializer()
    result, errors = serializer.dump(user)
    pprint(result)
    # {'created_at': 'Sun, 10 Nov 2013 15:48:19 -0000',
    #  'email': u'<EMAIL>',
    #  'name': u'Monty'}

.. note::

    Marshmallow provides a :func:`pprint` function for pretty-printing the ``OrderedDicts`` returned by the :meth:`dump <marshmallow.Serializer.dump>` method.

You can also serialize to a JSON-encoded string using :meth:`dumps <marshmallow.Serializer.dumps>`.

.. code-block:: python

    json_result, errors = serializer.dumps(user)
    pprint(json_result)
    # '{"created_at": "Sun, 10 Nov 2013 15:48:19 -0000", "name": "Monty", "email": "<EMAIL>"}'

Filtering output
++++++++++++++++

You may not need to output all declared fields every time you use a serializer. You can specify which fields to output with the ``only`` parameter.

.. code-block:: python

    summary_serializer = UserSerializer(only=('name', 'email'))
    summary_serializer.dump(user)[0]
    # {"name": "<NAME>", "email": "<EMAIL>"}

You can also exclude fields by passing in the ``exclude`` parameter.


Deserializing Objects
---------------------

The opposite of the :meth:`dump <Serializer.dump>` method is the :meth:`load <Serializer.load>` method, which deserializes an input dictionary to an application-level data structure (e.g. an ORM object in a web application).

By default, :meth:`load <Serializer.load>` will return a dictionary of field names mapped to the deserialized values.

.. code-block:: python

    from pprint import pprint

    user_data = {
        'created_at': '2014-08-11T05:26:03.869245',
        'email': u'<EMAIL>',
        'name': u'Ken'
    }
    serializer = UserSerializer()
    result, errors = serializer.load(user_data)
    pprint(result)
    # {'created_at': datetime.datetime(2014, 8, 11, 5, 26, 3, 869245),
    #  'email': '<EMAIL>',
    #  'name': 'Ken'}

Notice that the datetime string was converted to a datetime object.

Deserializing to Objects
++++++++++++++++++++++++

In order to deserialize to an object, define the :meth:`make_object <Serializer.make_object>` method of your :class:`Serializer`. The method receives a dictionary of deserialized data as its only parameter.

.. code-block:: python

    # Same as above, but this time we define ``make_object``
    class UserSerializer(Serializer):

        name = fields.String()
        email = fields.Email()
        created_at = fields.DateTime()

        def make_object(self, data):
            return User(**data)

Now, the :meth:`load <Serializer.load>` method will return a ``User`` object.

.. code-block:: python

    user_data = {
        'name': 'Ronnie',
        'email': '<EMAIL>'
    }
    serializer = UserSerializer()
    result, errors = serializer.load(user_data)
    result  # => <User(name='Ronnie')>

Handling Collections of Objects
-------------------------------

Iterable collections of objects are also serializable and deserializable. Just set ``many=True``.

.. code-block:: python

    user1 = User(name="Mick", email="<EMAIL>")
    user2 = User(name="Keith", email="<EMAIL>")
    users = [user1, user2]
    serializer = UserSerializer(many=True)
    results, errors = serializer.dump(users)
    # [{'created_at': 'Fri, 08 Nov 2013 17:02:17 -0000',
    #   'email': u'<EMAIL>',
    #   'name': u'Mick'},
    #  {'created_at': 'Fri, 08 Nov 2013 17:02:17 -0000',
    #   'email': u'<EMAIL>',
    #   'name': u'Keith'}]

Validation
----------

Both :meth:`Serializer.dump` and :meth:`Serializer.load` (as well as their JSON-encoding counterparts :meth:`Serializer.dumps` and :meth:`Serializer.loads`) return a dictionary of validation errors as the second element of their return value.

.. code-block:: python

    result, errors = UserSerializer().load({'email': 'foo'})
    errors  # => {'email': u'foo is not a valid email address.'}

You can give fields a custom error message by passing the ``error`` parameter to a field's constructor.

.. code-block:: python

    email = fields.Email(error='Invalid email address. Try again.')

You can perform additional validation for a field by passing it a ``validate`` callable (function, lambda, or object with ``__call__`` defined) which evaluates to a boolean.

.. code-block:: python

    class ValidatedUserSerializer(UserSerializer):
        age = fields.Number(validate=lambda n: 18 <= n <= 40,
                            error='User is over the hill')

    jagger = User(name="Mick", email="<EMAIL>", age=71)<commit_msg>Updated the doc (the user can now pass list of callables)<commit_after>.. _quickstart:
.. module:: marshmallow

Quickstart
==========

This guide will walk you through the basics of creating an object serializer.

Declaring Serializers
---------------------

Let's start with a basic user model.

.. code-block:: python

    import datetime as dt

    class User(object):
        def __init__(self, name, email, age=None):
            self.name = name
            self.email = email
            self.created_at = dt.datetime.now()
            self.friends = []
            self.age = age

        def __repr__(self):
            return '<User(name={self.name!r})>'.format(self=self)


Create a serializer by defining a class with variables mapping attribute names to a field class object that formats the final output of the serializer.

.. code-block:: python

    from marshmallow import Serializer, fields, pprint

    class UserSerializer(Serializer):
        name = fields.String()
        email = fields.Email()
        created_at = fields.DateTime()

For a full reference on the field classes, see the :ref:`API Docs <api_fields>`.


Serializing Objects
-------------------

Serialize objects by passing them to your serializer's :meth:`dump <marshmallow.Serializer.dump>` method, which returns the serialized ``result`` as a dictionary and a dictionary of validation errors.

.. code-block:: python

    user = User(name="Monty", email="<EMAIL>")
    serializer = UserSerializer()
    result, errors = serializer.dump(user)
    pprint(result)
    # {'created_at': 'Sun, 10 Nov 2013 15:48:19 -0000',
    #  'email': u'<EMAIL>',
    #  'name': u'Monty'}

.. note::

    Marshmallow provides a :func:`pprint` function for pretty-printing the ``OrderedDicts`` returned by the :meth:`dump <marshmallow.Serializer.dump>` method.

You can also serialize to a JSON-encoded string using :meth:`dumps <marshmallow.Serializer.dumps>`.

.. code-block:: python

    json_result, errors = serializer.dumps(user)
    pprint(json_result)
    # '{"created_at": "Sun, 10 Nov 2013 15:48:19 -0000", "name": "Monty", "email": "<EMAIL>"}'

Filtering output
++++++++++++++++

You may not need to output all declared fields every time you use a serializer. You can specify which fields to output with the ``only`` parameter.

.. code-block:: python

    summary_serializer = UserSerializer(only=('name', 'email'))
    summary_serializer.dump(user)[0]
    # {"name": "<NAME>", "email": "<EMAIL>"}

You can also exclude fields by passing in the ``exclude`` parameter.


Deserializing Objects
---------------------

The opposite of the :meth:`dump <Serializer.dump>` method is the :meth:`load <Serializer.load>` method, which deserializes an input dictionary to an application-level data structure (e.g. an ORM object in a web application).

By default, :meth:`load <Serializer.load>` will return a dictionary of field names mapped to the deserialized values.

.. code-block:: python

    from pprint import pprint

    user_data = {
        'created_at': '2014-08-11T05:26:03.869245',
        'email': u'<EMAIL>',
        'name': u'Ken'
    }
    serializer = UserSerializer()
    result, errors = serializer.load(user_data)
    pprint(result)
    # {'created_at': datetime.datetime(2014, 8, 11, 5, 26, 3, 869245),
    #  'email': '<EMAIL>',
    #  'name': 'Ken'}

Notice that the datetime string was converted to a datetime object.

Deserializing to Objects
++++++++++++++++++++++++

In order to deserialize to an object, define the :meth:`make_object <Serializer.make_object>` method of your :class:`Serializer`. The method receives a dictionary of deserialized data as its only parameter.

.. code-block:: python

    # Same as above, but this time we define ``make_object``
    class UserSerializer(Serializer):

        name = fields.String()
        email = fields.Email()
        created_at = fields.DateTime()

        def make_object(self, data):
            return User(**data)

Now, the :meth:`load <Serializer.load>` method will return a ``User`` object.

.. code-block:: python

    user_data = {
        'name': 'Ronnie',
        'email': '<EMAIL>'
    }
    serializer = UserSerializer()
    result, errors = serializer.load(user_data)
    result  # => <User(name='Ronnie')>

Handling Collections of Objects
-------------------------------

Iterable collections of objects are also serializable and deserializable. Just set ``many=True``.

.. code-block:: python

    user1 = User(name="Mick", email="<EMAIL>")
    user2 = User(name="Keith", email="<EMAIL>")
    users = [user1, user2]
    serializer = UserSerializer(many=True)
    results, errors = serializer.dump(users)
    # [{'created_at': 'Fri, 08 Nov 2013 17:02:17 -0000',
    #   'email': u'<EMAIL>',
    #   'name': u'Mick'},
    #  {'created_at': 'Fri, 08 Nov 2013 17:02:17 -0000',
    #   'email': u'<EMAIL>',
    #   'name': u'Keith'}]

Validation
----------

Both :meth:`Serializer.dump` and :meth:`Serializer.load` (as well as their JSON-encoding counterparts :meth:`Serializer.dumps` and :meth:`Serializer.loads`) return a dictionary of validation errors as the second element of their return value.

.. code-block:: python

    result, errors = UserSerializer().load({'email': 'foo'})
    errors  # => {'email': u'foo is not a valid email address.'}

You can give fields a custom error message by passing the ``error`` parameter to a field's constructor.

.. code-block:: python

    email = fields.Email(error='Invalid email address. Try again.')

You can perform additional validation for a field by passing it a ``validate`` callable (function, lambda, or object with ``__call__`` defined) which evaluates to a boolean.

.. code-block:: python

    class ValidatedUserSerializer(UserSerializer):
        age = fields.Number(validate=lambda n: 18 <= n <= 40,
                            error='User is over the hill')

    jagger = User(name="Mick", email="<EMAIL>", age=71)
    result, errors = ValidatedUserSerializer().dump(jagger)
    errors  # => {'age': 'User is over the hill'}

If you have multiple validations to perform, you can even pass a list of callables. So with a slight modification our previous example would become:

.. code-block:: python

    class ValidatedUserSerializer(UserSerializer):
        age = fields.Number(validate=[lambda n: n >= 18, lambda n: n <= 40],
                            error='User is over the hill')

    jagger = User(name="Mick", email="<EMAIL>", age=71)
{'fraction_non_alphanumeric': 0.14605742013748482, 'fraction_numerical': 0.01860088960776385, 'mean_word_length': 3.233481684354673, 'pattern_counts': {'":': 10, '<': 57, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2314310', 'n_tokens_mistral': 3811, 'n_tokens_neox': 3523, 'n_words': 1234}