Nasza strona używa cookies. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Dlaczego warto używać FastAPI

Tivadar Danka Co-Founder / telesto.ai
Poznaj powody, dla których warto używać FastAPI oraz sposoby, w jakie ten framework ułatwi pracę przy rzeczywistych projektach.
Dlaczego warto używać FastAPI

Python zawsze był popularny, jeśli chodzi o tworzenie lekkich aplikacji webowych dzięki takim frameworkom, jak Flask, Django, Falcon i wiele innych. Ze względu na pozycję Pythona jako języka numer jeden w uczeniu maszynowym, jest on szczególnie przydatny przy opakowywaniu modeli i prezentowaniu ich jako usługi. Przez wiele lat Flask był tutaj czołowym narzędziem, ale powoli zostaje on wypierany przez FastAPI. Jest to stosunkowo nowy framework webowy dla Pythona, który czerpie inspirację od swoich poprzedników, udoskonalając i naprawiając wiele ich wad.

FastAPI jest zbudowany na Starlette i ma wiele świetnych funkcji. Zyskał on ostatnio dużą popularność, a po spędzeniu ostatnich 8 miesięcy na codziennej pracy z nim, mogę śmiało powiedzieć, że cały ten szum wokół niego jest uzasadniony. Chciałbym Wam podać pięć powodów, dla których warto spróbować z FastAPI.


Prosty, ale genialny interfejs

Wszystkie frameworki webowe muszą balansować między funkcjami, a dawaniem programiście wolności. Django dostarcza mnóstwo funkcji, ale jednocześnie narzuca dość sztywny sposób robienia większości rzeczy. Z drugiej strony Flask jest na tyle niskopoziomowy, aby zapewnić duży stopień swobody, ale użytkownikowi pozostaje potem wiele do zrobienia. FastAPI jest bardziej podobny do Flaska, jednak udaje mu się osiągnąć większą i zdrowszą równowagę.

Zobaczmy dla przykładu, jak w FastAPI definiowany jest punkt końcowy.

from fastapi import FastAPI
from pydantic import BaseModel


class User(BaseModel):
    email: str
    password: str


app = FastAPI()


@app.post("/login")
def login(user: User):
    # ...
    # do some magic
    # ...
    return {"msg": "login successful"}

Pydantic jest wykorzystywana do zdefiniowania schematu. Jest to niesamowita biblioteka Pythona, używana do walidacji danych. Tutaj wygląda to prosto, ale w tle dzieje się bardzo wiele. Odpowiedzialność za sprawdzenie poprawności danych wejściowych jest delegowana do FastAPI. Jeśli żądanie nie jest poprawne (na przykład pole wiadomości e-mail zawiera int), to zamiast awarii aplikacji z przerażającym Internal Server Error (500), zwrócony zostanie odpowiedni kod błędu. Jest to też bardzo proste do zrobienia. 

Ta prosta aplikacja może zostać obsłużona przez uvicorn:

uvicorn main:app


Teraz aplikacja jest gotowa do przyjmowania żądań. W takim przypadku wyglądałoby to następująco:

curl -X POST "http://localhost:8000/login" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"email\":\"string\",\"password\":\"string\"}"


Wisienką na torcie jest to, że FastAPI automatycznie generuje dokumentację zgodną z OpenAPI przy użyciu interaktywnego Swagger UI.


Swagger UI dla aplikacji FastAPI


Async

Jedną z największych wad frameworków webowych Python WSGI w porównaniu do tych w Node.js czy Go była niemożność asynchronicznej obsługi żądań.

Od czasu wprowadzenia ASGI nie stanowi to już jednak problemu, a FastAPI w pełni to wykorzystuje. Wszystko, co musisz zrobić, to po prostu zadeklarować punkty końcowe za pomocą słowa kluczowego async w następujący sposób:

@app.post("/")
async def endpoint():
    # ...
    # call async functions here with `await`
    # ...
    return {"msg": "FastAPI is awesome!"}


Wstrzykiwanie zależności

FastAPI ma naprawdę fajny sposób na zarządzanie zależnościami. Chociaż nie jest to wymuszane na programistach, to zdecydowanie zaleca się używanie wbudowanego systemu wstrzykiwania do obsługi zależności w punktach końcowych. Jako przykład napiszemy punkt końcowy, w którym użytkownicy mogą publikować komentarze do niektórych artykułów.

