Рекомендации фреймворка Python REST (веб-сервисы)? [закрыто]


321

Есть ли где-то список рекомендаций различных основанных на Python сред REST для использования на стороне сервера для написания собственных API RESTful? Желательно с плюсами и минусами.

Пожалуйста, не стесняйтесь добавлять рекомендации здесь. :)


Вот хороший урок по использованию web.py dreamsyssoft.com/blog/blog.php?/archives/…
Тритон Мэн,

Ответы:


192

При разработке RESTful API следует соблюдать осторожность при сопоставлении GET и POST, как если бы они были одним и тем же. Эту ошибку легко совершить с помощью представлений Django на основе функций и диспетчера CherryPy по умолчанию, хотя обе платформы теперь позволяют обойти эту проблему ( представления на основе классов и MethodDispatcher соответственно).

HTTP-глаголы очень важны в REST, и если вы не будете очень осторожны с этим, вы в конечном итоге попадете в анти-шаблон REST .

Некоторые рамки, которые понимают это правильно, - это web.py , Flask и Bottle . В сочетании с библиотекой mimerender (полное раскрытие: я ее написал) они позволяют вам писать хорошие веб-сервисы 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()

Логика сервиса реализуется только один раз, и правильный выбор представления (заголовок Accept) + отправка в соответствующую функцию рендеринга (или шаблон) выполняется аккуратно и прозрачно.

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

Обновление (апрель 2012 г.) : добавлена ​​информация об основанных на классах представлениях Django, структурах CherryPy MethodDispatcher и Flask and Bottle. Ни один не существовал назад, когда вопрос был задан.


12
Это неверно, Django полностью поддерживает распознавание POST и GET и ограничение представлений только определенными методами.
aehlke

20
Я имел в виду, что по умолчанию Django рассматривает POST и GET так, как если бы они были одним и тем же, что очень неудобно, когда вы предоставляете сервисы RESTful, поскольку это заставляет вас делать: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py не имеет этой проблемы
Мартин Блех

19
@Wahnfrieden: Если в Django есть встроенная поддержка для обработки различных HTTP-глаголов отдельно (под "native" я имею в виду не нужно "if request.method == X"), не могли бы вы указать мне некоторую документацию?
Мартин Блех

3
Смешение POST и GET не относится к представлениям на основе классов в Django (добавлено в 1.3), но я считаю, что это справедливо для более ранних выпусков.
ncoghlan

1
Неправильный ответ о CherryPy. Из Документов: «REST (Transfer State State) - это архитектурный стиль, который хорошо подходит для реализации в CherryPy». - docs.cherrypy.org/dev/progguide/REST.html
Дерек Лиц

70

Удивлен никто не упомянул колбу .

from flask import Flask
app = Flask(__name__)

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

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

7
Когда вопрос был задан, колбы не было ...
Мартин Блех

2
Flask не работает с Python 3.x
bitek

3
Flask.dev теперь поддерживает Python 3
Шон Виейра

2
Flask поддерживает Python 3.3 или выше.
mb21

3
Нуб здесь, как это RESTful?
Ави

23

Мы используем Django для веб-сервисов RESTful.

Обратите внимание, что - из коробки - у Django не было достаточно тонкой аутентификации для наших нужд. Мы использовали интерфейс Django-REST , который очень помог. [С тех пор мы сделали свой собственный проект, потому что сделали так много расширений, что это стало кошмаром обслуживания.]

У нас есть два типа URL: «HTML» URL, которые реализуют ориентированные на человека HTML-страницы, и «JSON» URL, которые реализуют обработку, ориентированную на веб-сервисы. Наши функции просмотра часто выглядят так.

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

Дело в том, что полезная функциональность основана на двух презентациях. Представление JSON обычно представляет собой только один объект, который был запрошен. HTML-презентация часто включает в себя все виды навигационных средств и другие контекстные подсказки, которые помогают людям быть продуктивными.

Все jsonViewфункции очень похожи, что может немного раздражать. Но это Python, поэтому сделайте их частью вызываемого класса или напишите декораторы, если это поможет.


2
Ужасное повторение d = someUsefulThing ... Даже парни из Django предлагают DRY.
Темото

5
@temoto: Если y = someUsefulThing(...)это «Ужасное повторение», то все ссылки на все функции и методы «ужасны». Я не понимаю, как избежать ссылки на функцию более одного раза.
С.Лотт

5
@temoto: «Когда вам нужно изменить аргументы, передаваемые someUsefulThing, есть шанс, что вы забудете сделать это во всех вызовах»? Какой? Как это "ужасно"? Это тривиальное следствие ссылки на функцию более одного раза. Я не понимаю, о чем вы говорите, и как справочник функций «ужасен», поскольку он неизбежен.
С.Лотт

4
Смотрите принятый ответ. Результирующее выражение {'message': 'Hello,' + name + '!'} Пишется один раз для всех презентаций.
Темото

3
Ваши функции htmlView и jsonView служат для разных представлений одних и тех же данных, верно? Так someUsefulThing(request, object_id)же и выражение для поиска данных. Теперь у вас есть две копии одного и того же выражения в разных точках вашей программы. В принятом ответе выражение данных записывается один раз. Замените ваш someUsefulThingзвонок длинной строкой, как paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))и посмотрите на код. Я надеюсь, что это проиллюстрирует мою точку зрения.
Темото

11

