FastAPI Python web framework: modernūs API

Kas yra FastAPI ir kodėl visi apie jį kalba

Jei dirbi su Python ir kuri web API, tikrai esi girdėjęs apie FastAPI. Šis framework’as pastaraisiais metais tapo tikra sensacija Python bendruomenėje, ir ne be priežasties. Sukurtas Sebastiano Ramirezo 2018 metais, FastAPI greitai tapo vienu populiariausių pasirinkimų kuriant modernias API aplikacijas.

Kas gi daro FastAPI tokį ypatingą? Pirmiausia – greitis. Pavadinimas neapgaudinėja – tai tikrai vienas greičiausių Python framework’ų, konkuruojantis su NodeJS ir Go sprendimais. Bet greitis čia tik viena medalio pusė. FastAPI suteikia kažką, ko daugelis Python framework’ų neturi – automatinę dokumentaciją, duomenų validaciją ir modernią asinchroninę architektūrą iš dėžės.

Tradiciniai framework’ai kaip Flask ar Django buvo sukurti prieš daugelį metų, kai web’o pasaulis atrodė visai kitaip. FastAPI gimė jau modernios web architektūros eroje, todėl nuo pat pradžių buvo projektuojamas atsižvelgiant į dabartines realijas – mikroservisus, REST API, GraphQL, WebSocket’us ir kitus šiuolaikinius standartus.

Type hints ir automatinė validacija – kodėl tai keičia žaidimą

Vienas didžiausių FastAPI privalumų yra jo naudojimas Python type hints. Jei dar nenaudoji type hints savo Python kode, FastAPI gali būti puiki priežastis pradėti. Šis framework’as ne tik skatina, bet ir reikalauja naudoti tipų anotacijas, ir mainais už tai gauni neįtikėtinai daug.

Įsivaizduok, kad rašai endpoint’ą, kuris priima vartotojo duomenis. Tradiciškai su Flask turėtum patikrinti kiekvieną lauką rankiniu būdu – ar email’as tikrai email’as, ar amžius yra skaičius, ar slaptažodis pakankamai ilgas. Su FastAPI visa tai vyksta automatiškai:


from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

class User(BaseModel):
username: str
email: EmailStr
age: int
is_active: bool = True

@app.post("/users/")
async def create_user(user: User):
return {"message": f"User {user.username} created"}

Štai ir viskas. FastAPI automatiškai patikrina, ar gautas JSON atitinka User modelį, ar email’as yra tinkamo formato, ar age yra sveikasis skaičius. Jei kažkas negerai – automatiškai grąžinamas 422 klaidos kodas su detaliu aprašymu, kas konkrečiai netinka. Nereikia rašyti dešimčių eilučių validacijos kodo.

Bet tai dar ne viskas. Pydantic modeliai, kuriuos naudoja FastAPI, palaiko sudėtingas validacijas, įterptus modelius, pasirinktinius laukus ir daug daugiau. Galima apibrėžti minimalias ir maksimalias reikšmes, reguliarias išraiškas, custom validatorius – visa tai veikia automatiškai.

Dokumentacija, kuri kuria save pati

Kiekvienas, kuris yra rašęs API dokumentaciją, žino, koks tai nuobodus ir daug laiko reikalaujantis darbas. O dar blogiau – dokumentacija greitai pasidaro pasenusi, nes po kiekvieno pakeitimo reikia ją atnaujinti rankiniu būdu. FastAPI išsprendžia šią problemą radikaliai.

Kai tik paleidžiate FastAPI aplikaciją, automatiškai generuojamos dvi interaktyvios dokumentacijos versijos: Swagger UI (pasiekiama `/docs` adresu) ir ReDoc (pasiekiama `/redoc` adresu). Ir tai ne tik statinė dokumentacija – tai pilnai funkcionali interaktyvi sąsaja, kur galima išbandyti visus endpoint’us tiesiogiai naršyklėje.

Kas svarbiausia – ši dokumentacija visada aktuali. Ji generuojama iš jūsų kodo, todėl jei pakeičiate endpoint’ą, dokumentacija atsinaujina automatiškai. Nereikia jokių papildomų įrankių, nereikia rašyti YAML failų ar komentarų – viskas veikia iš dėžės.

Dokumentacijoje automatiškai atsiranda visi parametrai, jų tipai, aprašymai (jei juos pridedi), pavyzdiniai request’ai ir response’ai. Galima net autentifikuotis ir testuoti endpoint’us, kurie reikalauja autorizacijos. Tai neįtikėtinai pagreitina developmentą ir palengvina komunikaciją su frontend developeriais ar API vartotojais.

Asinchroninis programavimas be galvos skausmo

Python async/await sintaksė egzistuoja jau keletą metų, bet daugelis framework’ų ją palaiko tik iš dalies arba visai nepalaiko. FastAPI buvo sukurtas nuo nulio su async galvoje, ir tai vienas jo didžiausių privalumų.

