Zalecenia frameworku Python REST (usługi sieciowe)? [Zamknięte]


321

Czy jest gdzieś lista rekomendacji różnych frameworków REST opartych na Pythonie do wykorzystania na serwerze do pisania własnych interfejsów API RESTful? Najlepiej z zaletami i wadami.

Tutaj możesz dodać rekomendacje. :)


Oto dobry samouczek na temat korzystania z web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Odpowiedzi:


192

Podczas projektowania interfejsu API RESTful należy zachować ostrożność, jeśli chodzi o połączenie GET i POST, tak jakby były one tym samym. To proste, aby ten błąd z Django 's poglądów opartych funkcyjnych i CherryPy jest domyślnym dyspozytora, choć obie ramy teraz dostarczyć sposób wokół tego problemu ( poglądów opartych na klasach i MethodDispatcher , odpowiednio).

Czasowniki HTTP są bardzo ważne w REST i jeśli nie będziesz bardzo ostrożny, skończysz w anty-wzorcu REST .

Niektóre frameworki, które dobrze to robią , to web.py , Flask i Bottle . W połączeniu z biblioteką mimerender (pełne ujawnienie: napisałem to), pozwalają ci pisać fajne usługi internetowe 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()

Logika usługi jest implementowana tylko raz, a poprawny wybór reprezentacji (nagłówek Akceptuj) + wysłanie do odpowiedniej funkcji renderowania (lub szablonu) odbywa się w uporządkowany, przejrzysty sposób.

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

Aktualizacja (kwiecień 2012 r.) : Dodano informacje o widokach klasowych Django, metodach MethodDispatcher CherryPy oraz platformach Flask i Bottle. Żadne z nich nie istniało, kiedy zadano pytanie.


12
Jest to niepoprawne, Django ma pełne wsparcie dla rozpoznawania testu POST vs. GET i ograniczania widoków tylko do niektórych metod.
aehlke

20
Miałem na myśli, że domyślnie Django traktuje POST i GET tak, jakby były tym samym, co jest bardzo niewygodne, gdy wykonujesz usługi RESTful, ponieważ zmusza cię to do zrobienia: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py nie ma tego problemu
Martin Blech,

19
@Wahnfrieden: Jeśli w Django istnieje natywna obsługa oddzielnych poleceń dla różnych czasowników HTTP (przez „natywny” mam na myśli, że nie potrzebuję, jeśli request.method == X ”), czy mógłbyś wskazać mi jakąś dokumentację?
Martin Blech,

3
Połączenie POST i GET nie dotyczy widoków opartych na klasach Django (dodanych w 1.3), ale uważam, że jest poprawny dla wcześniejszych wydań.
ncoghlan

1
Odpowiedź jest nieprawidłowa na temat CherryPy. From Docs: „REST (Representational State Transfer) to styl architektoniczny, który dobrze nadaje się do wdrożenia w CherryPy”. - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz


23

Używamy Django do usług sieciowych RESTful.

Zauważ, że - po wyjęciu z pudełka - Django nie miał wystarczająco szczegółowego uwierzytelnienia na nasze potrzeby. Użyliśmy interfejsu Django-REST , który bardzo nam pomógł. [Od tego czasu stworzyliśmy własne, ponieważ zrobiliśmy tyle rozszerzeń, że stał się koszmarem konserwacji.]

Mamy dwa rodzaje adresów URL: adresy URL „html”, które implementują strony HTML zorientowane na człowieka, oraz adresy URL „json”, które implementują przetwarzanie zorientowane na usługi sieciowe. Nasze funkcje widoku często wyglądają tak.

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

Chodzi o to, że użyteczna funkcjonalność jest uwzględniona w dwóch prezentacjach. Prezentacja JSON jest zwykle tylko jednym obiektem, który został zamówiony. Prezentacja HTML często zawiera wszelkiego rodzaju pomoce nawigacyjne i inne wskazówki kontekstowe, które pomagają ludziom w produktywności.

Wszystkie jsonViewfunkcje są bardzo podobne, co może być nieco denerwujące. Ale to jest Python, więc włącz ich do klasy na żądanie lub napisz dekoratorów, jeśli to pomoże.


2
Okropne powtórzenie d = someUsefulThing ... Nawet chłopaki Django sugerują SUCHO.
temoto

5
@temoto: Jeśli y = someUsefulThing(...)jest to „Okropne powtórzenie”, wówczas wszystkie odniesienia do wszystkich funkcji i metod są „okropne”. Nie rozumiem, jak unikać odwoływania się do funkcji więcej niż raz.
S.Lott,

5
@temoto: „Kiedy trzeba zmienić argumenty przekazane do someUsefulThing, istnieje szansa, że ​​zapomni się tego zrobić we wszystkich wywołaniach”? Co? Jak to jest „okropne”? To banalna konsekwencja wielokrotnego odwoływania się do funkcji. Nie rozumiem o czym mówisz i jak odniesienie do funkcji jest „okropne”, ponieważ jest nieuniknione.
S.Lott,

4
Zobacz zaakceptowaną odpowiedź. Wyrażenie wynikowe {„message”: „Hello” + name + „!”} Jest zapisywane raz dla wszystkich prezentacji.
temoto

3
Twoje funkcje htmlView i jsonView służą do różnych reprezentacji tych samych danych, prawda? Podobnie someUsefulThing(request, object_id)jest z wyrażeniem pobierania danych. Teraz masz dwie kopie tego samego wyrażenia w różnych punktach swojego programu. W zaakceptowanej odpowiedzi wyrażenie danych jest zapisywane jeden raz. Zastąp swoje someUsefulThingpołączenie długim ciągiem, polub paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))i spójrz na kod. Mam nadzieję, że to zilustruje mój punkt widzenia.
temoto


