Recommandations du cadre Python REST (services Web)? [fermé]

321

Existe-t-il une liste de recommandations de différents frameworks REST basés sur Python à utiliser côté serveur pour écrire vos propres API RESTful? De préférence avec des avantages et des inconvénients.

N'hésitez pas à ajouter des recommandations ici. :)

darius
la source
Voici un bon tutoriel sur l'utilisation de web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Réponses:

192

Une chose à laquelle il faut faire attention lors de la conception d'une API RESTful est la fusion de GET et POST, comme si c'était la même chose. Il est facile de commettre cette erreur avec les vues basées sur les fonctions de Django et le répartiteur par défaut de CherryPy , bien que les deux frameworks fournissent désormais un moyen de contourner ce problème ( vues basées sur les classes et MethodDispatcher , respectivement).

Les verbes HTTP sont très importants dans REST, et à moins que vous ne soyez très prudent à ce sujet, vous finirez par tomber dans un anti-modèle REST .

Certains frameworks qui réussissent sont web.py , Flask et Bottle . Lorsqu'ils sont combinés avec la bibliothèque mimerender (divulgation complète: je l'ai écrite), ils vous permettent d'écrire de jolis services 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 logique du service n'est implémentée qu'une seule fois, et la sélection de représentation correcte (en-tête Accept) + la répartition vers la fonction de rendu appropriée (ou modèle) est effectuée de manière ordonnée et transparente.

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

Mise à jour (avril 2012) : ajout d'informations sur les vues basées sur les classes de Django, les frameworks MethodDispatcher et Flask and Bottle de CherryPy. Aucun n'existait à l'époque où la question a été posée.

Martin Blech
la source
12
C'est incorrect, Django a un support complet pour reconnaître POST vs GET et limiter les vues à seulement certaines méthodes.
aehlke
20
Je voulais dire que, par défaut, Django traite POST et GET comme s'ils étaient la même chose, ce qui est très gênant lorsque vous effectuez des services RESTful car cela vous oblige à faire: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py n'a pas ce problème
Martin Blech
19
@Wahnfrieden: S'il existe une prise en charge native dans Django pour gérer les différents verbes HTTP séparément (par "natif", je veux dire ne pas avoir besoin de "if request.method == X"), pourriez-vous me signaler une documentation?
Martin Blech
3
La fusion de POST et GET ne s'applique pas aux vues basées sur la classe de Django (ajoutées en 1.3), mais je crois que c'est valable pour les versions antérieures.
ncoghlan
1
La réponse est incorrecte à propos de CherryPy. De Docs: "REST (Representational State Transfer) est un style architectural bien adapté à l'implémentation dans CherryPy." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz
70

Surpris, personne n'a mentionné la fiole .

from flask import Flask
app = Flask(__name__)

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

if __name__ == "__main__":
    app.run()
user161642
la source
7
Flask n'était pas là quand la question a été posée ...
Martin Blech
2
Flask ne fonctionne pas avec Python 3.x
bitek
3
Flask.dev prend désormais en charge Python 3
Sean Vieira
2
Flask prend en charge Python 3.3 ou supérieur.
mb21
3
noob ici, comment c'est un RESTful?
avi
23

Nous utilisons Django pour les services Web RESTful.

Notez que - hors de la boîte - Django n'avait pas d'authentification assez fine pour nos besoins. Nous avons utilisé l' interface Django-REST , ce qui a beaucoup aidé. [Nous avons depuis lancé la nôtre parce que nous avions fait tellement d'extensions que c'était devenu un cauchemar de maintenance.]

Nous avons deux types d'URL: les URL "html" qui implémentent les pages HTML orientées vers l'homme, et les URL "json" qui implémentent le traitement orienté services Web. Nos fonctions d'affichage ressemblent souvent à ceci.

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

Le fait étant que la fonctionnalité utile est prise en compte dans les deux présentations. La présentation JSON n'est généralement qu'un seul objet qui a été demandé. La présentation HTML comprend souvent toutes sortes d'aides à la navigation et d'autres indices contextuels qui aident les gens à être productifs.

