Empfehlungen des Python REST (Web Services) Frameworks? [geschlossen]

321

Gibt es irgendwo eine Liste mit Empfehlungen verschiedener Python-basierter REST-Frameworks, die auf der Serverseite zum Schreiben eigener RESTful-APIs verwendet werden können? Am besten mit Vor- und Nachteilen.

Bitte zögern Sie nicht, hier Empfehlungen hinzuzufügen. :) :)

Darius
quelle
Hier ist ein gutes Tutorial zur Verwendung von web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Antworten:

192

Beim Entwerfen einer RESTful-API ist die Verschmelzung von GET und POST so zu beachten, als ob sie dasselbe wären. Es ist leicht, diesen Fehler mit den funktionsbasierten Ansichten von Django und dem Standard-Dispatcher von CherryPy zu machen , obwohl beide Frameworks jetzt einen Weg bieten, um dieses Problem zu umgehen ( klassenbasierte Ansichten bzw. MethodDispatcher ).

HTTP-Verben sind in REST sehr wichtig , und wenn Sie nicht sehr vorsichtig sind, fallen Sie in ein REST-Anti-Pattern .

Einige Frameworks, die es richtig machen, sind web.py , Flask und Bottle . In Kombination mit der Mimerender- Bibliothek (vollständige Offenlegung: Ich habe sie geschrieben) können Sie nette RESTful-Webservices schreiben:

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

Die Logik des Dienstes wird nur einmal implementiert, und die richtige Auswahl der Darstellung (Kopfzeile akzeptieren) + Versand an die richtige Renderfunktion (oder Vorlage) erfolgt auf ordentliche, transparente Weise.

$ 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) : Informationen zu den klassenbasierten Ansichten von Django, CherryPys MethodDispatcher und Flask and Bottle-Frameworks hinzugefügt. Beides existierte nicht, als die Frage gestellt wurde.

Martin Blech
quelle
12
Dies ist falsch. Django hat volle Unterstützung für das Erkennen von POST vs GET und das Beschränken von Ansichten auf nur bestimmte Methoden.
Aehlke
20
Ich meinte, dass Django POST und GET standardmäßig so behandelt, als wären sie dasselbe, was sehr unpraktisch ist, wenn Sie RESTful-Services ausführen, da dies Sie dazu zwingt: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py hat dieses Problem nicht
Martin Blech
19
@Wahnfrieden: Wenn es in Django native Unterstützung für die getrennte Behandlung verschiedener HTTP-Verben gibt (mit "native" meine ich nicht "wenn request.method == X"), können Sie mich bitte auf eine Dokumentation verweisen?
Martin Blech
3
Die Verschmelzung von POST und GET gilt nicht für Djangos klassenbasierte Ansichten (hinzugefügt in 1.3), aber ich glaube, dass dies für die früheren Versionen gilt.
Ncoghlan
1
Die Antwort zu CherryPy ist falsch. Aus den Dokumenten: "REST (Representational State Transfer) ist ein Architekturstil, der sich gut für die Implementierung in CherryPy eignet." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz
70

Überrascht erwähnte niemand die Flasche .

from flask import Flask
app = Flask(__name__)

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

if __name__ == "__main__":
    app.run()
user161642
quelle
7
Flask war nicht da draußen, als die Frage gestellt wurde ...
Martin Blech
2
Flask funktioniert nicht mit Python 3.x
Bitek
3
Flask.dev unterstützt jetzt Python 3
Sean Vieira
2
Flask unterstützt Python 3.3 oder höher.
mb21
3
noob hier, wie ist das ein RESTful?
Avi
23

Wir verwenden Django für RESTful-Webdienste.

Beachten Sie, dass Django nicht sofort über eine ausreichende Authentifizierung für unsere Anforderungen verfügte. Wir haben die Django-REST-Schnittstelle verwendet , was sehr hilfreich war. [Wir haben seitdem unsere eigenen gerollt, weil wir so viele Erweiterungen vorgenommen hatten, dass es zu einem Alptraum für die Wartung geworden war.]

Wir haben zwei Arten von URLs: "HTML" -URLs, die die menschlich orientierten HTML-Seiten implementieren, und "json" -URLs, die die webdienstorientierte Verarbeitung implementieren. Unsere Ansichtsfunktionen sehen oft so aus.

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

Der Punkt ist, dass die nützliche Funktionalität aus den beiden Präsentationen herausgerechnet wird. Die JSON-Präsentation ist normalerweise nur ein Objekt, das angefordert wurde. Die HTML-Präsentation enthält häufig alle Arten von Navigationshilfen und andere kontextbezogene Hinweise, die Menschen dabei helfen, produktiv zu sein.

