pythonpyramid

Route requests based on the Accept header in Python web frameworks


I have some experience with different web frameworks (Django, web.py, Pyramid and CherryPy), and I'm wondering in which one will it be easier and hopefully cleaner to implement a route dispatcher to a different "view/handler" based on the "Accept" header and the HTTP method e.g.:

Accept: application/json
POST /post/

is handled different than:

Accept: text/html
POST /post/

So the request gets routed to the particular view of the corresponding handler of the MIME "application/json" and the HTTP method "POST".

I do know how to implement something like that in CherryPy, but I lose the use of the CherryPy tools for the internal redirection of the request because I'm calling the specific method directly instead of automagically from the dispatcher. Another option is to implement a full new dispatcher from scratch, but that's the last option.

I'm aware of the alternative to use extensions in the url like /post.json or /post/.json, but I'm looking to keep the same url?


Solution

  • If all you are looking for is one framework that can do this easily, then use pyramid.

    Pyramid view definitions are made with predicates, not just routes, and a view only matches if all predicates match. One such predicate is the accept predicate, which does exactly what you want; make view switching depending on the Accept header easy and simple:

    from pyramid.view import view_config
    
    @view_config(route_name='some_api_name', request_method='POST', accept='application/json')
    def handle_someapi_json(request):
        # return JSON
    
    @view_config(route_name='some_api_name', request_method='POST', accept='text/html')
    def handle_someapi_html(request):
        # return HTML