Les jsonViewfonctions sont toutes très similaires, ce qui peut être un peu ennuyeux. Mais c'est Python, alors faites-les partie d'une classe appelable ou écrivez des décorateurs si cela vous aide.

S.Lott
la source
2
Répétition affreuse de d = someUsefulThing ... Même les gars de Django suggèrent SEC.
temoto
5
@temoto: S'il y = someUsefulThing(...)s'agit d'une "répétition horrible", toutes les références à toutes les fonctions et méthodes sont "horribles". Je n'arrive pas à comprendre comment éviter de référencer une fonction plus d'une fois.
S.Lott
5
@temoto: "Lorsque vous devez modifier des arguments passés à someUsefulThing, il y a une chance que l'on oublie de le faire dans tous les appels"? Quoi? Comment est-ce "horrible"? C'est une conséquence triviale de référencer une fonction plus d'une fois. Je n'arrive pas à comprendre de quoi vous parlez et comment la référence de fonction est "horrible" car elle est incontournable.
S.Lott
4
Voir la réponse acceptée. L'expression de résultat {'message': 'Bonjour', '+ nom +'! '} Est écrite une fois pour toutes les présentations.
temoto
3
Vos fonctions htmlView et jsonView servent des représentations différentes pour les mêmes données, non? Il en someUsefulThing(request, object_id)va de même pour une expression de récupération de données. Vous avez maintenant deux copies de la même expression à différents points de votre programme. Dans la réponse acceptée, l'expression de données est écrite une fois. Remplacez votre someUsefulThingappel par une longue chaîne, comme paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))et regardez le code. J'espère que cela illustrera mon propos.
temoto
11

Voir le wiki Python Web Frameworks .

Vous n'avez probablement pas besoin des cadres de pile complets , mais la liste restante est encore assez longue.

gimel
la source
8

J'aime vraiment CherryPy . Voici un exemple de service Web reposant:

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

Cela souligne ce que j'aime vraiment chez CherryPy; il s'agit d'un exemple complètement fonctionnel qui est très compréhensible même pour quelqu'un qui ne connaît pas le cadre. Si vous exécutez ce code, vous pouvez immédiatement voir les résultats dans votre navigateur Web; par exemple, visiter http: // localhost: 8080 / celc_to_fahr? degrés = 50 s'affichera 122.0dans votre navigateur Web.

Eli Courtwright
la source
35
C'est un bel exemple, mais il n'y a rien de reposant à ce sujet.
aehlke
3
@Wahnfrieden: Pourriez-vous nous aider en clarifiant pourquoi vous ne pensez pas que ce qui précède est RESTful? De mon point de vue, cela ressemble à un exemple classique de REST et ne semble enfreindre aucune des règles ou contraintes d'un système RESTful.
lilbyrdie
42
En termes simples, ce que fait l'exemple CherryPy ci-dessus est d'exposer des méthodes en tant que procédures distantes "appelables HTTP". C'est RPC. Il est entièrement orienté "verbe". Les architectures RESTful se concentrent sur les ressources gérées par un serveur et offrent ensuite un ensemble très limité d'opérations sur ces ressources: spécifiquement, POST (créer), GET (lire), PUT (mettre à jour) et DELETE (supprimer). La manipulation de ces ressources, en particulier la modification de leur état via PUT, est la voie clé par laquelle "des choses arrivent".
verveguy
2
Vous pouvez écrire plus d'API RESTfull à l'aide de CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian
8

Je ne vois aucune raison d'utiliser Django juste pour exposer une API REST, il existe des solutions plus légères et plus flexibles. Django apporte beaucoup d'autres choses à la table, qui ne sont pas toujours nécessaires. Bien sûr, pas nécessaire si vous souhaitez uniquement exposer du code en tant que service REST.

Mon expérience personnelle, fwiw, est qu'une fois que vous avez un cadre unique, vous commencerez à utiliser son ORM, ses plugins, etc. simplement parce que c'est facile, et en un rien de temps vous finirez par avoir une dépendance c'est très difficile à éliminer.

