Is there a list somewhere of recommendations of different Python-based REST frameworks for use on the serverside to write your own RESTful APIs? Preferably with pros and cons.
Please feel free to add recommendations here. đ
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & Iâll get back to you as soon as possible.
Method 1
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 web
import json
from mimerender import mimerender
render_xml = lambda message: '<message>%s</message>'%message
render_json = lambda **args: json.dumps(args)
render_html = lambda message: '<html><body>%s</body></html>'%message
render_txt = lambda message: message
urls = (
'/(.*)', '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/x
Hello, 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.
Method 2
Surprised no one mentioned flask.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
Method 3
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.
Method 4
See Python Web Frameworks wiki.
You probably do not need the full stack frameworks, but the remaining list is still quite long.
Method 5
I really like CherryPy. Hereâs an example of a restful web service:
import cherrypy
from cherrypy import expose
class Converter:
@expose
def index(self):
return "Hello World!"
@expose
def fahr_to_celc(self, degrees):
temp = (float(degrees) - 32) * 5 / 9
return "%.01f" % temp
@expose
def celc_to_fahr(self, degrees):
temp = float(degrees) * 9 / 5 + 32
return "%.01f" % temp
cherrypy.quickstart(Converter())
This emphasizes what I really like about CherryPy; this is a completely working example thatâs very understandable even to someone who doesnât know the framework. If you run this code, then you can immediately see the results in your web browser; e.g. visiting http://localhost:8080/celc_to_fahr?degrees=50 will display 122.0 in your web browser.
Method 6
Take a look at
Method 7
I donât see any reason to use Django just to expose a REST api, there are lighter and more flexible solutions. Django carries a lot of other things to the table, that are not always needed. For sure not needed if you only want to expose some code as a REST service.
My personal experience, fwiw, is that once you have a one-size-fits-all framework, youâll start to use its ORM, its plugins, etc. just because itâs easy, and in no time you end up having a dependency that is very hard to get rid of.
Choosing a web framework is a tough decision, and I would avoid picking a full stack solution just to expose a REST api.
Now, if you really need/want to use Django, then Piston is a nice REST framework for django apps.
That being said, CherryPy looks really nice too, but seems more RPC than REST.
Looking at the samples (I never used it), probably web.py is the best and cleanest if you only need REST.
Method 8
Here is a discussion in CherryPy docs on REST: http://docs.cherrypy.org/dev/progguide/REST.html
In particular it mentions a built in CherryPy dispatcher called MethodDispatcher, which invokes methods based on their HTTP-verb identifiers (GET, POST, etcâŚ).
Method 9
In 2010, the Pylons and repoze.bfg communities âjoined forcesâ to create Pyramid, a web framework based most heavily on repoze.bfg. It retains the philosophies of its parent frameworks, and can be used for RESTful services. Itâs worth a look.
Method 10
Piston is very flexible framework for wirting RESTful APIs for Django applications.
Method 11
Seems all kinds of python web frameworks can implement RESTful interfaces now.
For Django, besides tastypie and piston, django-rest-framework is a promising one worth to mention. Iâve already migrated one of my project on it smoothly.
Django REST framework is a lightweight REST framework for Django, that
aims to make it easy to build well-connected, self-describing RESTful
Web APIs.
Quick example:
from django.conf.urls.defaults import patterns, url
from djangorestframework.resources import ModelResource
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from myapp.models import MyModel
class MyResource(ModelResource):
model = MyModel
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
url(r'^(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MyResource)),
)
Take the example from official site, all above codes provide api, self explained document(like soap based webservice) and even sandbox to test a bit. Very convenience.
Links:
http://django-rest-framework.org/
Method 12
I am not an expert on the python world but I have been using django which is an excellent web framework and can be used to create a restful framework.
Method 13
web2py includes support for easily building RESTful APIâs, described here and here (video). In particular, look at parse_as_rest, which lets you define URL patterns that map request args to database queries; and smart_query, which enables you to pass arbitrary natural language queries in the URL.
Method 14
I you are using Django then you can consider django-tastypie as an alternative to django-piston. It is easier to tune to non-ORM data sources than piston, and has great documentation.
Method 15
I strongly recommend TurboGears or Bottle:
TurboGears:
- less verbose than django
- more flexible, less HTML-oriented
- but: less famous
Bottle:
- very fast
- very easy to learn
- but: minimalistic and not mature
Method 16
We are working on a framework for strict REST services, check out http://prestans.googlecode.com
Its in early Alpha at the moment, we are testing against mod_wsgi and Googleâs AppEngine.
Looking for testers and feedback. Thanks.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0