Recommendations of Python REST (web services) framework? [closed] Recommendations of Python REST (web services) framework? [closed] python python

Recommendations of Python REST (web services) framework? [closed]


Something to be careful about when designing a RESTful API is the conflation of GET and POST, as if they were the same thing. It's easy to make this mistake with Django's function-based views and CherryPy's default dispatcher, although both frameworks now provide a way around this problem (class-based views and MethodDispatcher, respectively).

HTTP-verbs are very important in REST, and unless you're very careful about this, you'll end up falling into a REST anti-pattern.

Some frameworks that get it right are web.py, Flask and Bottle. When combined with the mimerender library (full disclosure: I wrote it), they allow you to write nice RESTful webservices:

import webimport jsonfrom mimerender import mimerenderrender_xml = lambda message: '<message>%s</message>'%messagerender_json = lambda **args: json.dumps(args)render_html = lambda message: '<html><body>%s</body></html>'%messagerender_txt = lambda message: messageurls = (    '/(.*)', 'greet')app = web.application(urls, globals())class greet:    @mimerender(        default = 'html',        html = render_html,        xml  = render_xml,        json = render_json,        txt  = render_txt    )    def GET(self, name):        if not name:             name = 'world'        return {'message': 'Hello, ' + name + '!'}if __name__ == "__main__":    app.run()

The service's logic is implemented only once, and the correct representation selection (Accept header) + dispatch to the proper render function (or template) is done in a tidy, transparent way.

$ curl localhost:8080/x<html><body>Hello, x!</body></html>$ curl -H "Accept: application/html" localhost:8080/x<html><body>Hello, x!</body></html>$ curl -H "Accept: application/xml" localhost:8080/x<message>Hello, x!</message>$ curl -H "Accept: application/json" localhost:8080/x{'message':'Hello, x!'}$ curl -H "Accept: text/plain" localhost:8080/xHello, x!

Update (April 2012): added information about Django's class-based views, CherryPy's MethodDispatcher and Flask and Bottle frameworks. Neither existed back when the question was asked.


Surprised no one mentioned flask.

from flask import Flaskapp = Flask(__name__)@app.route("/")def hello():    return "Hello World!"if __name__ == "__main__":    app.run()


We're using Django for RESTful web services.

Note that -- out of the box -- Django did not have fine-grained enough authentication for our needs. We used the Django-REST interface, which helped a lot. [We've since rolled our own because we'd made so many extensions that it had become a maintenance nightmare.]

We have two kinds of URL's: "html" URL's which implement the human-oriented HTML pages, and "json" URL's which implement the web-services oriented processing. Our view functions often look like this.

def someUsefulThing( request, object_id ):    # do some processing    return { a dictionary with results }def htmlView( request, object_id ):    d = someUsefulThing( request, object_id )    render_to_response( 'template.html', d, ... )def jsonView( request, object_id ):    d = someUsefulThing( request, object_id )    data = serializers.serialize( 'json', d['object'], fields=EXPOSED_FIELDS )    response = HttpResponse( data, status=200, content_type='application/json' )    response['Location']= reverse( 'some.path.to.this.view', kwargs={...} )    return response

The point being that the useful functionality is factored out of the two presentations. The JSON presentation is usually just one object that was requested. The HTML presentation often includes all kinds of navigation aids and other contextual clues that help people be productive.

The jsonView functions are all very similar, which can be a bit annoying. But it's Python, so make them part of a callable class or write decorators if it helps.