Die jsonViewFunktionen sind alle sehr ähnlich, was etwas nervig sein kann. Aber es ist Python, also machen Sie sie zu einem Teil einer aufrufbaren Klasse oder schreiben Sie Dekorateure, wenn es hilft.

S.Lott
quelle
2
Schreckliche Wiederholung von d = someUsefulThing ... Sogar Django-Leute schlagen DRY vor.
Temoto
5
@temoto: Wenn y = someUsefulThing(...)es sich um eine "schreckliche Wiederholung" handelt, sind alle Verweise auf alle Funktionen und Methoden "schrecklich". Ich verstehe nicht, wie ich vermeiden kann, eine Funktion mehr als einmal zu referenzieren .
S.Lott
5
@temoto: "Wenn Sie Argumente ändern müssen, die an someUsefulThing übergeben wurden, besteht die Möglichkeit, dass man dies bei allen Aufrufen vergisst"? Was? Wie ist das "schrecklich"? Dies ist eine triviale Folge der mehrmaligen Referenzierung einer Funktion. Ich verstehe nicht, wovon Sie sprechen und wie Funktionsreferenz "schrecklich" ist, da sie unvermeidlich ist.
S.Lott
4
Siehe die akzeptierte Antwort. Der Ergebnisausdruck {'message': 'Hello,' + name + '!'} Wird für alle Präsentationen einmal geschrieben.
Temoto
3
Ihre Funktionen htmlView und jsonView dienen unterschiedlichen Darstellungen für dieselben Daten, oder? Dies someUsefulThing(request, object_id)gilt auch für einen Datenabrufausdruck. Jetzt haben Sie zwei Kopien desselben Ausdrucks an verschiedenen Stellen in Ihrem Programm. In der akzeptierten Antwort wird der Datenausdruck einmal geschrieben. Ersetzen Sie Ihren someUsefulThingAnruf durch eine lange Zeichenfolge paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))und sehen Sie sich den Code an. Ich hoffe, es wird meinen Standpunkt veranschaulichen.
Temoto
11

Siehe Python Web Frameworks- Wiki.

Sie benötigen wahrscheinlich nicht die vollständigen Stack- Frameworks, aber die verbleibende Liste ist noch ziemlich lang.

gimel
quelle
8

Ich mag CherryPy wirklich . Hier ist ein Beispiel für einen erholsamen Webdienst:

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

Dies unterstreicht, was ich an CherryPy wirklich mag; Dies ist ein vollständig funktionierendes Beispiel, das selbst für jemanden, der das Framework nicht kennt, sehr verständlich ist. Wenn Sie diesen Code ausführen, können Sie die Ergebnisse sofort in Ihrem Webbrowser anzeigen. Wenn Sie beispielsweise http: // localhost: 8080 / celc_to_fahr? Grad = 50 besuchen, wird dies 122.0in Ihrem Webbrowser angezeigt.

Eli Courtwright
quelle
35
Das ist ein schönes Beispiel, aber es ist nichts RESTful daran.
Aehlke
3
@Wahnfrieden: Könnten Sie dem Rest von uns helfen, indem Sie klarstellen, warum Sie das oben Gesagte nicht für RESTful halten? Aus meiner Sicht sieht es wie ein klassisches Beispiel für REST aus und scheint keine der Regeln oder Einschränkungen eines RESTful-Systems zu brechen.
Lilbyrdie
42
In einfachen Worten, das obige CherryPy-Beispiel macht Methoden als "HTTP-aufrufbare" Remote-Prozeduren verfügbar. Das ist RPC. Es ist völlig "verb" orientiert. RESTful-Architekturen konzentrieren sich auf die von einem Server verwalteten Ressourcen und bieten dann eine sehr begrenzte Anzahl von Vorgängen für diese Ressourcen: insbesondere POST (Erstellen), GET (Lesen), PUT (Aktualisieren) und DELETE (Löschen). Die Manipulation dieser Ressourcen, insbesondere die Änderung ihres Zustands über PUT, ist der Schlüsselweg, auf dem "Dinge passieren".
Verveguy
2
Sie können weitere RESTfull-APIs mit CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian
8

Ich sehe keinen Grund, Django nur zu verwenden, um eine REST-API freizulegen. Es gibt leichtere und flexiblere Lösungen. Django bringt viele andere Dinge auf den Tisch, die nicht immer benötigt werden. Sicherlich nicht erforderlich, wenn Sie nur Code als REST-Service verfügbar machen möchten.

