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. :)
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. :)
Risposte:
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.
Sorpreso nessuno menzionato pallone .
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
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 jsonView
funzioni 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.
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.
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 someUsefulThing
chiamata 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.
Vedi il wiki di Python Web Frameworks .
Probabilmente non hai bisogno dei framework dello stack completo , ma l'elenco rimanente è ancora piuttosto lungo.
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.0
nel tuo browser web.
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.
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 ...).
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.
Piston è un framework molto flessibile per il controllo delle API RESTful per le applicazioni Django.
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.
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.
Se stai usando Django, allora puoi prendere in considerazione django-tastypie come alternativa al django-piston . È più facile sintonizzarsi su fonti di dati non ORM rispetto al pistone e ha un'ottima documentazione .
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.