Response rendering

Guillotina has a rendering framework to be able to dynamically handle multiple request Accept headers.

Out of the box, Guillotina only supports application/json, text/html and text/plain dynamic response types. Streaming and web socket type responses are also supported but are not handled by the dyanamic rendering framework.

Customizing responses

Services can provide simple type values for responses. Ideally anything that can be serialized as json(default renderer).

Additionally, services can provide custom response objects to customize status and header.

from guillotina import configure
from guillotina.interfaces import IResource
from guillotina.response import Response

@configure.service(
    context=IResource, name='@custom-status',
    method='GET', permission='guillotina.Public',
    allow_access=True)
async def custom_status(context, request):
    return Response(content={'foo': 'bar'}, status=201)


@configure.service(
    context=IResource, name='@custom-headers',
    method='GET', permission='guillotina.Public',
    allow_access=True)
async def custom_headers(context, request):
    return Response(content={'foo': 'bar'}, status=200, headers={'X-Foobar': 'foobar'})

Response types

Guillotina will automatically transform any response types in the guillotina.response library.

These response objects should have simple dict values for their content if provided.

Bypassing responses rendering

If you return a guillotina.response.ASGISimpleResponse response object, they will be ignored by the rendering framework.

This is useful when streaming data for example and it should not be transformed.

Custom rendering

It’s also very easy to provide your own renderer. All you need to do is provide your own renderer class and configure it with the configuration object.

Here is a yaml example:

from guillotina import configure
from guillotina.renderers import Renderer
import yaml

# yaml is known to have a lot of different content types, it's okay!
@configure.renderer(name='text/vnd.yaml')
@configure.renderer(name='application/yaml')
@configure.renderer(name='application/x-yaml')
@configure.renderer(name='text/x-yaml')
@configure.renderer(name='text/yaml')
class RendererYaml(Renderer):
    content_type = 'application/yaml'

    def get_body(self, value) -> bytes:
        if value is not None:
            value = yaml.dump(value)
            return value.encode('utf-8')