Python REST (web hizmetleri) çerçevesinin önerileri? [kapalı]


321

Kendi RESTful API'lerinizi yazmak için sunucu tarafında kullanılmak üzere farklı Python tabanlı REST çerçevelerinin önerilerinin bir listesi var mı? Tercihen artıları ve eksileri ile.

Lütfen buraya öneriler eklemekten çekinmeyin. :)


Yanıtlar:


192

RESTful API tasarlarken dikkat edilmesi gereken bir şey, GET ve POST'un aynı şeymiş gibi birleşmesidir. O bu hata yapmak kolaydır Django 'ın fonksiyonu tabanlı görünümleri ve CherryPy hem çerçeveler şimdi (Bu soruna bir yol sağlar, ancak' ın varsayılan memuru sınıf tabanlı görünümleri ve MethodDispatcher sırasıyla).

HTTP fiilleri REST'te çok önemlidir ve bu konuda çok dikkatli değilseniz, bir REST anti-desenine düşersiniz .

Doğru yapan bazı çerçeveler web.py , Flask ve Bottle . Mimerender kütüphanesi ile birleştirildiğinde (tam açıklama: yazdım), güzel RESTful web hizmetleri yazmanıza izin verir:

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

Hizmetin mantığı yalnızca bir kez uygulanır ve doğru sunum seçimi (Üstbilgiyi kabul et) + uygun oluşturma işlevine (veya şablona) gönderim düzenli ve şeffaf bir şekilde yapılır.

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

Güncelleme (Nisan 2012) : Django'nun sınıf tabanlı görünümleri, CherryPy'nin MethodDispatcher ve Flask ve Şişe çerçeveleri hakkında bilgi eklendi. Soru sorulduğunda ikisi de yoktu.


12
Bu yanlıştır, Django POST ve GET'in tanınması ve görünümlerin sadece belirli yöntemlerle sınırlandırılması için tam desteğe sahiptir.
aehlke

20
Django'nun varsayılan olarak POST ve GET'e sanki aynı şeymiş gibi davrandığını söylemiştim. elif request.method == 'POST': do_something_else () web.py'ın bu sorunu yok
Martin Blech

19
@Wahnfrieden: Django'da farklı HTTP fiillerini ayrı ayrı işlemek için yerel destek varsa (request.method == X "ise" native "ile ihtiyacım yok" demek istiyorum), lütfen beni bazı belgelere yönlendirebilir misiniz?
Martin Blech

3
POST ve GET'in birleşimi Django'nun Sınıf Tabanlı Görünümleri için geçerli değildir (1.3'te eklenmiştir), ancak önceki sürümler için geçerli olduğuna inanıyorum.
ncoghlan

1
CherryPy hakkında cevap yanlış. Dokümanlar'dan: "REST (Temsil Edici Devlet Transferi), CherryPy'de uygulamaya uygun mimari bir stildir." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz

70

Kimse flask bahsetmedi şaşırttı .

from flask import Flask
app = Flask(__name__)

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

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

7
Soru sorulduğunda
şişe

2
Flask Python 3.x ile çalışmaz
bitek

3
Flask.dev artık Python 3'ü destekliyor
Sean Vieira

2
Flask , Python 3.3 veya üstünü destekler .
mb21

3
noob burada, bu nasıl bir RESTful?
avi

23

RESTful web hizmetleri için Django kullanıyoruz .

- Kutunun dışında - Django'nun ihtiyaçlarımız için yeterince kimlik doğrulamasına sahip olmadığını unutmayın. Çok yardımcı olan Django-REST arayüzünü kullandık . [O zamandan beri kendimizi seçtik çünkü bakım kabusu haline gelecek kadar çok uzantı geliştirmiştik.]

İki tür URL'miz vardır: İnsan odaklı HTML sayfalarını uygulayan "html" URL'leri ve web hizmetlerine yönelik işlemeyi uygulayan "json" URL'leri. Görüş fonksiyonlarımız genellikle böyle görünür.

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

Mesele şu ki, kullanışlı işlevsellik iki sunumun dışındadır. JSON sunumu genellikle istenen bir nesnedir. HTML sunumu genellikle insanların üretken olmasına yardımcı olan her türlü gezinme yardımcısı ve diğer bağlamsal ipuçlarını içerir.

jsonViewFonksiyonlar biraz can sıkıcı olabilen, hepsi çok benzer. Ama bu Python, bu yüzden onları çağrılabilir bir sınıfın parçası yapın veya yardımcı olursa dekoratörler yazın.


2
D = someUsefulThing'in korkunç tekrarı ... Django adamları bile KURU önerir.
temoto

5
@temoto: Eğer y = someUsefulThing(...)"Korkunç bir tekrar" ise, tüm işlevlere ve yöntemlere yapılan tüm başvurular "korkunç" olur. Ben önlemek için nasıl çalıştığını anlamak için başarısız referans kereden fazla bir fonksiyon.
S.Lott

5
@temoto: "someUsefulThing'e iletilen bağımsız değişkenleri değiştirmeniz gerektiğinde, kişinin tüm çağrılarda bunu yapmayı unutması ihtimali var"? Ne? Bu nasıl "korkunç"? Bu, bir işleve birden çok kez başvurmanın önemsiz bir sonucudur. Neden bahsettiğinizi ve işlev referansının kaçınılmaz olduğu için nasıl "korkunç" olduğunu anlamıyorum.
S.Lott

4
Kabul edilen cevaba bakınız. Sonuç ifadesi {'message': 'Merhaba,' + ad + '!'} Tüm sunumlar için bir kez yazılır.
temoto

3
HtmlView ve jsonView işlevleriniz aynı veriler için farklı sunumlar sunar, değil mi? Yani someUsefulThing(request, object_id)bir veri alma ifadesidir. Şimdi programınızdaki farklı noktalarda aynı ifadenin iki kopyası var. Kabul edilen cevapta veri ifadesi bir kez yazılır. someUsefulThingAramanızı uzun bir dize ile değiştirin paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count')), kodu gibi ve bakın. Umarım bu benim açımdan örnek olur.
temoto


8

CherryPy'yi gerçekten seviyorum . İşte dinlendirici bir web hizmeti örneği:

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

Bu CherryPy hakkında gerçekten sevdiğim şeyleri vurgular; Bu, çerçeveyi bilmeyen biri için bile çok anlaşılır olan tamamen çalışan bir örnektir. Bu kodu çalıştırırsanız, sonuçları hemen web tarayıcınızda görebilirsiniz; örneğin ziyaret http: // localhost: 8080 / celc_to_fahr derece = 50 gösterecektir 122.0web tarayıcınızda.


35
Bu güzel bir örnek, ama RESTful hakkında hiçbir şey yok.
aehlke

3
@Wahnfrieden: Yukarıdakilerin neden RESTful olduğunu düşünmediğinizi açıklayarak geri kalanlarımıza yardım edebilir misiniz? Benim bakış açımdan, REST'in klasik bir örneğine benziyor ve RESTful sisteminin kurallarından veya kısıtlamalarından herhangi birini ihlal etmiyor gibi görünüyor.
lilbyrdie

42
Basit bir ifadeyle, yukarıdaki CherryPy örneğinin yaptığı, yöntemleri "HTTP çağrılabilir" uzak yordamlar olarak göstermektir. Bu RPC. Tamamen "fiil" odaklı. RESTful mimariler bir sunucu tarafından yönetilen kaynaklara odaklanır ve daha sonra bu kaynaklar üzerinde çok sınırlı bir işlem kümesi sunar: özellikle POST (oluşturma), GET (okuma), PUT (güncelleme) ve DELETE (silme). Bu kaynakların manipüle edilmesi, özellikle durumlarının PUT yoluyla değiştirilmesi, "şeylerin meydana geldiği" anahtar yoldur.
verveguy

2
CherryPy'yi kullanarak daha fazla RESTfull API'si yazabilirsiniz docs.cherrypy.org/stable/progguide/REST.html
Radian


8

Django'yu sadece bir REST API'sini göstermek için kullanmak için herhangi bir neden görmüyorum, daha hafif ve daha esnek çözümler var. Django masaya her zaman ihtiyaç duyulmayan birçok şey taşır. Sadece bazı kodları bir REST hizmeti olarak göstermek istiyorsanız, mutlaka gerekli değildir.

Kişisel deneyimim, fwiw, tek bedene uyan bir çerçeveye sahip olduğunuzda, ORM'sini, eklentilerini vb. kurtulmak çok zor.

Bir web çerçevesi seçmek zor bir karardır ve sadece bir REST API'sini ortaya çıkarmak için tam bir yığın çözüm seçmekten kaçınırım.

Şimdi, gerçekten Django'ya ihtiyacınız varsa / kullanmak istiyorsanız, Piston django uygulamaları için güzel bir REST çerçevesidir.

Bununla birlikte, CherryPy de gerçekten güzel görünüyor, ancak REST'ten daha fazla RPC gibi görünüyor.

Örneklere baktığımda (hiç kullanmadım), muhtemelen REST'e ihtiyacınız varsa web.py en iyisi ve en temizidir.


6

İşte REST ile ilgili CherryPy belgelerinde bir tartışma: http://docs.cherrypy.org/dev/progguide/REST.html

Özellikle, HTTP-fiil tanımlayıcılarına (GET, POST, vb.) Dayalı yöntemleri çağıran MethodDispatcher adlı yerleşik bir CherryPy dağıtıcısından bahseder.


6

2010 yılında, Pilonlar ve repoze.bfg toplulukları , en çok repoze.bfg'ye dayanan bir web çerçevesi olan Piramit'i oluşturmak için "güçlerini birleştirdi" . Ana çerçevelerinin felsefelerini korur ve RESTful hizmetleri için kullanılabilir . Bir göz atmaya değer.


Piramidin ile yararlanabilir korniş bina ve DİNLENME web hizmetleri belgeleyen için faydalı yardımcıları sağlar.
Calvin


5

Python web çerçevelerinin her türlü RESTful arayüzleri şimdi uygulayabilir gibi görünüyor.

Django için, tastypie ve pistonun yanı sıra, django-rest-framework bahsetmeye değer ümit vericidir. Projemden birini sorunsuz bir şekilde taşıdım.

Django REST çerçevesi, iyi bağlantılı, kendi kendini tanımlayan RESTful Web API'leri oluşturmayı kolaylaştıran Django için hafif bir REST çerçevesidir.

Hızlı örnek:

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

Resmi siteden örnek alın, yukarıdaki tüm kodlar api, kendi kendini açıklayan belge (sabun tabanlı web hizmeti gibi) ve hatta biraz test etmek için kum havuzu sağlar. Çok kolaylık.

Bağlantılar: http://django-rest-framework.org/


2
Özellikle göz atılabilir arayüz geliştirirken çok zaman kazanıyor! Diğer birçok avantaj, bu nedenle dinlenme uygulamasına başlayan herkes bir göz atmalıdır. Tastypie ile başladım, ancak tamamen django-rest-framework'e
geçtim

3

Ben python dünyasında bir uzman değilim ama ben mükemmel bir web çerçeve ve dinlendirici bir çerçeve oluşturmak için kullanılabilir django kullanıyorum .


3

web2py , burada ve burada açıklanan RESTful API'leri kolayca oluşturmak için destek içerir (video). Özellikle, parse_as_restistek bağımsız değişkenlerini veritabanı sorgularıyla eşleştiren URL kalıplarını tanımlamanıza izin veren; ve smart_queryURL'ye rastgele doğal dil sorguları iletmenizi sağlar.


Bahsedilen bağlantılar artık mevcut değil
milovanderlinden

Bağlantılar güncellendi - tekrar deneyin.
Anthony


0

TurboGears veya Bottle'ı şiddetle tavsiye ederim:

TurboGears:

  • django'dan daha az ayrıntılı
  • daha esnek, daha az HTML odaklı
  • ama: daha az ünlü

Şişe:

  • çok hızlı
  • öğrenmesi çok kolay
  • ama: minimalist ve olgun değil

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.