[SGHLT]s weblog
computer science without borders
[SGHLT]s weblog

Making pyramids json renderer datetime aware

Share Tweet Share

How to tackle the json rendering of datetime objects correctly.

The Pyramid json renderer

Pyramid offers a convenient approach for rendering views in different manners: renderers. The json renderer can be used to build simple to large scale REST APIs. There's only one problem which he, who is playing and poking around with this tool for the first time, suffers from. When you give a datetime object to the json renderer it'll completely deny its service and leaves you alone with an exception message.

...
from datetime import datetime

# everything's gonna be alright

@view_config(..., renderer="json")
def my_first_view(request):
    return {
        "title": "Hello world",
    }


# let's open the gate to hell...

@view_config(..., renderer="json")
def my_second_view(request):
    return {
        "title": "Hello second world",
        "created_at": datetime.now(),
    }

Solution

Though there are a zillion approaches to handle the described problem I cannot help but offer you my own :) Most of them (e.g. on stackoverflow) offer a solution by introducing a completly new renderer or creating a new object containing a __json__ method. Especially for small projects I find these solutions too enterprisy.

What baffles me is that pyramids documentation itself figures out this better solution, which seems doomed to be ignored.

    # somewhere at __init__.py

    def datetime_adapter(obj: datetime, request: Request):
        return obj.isoformat()


    def main(global_config, **settings):
        config = Configurator(settings=settings)

        # add adapter to enable JSON renderer to serialize datetime objects
        json_renderer = config.registry.getUtility(IRendererFactory, name="json")
        json_renderer.add_adapter(datetime, datetime_adapter)
        # or smaller: json_renderer.add_adapter(datetime, lambda o, r: o.isoformat())

Receive Updates

ATOM

Contacts