We return the values of the attributes which make up a Person object, and since they’re all native types, we can pass this dictionary into an encoding function to finally get the JSON notation. Looks good!

Note that we need to call isoformat on self.birth_date to get a string back since a Python datetime object is not a native datatype. Also note that we’re recursively calling the to_json function on self.sidekick to get its JSON representation. If we don’t, that variable will end up being a Person object which can’t be converted directly to JSON.

While this works, there are a few issues here. For one, we can’t define the field types. So if some code is consuming this JSON representation and we encounter a boolean value for id , the calling code would be confused. Ideally we would like to handle such cases already at serialization time. Additionally, some use cases might require that the returned value be different based on some context. As an example, consider a web application that allows chat rooms where two or more users can talk to each other. In such cases, the number of unread messages for the same chat room would be different based on which user is requesting the value.

The simplest thing to do here would be to separate the serializer definition from the original class definition. This is where serpy comes in. If serpy is not yet installed, type pip install serpy==0.1.1 on the command line, and let’s see how we can use it!

Approach #2: Define a Serializer