Đề xuất của khung Python REST (dịch vụ web)? [đóng cửa]


321

Có một danh sách nào đó đề xuất các khung REST dựa trên Python khác nhau để sử dụng trên các máy chủ để viết API RESTful của riêng bạn không? Tốt nhất là với ưu và nhược điểm.

Xin vui lòng thêm các khuyến nghị ở đây. :)


Đây là một hướng dẫn tốt về cách sử dụng web.py dreamyssoft.com/blog/blog.php?/archives/ mẹo
Triton Man

Câu trả lời:


192

Một điều cần cẩn thận khi thiết kế API RESTful là sự kết hợp giữa GET và POST, như thể chúng là cùng một thứ. Thật dễ dàng mắc lỗi này với các khung nhìn dựa trên chức năng của Django và bộ điều phối mặc định của CherryPy , mặc dù cả hai khung công tác hiện đang giải quyết vấn đề này ( các khung nhìn dựa trên lớpPhương thức tương ứng).

Động từ HTTP rất quan trọng trong REST và trừ khi bạn rất cẩn thận về điều này, cuối cùng bạn sẽ rơi vào một mô hình chống REST .

Một số khung làm cho nó đúng là web.py , FlaskChai . Khi kết hợp với thư viện mô phỏng (tiết lộ đầy đủ: Tôi đã viết nó), chúng cho phép bạn viết các dịch vụ web RESTful đẹp:

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

Logic của dịch vụ chỉ được triển khai một lần và lựa chọn biểu diễn chính xác (Tiêu đề chấp nhận) + gửi đến chức năng kết xuất (hoặc mẫu) phù hợp được thực hiện một cách gọn gàng, minh bạch.

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

Cập nhật (tháng 4 năm 2012) : thêm thông tin về các chế độ xem dựa trên lớp của Django, các khung công tác Phương pháp Cherry và của Flask và Chai. Không tồn tại trở lại khi câu hỏi được hỏi.


12
Điều này là không chính xác, Django có hỗ trợ đầy đủ để nhận dạng POST vs GET và giới hạn lượt xem chỉ với một số phương thức nhất định.
aehlke

20
Ý tôi là, theo mặc định, Django đối xử với POST và GET như thể chúng là cùng một thứ, điều này rất bất tiện khi bạn đang thực hiện các dịch vụ RESTful vì nó buộc bạn phải làm: if request.method == 'GET': do_s Something () elif request.method == 'POST': do_s Something_else () web.py không có vấn đề đó
Martin Blech

19
@Wahnfrieden: Nếu có sự hỗ trợ riêng trong Django để xử lý các động từ HTTP khác nhau một cách riêng biệt (bởi "bản địa" tôi có nghĩa là không cần "if request.method == X"), bạn có thể vui lòng chỉ cho tôi một số tài liệu không?
Martin Blech

3
Sự kết hợp của POST và GET không áp dụng cho Chế độ xem dựa trên lớp của Django (được thêm vào 1.3), nhưng tôi tin là hợp lệ cho các bản phát hành trước đó.
ncoghlan

1
Câu trả lời không chính xác về CherryPy. Từ Docs: "REST (Chuyển giao trạng thái đại diện) là một kiểu kiến ​​trúc rất phù hợp để thực hiện trong CherryPy." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz

70

Ngạc nhiên không ai nhắc đến bình .

from flask import Flask
app = Flask(__name__)

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

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

7
Flask không ở ngoài đó khi câu hỏi được hỏi ...
Martin Blech

2
Flask không hoạt động với Python 3.x
cắn

3
Flask.dev hiện hỗ trợ Python 3
Sean Vieira

2
Flask hỗ trợ Python 3.3 trở lên.
mb21

3
Noob ở đây, làm thế nào đây là một RESTful?
avi

23

Chúng tôi đang sử dụng Django cho các dịch vụ web RESTful.

Lưu ý rằng - ra khỏi hộp - Django không có xác thực đủ chi tiết cho nhu cầu của chúng tôi. Chúng tôi đã sử dụng giao diện Django-REST , giúp ích rất nhiều. [Chúng tôi đã tự lăn lộn vì chúng tôi đã tạo ra rất nhiều tiện ích mở rộng đến nỗi nó trở thành một cơn ác mộng bảo trì.]

Chúng tôi có hai loại URL: URL "html" triển khai các trang HTML hướng đến con người và URL "json" thực hiện xử lý theo định hướng dịch vụ web. Chức năng xem của chúng tôi thường trông như thế này.

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

