Consigli sul framework Python REST (servizi Web)? [chiuso]


321

C'è un elenco da qualche parte di raccomandazioni di diversi framework REST basati su Python da utilizzare sul lato server per scrivere le tue API RESTful? Preferibilmente con pro e contro.

Non esitate a aggiungere consigli qui. :)


Ecco un buon tutorial sull'uso di web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Risposte:


192

Qualcosa di cui prestare attenzione quando si progetta un'API RESTful è la conflazione di GET e POST, come se fossero la stessa cosa. E 'facile fare questo errore con Django 's vista basati su funzioni e CherryPy ' dispatcher di default s, anche se entrambi i quadri ora fornire un modo per aggirare questo problema ( vista basati su classi e MethodDispatcher , rispettivamente).

I verbi HTTP sono molto importanti in REST e, a meno che tu non sia molto attento a questo, finirai per cadere in un anti-pattern REST .

Alcuni framework che funzionano bene sono web.py , Flask e Bottle . Se combinati con la libreria mimerender (informativa completa: l'ho scritto), ti permettono di scrivere bei servizi web 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()

La logica del servizio viene implementata una sola volta e la selezione della rappresentazione corretta (Accetta intestazione) + invio alla funzione di rendering (o modello) corretta viene eseguita in modo ordinato e trasparente.

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

Aggiornamento (aprile 2012) : aggiunte informazioni sulle viste di classe basate su Django, sui metodi MethodDispatcher e sui framework Flask and Bottle di CherryPy. Nessuno dei due esisteva quando fu posta la domanda.


12
Ciò non è corretto, Django ha il pieno supporto per riconoscere POST vs GET e limitare le visualizzazioni solo a determinati metodi.
aehlke,

20
Volevo dire che, per impostazione predefinita, Django tratta POST e GET come se fossero la stessa cosa, il che è molto scomodo quando stai facendo servizi RESTful come ti costringe a fare: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py non ha questo problema
Martin Blech

19
@Wahnfrieden: Se in Django esiste un supporto nativo per la gestione separata di diversi verbi HTTP (per "nativo" intendo non aver bisogno di "se request.method == X"), potresti indicarmi un po 'di documentazione?
Martin Blech,

3
La fusione tra POST e GET non si applica alle viste basate sulla classe di Django (aggiunte in 1.3), ma credo che sia valido per le versioni precedenti.
ncoghlan,

1
La risposta non è corretta su CherryPy. Da Docs: "REST (Representational State Transfer) è uno stile architettonico che ben si adatta all'implementazione in CherryPy." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz,

70

Sorpreso nessuno menzionato pallone .

from flask import Flask
app = Flask(__name__)

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

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

7
Flask non era là fuori quando fu posta la domanda ...
Martin Blech,

2
Flask non funziona con Python 3.x
bitek,

3
Flask.dev ora supporta Python 3
Sean Vieira il

2
Flask supporta Python 3.3 o versioni successive.
mb21

3
noob qui, come è un RESTful?
avi

23

Stiamo usando Django per i servizi web RESTful.

Si noti che - out of the box - Django non disponeva di un'autenticazione abbastanza dettagliata per le nostre esigenze. Abbiamo usato l' interfaccia Django-REST , che ci ha aiutato molto. [Da allora abbiamo lanciato il nostro perché avevamo creato così tante estensioni che era diventato un incubo per la manutenzione.]

Abbiamo due tipi di URL: URL "html" che implementano le pagine HTML orientate all'uomo e URL "json" che implementano l'elaborazione orientata ai servizi web. Le nostre funzioni di visualizzazione sembrano spesso così.

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

Il punto è che l'utile funzionalità è presa in considerazione dalle due presentazioni. La presentazione JSON è in genere solo un oggetto richiesto. La presentazione HTML spesso include tutti i tipi di aiuti alla navigazione e altri indizi contestuali che aiutano le persone a essere produttive.

Le jsonViewfunzioni sono tutte molto simili, il che può essere un po 'fastidioso. Ma è Python, quindi rendili parte di una classe richiamabile o scrivi decoratori se aiuta.


2
Terribile ripetizione di d = someUsefulThing ... Anche i ragazzi di Django suggeriscono DRY.
temoto,

5
@temoto: se y = someUsefulThing(...)è una "ripetizione terribile", tutti i riferimenti a tutte le funzioni e metodi sono "terribili". Non riesco a capire come evitare di fare riferimento a una funzione più di una volta.
S. Lott,

5
@temoto: "Quando devi cambiare gli argomenti passati a someUsefulThing, c'è la possibilità che uno si dimentichi di farlo in tutte le chiamate"? Che cosa? Come è "terribile"? Questa è una banale conseguenza del riferimento a una funzione più di una volta. Non riesco a capire di cosa stai parlando e come il riferimento alle funzioni sia "orribile" poiché è inevitabile.
S. Lott,

4
Vedi la risposta accettata L'espressione del risultato {'message': 'Hello,' + name + '!'} Viene scritta una volta per tutte le presentazioni.
temoto,

3
Le tue funzioni htmlView e jsonView servono rappresentazioni diverse per gli stessi dati, giusto? Così someUsefulThing(request, object_id)è un'espressione di recupero dei dati. Ora hai due copie della stessa espressione in diversi punti del tuo programma. Nella risposta accettata, l'espressione dei dati viene scritta una volta. Sostituisci la tua someUsefulThingchiamata con una lunga stringa, come paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))e guarda il codice. Spero che illustrerà il mio punto.
temoto,

11

Vedi il wiki di Python Web Frameworks .