Meine persönliche Erfahrung, fwiw, ist, dass Sie, sobald Sie ein einheitliches Framework haben, das ORM, die Plugins usw. verwenden, nur weil es einfach ist und Sie in kürzester Zeit eine Abhängigkeit haben das ist sehr schwer loszuwerden.

Die Auswahl eines Webframeworks ist eine schwierige Entscheidung, und ich würde es vermeiden, eine Full-Stack-Lösung auszuwählen, nur um eine REST-API verfügbar zu machen.

Wenn Sie Django wirklich brauchen / wollen, dann ist Piston ein schönes REST-Framework für Django-Apps.

Davon abgesehen sieht CherryPy auch sehr gut aus, scheint aber mehr RPC als REST zu sein.

Wenn Sie sich die Beispiele ansehen (ich habe sie nie verwendet), ist web.py wahrscheinlich die beste und sauberste, wenn Sie nur REST benötigen.

Savino Sguera
quelle
6

Hier ist eine Diskussion in CherryPy-Dokumenten zu REST: http://docs.cherrypy.org/dev/progguide/REST.html

Insbesondere wird ein integrierter CherryPy-Dispatcher namens MethodDispatcher erwähnt, der Methoden aufruft, die auf ihren HTTP-Verb-IDs (GET, POST usw.) basieren.

nir
quelle
6

Im Jahr 2010 haben sich die Communitys Pylons und repoze.bfg "zusammengeschlossen", um Pyramid zu erstellen , ein Webframework, das am stärksten auf repoze.bfg basiert. Es behält die Philosophie seiner übergeordneten Frameworks bei und kann für RESTful-Services verwendet werden . Es ist einen Blick wert.

asthasr
quelle
Mit Pyramid können Sie Cornice verwenden , das nützliche Hilfestellungen zum Erstellen und Dokumentieren von REST-Webdiensten bietet.
Calvin
5

Piston ist ein sehr flexibles Framework für die Verkabelung von RESTful-APIs für Django-Anwendungen.

DenisKolodin
quelle
5

Anscheinend können alle Arten von Python-Webframeworks jetzt RESTful-Schnittstellen implementieren.

Für Django ist neben Tastypie und Kolben das Django-Rest-Framework ein vielversprechendes, erwähnenswertes. Ich habe bereits eines meiner Projekte reibungslos darauf migriert.

Das Django REST-Framework ist ein leichtes REST-Framework für Django, mit dem sich auf einfache Weise gut verbundene, selbstbeschreibende RESTful-Web-APIs erstellen lassen.

Kurzes Beispiel:

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

Nehmen Sie das Beispiel von der offiziellen Website, alle oben genannten Codes bieten API, selbsterklärendes Dokument (wie Seifen-basierter Webservice) und sogar Sandbox, um ein wenig zu testen. Sehr bequem.

Links: http://django-rest-framework.org/

Sun Liwen
quelle
2
Besonders die browesable Oberfläche spart beim Entwickeln viel Zeit! Viele andere Vorteile, damit jeder, der mit der Implementierung von Ruhe beginnt, einen Blick darauf werfen sollte. Ich begann mit Tastypie, wechselte aber komplett zu Django-Rest-Framework
michel.iamit
3

Ich bin kein Experte für die Python-Welt, aber ich habe Django verwendet , ein ausgezeichnetes Web-Framework, mit dem ein erholsames Framework erstellt werden kann.

Jeremy B.
quelle
3

web2py bietet Unterstützung für das einfache Erstellen von RESTful-APIs, die hier und hier beschrieben werden (Video). Sehen parse_as_restSie sich insbesondere an , mit dem Sie URL-Muster definieren können, mit denen Anforderungsargumente Datenbankabfragen zugeordnet werden. und smart_query, wodurch Sie beliebige Abfragen in natürlicher Sprache in der URL übergeben können.

Anthony
quelle
Die genannten Links sind nicht mehr verfügbar
milovanderlinden
Die Links wurden aktualisiert - versuchen Sie es erneut.
Anthony
0

Ich empfehle TurboGears oder Bottle:

TurboGears:

  • weniger ausführlich als Django
  • flexibler, weniger HTML-orientiert
  • aber: weniger berühmt

Flasche:

  • sehr schnell
  • sehr leicht zu lernen
  • aber: minimalistisch und nicht ausgereift
Federico
quelle
0

Wir arbeiten an einem Framework für strenge REST-Services. Weitere Informationen finden Sie unter http://prestans.googlecode.com

Es ist im frühen Alpha im Moment, wir testen gegen mod_wsgi und Googles AppEngine.

Auf der Suche nach Testern und Feedback. Vielen Dank.

Devraj
quelle