¿Recomendaciones del marco Python REST (servicios web)? [cerrado]


321

¿Hay alguna lista de recomendaciones de diferentes marcos REST basados ​​en Python para usar en el lado del servidor para escribir sus propias API RESTful? Preferiblemente con pros y contras.

Por favor, siéntase libre de agregar recomendaciones aquí. :)


Aquí hay un buen tutorial sobre el uso de web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Respuestas:


192

Algo a tener en cuenta al diseñar una API RESTful es la combinación de GET y POST, como si fueran lo mismo. Es fácil cometer este error con las vistas basadas en funciones de Django y el despachador predeterminado de CherryPy , aunque ambos marcos ahora brindan una solución a este problema ( vistas basadas en clases y MethodDispatcher , respectivamente).

Los verbos HTTP son muy importantes en REST, y a menos que tengas mucho cuidado con esto, terminarás cayendo en un antipatrón REST .

Algunos marcos que lo hacen bien son web.py , Flask y Bottle . Cuando se combina con la biblioteca mimerender (divulgación completa: lo escribí), le permiten escribir buenos servicios 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 lógica del servicio se implementa solo una vez, y la selección de representación correcta (aceptar encabezado) + envío a la función (o plantilla) de procesamiento adecuada se realiza de una manera ordenada y 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!

Actualización (abril de 2012) : se agregó información sobre las vistas basadas en clases de Django, los métodos MethodDispatcher y Flask and Bottle de CherryPy. Tampoco existía cuando se hizo la pregunta.


12
Esto es incorrecto, Django tiene soporte completo para reconocer POST vs GET y limitar las vistas solo a ciertos métodos.
aehlke

20
Quise decir que, por defecto, Django trata POST y GET como si fueran lo mismo, lo cual es muy inconveniente cuando estás haciendo servicios RESTful, ya que te obliga a hacer: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py no tiene ese problema
Martin Blech el

19
@Wahnfrieden: Si hay soporte nativo en Django para manejar diferentes verbos HTTP por separado (por "nativo" quiero decir que no necesito "if request.method == X"), ¿podría indicarme alguna documentación?
Martin Blech el

3
La combinación de POST y GET no se aplica a las Vistas basadas en clases de Django (agregadas en 1.3), pero creo que es válido para las versiones anteriores.
ncoghlan

1
La respuesta es incorrecta sobre CherryPy. De Docs: "REST (Representational State Transfer) es un estilo arquitectónico que se adapta bien a la implementación en CherryPy". - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz

70

Sorprendido, nadie mencionó el matraz .

from flask import Flask
app = Flask(__name__)

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

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

77
Flask no estaba allí cuando se hizo la pregunta ...
Martin Blech

2
Flask no funciona con Python 3.x
bitek

3
Flask.dev ahora es compatible con Python 3
Sean Vieira

2
Flask es compatible con Python 3.3 o superior.
mb21

3
novato aquí, ¿cómo es esto un RESTful?
avi

23

Estamos usando Django para servicios web RESTful.

Tenga en cuenta que, fuera de la caja, Django no tenía una autenticación lo suficientemente precisa para nuestras necesidades. Utilizamos la interfaz Django-REST , que ayudó mucho. [Desde entonces, lanzamos la nuestra porque habíamos hecho tantas extensiones que se había convertido en una pesadilla de mantenimiento].

Tenemos dos tipos de URL: URL "html" que implementan las páginas HTML orientadas a las personas, y URL "json" que implementan el procesamiento orientado a los servicios web. Nuestras funciones de vista a menudo se ven así.

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

El punto es que la funcionalidad útil se tiene en cuenta a partir de las dos presentaciones. La presentación JSON suele ser solo un objeto solicitado. La presentación HTML a menudo incluye todo tipo de ayudas de navegación y otras pistas contextuales que ayudan a las personas a ser productivas.

Las jsonViewfunciones son muy similares, lo que puede ser un poco molesto. Pero es Python, así que hágalos parte de una clase invocable o escriba decoradores si es útil.


2
Horrible repetición de d = someUsefulThing ... Incluso los chicos de Django sugieren DRY.
temoto

55
@temoto: Si y = someUsefulThing(...)es una "horrible repetición", entonces todas las referencias a todas las funciones y métodos son "horribles". No entiendo cómo evitar hacer referencia a una función más de una vez.
S.Lott

55
@temoto: "Cuando necesita cambiar los argumentos pasados ​​a someUsefulThing, existe la posibilidad de que uno se olvide de hacerlo en todas las llamadas"? ¿Qué? ¿Cómo es eso "horrible"? Esa es una consecuencia trivial de hacer referencia a una función más de una vez. No entiendo de qué está hablando y cómo la referencia de funciones es "horrible" ya que es inevitable.
S.Lott

44
Ver la respuesta aceptada. La expresión de resultado {'mensaje': 'Hola,' + nombre + '!'} Se escribe una vez para todas las presentaciones.
temoto

3
Sus funciones htmlView y jsonView sirven diferentes representaciones para los mismos datos, ¿verdad? Entonces, someUsefulThing(request, object_id)es una expresión de recuperación de datos. Ahora tiene dos copias de la misma expresión en diferentes puntos de su programa. En la respuesta aceptada, la expresión de datos se escribe una vez. Reemplace su someUsefulThingllamada con una cadena larga, como paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))y mire el código. Espero que ilustre mi punto.
temoto