Vấn đề là chức năng hữu ích được bao gồm trong hai bài thuyết trình. Bản trình bày JSON thường chỉ là một đối tượng được yêu cầu. Bản trình bày HTML thường bao gồm tất cả các loại công cụ hỗ trợ điều hướng và các đầu mối theo ngữ cảnh khác giúp mọi người làm việc hiệu quả.

Các jsonViewchức năng đều rất giống nhau, có thể gây một chút khó chịu. Nhưng đó là Python, vì vậy hãy biến chúng thành một phần của lớp có thể gọi được hoặc viết trang trí nếu nó giúp.


2
Sự lặp lại khủng khiếp của d = someUsefulT Breath ... Ngay cả những người Django cũng đề nghị DRY.
temoto

5
@temoto: Nếu y = someUsefulThing(...)là "sự lặp lại khủng khiếp", thì tất cả các tham chiếu đến tất cả các chức năng và phương thức là "khủng khiếp". Tôi không hiểu làm thế nào để tránh tham chiếu một chức năng nhiều hơn một lần.
S.Lott

5
@temoto: "Khi bạn cần thay đổi đối số được chuyển sang someUsefulThing, có khả năng người ta quên làm như vậy trong tất cả các cuộc gọi" không? Gì? Làm thế nào là "khủng khiếp"? Đó là một hậu quả tầm thường của việc tham chiếu một chức năng nhiều lần. Tôi không hiểu những gì bạn đang nói và làm thế nào tham chiếu chức năng là "khủng khiếp" vì nó không thể truy cập được.
S.Lott

4
Xem câu trả lời được chấp nhận. Biểu thức kết quả {'message': 'Xin chào,' + name + '!'} Được viết một lần cho tất cả các bài thuyết trình.
temoto

3
Các hàm htmlView và jsonView của bạn phục vụ các biểu diễn khác nhau cho cùng một dữ liệu, phải không? Vì vậy, someUsefulThing(request, object_id)là một biểu thức truy xuất dữ liệu. Bây giờ bạn có hai bản sao của cùng một biểu thức ở các điểm khác nhau trong chương trình của bạn. Trong câu trả lời được chấp nhận, biểu thức dữ liệu được viết một lần. Thay thế someUsefulThingcuộc gọi của bạn bằng một chuỗi dài, thích paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))và nhìn vào mã. Tôi hy vọng nó sẽ minh họa quan điểm của tôi.
temoto

11

Xem wiki Web Framework của wiki.

Bạn có thể không cần các khung ngăn xếp đầy đủ , nhưng danh sách còn lại vẫn còn khá dài.


8

Tôi thực sự thích CherryPy . Đây là một ví dụ về một dịch vụ web yên tĩnh:

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

Điều này nhấn mạnh những gì tôi thực sự thích về CherryPy; đây là một ví dụ hoàn toàn hiệu quả, rất dễ hiểu ngay cả với những người không biết khung. Nếu bạn chạy mã này, thì bạn có thể thấy ngay kết quả trong trình duyệt web của mình; ví dụ: truy cập http: // localhost: 8080 / celc_to_fahr? độ = 50 sẽ hiển thị 122.0trong trình duyệt web của bạn.


35
Đó là một ví dụ hay, nhưng không có gì RESTful về nó.
aehlke

3
@Wahnfrieden: Bạn có thể giúp phần còn lại của chúng tôi bằng cách làm rõ lý do tại sao bạn không nghĩ rằng ở trên là RESTful? Theo quan điểm của tôi, nó trông giống như một ví dụ cổ điển về REST và dường như không phá vỡ bất kỳ quy tắc hoặc ràng buộc nào của hệ thống RESTful.
lilbyrdie

42
Nói một cách đơn giản, những gì mà ví dụ CherryPy ở trên đang làm là phơi bày các phương thức dưới dạng các thủ tục từ xa "có thể gọi được HTTP". Đó là RPC. Đó hoàn toàn là "động từ" định hướng. Các kiến ​​trúc RESTful tập trung vào các tài nguyên được quản lý bởi một máy chủ và sau đó cung cấp một bộ hoạt động rất hạn chế trên các tài nguyên đó: cụ thể, POST (tạo), GET (đọc), PUT (cập nhật) và DELETE (xóa). Việc thao túng các tài nguyên này, đặc biệt là thay đổi trạng thái của chúng thông qua PUT, là con đường chính trong đó "công cụ xảy ra".
verveguy

2
Bạn có thể viết thêm API RESTfull bằng CherryPy docs.cherrypy.org/urdy/progguide/REST.html
Radian


8

Tôi không thấy bất kỳ lý do nào để sử dụng Django chỉ để đưa ra một api REST, có những giải pháp nhẹ hơn và linh hoạt hơn. Django mang rất nhiều thứ khác lên bàn, điều đó không phải lúc nào cũng cần thiết. Để chắc chắn không cần thiết nếu bạn chỉ muốn hiển thị một số mã dưới dạng dịch vụ REST.