Kodėl async svarbu? Tradiciniai sinchroniniai framework’ai kiekvienam request’ui skiria atskirą thread’ą ar procesą. Tai veikia gerai, kol neturi daug concurrent vartotojų. Bet kai aplikacija auga, thread’ų skaičius didėja, ir serveris pradeda springti. Asinchroninis kodas leidžia vienam procesui apdoroti tūkstančius request’ų vienu metu, nes kol laukiama duomenų bazės atsakymo ar išorinio API, procesas gali užsiimti kitais request’ais.

FastAPI leidžia rašyti tiek sinchroninius, tiek asinchroninius endpoint’us. Jei tavo funkcija naudoja async operacijas (duomenų bazės užklausos, HTTP request’ai), tiesiog naudok `async def` vietoj `def`:


@app.get("/users/{user_id}")
async def get_user(user_id: int):
user = await database.fetch_user(user_id)
return user

FastAPI automatiškai aptinka, ar funkcija asinchroninė, ir apdoroja ją tinkamu būdu. Tai reiškia, kad gali maišyti sinchroninius ir asinchroninius endpoint’us toje pačioje aplikacijoje be jokių problemų.

Dependency injection sistema, kuri iš tiesų veikia

Dependency injection skamba kaip sudėtingas enterprise pattern’as, bet FastAPI padaro jį paprastą ir intuityvų. Tai vienas iš framework’o aspektų, kuris iš pradžių gali atrodyti nesvarbus, bet vėliau supranti, kad be jo jau nebegali gyventi.

Įsivaizduok, kad daugelis tavo endpoint’ų reikalauja autentifikuoto vartotojo. Tradiciškai turėtum kiekviename endpoint’e rašyti tą patį kodą – tikrinti token’ą, ieškoti vartotojo duomenų bazėje, grąžinti klaidą jei kas negerai. Su FastAPI dependency injection tai tampa trivialiu dalyku:


from fastapi import Depends, HTTPException

async def get_current_user(token: str = Header(...)):
user = await verify_token(token)
if not user:
raise HTTPException(status_code=401)
return user

@app.get("/profile")
async def get_profile(current_user: User = Depends(get_current_user)):
return current_user

Dabar `get_current_user` funkcija automatiškai vykdoma prieš kiekvieną endpoint’ą, kur ji nurodyta kaip dependency. Galima kurti dependency grandines – viena dependency gali priklausyti nuo kitos, ir FastAPI viską išspręs automatiškai.

Tai puikiai tinka ne tik autentifikacijai. Galima naudoti dependencies duomenų bazės sesijoms, konfigūracijai, logging’ui, rate limiting’ui – bet kam, ką nori pakartotinai naudoti skirtinguose endpoint’uose. Ir viskas testuojama lengvai, nes galima override’inti dependencies testavimo metu.

Realūs performance rezultatai ir benchmarkai

Kalbėti apie greitį yra viena, bet pažiūrėkime į konkrečius skaičius. Pagal TechEmpower benchmarkus, FastAPI yra vienas greičiausių Python framework’ų, dažnai lenkiantis net NodeJS ir Go sprendimus tam tikrose kategorijose.

Žinoma, benchmarkai nėra viskas. Realiame pasaulyje performance priklauso nuo daugelio faktorių – kaip rašai kodą, kokią duomenų bazę naudoji, kaip optimizuoji užklausas. Bet FastAPI suteikia gerą startinę poziciją. Jis pastatytas ant Starlette – vieno greičiausių Python ASGI framework’ų, ir naudoja Uvicorn – labai spartų ASGI serverį.

Praktikoje tai reiškia, kad FastAPI aplikacija gali apdoroti tūkstančius request’ų per sekundę viename procese. Jei naudoji async endpoint’us ir optimizuoji duomenų bazės užklausas, gali pasiekti tikrai įspūdingų rezultatų. Esu matęs FastAPI aplikacijas, kurios su 4 CPU core’ais apdoroja 10,000+ request’ų per sekundę.

Bet svarbiausia – FastAPI neaukoja developer experience dėl performance. Nereikia rašyti sudėtingo, sunkiai skaitomo kodo, kad pasiektum gerų rezultatų. Paprastas, aiškus kodas su FastAPI dažnai būna greitesnis nei optimizuotas kodas su senesniais framework’ais.

Ekosistema ir integracija su kitais įrankiais

FastAPI puikiai integruojasi su modernia Python ekosistema. Nori naudoti SQLAlchemy duomenų bazei? Veikia puikiai, yra net oficialūs pavyzdžiai. Tortoise ORM? Taip pat. MongoDB su Motor? Be problemų. Redis? Celery background task’ams? Viskas veikia sklandžiai.