from fastapi import FastAPI, Depends
from pydantic import BaseModel


class Comment(BaseModel):
    username: str
    content: str


app = FastAPI()


database = {
    "articles": {
        1: {
            "title": "Top 3 Reasons to Start Using FastAPI Now",
            "comments": []
        }
    }
}


def get_database():
    return database


@app.post("/articles/{article_id}/comments")
def post_comment(article_id: int, comment: Comment, database = Depends(get_database)):
    database["articles"][article_id]["comments"].append(comment)
    return {"msg": "comment posted!"}


FastAPI automatycznie ewaluuje funkcję get_database w czasie uruchamiania, gdy wywoływany jest punkt końcowy, więc jeśli chcesz, możesz użyć zwracanej wartości. Istnieją ku temu przynajmniej dwa dobre powody.

  1. Zależności można zastąpić globalnie, modyfikując słownik app.dependency_overrides. Być może sprawi to, że testowanie będzie proste, ponieważ można wtedy łatwo mockować obiekty.
  2. Zależność (którą w naszym przypadku jest get_database) może wykonywać bardziej wyrafinowane testy, pozwalając oddzielić je od logiki biznesowej. Znacznie upraszcza to sprawę. W taki sposób można na przykład łatwo zaimplementować uwierzytelnianie użytkownika.


Prosta integracja z bazami danych

FastAPI nie zmusza Cię do budowania aplikacji wokół jakiejś bazy danych (niezależnie od tego, czy chodzi o SQL, MongoDB, czy Redis). Jeśli ktoś z Was próbował pracować z MongoDB przy użyciu Django, to wie, jakie to bolesne.

Dzięki FastAPI nie musisz wkładać dużo dodatkowej pracy, ponieważ dodawanie bazy danych do stosu jest tak proste, jak to tylko możliwe (lub, mówiąc dokładniej, ilość pracy do wykonania zależy od wybranej bazy danych, a nie od komplikacji dodanych przez framework).

Spójrzcie jednak:

from fastapi import FastAPI, Depends

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker


engine = create_engine("sqlite:///./database.db")
Session = sessionmaker(bind=engine)


def get_db():
    return Session()


app = FastAPI()


@app.get("/")
def an_endpoint_using_sql(db = Depends(get_db)):
    # ...
    # do some SQLAlchemy
    # ...
    return {"msg": "an exceptionally successful operation!"}


No i proszę! Już widzę, jak to piszecie

pip install fastapi


w swoim terminalu.


Obsługa GraphQL

REST może być poważną przeszkodą przy pracy ze złożonym modelem danych. Nikt się raczej nie śmieje, gdy drobna zmiana w interfejsie wymaga zaktualizowania schematu punktu końcowego. W takich sytuacjach sprawdza się GraphQL.

Chociaż obsługa GraphQL nie jest niczym nowym wśród frameworków webowych Pythona, Graphene i FastAPI współpracują ze sobą bezproblemowo. Nie ma potrzeby instalowania rozszerzeń, takich jak graphene_django dla Django, bo wszystko działa natywnie.


+1: Świetna dokumentacja

Świetny framework nie będzie już taki świetny bez równie świetnej dokumentacji. Django, Flask i wszystkie inne frameworki są tutaj liderami, ale FastAPI jest z nimi na równi. Ponieważ FastAPI jest znacznie młodsze, to nie ma jeszcze o nim jeszcze żadnych książek, ale to tylko kwestia czasu.

Jeśli chcesz zobaczyć FastAPI w akcji, mam dla Ciebie idealny przewodnik! Napisałem szczegółowy tutorial, w którym możesz wdrożyć model uczenia maszynowego za pomocą Docker, Docker Compose i GitHub Actions.

Podsumowując, czy szukasz szybkiego i lekkiego frameworku do serwowania swoich modeli uczenia maszynowego, czy czegoś bardziej złożonego, to FastAPI Ci to zapewni. Jeśli jeszcze nie próbowaliście pracy z nim, to gorąco do tego zachęcam. Jestem pewny, że Wam się spodoba.


Oryginał tekstu w języku angielskim możesz przeczytać tutaj.

Rozpocznij dyskusję

Lubisz dzielić się wiedzą i chcesz zostać autorem?

Podziel się wiedzą z 160 tysiącami naszych czytelników

Dowiedz się więcej