Kinh nghiệm cá nhân của tôi, fwiw, là một khi bạn có khung công tác phù hợp với một kích thước, bạn sẽ bắt đầu sử dụng ORM của nó, các plugin của nó, v.v. chỉ vì nó dễ dàng và cuối cùng bạn sẽ không bị phụ thuộc đó là rất khó để thoát khỏi.

Chọn một khung web là một quyết định khó khăn và tôi sẽ tránh chọn một giải pháp ngăn xếp đầy đủ chỉ để lộ api REST.

Bây giờ, nếu bạn thực sự cần / muốn sử dụng Django, thì Piston là một khung REST đẹp cho các ứng dụng django.

Điều đó đang được nói, CherryPy trông cũng rất đẹp, nhưng dường như RPC nhiều hơn REST.

Nhìn vào các mẫu (tôi chưa bao giờ sử dụng nó), có lẽ web.py là tốt nhất và sạch nhất nếu bạn chỉ cần REST.


6

Đây là một cuộc thảo luận trong tài liệu CherryPy trên REST: http://docs.cherrypy.org/dev/progguide/REST.html

Cụ thể, nó đề cập đến một bộ điều phối CherryPy được xây dựng có tên là MethodDispatcher, gọi các phương thức dựa trên các định danh động từ HTTP (GET, POST, v.v.).


6

Vào năm 2010, các cộng đồng Pylons và repoze.bfg đã "hợp lực" để tạo ra Kim tự tháp , một khung web dựa chủ yếu vào repoze.bfg. Nó giữ lại các triết lý của khung công tác mẹ và có thể được sử dụng cho các dịch vụ RESTful . Thật đáng xem.


Với Kim tự tháp, bạn có thể sử dụng Cornice , nơi cung cấp các trợ giúp hữu ích để xây dựng và ghi lại các dịch vụ web REST.
Calvin


5

Có vẻ như tất cả các loại khung web python có thể thực hiện giao diện RESTful ngay bây giờ.

Đối với Django, bên cạnh ngon miệng và pít-tông, django-rest-framework là một triển vọng đáng để đề cập. Tôi đã di chuyển một trong những dự án của tôi trên đó một cách suôn sẻ.

Django REST framework là một khung REST nhẹ cho Django, nhằm mục đích giúp dễ dàng xây dựng các API Web RESTful tự mô tả, được kết nối tốt.

Ví dụ nhanh:

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

Lấy ví dụ từ trang web chính thức, tất cả các mã trên cung cấp api, tài liệu tự giải thích (như dịch vụ web dựa trên xà phòng) và thậm chí cả hộp cát để kiểm tra một chút. Rất tiện lợi.

Liên kết: http://django-rest-framework.org/


2
Đặc biệt là giao diện browesable đang tiết kiệm rất nhiều thời gian trong khi phát triển! Nhiều lợi thế khác, vì vậy mọi người bắt đầu thực hiện nghỉ ngơi nên có một cái nhìn. Tôi bắt đầu với ngon miệng, nhưng chuyển hoàn toàn sang django-rest-framework
michel.iamit

3

Tôi không phải là một chuyên gia về thế giới python nhưng tôi đã sử dụng django , một khung web tuyệt vời và có thể được sử dụng để tạo ra một khung công tác yên tĩnh.


3

web2py bao gồm hỗ trợ để dễ dàng xây dựng API RESTful, được mô tả tại đâytại đây (video). Cụ thể, hãy xem parse_as_rest, cho phép bạn xác định các mẫu URL yêu cầu ánh xạ đối với các truy vấn cơ sở dữ liệu; và smart_query, cho phép bạn vượt qua các truy vấn ngôn ngữ tự nhiên tùy ý trong URL.


Các liên kết được đề cập không còn có sẵn
milovanderlinden

Các liên kết đã được cập nhật - thử lại.
Anthony


0

Tôi thực sự khuyên dùng TurboGears hoặc Chai:

TurboGears:

  • ít dài dòng hơn django
  • linh hoạt hơn, ít hướng HTML hơn
  • nhưng: ít nổi tiếng

Chai:

  • rất nhanh
  • rất dễ học
  • nhưng: tối giản và không trưởng thành

0

Chúng tôi đang làm việc trên một khuôn khổ cho các dịch vụ REST nghiêm ngặt, hãy xem http://prestans.googlecode.com

Vào thời điểm đầu Alpha, chúng tôi đang thử nghiệm mod_wsgi và AppEngine của Google.

Tìm kiếm người thử nghiệm và thông tin phản hồi. Cảm ơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.