Autentifikacijai ir autorizacijai yra puikus `fastapi-users` package, kuris suteikia pilną user management sistemą su registracija, login’u, password reset ir OAuth2. Jei reikia GraphQL, galima naudoti Strawberry ar Graphene. WebSocket’ai palaikomi natyviai. Server-Sent Events? Taip pat.

Testavimui FastAPI naudoja `pytest` ir suteikia puikų `TestClient`, kuris leidžia testuoti API endpoint’us be realaus serverio paleidimo. Tai labai pagreitina testų vykdymą ir daro TDD (Test-Driven Development) malonumu:


from fastapi.testclient import TestClient

client = TestClient(app)

def test_create_user():
response = client.post("/users/", json={
"username": "testuser",
"email": "[email protected]",
"age": 25
})
assert response.status_code == 200
assert response.json()["message"] == "User testuser created"

Docker integracija taip pat paprasta. FastAPI aplikacijos dažniausiai yra labai lengvos ir greitai startuoja, todėl puikiai tinka containerizacijai ir Kubernetes deployment’ui.

Kada FastAPI yra geriausias pasirinkimas ir kada ne

FastAPI nėra sidabrinis kulka, kuri tinka visoms situacijoms. Yra scenarijai, kur jis puikiai tinka, ir yra atvejai, kur galbūt verta apsvarstyti alternatyvas.

FastAPI puikiai tinka, kai:
– Kuri REST API ar GraphQL endpoint’us
– Reikia gero performance ir galimybės skalėti
– Nori automatinės dokumentacijos
– Dirbi su mikroservisų architektūra
– Reikalingas WebSocket’ų palaikymas
– Komanda vertina type safety ir modernų Python kodą

Galbūt verta apsvarstyti alternatyvas, kai:
– Kuri tradicinę web aplikaciją su server-side rendering (čia Django ar Flask su Jinja2 gali būti geresni)
– Turi labai paprastą projektą ir nori minimalaus framework’o (Flask gali užtekti)
– Komanda neturi patirties su async Python (nors tai gera proga išmokti)
– Projektas jau naudoja kitą framework’ą ir migracija neduotų didelės naudos

Praktiškai, jei šiandien pradėčiau naują API projektą su Python, FastAPI būtų mano pirmasis pasirinkimas. Jis turi puikų balansą tarp paprastumo, galingumo ir performance. O mokymosi kreivė nėra per stačią – jei žinai Python ir esi rašęs bent kokį nors web kodą, su FastAPI pradėsi produktyviai dirbti per kelias valandas.

Kaip pradėti ir ko išmokti pirmiausia

Jei nusprendei išbandyti FastAPI, štai keletas praktinių patarimų, kaip pradėti efektyviai. Pirmiausia, įsitikink, kad supranti Python type hints. Tai fundamentalus dalykas, ant kurio pastatytas visas FastAPI. Jei dar neesi susipažinęs su typing moduliu, skirkite valandą-kitą jo išmokimui – tai atsipirks šimteriopai.

Instaliacija paprasta kaip ir visada su Python:


pip install fastapi
pip install "uvicorn[standard]"

Pradėk nuo paprastos aplikacijos. Nesistengk iš karto naudoti visų feature’ų – pradėk nuo kelių paprastų endpoint’ų, pažiūrėk kaip veikia automatinė dokumentacija, išbandyk validaciją. Palaipsniui pridėk duomenų bazę, autentifikaciją, background task’us.

Oficiali FastAPI dokumentacija yra išties puiki. Ji ne tik išsami, bet ir parašyta taip, kad būtų lengva skaityti ir suprasti. Yra daug pavyzdžių, tutorial’ų, ir net advanced topics aprašyti aiškiai. Rekomenduoju pradėti nuo tutorial’o ir pereiti jį nuo pradžios iki galo – tai užtruks keletą valandų, bet suteiks tvirtą pagrindą.

Kai jau suprasi pagrindus, pabandyk sukurti kažką realaus. Gal paprastą blog API, ar task management sistemą, ar bet ką kita, kas tau įdomu. Realus projektas išmokys daugiau nei bet koks tutorial’as. Naudok SQLAlchemy ar Tortoise ORM duomenų bazei, pridėk JWT autentifikaciją, parašyk testus. Tai geriausias būdas išmokti framework’ą iš tiesų gerai.

Dar vienas patarimas – sekite FastAPI GitHub repository ir Discord kanalą. Bendruomenė labai aktyvi ir draugiška, visada padės, jei užstrigsi. O GitHub issues yra puikus būdas sužinoti apie best practices ir kaip kiti sprendžia panašias problemas.

FastAPI tikrai nusipelno dėmesio, jei dirbi su Python ir kuri API. Jis atstovauja naują kartą Python web framework’ų – greitų, modernių ir malonių naudoti. Nebijok išbandyti, ir yra didelė tikimybė, kad jis taps tavo go-to pasirinkimu būsimiems projektams.

Daugiau

OVHcloud Europos debesų sprendimai