FastAPI to nowoczesny framework Pythona do budowania API, który na podstawie adnotacji typów sam waliduje dane wejściowe i generuje interaktywną dokumentację pod adresem `/docs`. Pierwsze działające API napiszesz w kilkunastu liniach kodu, a jego pracę sprawdzisz w przeglądarce bez dodatkowych narzędzi.
Jeśli znasz Pythona i chcesz, żeby Twój kod mógł rozmawiać z aplikacją frontendową, telefonem albo modelem językowym, potrzebujesz API. FastAPI jest dziś jednym z najprostszych sposobów, żeby je zbudować, a jednocześnie nie jest zabawką: tego samego frameworka używa się w prawdziwych projektach.
Czym jest FastAPI i do czego służy?
FastAPI to framework webowy do Pythona skupiony na jednym zadaniu: budowaniu API, czyli „drzwi”, przez które inne programy wysyłają zapytania do Twojej aplikacji i dostają dane, najczęściej w formacie JSON. Nie renderuje stron z szablonów jak Django, tylko odpowiada danymi.
Trzy cechy decydują o jego popularności:
- Adnotacje typów jako źródło prawdy. Piszesz
task_id: int, a FastAPI sprawdza, czy ktoś naprawdę przysłał liczbę. - Automatyczna dokumentacja. Z kodu powstaje interaktywna strona
/docs(Swagger UI), na której klikasz i testujesz endpointy. - Obsługa asynchroniczności. Framework działa na standardzie ASGI i potrafi obsługiwać wiele zapytań naraz, gdy aplikacja czeka na sieć lub bazę danych. Wrócimy do tego niżej i w osobnym artykule.
Za walidację danych odpowiada biblioteka Pydantic, o której piszemy w artykule Czym jest Pydantic w Pythonie.
Czym FastAPI różni się od Flaska i Django?
Wszystkie trzy to frameworki Pythona, ale rozwiązują trochę inne problemy.
| Cecha | FastAPI | Flask | Django |
|---|---|---|---|
| Do czego jest głównie | API | małe aplikacje i API | pełne aplikacje webowe |
| Walidacja danych | wbudowana (Pydantic) | trzeba dodać bibliotekę | formularze i serializery (DRF) |
| Dokumentacja API | generowana automatycznie | trzeba dodać rozszerzenie | trzeba dodać (DRF) |
| Asynchroniczność | podstawa działania | dodatek | obsługiwana, ale nie jest sercem |
| Panel admina i ORM | brak | brak | wbudowane |
To nie jest ranking „lepszy i gorszy”. Jeśli budujesz serwis z panelem administracyjnym, użytkownikami i bazą danych, Django da Ci dużo gotowych elementów. Jeśli piszesz samo API, FastAPI zwykle będzie krótsze. Pełne porównanie przygotowujemy w osobnym artykule.
Jak zainstalować FastAPI?
Najpierw utwórz środowisko wirtualne i zainstaluj framework z dodatkami, które obejmują serwer deweloperski:
python -m venv .venv
source .venv/bin/activate
pip install "fastapi[standard]"
Na Windowsie aktywujesz środowisko poleceniem .venv\Scripts\activate.
Jak napisać pierwszy endpoint?
Utwórz plik main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Cześć, FastAPI!"}
Obiekt app to Twoja aplikacja, a dekorator @app.get("/") mówi: „gdy ktoś wyśle zapytanie GET pod adres główny, uruchom tę funkcję”. Słownik, który zwracasz, FastAPI zamienia na JSON.
Jak uruchomić aplikację i gdzie jest dokumentacja?
Uruchom serwer deweloperski:
fastapi dev main.py
Wejdź na http://127.0.0.1:8000, a zobaczysz JSON z komunikatem. Pod adresem http://127.0.0.1:8000/docs czeka interaktywna dokumentacja, w której każdy endpoint możesz wypróbować jednym kliknięciem. Dostępna jest też alternatywna wersja pod /redoc.
Jeśli wolisz klasyczne uruchamianie przez Uvicorn, polecenie wygląda tak:
uvicorn main:app --reload
Co oznacza błąd „Error loading ASGI app. Could not import module”?
To jeden z najczęstszych błędów na starcie. Zapis main:app ma dwie części: main to nazwa pliku (main.py), a app to nazwa zmiennej z aplikacją wewnątrz niego. Jeśli plik nazywa się api.py, a Ty piszesz uvicorn main:app, Python nie znajdzie modułu. Sprawdź więc trzy rzeczy: nazwę pliku, nazwę zmiennej i to, czy uruchamiasz polecenie z katalogu, w którym ten plik leży.
Jak dodać parametry i walidację danych?
Prawdziwe API przyjmuje dane. Rozbudujmy main.py o proste zarządzanie zadaniami zapisanymi w pamięci:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class Task(BaseModel):
title: str
done: bool = False
tasks: dict[int, Task] = {}
@app.post("/tasks/{task_id}", status_code=201)
def create_task(task_id: int, task: Task):
tasks[task_id] = task
return task
@app.get("/tasks/{task_id}")
def get_task(task_id: int):
if task_id not in tasks:
raise HTTPException(status_code=404, detail="Nie ma takiego zadania")
return tasks[task_id]
Co tu się dzieje:
task_idw ścieżce jest liczbą, bo tak go otypowałeś.Taskto model Pydantic:titlejest wymagany, adonema domyślną wartośćFalse.- Gdy zadania nie ma,
HTTPExceptionzwraca czytelną odpowiedź 404.
Wyślij zapytanie z terminala:
curl -X POST http://127.0.0.1:8000/tasks/1 \
-H "Content-Type: application/json" \
-d '{"title": "Nauczyć się FastAPI"}'
W odpowiedzi dostaniesz zadanie z done ustawionym na false. Odczytasz je pod GET /tasks/1.
Dlaczego dostaję błąd 422 przy wysyłaniu JSON?
Kod 422 oznacza, że dane przyszły, ale nie pasują do modelu. Dla powyższego przykładu wystarczy pominąć pole title lub wysłać go w złym formacie, np. z literówką w nazwie pola. FastAPI odpowie listą błędów mówiącą, które pole jest problemem, na przykład że title jest wymagane. Najczęstsze przyczyny:
- brak nagłówka
Content-Type: application/json, - nazwa pola w JSON-ie różni się od nazwy w modelu,
- zły typ wartości, np. tekst tam, gdzie model oczekuje liczby.
Zajrzyj do treści odpowiedzi 422: jest tam dokładna lokalizacja błędu, więc zwykle naprawa zajmuje chwilę. To ten sam mechanizm, który chroni Twoje API przed śmieciowymi danymi bez pisania ręcznych if-ów.
Kiedy użyć def, a kiedy async def?
FastAPI pozwala pisać endpointy na dwa sposoby. Zasada jest prosta:
| Sytuacja | Użyj |
|---|---|
Kod robi await (asynchroniczny klient HTTP, baza z async) | async def |
Kod jest zwykły i blokujący (requests, time.sleep, klasyczna biblioteka bazodanowa) | def |
Dlaczego to ważne? Funkcja async def działa w głównej pętli zdarzeń serwera. Jeśli wywołasz w niej coś blokującego, na przykład time.sleep(5), zatrzymasz całą pętlę, a inni użytkownicy będą czekać, aż skończysz. Zwykłe def FastAPI uruchamia osobno, więc blokujący kod mu nie przeszkadza. To częsta przyczyna pytań w stylu „dlaczego moje API obsługuje zapytania po kolei zamiast równolegle”.
Jak dokładnie wykorzystać asynchroniczność, gdy Twoje API czeka na odpowiedź modelu językowego, pokażemy w osobnym artykule cyklu.
Jaki błąd mentor poprawia najczęściej?
Uwaga mentora: na code review w FastAPI najczęściej poprawiamy to, że endpoint zwraca zwykły słownik zamiast modelu Pydantic. Działa, ale tracisz walidację odpowiedzi i opis pól w dokumentacji /docs. Warto od początku opisywać także to, co API zwraca.
Co dalej po pierwszym API?
Masz teraz działające API z walidacją i dokumentacją. Naturalne kolejne kroki to:
- walidacja bardziej złożonych danych z użyciem Pydantic,
- zapis do prawdziwej bazy zamiast słownika w pamięci,
- konfiguracja CORS, jeśli wołasz API z frontendu działającego na innym adresie,
- podłączenie do API modelu językowego, jak w artykule API OpenAI w Pythonie.
Jeśli wolisz uczyć się backendu w Pythonie z mentorem, który na bieżąco sprawdza Twój kod, zobacz kurs Python online z certyfikatem ukończenia.


