• I have a cornice based pyramid web server running in Python 3.8(alpine linux) and a client calling one of its API using python requests without any requests headers.

  • Cornice+Pyramid web server has msgpack (custom renderer added by me) and simplejson (default renderer of cornice) as renderers.

  • Currently, I am getting inconsistent content-type (sometimes 'application/x-msgpack' and sometimes 'application/json') in the response headers.

  • As per cornice documentation, default renderer is simplejson thus I am expecting it should always convert the response object into JSON using json renderer factory of pyramid/cornice and send the response to the client with content-type as 'application/json'.

  • Earlier, I used to have the same web server running on python 2.7 version, where it was always sending response in JSON format with consistent content-type as 'application/json'.

  • When I am passing request headers as {'Accept': 'application/json'} or {'Accept': 'application/x-msgpack'} then I am getting response as expected with the response been rendered with the appropriate renderer.

  • I want to know exact reason, why the default renderer been considered by the web server is changing between msgpack and simplejson.

  • Below are the files/configuration been used:

A. requirements.txt

simplejson==3.10.0
pyramid==1.5.7
chardet==3.0.4
colander==1.0b1
cornice==1.0
msgpack==1.0.4
lz4==4.0.2
lz4tools==1.3.1.2
PyYAML==3.11
SQLAlchemy==1.4.0
psycopg2-binary==2.9.5
enum34==1.1.6
python-dateutil==2.2
pytz==2014.10
requests==2.7.0
waitress==0.8.9
Paste==3.5.2
jsonschema==2.3.0

B. webserver/__init__.py

# -*- coding: utf-8 -*-

"""Main entry point
"""

import os

from pyramid.config import Configurator
from pyramid.events import NewResponse
from sdk.pyramid.viewutils import MsgpackRendererFactory, notfound, lz4_compress_response


class MsgpackRendererFactory(object):

    def __init__(self, info):
        pass

    def __call__(self, value, system):
        request = system.get('request')
        if request is not None:
            response = request.response
            response.content_type = 'application/x-msgpack'
        return msgpack.dumps(value)


def main(global_config, **settings):
    route_prefix = settings.get('reports.route_prefix')
    config = Configurator(settings=settings, route_prefix=route_prefix)

    config.add_settings(handle_exceptions=False)
    config.add_notfound_view(notfound, append_slash=True)

    config.add_renderer(name='msgpack', factory=MsgpackRendererFactory)

    config.include('cornice')

    return config.make_wsgi_app()

C. webserver/views.py

@resource(path='path_to_the_api')
class ResourceView():

    @view(accept='application/x-msgpack', renderer='msgpack')
    @view(accept='application/json', renderer='simplejson')
    def get(self):
    
        # Data fetched from DB stored in 'resource' variable
        
        resource = .......... # Calling DB to get data
        
        return {'resources': resource}

D. Client code

import requests

url = 'https://X.X.X.X/path_to_webserver_api'
response = requests.get(url)

body = response.json() # works only if the content-type received is 'application/json' else code                 
                       # breaks at this point 

  • All the required information is provided here. Please reply if you face any doubts.
  • I have read docs of cornice and pyramid but was not able to find the solution for the problem I am facing.
0

There are 0 best solutions below