Смотрите Python Web Frameworks вики.

Возможно, вам не нужны полностью интегрированные стеки , но оставшийся список все еще довольно длинный.


8

Мне очень нравится CherryPy . Вот пример спокойного веб-сервиса:

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

Это подчеркивает то, что мне действительно нравится в CherryPy; Это полностью рабочий пример, который очень понятен даже тем, кто не знает основы. Если вы запустите этот код, вы сразу увидите результаты в своем веб-браузере; например, посещение http: // localhost: 8080 / celc_to_fahr? градусов = 50 будет отображаться 122.0в вашем веб-браузере.


35
Это хороший пример, но в этом нет ничего интересного.
aehlke

3
@Wahnfrieden: Не могли бы вы помочь остальным из нас, объяснив, почему вы не думаете, что выше, является RESTful? С моей точки зрения, это выглядит как классический пример REST и не нарушает каких-либо правил или ограничений системы RESTful.
Lilbyrdie

42
Проще говоря, то, что делает приведенный выше пример CherryPy, представляет методы как «вызываемые по HTTP» удаленные процедуры. Это RPC. Он полностью ориентирован на глагол. Архитектуры RESTful ориентированы на ресурсы, управляемые сервером, и затем предлагают очень ограниченный набор операций с этими ресурсами: в частности, POST (создание), GET (чтение), PUT (обновление) и DELETE (удаление). Манипулирование этими ресурсами, в частности изменение их состояния через PUT, является ключевым путем, посредством которого «происходит что-то».
verveguy

2
Вы можете написать больше API RESTfull, используя CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian


8

Я не вижу смысла использовать Django просто для того, чтобы представить REST API, есть более легкие и более гибкие решения. Джанго несет на стол много других вещей, которые не всегда нужны. Конечно, не нужно, если вы хотите предоставить какой-то код только как REST-сервис.

Мой личный опыт, fwiw, заключается в том, что, как только у вас будет универсальный фреймворк, вы начнете использовать его ORM, его плагины и т. Д. Только потому, что это легко, и вы сразу же получите зависимость. от этого очень трудно избавиться.

Выбор веб-фреймворка - сложное решение, и я бы не стал выбирать решение с полным стеком, просто чтобы представить REST API.

Теперь, если вам действительно нужно / нужно использовать Django, тогда Piston - это хорошая среда REST для приложений django.

Тем не менее, CherryPy выглядит действительно хорошо, но кажется больше RPC, чем REST.

Глядя на примеры (я никогда не использовал их), вероятно, web.py - лучший и самый чистый, если вам нужен только REST.


6

Вот обсуждение в документах CherryPy по REST: http://docs.cherrypy.org/dev/progguide/REST.html

В частности, он упоминает встроенный диспетчер CherryPy с именем MethodDispatcher, который вызывает методы на основе их идентификаторов HTTP-глаголов (GET, POST и т. Д.).


6

В 2010 году сообщества Pylons и repoze.bfg «объединили усилия» для создания Pyramid , веб-фреймворка, основанного в основном на repoze.bfg. Он сохраняет философию своих родительских структур и может использоваться для служб RESTful . Это стоит посмотреть.


С Pyramid вы можете использовать Cornice , который предоставляет полезные помощники для создания и документирования веб-сервисов REST.
Calvin


5

Кажется, что все виды веб-фреймворков Python теперь могут реализовывать интерфейсы RESTful.

Для Django, помимо вкусного пирога и поршня, django-rest-framework - многообещающая вещь, которую стоит упомянуть. Я уже перенес один из моих проектов на него гладко.

Среда Django REST - это облегченная среда REST для Django, цель которой - упростить создание веб-API-интерфейсов RESTful с хорошими связями и самоописанием.

Быстрый пример:

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

Возьмите пример с официального сайта, все приведенные выше коды предоставляют API, самодостаточный документ (например, веб-сервис на основе мыла) и даже песочницу, чтобы немного протестировать. Очень удобство

Ссылки: http://django-rest-framework.org/


2
Особенно удобный интерфейс экономит много времени при разработке! Многие другие преимущества, так что каждый, кто начинает реализацию rest, должен посмотреть. Я начал со вкусного пирога, но полностью перешел на django-rest-framework
michel.iamit

3

Я не эксперт в мире питонов, но я использую django, который является отличным веб-фреймворком и может быть использован для создания полноценного фреймворка.


3

web2py включает поддержку простого построения RESTful API, описанную здесь и здесь (видео). В частности, посмотрите parse_as_rest, что позволяет вам определять шаблоны URL, которые сопоставляют аргументы запроса с запросами к базе данных; и smart_query, который позволяет вам передавать произвольные запросы на естественном языке в URL.


Упомянутые ссылки больше не доступны
milovanderlinden

Ссылки были обновлены - попробуйте еще раз.
Энтони


0

Я настоятельно рекомендую TurboGears или Bottle:

TurboGears:

  • менее многословен, чем Джанго
  • более гибкий, менее ориентированный на HTML
  • но: менее известный

Бутылка:

  • очень быстро
  • очень легко учиться
  • но: минималистичный и не зрелый

0

Мы работаем над структурой для строгих служб REST, ознакомьтесь с http://prestans.googlecode.com

Сейчас мы работаем с ранней версией Alpha, мы тестируем ее с mod_wsgi и Google AppEngine.

Нужны тестеры и отзывы. Спасибо.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.