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.