8

Me gusta mucho CherryPy . Aquí hay un ejemplo de un servicio web tranquilo:

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

Esto enfatiza lo que realmente me gusta de CherryPy; Este es un ejemplo completamente funcional que es muy comprensible incluso para alguien que no conoce el marco. Si ejecuta este código, puede ver inmediatamente los resultados en su navegador web; por ejemplo, visitar http: // localhost: 8080 / celc_to_fahr? grados = 50 se mostrará 122.0en su navegador web.


35
Ese es un buen ejemplo, pero no tiene nada de RESTANTE.
aehlke

3
@Wahnfrieden: ¿Podría ayudarnos al resto de nosotros aclarando por qué no cree que lo anterior sea RESTful? Desde mi punto de vista, parece un ejemplo clásico de REST y no parece romper ninguna de las reglas o restricciones de un sistema RESTful.
lilbyrdie

42
En términos simples, lo que está haciendo el ejemplo de CherryPy anterior es exponer métodos como procedimientos remotos "HTTP invocables". Eso es RPC. Está totalmente orientado al "verbo". Las arquitecturas RESTful se centran en los recursos administrados por un servidor y luego ofrecen un conjunto muy limitado de operaciones en esos recursos: específicamente, POST (crear), GET (leer), PUT (actualizar) y DELETE (eliminar). La manipulación de estos recursos, en particular cambiando su estado a través de PUT, es la vía clave por la cual "suceden cosas".
verveguy

2
Puede escribir más API RESTfull usando CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian


8

No veo ninguna razón para usar Django solo para exponer una API REST, hay soluciones más ligeras y más flexibles. Django lleva muchas otras cosas a la mesa, que no siempre son necesarias. Seguro que no es necesario si solo desea exponer algún código como un servicio REST.

Mi experiencia personal, fwiw, es que una vez que tenga un marco de trabajo único, comenzará a usar su ORM, sus complementos, etc. solo porque es fácil y en poco tiempo terminará teniendo una dependencia eso es muy difícil de eliminar.

Elegir un marco web es una decisión difícil, y evitaría elegir una solución de pila completa solo para exponer una API REST.

Ahora, si realmente necesita / quiere usar Django, entonces Piston es un buen marco REST para aplicaciones django.

Dicho esto, CherryPy también se ve muy bien, pero parece más RPC que REST.

Mirando las muestras (nunca lo usé), probablemente web.py es el mejor y más limpio si solo necesita REST.


6

Aquí hay una discusión en los documentos de CherryPy sobre REST: http://docs.cherrypy.org/dev/progguide/REST.html

En particular, menciona un despachador CherryPy integrado llamado MethodDispatcher, que invoca métodos basados ​​en sus identificadores verbales HTTP (GET, POST, etc.).


6

En 2010, las comunidades Pylons y repoze.bfg "unieron fuerzas" para crear Pyramid , un marco web basado principalmente en repoze.bfg. Conserva las filosofías de sus marcos primarios y puede utilizarse para servicios RESTful . Vale la pena echarle un vistazo.


Con Pyramid puede hacer uso de Cornice , que proporciona ayudantes útiles para crear y documentar servicios web REST.
Calvin


5

Parece que todo tipo de marcos web de Python pueden implementar interfaces RESTful ahora.

Para Django, además de tastypie y pistón, django-rest-framework es prometedor y vale la pena mencionarlo. Ya migré uno de mis proyectos sin problemas.

El marco REST de Django es un marco REST ligero para Django, que tiene como objetivo facilitar la creación de API web RESTful bien descritas y autodescriptivas.

Ejemplo rápido:

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

Tomemos el ejemplo del sitio oficial, todos los códigos anteriores proporcionan una API, un documento autoexplicado (como un servicio web basado en jabón) e incluso un sandbox para probar un poco. Muy conveniencia.

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


2
¡Especialmente la interfaz navegable ahorra mucho tiempo mientras se desarrolla! Muchas otras ventajas, por lo que todos los que comienzan la implementación del descanso deben echar un vistazo. Comencé con tastypie, pero cambié completamente a django-rest-framework
michel.iamit el

3

No soy un experto en el mundo de Python, pero he estado usando django, que es un excelente marco web y se puede utilizar para crear un marco tranquilo.


3

web2py incluye soporte para construir fácilmente API RESTful, descritas aquí y aquí (video). En particular, mire parse_as_rest, que le permite definir patrones de URL que asignan argumentos de solicitud a consultas de la base de datos; y smart_query, que le permite pasar consultas arbitrarias de lenguaje natural en la URL.


Los enlaces mencionados ya no están disponibles
milovanderlinden

Los enlaces se han actualizado. Inténtalo de nuevo.
Anthony


0

Recomiendo TurboGears o Bottle:

TurboGears:

  • menos detallado que django
  • más flexible, menos orientado a HTML
  • pero: menos famoso

Botella:

  • muy rapido
  • muy facil de aprender
  • pero: minimalista y no maduro

0

Estamos trabajando en un marco para servicios REST estrictos, visite http://prestans.googlecode.com

En este momento, en Alpha, estamos probando contra mod_wsgi y AppEngine de Google.

Buscando probadores y comentarios. Gracias.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.