Le choix d'un framework web est une décision difficile, et j'éviterais de choisir une solution de pile complète juste pour exposer une api REST.

Maintenant, si vous avez vraiment besoin / voulez utiliser Django, alors Piston est un joli framework REST pour les applications django.

Cela étant dit, CherryPy a l'air vraiment bien aussi, mais semble plus RPC que REST.

En regardant les exemples (je ne l'ai jamais utilisé), web.py est probablement le meilleur et le plus propre si vous n'avez besoin que de REST.

Savino Sguera
la source
6

Voici une discussion dans les documents CherryPy sur REST: http://docs.cherrypy.org/dev/progguide/REST.html

En particulier, il mentionne un répartiteur CherryPy intégré appelé MethodDispatcher, qui invoque des méthodes basées sur leurs identificateurs de verbe HTTP (GET, POST, etc ...).

nir
la source
6

En 2010, les communautés Pylons et repoze.bfg "ont uni leurs forces" pour créer Pyramid , un framework web basé principalement sur repoze.bfg. Il conserve les philosophies de ses cadres parents et peut être utilisé pour les services RESTful . Ça vaut le coup d'oeil.

asthasr
la source
Avec Pyramid, vous pouvez utiliser Cornice , qui fournit des aides utiles pour la création et la documentation des services Web REST.
Calvin
5

Piston est un framework très flexible pour le wirting des API RESTful pour les applications Django.

DenisKolodin
la source
5

Il semble que toutes sortes de frameworks web python puissent implémenter des interfaces RESTful maintenant.

Pour Django, outre tastypie et piston, django-rest-framework est prometteur et mérite d'être mentionné. J'ai déjà fait migrer l'un de mes projets en douceur.

Le framework Django REST est un framework REST léger pour Django, qui vise à faciliter la création d'API Web RESTful bien connectées et auto-descriptives.

Exemple rapide:

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

Prenez l'exemple du site officiel, tous les codes ci-dessus fournissent une API, un document auto-expliqué (comme un service Web basé sur du savon) et même un bac à sable pour tester un peu. Très pratique.

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

Sun Liwen
la source
2
En particulier, l'interface navigable permet de gagner beaucoup de temps lors du développement! Beaucoup d'autres avantages, donc tout le monde qui commence la mise en œuvre du repos devrait y jeter un œil. J'ai commencé avec tastypie, mais je suis passé complètement à django-rest-framework
michel.iamit
3

Je ne suis pas un expert du monde python mais j'utilise django qui est un excellent framework web et peut être utilisé pour créer un framework reposant.

Jeremy B.
la source
3

web2py inclut le support pour construire facilement des API RESTful, décrites ici et ici (vidéo). En particulier, regardez parse_as_rest, qui vous permet de définir des modèles d'URL qui mappent les arguments des requêtes aux requêtes de base de données; et smart_query, ce qui vous permet de passer des requêtes arbitraires en langage naturel dans l'URL.

Anthony
la source
Les liens mentionnés ne sont plus disponibles
milovanderlinden
Les liens ont été mis à jour - réessayez.
Anthony
2

Si vous utilisez Django, vous pouvez considérer django-tastypie comme une alternative à django-piston . Il est plus facile de syntoniser des sources de données non-ORM que piston, et dispose d'une excellente documentation .

Kristian
la source
0

Je recommande fortement TurboGears ou Bottle:

TurboGears:

  • moins verbeux que django
  • plus flexible, moins orienté HTML
  • mais: moins célèbre

Bouteille:

  • très vite
  • très facile à apprendre
  • mais: minimaliste et pas mature
Federico
la source
0

Nous travaillons sur un cadre pour des services REST stricts, consultez http://prestans.googlecode.com

C'est au début d'Alpha en ce moment, nous testons contre mod_wsgi et AppEngine de Google.

Vous recherchez des testeurs et des commentaires. Merci.

Devraj
la source