FastAPI to szybki, prosty 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 3.6+ bazujący na standardowym typowaniu Pythona.
Cechami kluczowymi są:
-
Wydajność: FastApi jest bardzo wydajny, na równi z NodeJS oraz Go (podziękowania dla Starlette i Pydantic). Jeden z najszybszych dostępnych frameworków Pythonowych .
-
Szybkość napisania: Przyśpiesz czas pisania funkcji o około 200% do 300%. *
-
Mniejsza ilość błędów: Zmniejsz ludzkie (dewelopera) błędy o około 40%. *
-
Intuicyjność: Wspaniałe wsparcie przez edytory kodu. Wszędzie automatyczne uzupełnianie. Mniejszy czas debugowania.
-
Łatwość: Zaprojektowany by być prosty i łatwy do nauczenia. Mniej czasu spędzaj na czytanie dokumentacji.
-
Krótkość: Zmniejsz powtarzanie się kodu. Dla każdego parametru można dać wiele funkcji. Mniej błędów.
-
Solidność: Kod gotowy do środowiska produkyjnego. Wraz z automatyczną interaktywną dokumentacją.
-
Oparte na standardach: Oparte na (i w pełni kompatybilne z) otwartymi standardami w API: OpenAPI (wcześniej znane jako Swagger) oraz JSON Schema.
* oszacowania bazowane na testach przez wewnętrzny zespół deweloperów, budujących aplikacie używane na środowisku produkcyjnym.
{% if sponsors %} {% for sponsor in sponsors.gold -%} {% endfor -%} {%- for sponsor in sponsors.silver -%} {% endfor %} {% endif %}
"[...] 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 [...]"
Jeżeli tworzysz aplikacje CLI która ma być używana w terminalu zamiast API, sprawdź Typer.
Typer to młodsze rodzeństwo FastAPI. I jego przeznaczenie to bycie FastAPI aplikacji konsolowych . ⌨️ 🚀
Python 3.6+
FastAPI stoi na ramionach olbrzymów:
$ pip install fastapi
---> 100%
Do produkcji będziesz potrzebował również serwera ASGI, takich jak Uvicorn albo Hypercorn.
$ pip install uvicorn[standard]
---> 100%
- Stwórz plik o nazwie
main.py
z:
from typing import Optional
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: Optional[str] = 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 Optional
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: Optional[str] = None):
return {"item_id": item_id, "q": q}
Notatka:
Jeżeli nie wiesz, sprawdz sekcje "In a hurry?" (jeszcze nie przetłumaczone) o async
i await
w dokumentacji.
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` nawiązuje 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.
Otwórz link http://127.0.0.1:8000/items/5?q=somequery w przeglądarce.
Zobaczysz taką odpowiedź JSON:
{"item_id": 5, "q": "somequery"}
Właśnie stworzyłeś API które:
- Otrzymuje żądanie 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
.
Teraz wejdź na strone http://127.0.0.1:8000/docs.
Zobaczysz automatyczną interaktywną dokumentacje API (zrobiona z pomocą Swagger UI):
Teraz, wejdź na http://127.0.0.1:8000/redoc.
Zobaczysz alternatywną, lecz wciąż automatyczną dokumentacje (zrobiona z pomocą ReDoc):
Teraz zmodyfikujemy plik main.py
aby otrzmywał treść (body, w przykładzie nazwane Item
) żądania PUT
.
Zadeklaruj treść żądania, używając standardowych typów w Pythonie dzięki Pydantic.
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = 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 odświeżyć automatycznie (ponieważ dodałeś --reload
do komendy uvicorn
powyżej).
Teraz wejdź na http://127.0.0.1:8000/docs.
- Interaktywna dokumentacja API zaktualizuje sie automatycznie, wliczając nową treść żądania (body):
- Kliknij przycisk "Try it out" (wypróbuj), pozwoli to ci wypełnić parametry i bezpośrednio użyć API:
- Potem kliknij przycisk "Execute", interfejs użytkownika skontaktuje się z API, wyśle parametry, otrzyma odpowiedź i wyświetli ją na ekranie:
Teraz, przejdź na http://127.0.0.1:8000/redoc.
- Alternatywna dokumentacja również pokaże zaktualizowane parametry i treść żądania (body):
W podsumowaniu, musiałeś zadeklarować typy parametrów, treści żądania (body) itp. tylko raz, i są dostępne jako parametry w funkcji.
Robisz to tak samo jak z standardowymi (na ten czas) typami w Pythonie.
Nie musisz sie uczyć żadnej nowej składni, używać metod lub klas z specyficznych bibliotek, itp.
Po prostu Python 3.6+.
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.
- Zatwierdzenie 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 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 jesst 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ćfloat
. - Sprawdzi czy posiada opcjonalny atrybut
is_offer
, który (jeżeli obecny) powinien być typubool
. - To wszystko powinno również działać dla głęboko zagnieżdżonych obiektów JSON.
- Sprawdzi czy posiada wymagany atrybut
- Konwersuje z i do JSON automatycznie.
- Dokumentuje wszystko z OpenAPI, które może być używane przez:
- Interaktywne systemy dokumentacji.
- Systemy automatycznego generowania kodu klientowego, dla wielu języków.
- Dostarczy bezpośrednio 2 interaktywne dokumentacje sieciowe.
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 funkcji, zobacz Tutorial - User Guide (jeszcze nieprzetłumaczone).
Uwaga Spoiler: the tutorial - user guide zawiera:
- Deklaracje parametrów z innych miejsc takich jak: headery, 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 autoryzacja, 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 (podziękowania dla Pydantic).
- Wiele dodatkowych funkcji (dzięki Starlette) takie jak:
- WebSockety
- GraphQL
- bardzo proste testy bazujące na
requests
orazpytest
- CORS
- Sesje cookie
- ...i więcej.
Niezależne benchmarki TechEmpower pokazują że FastAPI (pod Uvicornem) jest jednym z najszybszych Pythonowych frameworków dostępnych, znajduje się tylko pod samymi Starlette i Uvicorn (używanymi wewnątrz FastAPI). (*)
Aby dowiedzieć się o tym więcej, zobacz sekcje Benchmarks (jeszcze nieprzetłumaczone).
Używane przez Pydantic:
ujson
- dla szybszego "parsowania" danych JSON.email_validator
- dla walidacji adresów email.
Używane przez Starlette:
requests
- Wymagane jeżeli chcesz korzystać zTestClient
.aiofiles
- Wymagane jeżeli chcesz korzystać zFileResponse
alboStaticFiles
.jinja2
- Wymagane jeżeli chcesz używać domyślnych szablonów konfiguracji.python-multipart
- Wymagane jeżelich chcesz wsparcie "parsowania" formularzy, używającrequest.form()
.itsdangerous
- Wymagany dla wsparciaSessionMiddleware
.pyyaml
- Wymagane dla wsparciaSchemaGenerator
do Starlette (z FastAPI prawdopodobnie tego nie potrzebujesz).graphene
- Wymagane dla wsparciaGraphQLApp
.ujson
- Wymagane jeżeli chcesz korzystać zUJSONResponse
.
Używane przez FastAPI / Starlette:
uvicorn
- dla serwera który ładuje i obsługuje twoją aplikacje.orjson
- Wymagane jeżeli chcesz używaćORJSONResponse
.
Możesz zainstalować wszystkie te aplikacje przy pomocy pip install fastapi[all]
.
Ten projekt jest pod licencją MIT.