Probabilmente non hai bisogno dei framework dello stack completo , ma l'elenco rimanente è ancora piuttosto lungo.


8

Mi piace molto CherryPy . Ecco un esempio di servizio web riposante:

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

Questo sottolinea ciò che mi piace molto di CherryPy; questo è un esempio completamente funzionante che è molto comprensibile anche a qualcuno che non conosce il framework. Se si esegue questo codice, è possibile visualizzare immediatamente i risultati nel browser Web; ad es. visitando http: // localhost: 8080 / celc_to_fahr? degree = 50 verrà visualizzato 122.0nel tuo browser web.


35
Questo è un bell'esempio, ma non c'è niente di RESTOSO al riguardo.
aehlke,

3
@Wahnfrieden: Potresti aiutare il resto di noi chiarendo perché non pensi che quanto sopra sia RESTful? Dal mio punto di vista, sembra un classico esempio di REST e non sembra violare alcuna delle regole o dei vincoli di un sistema RESTful.
lilbyrdie,

42
In termini semplici, ciò che sta facendo l'esempio CherryPy sopra sta esponendo i metodi come procedure remote "richiamabili HTTP". Questo è RPC. È interamente orientato al "verbo". Le architetture RESTful si concentrano sulle risorse gestite da un server e offrono quindi un insieme molto limitato di operazioni su tali risorse: in particolare, POST (crea), GET (leggi), PUT (aggiorna) e ELIMINA (elimina). La manipolazione di queste risorse, in particolare cambiando il loro stato tramite PUT, è il percorso chiave con cui "le cose accadono".
verveguy,

2
Puoi scrivere più API RESTfull usando CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian


8

Non vedo alcun motivo per usare Django solo per esporre un API REST, ci sono soluzioni più leggere e più flessibili. Django porta molte altre cose sul tavolo, che non sono sempre necessarie. Di sicuro non è necessario se si desidera esporre solo un codice come servizio REST.

La mia esperienza personale, a dirla tutta, è che una volta che hai un framework unico per tutti, inizierai a usare il suo ORM, i suoi plugin, ecc. Solo perché è facile e in pochissimo tempo finisci per avere una dipendenza è molto difficile sbarazzarsi di.

La scelta di un framework web è una decisione difficile e eviterei di scegliere una soluzione full stack solo per esporre un API REST.

Ora, se hai davvero bisogno / vuoi usare Django, Piston è un bel framework REST per le app di django.

Detto questo, CherryPy sembra anche molto carino, ma sembra più RPC che REST.

Guardando i campioni (non l'ho mai usato), probabilmente web.py è il migliore e più pulito se hai solo bisogno di REST.


6

Ecco una discussione nei documenti CherryPy su REST: http://docs.cherrypy.org/dev/progguide/REST.html

In particolare menziona un dispatcher CherryPy incorporato chiamato MethodDispatcher, che invoca metodi basati sui loro identificatori di verbi HTTP (GET, POST, ecc ...).


6

Nel 2010, le comunità di Piloni e repoze.bfg "hanno unito le forze" per creare Pyramid , un framework web basato principalmente su repoze.bfg. Mantiene le filosofie dei suoi framework principali e può essere utilizzato per i servizi RESTful . Vale la pena dare un'occhiata.


Con Pyramid puoi utilizzare Cornice , che fornisce utili aiutanti per la costruzione e la documentazione di servizi web REST.
Calvin,

5

Piston è un framework molto flessibile per il controllo delle API RESTful per le applicazioni Django.


5

Sembra che tutti i tipi di framework Web Python possano implementare interfacce RESTful ora.

Per Django, oltre a tastypie e pistone, django-rest-framework è una promessa degna di nota. Ho già migrato senza problemi uno dei miei progetti.

Il framework REST di Django è un framework REST leggero per Django, che mira a semplificare la creazione di API Web RESTful ben connesse e auto-descrittive.

Esempio rapido:

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

Prendi l'esempio dal sito ufficiale, tutti i codici sopra riportati forniscono api, documento autoesplicativo (come il servizio web a base di sapone) e persino sandbox per testare un po '. Molto comodo.

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


2
Soprattutto l'interfaccia browesable sta risparmiando molto tempo durante lo sviluppo! Molti altri vantaggi, quindi tutti coloro che iniziano l'implementazione di riposo dovrebbero dare un'occhiata. Ho iniziato con tastypie, ma sono passato completamente a django-rest-framework
michel.iamit

3

Non sono un esperto del mondo Python ma sto usando Django che è un eccellente framework Web e può essere usato per creare un framework riposante.


3

web2py include il supporto per creare facilmente API RESTful, descritte qui e qui (video). In particolare, guarda parse_as_rest, che ti consente di definire pattern URL che mappano gli argomenti di richiesta alle query del database; e smart_query, che consente di passare query arbitrarie in linguaggio naturale nell'URL.


I link citati non sono più disponibili
milovanderlinden,

I collegamenti sono stati aggiornati: riprovare.
Anthony,


0

Consiglio vivamente TurboGears o Bottle:

TurboGears:

  • meno prolisso del django
  • più flessibile, meno orientato all'HTML
  • ma: meno famoso

Bottiglia:

  • molto veloce
  • molto facile da imparare
  • ma: minimalista e non maturo

0

Stiamo lavorando a un framework per servizi REST rigorosi, controlla http://prestans.googlecode.com

È nei primi anni Alpha al momento, stiamo testando contro mod_wsgi e AppEngine di Google.

Alla ricerca di tester e feedback. Grazie.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.