FastAPI
FastAPI to szybki, prosty w nauce i gotowy do użycia w produkcji framework
Dokumentacja: https://fastapi.tiangolo.com
Kod żródłowy: https://github.com/tiangolo/fastapi
FastAPI to nowoczesny, wydajny framework webowy do budowania API z użyciem Pythona bazujący na standardowym typowaniu Pythona.
Kluczowe cechy:
- Wydajność: FastAPI jest bardzo wydajny, na równi z NodeJS oraz Go (dzięki Starlette i Pydantic). Jeden z najszybszych dostępnych frameworków Pythonowych.
- Szybkość kodowania: Przyśpiesza szybkość pisania nowych funkcjonalności o około 200% do 300%. *
- Mniejsza ilość błędów: Zmniejsza ilość ludzkich (dewelopera) błędy o około 40%. *
- Intuicyjność: Wspaniałe wsparcie dla edytorów kodu. Dostępne wszędzie automatyczne uzupełnianie kodu. Krótszy czas debugowania.
- Łatwość: Zaprojektowany by być prosty i łatwy do nauczenia. Mniej czasu spędzonego na czytanie dokumentacji.
- Kompaktowość: Minimalizacja powtarzającego się kodu. Wiele funkcjonalności dla każdej deklaracji parametru. Mniej błędów.
- Solidność: Kod gotowy dla środowiska produkcyjnego. Wraz z automatyczną interaktywną dokumentacją.
- Bazujący na standardach: Oparty na (i w pełni kompatybilny z) otwartych standardach API: OpenAPI (wcześniej znane jako Swagger) oraz JSON Schema.
* oszacowania bazowane na testach wykonanych przez wewnętrzny zespół deweloperów, budujących aplikacie używane na środowisku produkcyjnym.
Sponsorzy¶
Opinie¶
"[...] I'm using FastAPI a ton these days. [...] I'm actually planning to use it for all of my team's ML services at Microsoft. Some of them are getting integrated into the core Windows product and some Office products."
"We adopted the FastAPI library to spawn a REST server that can be queried to obtain predictions. [for Ludwig]"
"Netflix is pleased to announce the open-source release of our crisis management orchestration framework: Dispatch! [built with FastAPI]"
"I’m over the moon excited about FastAPI. It’s so fun!"
"Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted Hug to be - it's really inspiring to see someone build that."
"If you're looking to learn one modern framework for building REST APIs, check out FastAPI [...] It's fast, easy to use and easy to learn [...]"
"We've switched over to FastAPI for our APIs [...] I think you'll like it [...]"
Typer, FastAPI aplikacji konsolowych¶
Jeżeli tworzysz aplikacje CLI, która ma być używana w terminalu zamiast API, sprawdź Typer.
Typer to młodsze rodzeństwo FastAPI. Jego celem jest pozostanie FastAPI aplikacji konsolowych . ⌨️ 🚀
Wymagania¶
FastAPI oparty jest na:
Instalacja¶
$ pip install fastapi
---> 100%
Na serwerze produkcyjnym będziesz także potrzebował serwera ASGI, np. Uvicorn lub Hypercorn.
$ pip install "uvicorn[standard]"
---> 100%
Przykład¶
Stwórz¶
- Utwórz plik o nazwie
main.py
z:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Albo użyj async def
...
Jeżeli twój kod korzysta z async
/ await
, użyj async def
:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Przypis:
Jeżeli nie znasz, sprawdź sekcję "In a hurry?" o async
i await
w dokumentacji.
Uruchom¶
Uruchom serwer używając:
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
O komendzie uvicorn main:app --reload
...
Komenda uvicorn main:app
odnosi się do:
main
: plikmain.py
("moduł" w Pythonie).app
: obiekt stworzony wmain.py
w liniapp = FastAPI()
.--reload
: spraw by serwer resetował się po każdej zmianie w kodzie. Używaj tego tylko w środowisku deweloperskim.
Wypróbuj¶
Otwórz link http://127.0.0.1:8000/items/5?q=somequery w przeglądarce.
Zobaczysz następującą odpowiedź JSON:
{"item_id": 5, "q": "somequery"}
Właśnie stworzyłeś API które:
- Otrzymuje żądania HTTP w ścieżce
/
i/items/{item_id}
. - Obie ścieżki używają operacji
GET
(znane także jako metody HTTP). - Ścieżka
/items/{item_id}
ma parametr ścieżkiitem_id
który powinien być obiektem typuint
. - Ścieżka
/items/{item_id}
ma opcjonalny parametr zapytania typustr
o nazwieq
.
Interaktywna dokumentacja API¶
Otwórz teraz stronę http://127.0.0.1:8000/docs.
Zobaczysz automatyczną interaktywną dokumentację API (dostarczoną z pomocą Swagger UI):
Alternatywna dokumentacja API¶
Otwórz teraz http://127.0.0.1:8000/redoc.
Zobaczysz alternatywną, lecz wciąż automatyczną dokumentację (wygenerowaną z pomocą ReDoc):
Aktualizacja przykładu¶
Zmodyfikuj teraz plik main.py
, aby otrzmywał treść (body) żądania PUT
.
Zadeklaruj treść żądania, używając standardowych typów w Pythonie dzięki Pydantic.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
Serwer powinien przeładować się automatycznie (ponieważ dodałeś --reload
do komendy uvicorn
powyżej).
Zaktualizowana interaktywna dokumentacja API¶
Wejdź teraz na http://127.0.0.1:8000/docs.
- Interaktywna dokumentacja API zaktualizuje sie automatycznie, także z nową treścią żądania (body):
- Kliknij przycisk "Try it out" (wypróbuj), pozwoli Ci to wypełnić parametry i bezpośrednio użyć API:
- Kliknij potem przycisk "Execute" (wykonaj), interfejs użytkownika połączy się z API, wyśle parametry, otrzyma odpowiedź i wyświetli ją na ekranie:
Zaktualizowana alternatywna dokumentacja API¶
Otwórz teraz http://127.0.0.1:8000/redoc.
- Alternatywna dokumentacja również pokaże zaktualizowane parametry i treść żądania (body):
Podsumowanie¶
Podsumowując, musiałeś zadeklarować typy parametrów, treści żądania (body) itp. tylko raz, i są one dostępne jako parametry funkcji.
Robisz to tak samo jak ze standardowymi typami w Pythonie.
Nie musisz sie uczyć żadnej nowej składni, metod lub klas ze specyficznych bibliotek itp.
Po prostu standardowy Python.
Na przykład, dla danych typu int
:
item_id: int
albo dla bardziej złożonego obiektu Item
:
item: Item
...i z pojedyńczą deklaracją otrzymujesz:
- Wsparcie edytorów kodu, wliczając:
- Auto-uzupełnianie.
- Sprawdzanie typów.
- Walidacja danych:
- Automatyczne i przejrzyste błędy gdy dane są niepoprawne.
- Walidacja nawet dla głęboko zagnieżdżonych obiektów JSON.
- Konwersja danych wejściowych: przychodzących z sieci na Pythonowe typy. Pozwala na przetwarzanie danych:
- JSON.
- Parametrów ścieżki.
- Parametrów zapytania.
- Dane cookies.
- Dane nagłówków (headers).
- Formularze.
- Pliki.
- Konwersja danych wyjściowych: wychodzących z Pythona do sieci (jako JSON):
- Przetwarzanie Pythonowych typów (
str
,int
,float
,bool
,list
, itp). - Obiekty
datetime
. - Obiekty
UUID
. - Modele baz danych.
- ...i wiele więcej.
- Przetwarzanie Pythonowych typów (
- Automatyczne interaktywne dokumentacje API, wliczając 2 alternatywne interfejsy użytkownika:
- Swagger UI.
- ReDoc.
Wracając do poprzedniego przykładu, FastAPI :
- Potwierdzi, że w ścieżce jest
item_id
dla żądańGET
iPUT
. - Potwierdzi, że
item_id
jest typuint
dla żądańGET
iPUT
.- Jeżeli nie jest, odbiorca zobaczy przydatną, przejrzystą wiadomość z błędem.
- Sprawdzi czy w ścieżce jest opcjonalny parametr zapytania
q
(np.http://127.0.0.1:8000/items/foo?q=somequery
) dla żądaniaGET
.- Jako że parametr
q
jest zadeklarowany jako= None
, jest on opcjonalny. - Gdyby tego
None
nie było, parametr ten byłby wymagany (tak jak treść żądania w żądaniuPUT
).
- Jako że parametr
- Dla żądania
PUT
z ścieżką/items/{item_id}
, odczyta treść żądania jako JSON:- Sprawdzi czy posiada wymagany atrybut
name
, który powinien być typustr
. - Sprawdzi czy posiada wymagany atrybut
price
, który musi być typufloat
. - Sprawdzi czy posiada opcjonalny atrybut
is_offer
, który (jeżeli obecny) powinien być typubool
. - To wszystko będzie również działać dla głęboko zagnieżdżonych obiektów JSON.
- Sprawdzi czy posiada wymagany atrybut
- Automatycznie konwertuje z i do JSON.
- Dokumentuje wszystko w OpenAPI, które może być używane przez:
- Interaktywne systemy dokumentacji.
- Systemy automatycznego generowania kodu klienckiego, dla wielu języków.
- Dostarczy bezpośrednio 2 interaktywne dokumentacje webowe.
To dopiero początek, ale już masz mniej-więcej pojęcie jak to wszystko działa.
Spróbuj zmienić linijkę:
return {"item_name": item.name, "item_id": item_id}
...z:
... "item_name": item.name ...
...na:
... "item_price": item.price ...
...i zobacz jak edytor kodu automatycznie uzupełni atrybuty i będzie znał ich typy:
Dla bardziej kompletnych przykładów posiadających więcej funkcjonalności, zobacz Tutorial - User Guide.
Uwaga Spoiler: tutorial - user guide zawiera:
- Deklaracje parametrów z innych miejsc takich jak: nagłówki, pliki cookies, formularze i pliki.
- Jak ustawić ograniczenia walidacyjne takie jak
maksymalna długość
lubregex
. - Potężny i łatwy w użyciu system Dependency Injection.
- Zabezpieczenia i autentykacja, wliczając wsparcie dla OAuth2 z tokenami JWT oraz autoryzacją HTTP Basic.
- Bardziej zaawansowane (ale równie proste) techniki deklarowania głęboko zagnieżdżonych modeli JSON (dzięki Pydantic).
- Wiele dodatkowych funkcji (dzięki Starlette) takie jak:
- WebSockety
- GraphQL
- bardzo proste testy bazujące na HTTPX oraz
pytest
- CORS
- Sesje cookie
- ...i więcej.
Wydajność¶
Niezależne benchmarki TechEmpower pokazują, że FastAPI (uruchomiony na serwerze Uvicorn) jest jednym z najszybszych dostępnych Pythonowych frameworków, zaraz po Starlette i Uvicorn (używanymi wewnątrznie przez FastAPI). (*)
Aby dowiedzieć się o tym więcej, zobacz sekcję Benchmarks.
Opcjonalne zależności¶
Używane przez Pydantic:
email_validator
- dla walidacji adresów email.
Używane przez Starlette:
httpx
- Wymagane jeżeli chcesz korzystać zTestClient
.aiofiles
- Wymagane jeżeli chcesz korzystać zFileResponse
alboStaticFiles
.jinja2
- Wymagane jeżeli chcesz używać domyślnej konfiguracji szablonów.python-multipart
- Wymagane jeżelich chcesz wsparcie "parsowania" formularzy, używającrequest.form()
.itsdangerous
- Wymagany dla wsparciaSessionMiddleware
.pyyaml
- Wymagane dla wsparciaSchemaGenerator
z Starlette (z FastAPI prawdopodobnie tego nie potrzebujesz).graphene
- Wymagane dla wsparciaGraphQLApp
.
Używane przez FastAPI / Starlette:
uvicorn
- jako serwer, który ładuje i obsługuje Twoją aplikację.orjson
- Wymagane jeżeli chcesz używaćORJSONResponse
.ujson
- Wymagane jeżeli chcesz korzystać zUJSONResponse
.
Możesz zainstalować wszystkie te aplikacje przy pomocy pip install fastapi[all]
.
Licencja¶
Ten projekt jest na licencji MIT.