推荐的Python REST框架?

321 投票
16 回答
242594 浏览
提问于 2025-04-15 11:05

有没有一个地方列出一些推荐的基于Python的REST框架,适合用在服务器上来编写自己的RESTful API?最好能有优缺点的对比。

欢迎大家在这里分享推荐哦。 :)

16 个回答

23

我们正在使用Django来提供RESTful网络服务。

需要注意的是,Django默认的身份验证功能对我们来说不够细致。因此,我们使用了Django-REST接口,这对我们帮助很大。[后来我们自己做了一个,因为我们添加了太多扩展,维护起来变得非常麻烦。]

我们有两种类型的URL:“html” URL用于实现面向人类的HTML页面,而“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,所以可以把它们放进一个可调用的类里,或者写一些装饰器来简化处理。

70

我很惊讶没有人提到flask这个东西。

from flask import Flask
app = Flask(__name__)

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

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

在设计RESTful API时,有一点需要特别注意,就是不要把GET和POST搞混了,仿佛它们是同一种东西。很多人容易在使用Django基于函数的视图CherryPy的默认调度器时犯这个错误,不过这两个框架现在都有办法解决这个问题,比如基于类的视图方法调度器

HTTP动词在REST中非常重要,如果你不小心,就可能会陷入REST反模式

一些做得不错的框架有web.pyFlaskBottle。当它们和mimerender库结合使用时(顺便说一下:这是我写的),可以让你写出很不错的RESTful网络服务:

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和Bottle框架的信息。这些在提问时是不存在的。

撰写回答