Wygoda i wszechstronność Pythona oznaczają, że jest on używany do budowania oprogramowania w niemal każdej dziedzinie życia informatycznego. Jedną z głównych nisz są usługi sieciowe, gdzie szybkość rozwoju Pythona i elastyczne metafory ułatwiają szybkie uruchamianie stron internetowych.
I tak jak można się domyślić, Python daje wiele możliwości wyboru i swobody w tworzeniu frameworków sieciowych, zarówno małych, jak i dużych. W końcu nie każdy projekt sieciowy musi być na skalę przedsiębiorstwa. Większość powinna być po prostu wystarczająco duża, aby wykonać zadanie, ale nie większa. Ten artykuł omawia osiem najbardziej znanych frameworków Pythona, które podkreślają prostotę, lekkość i ścisłe skupienie.
Bottle
Bottle może być uważany za rodzaj mini-Flask, ponieważ jest jeszcze bardziej kompaktowy i zwięzły niż ten inny „microframework”. Ze względu na swój minimalny rozmiar, Bottle jest idealny do włączenia do innych projektów lub do szybkiego dostarczania małych projektów, takich jak API REST. (Flask jest omówiony poniżej.)
Cała baza kodowa Bottle mieści się w jednym pliku i nie ma absolutnie żadnych zewnętrznych zależności. Mimo to Bottle jest wyposażony w wystarczającą funkcjonalność, aby budować typowe aplikacje internetowe bez korzystania z pomocy z zewnątrz.
System routingu w Bottle, który mapuje adresy URL na funkcje, ma prawie dokładnie taką samą składnię jak Flask. Nie jesteś też ograniczony do sztywnego zestawu ścieżek; możesz je tworzyć dynamicznie. Dane żądania i odpowiedzi, ciasteczka, zmienne zapytania, dane formularza z akcji POST, nagłówki HTTP i przesyłanie plików mogą być dostępne i manipulowane za pomocą obiektów w Bottle.
Każda z tych możliwości została zaimplementowana z dbałością o szczegóły. W przypadku przesyłania plików, na przykład, nie musisz zmieniać nazwy pliku, jeśli jego konwencja nazewnicza koliduje z docelowym systemem plików (np. ukośniki w nazwie w systemie Windows). Bottle może to zrobić za Ciebie.
Bottle zawiera swój własny, prosty silnik szablonów HTML. Ponownie, choć minimalny, silnik szablonów posiada wszystkie najważniejsze funkcje. Zmienne zawarte w szablonie są domyślnie renderowane w bezpiecznym HTML-u; musisz wskazać, które zmienne są bezpieczne, aby odtworzyć je dosłownie. Jeśli wolisz zamienić silnik szablonów Bottle na inny, taki jak Jinja2, Bottle pozwoli Ci to zrobić bez kłopotu. Ja wolę system prostych szablonów dołączony do Bottle; jest szybki, jego składnia jest bezpretensjonalna i pozwala na mieszanie kodu i tekstu szablonu bez zbędnych trudności.
Bottle obsługuje nawet wiele serwerów back-end. Dostarczany jest z własnym wbudowanym miniserverem do szybkiego testowania, ale obsługuje również WSGI, szeroki zakres serwerów HTTP kompatybilnych z WSGI oraz zwykłe stare CGI, jeśli zajdzie taka potrzeba.
Bottle nie potrzebuje tak dużo dokumentacji jak inne frameworki, ale dokumenty nie są w żadnym wypadku skąpe. Wszystkie najważniejsze rzeczy mieszczą się na jednej (aczkolwiek długiej) stronie internetowej. Poza tym, znajdziesz pełną dokumentację dla każdego API, przykłady wdrażania na różnych infrastrukturach, wyjaśnienie wbudowanego języka szablonów i mnóstwo wspólnych receptur.
Tak jak w przypadku Flaska, możesz rozszerzyć funkcjonalność Bottle ręcznie lub poprzez wtyczki. Wtyczki Bottle nie są tak liczne jak Flask, ale są tam przydatne elementy, takie jak integracja z różnymi warstwami baz danych i podstawowe uwierzytelnianie użytkownika. Do obsługi asynchronicznej, Bottle może użyć jednego z istniejących adapterów serwera, który działa asynchronicznie, takich jak aiohttp/uvloop, ale async/await
nie jest natywnie obsługiwany.
Jedną z konsekwencji minimalizmu Bottle jest to, że niektórych elementów po prostu nie ma. Walidacja formularzy, w tym funkcje takie jak CSRF (cross-site request forgery), nie jest uwzględniona. Jeśli chcesz zbudować aplikację internetową, która obsługuje wysoki stopień interakcji z użytkownikiem, będziesz musiał dodać tę obsługę samodzielnie.
Innym problemem związanym z Bottle jest to, że rozwój został wstrzymany; ostatnie wydanie punktowe, 0.12, pojawiło się w 2013 roku. To powiedziawszy, Bottle nadal jest utrzymywany, a jego wydania rozwojowe pozostają użyteczne dla produkcji. Deweloperzy zamierzają dostarczyć nowe wersje, które odrzucą wsparcie dla starszych wydań Pythona.
CherryPy
CherryPy istnieje w tej czy innej formie od prawie 20 lat, ale nie stracił minimalizmu i elegancji, które wyróżniały go od początku.
Celem stojącym za CherryPy, poza tym, że zawiera tylko gołe kawałki potrzebne do obsługi stron internetowych, jest to, aby czuć się, tak dalece jak to możliwe, nie jak „web framework”, ale jak każdy inny rodzaj aplikacji Pythona. Strony takie jak Hulu i Netflix używają CherryPy w produkcji, ponieważ framework zapewnia bardzo dyskretną bazę, na której można budować. CherryPy używa wątków połączonych w pulę pod maską, aby lepiej obsługiwać wielowątkowe adaptery serwera.
CherryPy pozwala trzymać aplikację internetową z dala od głównej logiki. Aby zmapować funkcje aplikacji do adresów URL lub tras obsługiwanych przez CherryPy, tworzysz klasę, w której przestrzenie nazw obiektów mapują się bezpośrednio do adresów URL, które chcesz obsługiwać. Na przykład, korzeń strony internetowej jest dostarczany przez funkcję o nazwie „index”. Parametry przekazywane do tych funkcji są używane do obsługi zmiennych dostarczanych przez metody GET lub POST.
Bity, które zawiera CherryPy, mają działać jako niskopoziomowe bloki konstrukcyjne. Identyfikatory sesji i obsługa ciasteczek są uwzględnione, ale szablonowanie HTML nie jest. Podobnie jak Bottle, CherryPy oferuje sposób na mapowanie tras do katalogów na dysku dla statycznego serwowania plików.
CherryPy często odrzuca istniejące biblioteki innych firm, aby wspierać daną funkcję, zamiast dostarczać ją natywnie. Aplikacje WebSocket, na przykład, nie są obsługiwane przez CherryPy bezpośrednio, ale poprzez bibliotekę ws4py.
Dokumentacja CherryPy zawiera poręczny przewodnik po różnych aspektach programu. Nie poprowadzi cię on przez kompletną aplikację, w przeciwieństwie do niektórych innych frameworków, ale i tak jest przydatny. Dokumenty zawierają przydatne notatki na temat wdrażania na wirtualnych hostach, odwrotnego proxy przez Apache i Nginx oraz wielu innych scenariuszy.
Falcon
Jeśli budujesz API oparte na REST i nic więcej, Falcon został stworzony właśnie dla ciebie. Szczupły i szybki, z prawie żadnymi zależnościami poza standardową biblioteką, Falcon zapewnia wszystko, czego potrzebujesz dla interfejsów API REST i nic więcej. Falcon 2.0, wydany w 2019 roku, pozbywa się obsługi Pythona 2.x i wymaga co najmniej Pythona 3.5.
Duża część tego, dlaczego Falcon zarabia na etykietę „lekki i smukły”, ma niewiele wspólnego z liczbą linii kodu w ramach. Jest tak dlatego, że Falcon nie narzuca prawie żadnej własnej struktury na aplikacje. Wszystko co aplikacja Falcona musi zrobić to wskazać, które funkcje mapują się na które punkty końcowe API. Zwrócenie JSON z punktu końcowego wymaga niewiele więcej niż ustawienie trasy i zwrócenie danych za pomocą funkcji json.dumps
z biblioteki standardowej Pythona. Wsparcie dla async nie wylądowało jeszcze w Falconie, ale trwają prace, aby tak się stało w Falconie 3.0.
Falcon stosuje również rozsądne domyślne ustawienia out-of-the-box, więc niewiele majstrowania jest potrzebne do konfiguracji. Na przykład, 404 jest podnoszone domyślnie dla każdej trasy, która nie jest jawnie zadeklarowana. Jeśli chcesz zwrócić błędy do klienta, możesz podnieść jeden z wielu wyjątków dołączonych do frameworka (takich jak HTTPBadRequest
) lub użyć ogólnego wyjątku falcon.HTTPError
. Jeśli potrzebujesz preprocessingu lub postprocessingu dla trasy, Falcon dostarcza również dla nich haki.
Skupienie się Falcona na API oznacza, że jest tu niewiele do budowania aplikacji internetowych z konwencjonalnymi interfejsami użytkownika HTML. Nie spodziewaj się na przykład zbyt wielu funkcji przetwarzania formularzy i narzędzi do ochrony CSRF. Niemniej jednak, Falcon zapewnia eleganckie opcje rozszerzania swojej funkcjonalności, dzięki czemu można budować bardziej zaawansowane elementy. Oprócz wspomnianego mechanizmu hookowania, znajdziesz interfejs do tworzenia middleware, który może być używany do owijania wszystkich API Falcona.
Dokumentacja Falcona jest szczupła w porównaniu do innych frameworków, ale tylko dlatego, że jest mniej do omówienia. Podręcznik użytkownika zawiera formalne przejście krok po kroku przez wszystkie główne funkcje, wraz z sekcją szybkiego startu, która pozwala na przeglądanie przykładowego kodu z lub bez adnotacji.
FastAPI
Nazwa FastAPI jest dobrym podsumowaniem tego, co robi. Jest zbudowany do szybkiego tworzenia punktów końcowych API i działa również szybko.
FastAPI korzysta z projektu Starlette dla jego rdzenia szybkiej sieci, ale nie musisz wiedzieć o wnętrzu Starlette, aby używać FastAPI. Definiujesz punkty końcowe w taki sam sposób jak aplikacje Flask lub Bottle – użyj dekoratorów, aby wskazać, które funkcje obsługują które trasy – a następnie zwróć słowniki, które są automatycznie tłumaczone na JSON.
Możesz łatwo zastąpić to, jak rzeczy są zwracane. Na przykład, jeśli chcesz zwrócić HTML/XML z niektórych punktów końcowych, możesz to zrobić po prostu zwracając niestandardowy obiekt Response
. Jeśli chcesz dodać niestandardowe oprogramowanie pośredniczące, możesz wstawić wszystko, co jest zgodne ze standardem ASGI.
FastAPI korzysta z podpowiedzi typu Pythona, aby zapewnić ograniczenia na rodzaje danych, które akceptują trasy. Na przykład, jeśli masz trasę o typie Optional
, FastAPI odrzuci wszelkie zgłoszenia z wyjątkiem liczb całkowitych. Nie musisz dodawać kodu sprawdzania poprawności danych do swoich punktów końcowych; możesz po prostu użyć podpowiedzi typu i pozwolić FastAPI wykonać pracę.
Naturalnie, niektóre rzeczy są pominięte. Na przykład nie ma natywnego silnika szablonów HTML, ale nie brakuje rozwiązań firm trzecich, które wypełniają tę lukę. To samo z łącznością z bazą danych, ale dokumentacja zawiera szczegóły o tym, jak zmusić niektóre ORMy (np. Peewee) do pracy z asynchronicznymi zachowaniami FastAPI.
Flask
Wiele dyskusji na temat frameworków Pythona zaczyna się od Flaska, i to nie bez powodu. Flask jest dobrze ugruntowanym, dobrze rozumianym frameworkiem, który jest łatwy w użyciu i dość stabilny. Jest prawie niemożliwe, aby pójść źle używając Flaska do lekkiego projektu webowego lub podstawowego REST API, ale będziesz musiał stawić czoła ciężkiemu liftingowi, jeśli spróbujesz zbudować coś większego.
Centralną zaletą Flaska jest jego niska bariera wejścia. Podstawowa aplikacja typu „hello world” może być stworzona w mniej niż 10 liniach Pythona. Flask zawiera szeroko stosowany system szablonów HTML, Jinja2, aby ułatwić renderowanie tekstu, ale Jinja2 może być zamieniony na dowolną liczbę innych silników szablonów (takich jak Mustache) lub można stworzyć własny.
W imię prostoty, Flask pomija takie drobiazgi jak warstwa danych lub ORM, i nie oferuje żadnych przepisów na walidację formularzy. Jednakże, Flask może być rozszerzony poprzez rozszerzenia, których są dziesiątki, obejmujące wiele typowych przypadków użycia, takich jak buforowanie, obsługa i walidacja formularzy oraz łączność z bazą danych. Ten szczupły, domyślny projekt pozwala rozpocząć tworzenie aplikacji Flask od absolutnego minimum funkcjonalności, a następnie nawarstwiać tylko te elementy, które są potrzebne, kiedy są potrzebne.
Dokumentacja Flask jest genialna i łatwa do czytania. Dokument quick-start doskonale nadaje się do rozpoczęcia pracy, jednocześnie wyjaśniając znaczenie domyślnych wyborów dla prostej aplikacji Flask, a dokumenty API są pełne dobrych przykładów. Doskonała jest również kolekcja snippetów Flasha, które są szybkimi i brudnymi przykładami, jak wykonać określone zadania, takie jak sposób zwracania obiektu, jeśli istnieje lub błąd 404, jeśli nie.
Flask trafił swój kamień milowy 1.0 wydanie w 2018 roku, z Pythonem 2.6 i Pythonem 3.3 będącym minimalnie obsługiwanymi wersjami, i z wieloma jego zachowaniami w końcu ustawionymi w kamieniu. Flask nie obsługuje jawnie składni async Pythona, ale kompatybilna z API odmiana Flask o nazwie Quart została wydzielona, aby zaspokoić to zapotrzebowanie.
Pyramid
Mały i lekki, Pyramid jest dobrze przystosowany do zadań takich jak eksponowanie istniejącego kodu Pythona jako REST API lub dostarczanie rdzenia dla projektu sieciowego, w którym deweloper wykonuje większość ciężkiej pracy.
„Pyramid pozwoli ci szybko stać się produktywnym i będzie rósł razem z tobą”, mówi dokumentacja. „Nie powstrzyma cię, gdy twoja aplikacja jest mała, i nie stanie ci na drodze, gdy twoja aplikacja stanie się duża.”
Dobrym sposobem na opisanie minimalizmu Pyramida byłoby „free of policy”, termin użyty w części dokumentacji, która omawia jak Pyramid wypada na tle innych frameworków internetowych. Zasadniczo, „free of policy” oznacza, że to, jaką bazę danych lub jaki język szablonów wybierzesz, nie jest zmartwieniem Pyramida.
Bardzo niewiele pracy potrzeba, aby zbudować podstawową aplikację Pyramida. Podobnie jak w przypadku Bottle i Flask, aplikacja Pyramid może składać się z pojedynczego pliku Pythona, nie licząc plików dla samego frameworka. Proste, jednokierunkowe API wymaga nie więcej niż kilkunastu linii kodu. Większość z nich to szablony, takie jak from … import
deklaracje i konfiguracja serwera WSGI.
Domyślnie Pyramid zawiera kilka elementów, które są powszechne w aplikacjach internetowych, ale są one dostarczane jako komponenty do zszycia razem, a nie jako pełne rozwiązania. Na przykład, wsparcie dla sesji użytkownika, jest nawet dostarczane z ochroną CSRF. Jednak obsługa kont użytkowników, takich jak logowanie czy zarządzanie kontami, nie jest częścią oferty. Będziesz musiał zrobić to sam lub dodać to poprzez wtyczkę. To samo dotyczy obsługi formularzy i połączeń z bazą danych.
Pyramid zapewnia nawet sposób na tworzenie szablonów z poprzednich projektów Pyramid, aby ponownie wykorzystać wcześniejszą pracę. Szablony te, zwane „rusztowaniami”, generują aplikację Pyramid z prostym routingiem i kilkoma startowymi szablonami HTML/CSS. Dołączone rusztowania zawierają przykładowy projekt startowy oraz projekt, który łączy się z bazami danych za pomocą popularnej biblioteki Pythona SQLAlchemy.
Smukłe narzędzia do testowania i debugowania Pyramida załatwiają sprawę. Dołącz rozszerzenie debugtoolbar
do aplikacji Pyramid, a otrzymasz klikalną ikonę na każdej stronie internetowej, która generuje szczegóły dotyczące działania aplikacji, w tym szczegółowy ślad w przypadku błędów. Logowanie i testy jednostkowe są również obecne.
Dokumentacja Pyramid jest doskonała. Oprócz szybkiej wycieczki po podstawach i przewodnika w stylu samouczka, znajdziesz zestaw samouczków stworzonych przez społeczność oraz książkę kucharską zawierającą wspólne przepisy. Ta ostatnia zawiera techniki wdrażania dla wielu środowisk docelowych, od Google App Engine do Nginx.
Pyramid obsługuje zarówno Pythona 2, jak i Pythona 3, ale nie używa składni async Pythona 3. Jeśli chcesz wykorzystać asynchroniczność w Pyramid, zobacz projekt aiopyramid, który zawiera rusztowanie dla aplikacji „hello world” napędzanej asynchronicznie.
Sanic
Zaprojektowany z myślą o szybkości i prostocie, Sanic działa z Pythonem 3.6 lub nowszym i używa składni Pythona async/await
(dostępnej od Pythona 3.5), aby umożliwić tworzenie wydajnych aplikacji internetowych.
Tak jak w przypadku Flaska lub Bottle, podstawowe „hello world” w Sanic składa się z około 10 linii kodu, z których większość to importy i inne szablony. Kluczowa różnica polega na tym, że trasy aplikacji muszą być zadeklarowane jako async def
funkcje, a ty musisz użyć await
do wywołania tych funkcji wewnątrz swojego kodu async. Jeśli pisałeś już wcześniej aplikacje napędzane asynchronicznie, to najtrudniejszą część masz już za sobą.
Wiele z mechanizmów, których Sanic używa do obsługi połączeń i odpowiedzi, będzie dobrze znanych. Żądania i odpowiedzi są po prostu obiektami o znajomo wyglądających właściwościach, takich jak przesyłane pliki, formularze, obiekty JSON, nagłówki i tak dalej.
Aplikacje z wieloma trasami stają się nieporęczne w zarządzaniu. Sanic rozwiązuje ten problem za pomocą „blueprintów”, obiektów, które mogą opisywać grupy tras i pozwalają na zarządzanie nimi za pomocą interfejsu wysokiego poziomu. Zamiast pisać każdą trasę jawnie, lub używać nadmiaru tras ze zmiennymi, można napisać kilka blueprintów, aby ogólnie opisać jak trasy działają w aplikacji (np. /object/object_id/action
). Blueprints mogą mieć wspólne middleware, co jest przydatne, jeśli chcesz zastosować funkcjonalność zarządzania do niektórych tras, ale nie do innych.
Sanic działa również z protokołami innymi niż HTTP. Punkty końcowe WebSocket wymagają jedynie innego dekoratora i nieco więcej wewnętrznej logiki (np. oczekiwanie i obsługa odpowiedzi). Niestandardowe protokoły sieciowe mogą być obsługiwane przez podklasowanie asyncio.protocol
.
Sanic celowo pomija funkcjonalność taką jak łączność z bazami danych i szablonowanie HTML, zachowując cechy, których można by użyć, aby te możliwości wykorzystać: oprogramowanie pośredniczące, scentralizowaną konfigurację aplikacji i tak dalej.
Tornado
Tornado jest kolejnym małym frameworkiem ukierunkowanym na konkretny przypadek użycia: asynchroniczne aplikacje sieciowe. Tornado dobrze nadaje się do tworzenia usług, które otwierają wiele połączeń sieciowych i utrzymują je przy życiu – czyli wszystkiego, co wiąże się z WebSockets lub długim pollingiem. Tornado 6.0 wymaga Pythona 3.5 lub nowszego i całkowicie porzuca obsługę Pythona 2.
Podobnie jak Bottle czy Falcon, Tornado pomija cechy nieistotne dla jego głównego celu. Tornado ma wbudowany system szablonów do generowania HTML i innych danych wyjściowych, a także zapewnia mechanizmy internacjonalizacji, obsługi formularzy, ustawiania ciasteczek, uwierzytelniania użytkowników i ochrony CSRF. Pomija jednak funkcje, takie jak sprawdzanie poprawności formularzy i ORM, które są przeznaczone głównie dla aplikacji internetowych skierowanych do użytkownika.
Tornado wyróżnia się w dostarczaniu infrastruktury aplikacjom, które potrzebują ścisłej kontroli nad asynchronicznymi połączeniami sieciowymi. Na przykład, Tornado dostarcza nie tylko wbudowany asynchroniczny serwer HTTP, ale także asynchronicznego klienta HTTP. Dzięki temu Tornado dobrze nadaje się do budowania aplikacji, takich jak web scraper czy bot, które równolegle odpytywać będą inne strony i działać na zwróconych danych.
Jeśli chcesz stworzyć aplikację, która korzysta z protokołów innych niż HTTP, Tornado ma cię pod ręką. Tornado zapewnia dostęp do niskopoziomowych połączeń TCP i gniazd do takich narzędzi, jak resolwery DNS, a także do usług uwierzytelniania innych firm, a także wspiera współpracę z innymi frameworkami poprzez standard WSGI. Dokumentacja, która jest niewielka, ale nie skąpa, zawiera liczne przykłady pozwalające to wszystko osiągnąć.
Tornado zarówno wykorzystuje, jak i uzupełnia natywną funkcjonalność Pythona w zakresie zachowań asynchronicznych. Jeśli używasz Pythona 3.5, Tornado obsługuje wbudowane słowa kluczowe async
i await
, które obiecują zwiększyć szybkość działania aplikacji. Można również używać futures lub callbacków do obsługi odpowiedzi na zdarzenia.
Tornado udostępnia bibliotekę prymitywów synchronizacji – semafory, zamki i tak dalej – do koordynowania zdarzeń między asynchronicznymi coroutines. Zauważ, że Tornado normalnie działa jednowątkowo, więc te prymitywy nie są takie same jak ich imiennicy pracujący w wątkach. Jeśli jednak chcesz uruchomić Tornado w procesach równoległych, aby wykorzystać wiele gniazd i rdzeni, dostępne są do tego narzędzia.
Dokumentacja Tornado obejmuje każdą główną koncepcję frameworka i wszystkie główne interfejsy API w modelu. Chociaż zawiera przykładową aplikację (web crawler), służy ona głównie do zademonstrowania modułu kolejkowania Tornado.
.