8

Naprawdę lubię CherryPy . Oto przykład spokojnej usługi internetowej:

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

Podkreśla to, co naprawdę lubię w CherryPy; jest to całkowicie działający przykład, który jest bardzo zrozumiały nawet dla kogoś, kto nie zna frameworka. Jeśli uruchomisz ten kod, możesz natychmiast zobaczyć wyniki w przeglądarce internetowej; np. odwiedzając http: // localhost: 8080 / celc_to_fahr? stopni = 50 wyświetli się 122.0w przeglądarce internetowej.


35
To dobry przykład, ale nie ma w tym nic RESTful.
aehlke

3
@Wahnfrieden: Czy możesz pomóc reszcie z nas, wyjaśniając, dlaczego nie uważasz, że powyższe jest RESTful? Z mojego punktu widzenia wygląda to jak klasyczny przykład REST i nie wydaje się łamać żadnej z reguł lub ograniczeń systemu RESTful.
lilbyrdie,

42
Mówiąc najprościej, powyższy przykład CherryPy pokazuje metody jako zdalne procedury „na żądanie HTTP”. To RPC. Jest całkowicie zorientowany na „czasownik”. Architektury RESTful koncentrują się na zasobach zarządzanych przez serwer, a następnie oferują bardzo ograniczony zestaw operacji na tych zasobach: w szczególności POST (tworzenie), GET (czytanie), PUT (aktualizacja) i DELETE (usuwanie). Manipulacja tymi zasobami, w szczególności zmiana ich stanu za pośrednictwem PUT, jest kluczową ścieżką, przy której „coś się dzieje”.
verveguy

2
Możesz napisać więcej interfejsów API RESTfull, używając CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian


8

Nie widzę żadnego powodu, aby używać Django tylko do ujawnienia interfejsu API REST, istnieją lżejsze i bardziej elastyczne rozwiązania. Django przenosi na stół wiele innych rzeczy, które nie zawsze są potrzebne. Na pewno nie jest to konieczne, jeśli chcesz udostępnić tylko część kodu jako usługę REST.

Moje osobiste doświadczenie, fwiw, polega na tym, że kiedy będziesz mieć uniwersalną strukturę, zaczniesz używać jej ORM, wtyczek itp. Tylko dlatego, że jest to łatwe i w żadnym momencie nie będziesz zależny bardzo trudno się go pozbyć.

Wybór frameworka jest trudną decyzją i unikałbym wyboru rozwiązania pełnego stosu tylko po to, aby odsłonić interfejs API REST.

Teraz, jeśli naprawdę potrzebujesz / chcesz korzystać z Django, to Piston to przyjemny framework REST dla aplikacji django.

To powiedziawszy, CherryPy też wygląda naprawdę ładnie, ale wydaje się bardziej RPC niż REST.

Patrząc na próbki (nigdy go nie użyłem), prawdopodobnie web.py jest najlepszy i najczystszy, jeśli potrzebujesz tylko REST.



6

W 2010 r. Społeczności Pylons i repoze.bfg „połączyły siły”, aby stworzyć Pyramid , platformę internetową opartą w największym stopniu na repoze.bfg. Zachowuje filozofię swoich struktur nadrzędnych i może być używany do usług RESTful . Warto spojrzeć.


Dzięki Pyramid możesz korzystać z gzymsu , który zapewnia przydatne pomoce do budowania i dokumentowania usług sieciowych REST.
Calvin


5

Wygląda na to, że wszelkiego rodzaju frameworki sieci Python mogą teraz implementować interfejsy RESTful.

Dla Django, oprócz tastypie i tłoka, django-rest-framework jest obiecującym wartym wspomnienia. Płynnie migrowałem już jeden z moich projektów.

Struktura REST Django to lekka platforma REST dla Django, której celem jest ułatwienie tworzenia dobrze połączonych, samoopisujących interfejsów API RESTful Web.

Szybki przykład:

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

Weźmy przykład z oficjalnej strony, wszystkie powyższe kody zapewniają interfejs API, własny objaśniający dokument (jak usługa internetowa na bazie mydła), a nawet piaskownicę, aby trochę przetestować. Bardzo wygoda.

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


2
Zwłaszcza przeglądalny interfejs oszczędza dużo czasu podczas programowania! Wiele innych zalet, więc każdy, kto zaczyna wdrażanie odpoczynku, powinien spojrzeć. Zacząłem od tastypie, ale całkowicie przerzuciłem się na django-rest-framework
michel.iamit

3

Nie jestem ekspertem w świecie Pythona, ale używam django, który jest doskonałym frameworkiem internetowym i można go użyć do stworzenia spokojnego frameworka.


3

web2py zawiera obsługę łatwego budowania RESTful API, opisanych tutaj i tutaj (wideo). W szczególności spójrz na parse_as_rest, co pozwala zdefiniować wzorce adresów URL, które mapują argumenty żądań na zapytania do bazy danych; i smart_query, który umożliwia przekazywanie dowolnych zapytań w języku naturalnym w adresie URL.


Wspomniane linki nie są już dostępne
milovanderlinden

Linki zostały zaktualizowane - spróbuj ponownie.
Anthony


0

Zdecydowanie polecam TurboGears lub Bottle:

TurboGears:

  • mniej gadatliwy niż django
  • bardziej elastyczny, mniej zorientowany na HTML
  • ale: mniej znany

Butelka:

  • bardzo szybki
  • bardzo łatwy do nauczenia
  • ale: minimalistyczny i nie dojrzały

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.