Existe uma lista de recomendações de diferentes estruturas REST baseadas em Python para uso no servidor para escrever suas próprias APIs RESTful? De preferência com prós e contras.
Por favor, sinta-se livre para adicionar recomendações aqui. :)
Existe uma lista de recomendações de diferentes estruturas REST baseadas em Python para uso no servidor para escrever suas próprias APIs RESTful? De preferência com prós e contras.
Por favor, sinta-se livre para adicionar recomendações aqui. :)
Respostas:
Algo para ter cuidado ao projetar uma API RESTful é a fusão de GET e POST, como se fossem a mesma coisa. É fácil cometer este erro com as visualizações baseadas em funções do Django e o despachante padrão do CherryPy , embora ambas as estruturas agora contornem esse problema ( visualizações baseadas em classe e MethodDispatcher , respectivamente).
Os verbos HTTP são muito importantes no REST e, a menos que você tenha muito cuidado com isso, você acabará caindo em um anti-padrão REST .
Algumas estruturas que acertam são web.py , Flask e Bottle . Quando combinados com a biblioteca mimerender (divulgação completa: escrevi), eles permitem que você escreva bons serviços da 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()
A lógica do serviço é implementada apenas uma vez, e a seleção correta da representação (cabeçalho Accept) + expedição para a função de renderização (ou modelo) apropriada é feita de maneira organizada e 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!
Atualização (abril de 2012) : informações adicionadas sobre as visualizações baseadas em classe do Django, os métodos MethodDispatcher da CherryPy e as estruturas Flask and Bottle. Nem existia quando a pergunta foi feita.
Surpreso, ninguém mencionou o frasco .
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
Estamos usando o Django para serviços web RESTful.
Note que - pronto para uso - o Django não possui autenticação suficientemente refinada para nossas necessidades. Usamos a interface Django-REST , o que ajudou muito. [Desde então, lançamos nossas próprias porque criamos tantas extensões que se tornaram um pesadelo de manutenção.]
Temos dois tipos de URLs: URLs "html", que implementam as páginas HTML orientadas para humanos, e URLs "json", que implementam o processamento orientado a serviços da Web. Nossas funções de visualização geralmente se parecem com isso.
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
O ponto é que a funcionalidade útil é fatorada nas duas apresentações. A apresentação JSON geralmente é apenas um objeto que foi solicitado. A apresentação em HTML geralmente inclui todos os tipos de auxílios à navegação e outras dicas contextuais que ajudam as pessoas a serem produtivas.
As jsonView
funções são todas muito semelhantes, o que pode ser um pouco irritante. Mas é Python, então faça parte de uma classe que pode ser chamada ou escreva decoradores, se isso ajudar.
y = someUsefulThing(...)
é uma "repetição terrível", todas as referências a todas as funções e métodos são "terríveis". Não consigo entender como evitar fazer referência a uma função mais de uma vez.
someUsefulThing(request, object_id)
vale para uma expressão de recuperação de dados. Agora você tem duas cópias da mesma expressão em pontos diferentes do seu programa. Na resposta aceita, a expressão de dados é escrita uma vez. Substitua sua someUsefulThing
chamada por uma sequência longa, curta paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))
e veja o código. Espero que ilustre meu argumento.
Consulte Frameworks da Web Python wiki do .
Você provavelmente não precisa das estruturas de pilha completa , mas a lista restante ainda é bastante longa.
Eu realmente gosto de CherryPy . Aqui está um exemplo de um serviço da Web repousante:
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())
Isso enfatiza o que eu realmente gosto no CherryPy; este é um exemplo completamente funcional que é muito compreensível até para alguém que não conhece a estrutura. Se você executar esse código, poderá ver imediatamente os resultados no seu navegador da web; por exemplo, visitando http: // localhost: 8080 / celc_to_fahr? degrees = 50 será exibido 122.0
no seu navegador.
Não vejo motivo para usar o Django apenas para expor uma API REST, existem soluções mais leves e flexíveis. O Django carrega muitas outras coisas para a mesa, que nem sempre são necessárias. Com certeza não é necessário se você deseja apenas expor algum código como um serviço REST.
Minha experiência pessoal, fwiw, é que, depois de ter uma estrutura única, você começará a usar seu ORM, seus plugins etc. apenas porque é fácil, e em pouco tempo você acaba tendo uma dependência isso é muito difícil de se livrar.
Escolher uma estrutura da web é uma decisão difícil, e eu evitaria escolher uma solução de pilha cheia apenas para expor uma API REST.
Agora, se você realmente precisa / deseja usar o Django, o Piston é uma boa estrutura REST para aplicativos de django.
Dito isto, o CherryPy também parece muito bom, mas parece mais RPC do que REST.
Olhando para as amostras (eu nunca a usei), provavelmente o web.py é o melhor e mais limpo se você precisar apenas de REST.
Aqui está uma discussão nos documentos CherryPy sobre o REST: http://docs.cherrypy.org/dev/progguide/REST.html
Em particular, ele menciona um distribuidor CherryPy incorporado chamado MethodDispatcher, que chama métodos com base em seus identificadores de verbo HTTP (GET, POST, etc ...).
Em 2010, as comunidades Pylons e repoze.bfg "uniram forças" para criar o Pyramid , uma estrutura da Web baseada mais fortemente em repoze.bfg. Ele mantém as filosofias de suas estruturas pai e pode ser usado para serviços RESTful . Vale a pena dar uma olhada.
O Piston é uma estrutura muito flexível para criar APIs RESTful para aplicativos Django.
Parece que todos os tipos de estruturas da web python podem implementar interfaces RESTful agora.
Para o Django, além de tastypie e piston, o django-rest-framework é promissor e vale a pena mencionar. Já migrei um dos meus projetos para ele sem problemas.
A estrutura REST do Django é uma estrutura REST leve para o Django, que visa facilitar a criação de APIs da Web RESTful bem conectadas e autoexplicativas.
Exemplo 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)),
)
Pegue o exemplo do site oficial, todos os códigos acima fornecem API, documento autoexplicado (como webservice baseado em sabão) e até caixa de areia para testar um pouco. Muito conveniência.
web2py inclui suporte para a criação fácil de APIs RESTful, descritas aqui e aqui (vídeo). Em particular, observe parse_as_rest
, que permite definir padrões de URL que mapeiam argumentos de solicitação para consultas de banco de dados; e smart_query
, que permite que você passe consultas arbitrárias em linguagem natural no URL.
Se você estiver usando o Django, poderá considerar o django-tastypie como uma alternativa ao django-piston . É mais fácil sintonizar fontes de dados não-ORM do que o pistão e possui ótima documentação .
Estamos trabalhando em uma estrutura para serviços REST rigorosos, confira http://prestans.googlecode.com
No início do Alpha, no momento, estamos testando o mod_wsgi e o AppEngine do Google.
Procurando testadores e feedback. Obrigado.