对Python REST(Web服务)框架的建议?[关闭]

问题:对Python REST(Web服务)框架的建议?[关闭]

在服务器端使用这些基于Python的不同REST框架的建议列表中是否可以编写自己的RESTful API?最好有优点和缺点。

请随时在此处添加建议。:)

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. 🙂


回答 0

设计RESTful API时要注意的一点是GET和POST的合并,就好像它们是同一件事一样。使用Django基于函数的视图CherryPy的默认分派器很容易犯此错误,尽管这两个框架现在都提供了解决此问题的方法(分别基于类的视图MethodDispatcher)。

HTTP谓词在REST 中非常重要,除非对此特别小心,否则最终会陷入REST反模式

一些正确的框架是web.pyFlaskBottle。当与mimerender库结合使用时(充分披露:我写了它),它们使您可以编写漂亮的RESTful Web服务:

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()

该服务的逻辑仅实现一次,并且正确的表示选择(Accept标头)+分配给正确的呈现函数(或模板)的操作是整齐,透明的。

$ 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!

更新(2012年4月):添加了有关Django基于类的视图,CherryPy的MethodDispatcher和Flask and Bottle框架的信息。提出问题时,两者都不存在。

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.


回答 1

没人惊讶烧瓶

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

Surprised no one mentioned flask.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

回答 2

我们正在将Django用于RESTful Web服务。

请注意,开箱即用的Django没有满足我们需求的足够细粒度的身份验证。我们使用了Django-REST接口,它帮了很多忙。[我们已经推出了自己的产品,因为我们进行了太多扩展,已经成为维护的噩梦。]

我们有两种URL:实现面向人的HTML页面的“ html” URL和实现面向Web服务的处理的“ json” URL。我们的视图功能通常看起来像这样。

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

关键是有用的功能是从两个演示中排除的。JSON表示形式通常只是所请求的一个对象。HTML演示文稿通常包括各种导航辅助工具和其他有助于人们提高工作效率的上下文提示。

这些jsonView功能都非常相似,可能有点烦人。但这是Python,因此请使其成为可调用类的一部分,或者在有帮助的情况下编写装饰器。

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.


回答 3

请参阅Python Web Frameworks Wiki。

您可能不需要完整的堆栈框架,但是其余列表仍然很长。

See Python Web Frameworks wiki.

You probably do not need the full stack frameworks, but the remaining list is still quite long.


回答 4

我真的很喜欢CherryPy。这是一个宁静的Web服务的示例:

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())

这强调了我对CherryPy的真正喜欢;这是一个完全可行的示例,即使对于不了解该框架的人也非常容易理解。如果运行此代码,则可以立即在Web浏览器中看到结果;例如,访问http:// localhost:8080 / celc_to_fahr?degrees = 50将显示122.0在您的Web浏览器中。

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.


回答 5


回答 6

我看不出有任何理由使用Django来公开REST api,有更轻便,更灵活的解决方案。Django将很多其他东西带到了表中,这些东西并非总是需要的。如果您只想将某些代码公开为REST服务,则可以肯定不需要。

我的个人经验是,一旦有了一个千篇一律的框架,您就会开始使用它的ORM,其插件等,只是因为它很容易,而且在任何时候您都最终没有依赖关系这很难摆脱。

选择一个Web框架是一个艰难的决定,并且我会避免为了展示REST api而选择一个完整的堆栈解决方案。

现在,如果您确实需要/想要使用Django,那么Piston是一个适用于Django应用程序的不错的REST框架。

话虽如此,CherryPy看起来也非常不错,但是看起来比REST更像RPC。

查看示例(我从未使用过),如果您只需要REST,则web.py可能是最好的和最干净的。

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.


回答 7

这是基于REST的CherryPy文档中的讨论:http : //docs.cherrypy.org/dev/progguide/REST.html

特别是提到了一个内置的CherryPy调度程序,称为MethodDispatcher,该调度程序根据其HTTP动词标识符(GET,POST等)调用方法。

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…).


回答 8

在2010年,Pylons和repoze.bfg社区“联合起来”创建了Pyramid,这是一个基于repoze.bfg的网络框架。它保留了其父框架的理念,并且可以用于RESTful服务。值得一看。

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.


回答 9

Piston是用于为Django应用程序编写RESTful API的非常灵活的框架。

Piston is very flexible framework for wirting RESTful APIs for Django applications.


回答 10

似乎所有种类的python Web框架现在都可以实现RESTful接口。

对于Django,除了好吃的东西和活塞,django-rest-framework是一个很有前途的值得一提的东西。我已经顺利地迁移了我的一个项目。

Django REST框架是适用于Django的轻量级REST框架,旨在简化构建相互连接,自描述的RESTful Web API的过程。

快速示例:

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)),
)

以官方网站为例,以上所有代码均提供api,自我解释的文档(如基于soap的webservice)甚至沙盒进行测试。非常方便。

链接:http//django-rest-framework.org/

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/


回答 11

我不是python世界的专家,但是我一直在使用django,它是一个出色的Web框架,可用于创建一个宁静的框架。

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.


回答 12

web2py包括对轻松构建RESTful API的支持,如此此处所述(视频)。特别地,请看一下parse_as_rest,它使您可以定义将请求参数映射到数据库查询的URL模式。和smart_query,使您可以在URL中传递任意自然语言查询。

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.


回答 13

如果您使用的是Django,则可以考虑使用django-tastypie替代django-piston。与活塞相比,调整到非ORM数据源更容易,并且文档丰富。

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.


回答 14

我强烈推荐TurboGears或Bottle:

TurboGears:

  • 不如django冗长
  • 更灵活,更少HTML
  • 但是:不太有名

瓶子:

  • 非常快
  • 很容易学习
  • 但是:简约而不成熟

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

回答 15

我们正在为严格的REST服务开发框架,请访问http://prestans.googlecode.com。

目前在Alpha早期,我们正在针对mod_wsgi和Google的AppEngine进行测试。

寻找测试人员和反馈。谢谢。

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.