Flask – co to jest i jak stworzyć pierwszą aplikację w Pythonie

Piotr Dul

17-10-2026

(aktualizacja: 18-10-2026)

Czym jest Flask, kiedy warto go wybrać zamiast Django lub FastAPI i jak napisać pierwszą aplikację z endpointami JSON, szablonem HTML i obsługą błędów. Z przetestowanym kodem.

Flask – co to jest i jak stworzyć pierwszą aplikację w Pythonie
Flask to lekki framework Pythona do budowania aplikacji webowych i API, który dostarcza tylko podstawy: trasy, obsługę zapytań i szablony. Resztę (baza danych, logowanie, walidacja) dobierasz sam, więc dobrze sprawdza się w małych projektach i do nauki, ale większe aplikacje wymagają więcej decyzji niż w Django.

Flask jest jednym z najstarszych i najpopularniejszych frameworków Pythona. Jeśli chcesz zrozumieć, jak działa serwer WWW, bez uczenia się ogromnego frameworka, to dobry punkt startowy. W tym artykule zbudujesz małą aplikację, a na końcu zobaczysz, kiedy lepiej sięgnąć po Django albo FastAPI.

Czym jest Flask i do czego służy?

Flask to tak zwany mikroframework. „Mikro” nie oznacza, że jest słaby, tylko że nie narzuca struktury projektu ani gotowych rozwiązań. W rdzeniu dostajesz:

  • trasy (routing), czyli przypisanie adresu URL do funkcji,
  • obsługę zapytań i odpowiedzi (request, zwracanie JSON i HTML),
  • szablony Jinja2 do generowania stron HTML,
  • serwer deweloperski do uruchamiania aplikacji na własnym komputerze.

Do bazy danych, logowania użytkowników czy walidacji formularzy używasz osobnych bibliotek. To daje swobodę, ale też odpowiedzialność za wybór i spięcie tych elementów.

Czym Flask różni się od Django i FastAPI?

CechaFlaskDjangoFastAPI
Podejścieminimalne, dobierasz dodatki„wszystko w zestawie”skupione na API
Panel admina, ORMbrak (osobne biblioteki)wbudowanebrak
Walidacja danychręcznie lub bibliotekaformularze i serializerywbudowana (Pydantic)
Dokumentacja APIosobne rozszerzenieosobne rozszerzeniegenerowana automatycznie
Szablony HTMLJinja2własny silnikmożliwe, ale nie to jest ich siłą
Najlepiej domałych aplikacji, nauki, prostych APIdużych serwisów z bazą i panelemAPI, w tym współpracy z modelami językowymi

To nie jest ranking. Wybór zależy od tego, co budujesz. Pełne porównanie wraz z pomiarem wydajności przygotowaliśmy w osobnym artykule cyklu.

Jak zainstalować Flaska?

Utwórz środowisko wirtualne i zainstaluj bibliotekę:

python -m venv .venv
source .venv/bin/activate
pip install flask

Na Windowsie aktywujesz środowisko poleceniem .venv\Scripts\activate.

Jak napisać pierwszą aplikację we Flasku?

Utwórz plik app.py:

from flask import Flask

app = Flask(__name__)


@app.get("/")
def index():
    return {"message": "Cześć, Flask!"}

Flask(__name__) tworzy aplikację, a dekorator @app.get("/") przypisuje funkcję do adresu głównego dla zapytań GET. Słownik, który zwracasz, Flask zamienia na JSON.

Uruchom serwer deweloperski:

flask --app app run --debug

Wejdź na http://127.0.0.1:5000 i zobaczysz JSON z komunikatem. Opcja --debug przeładowuje aplikację po każdej zmianie kodu, co przydaje się podczas nauki.

Jak odbierać i zwracać dane JSON?

Rozbudujmy aplikację o proste zarządzanie zadaniami zapisanymi w pamięci:

from flask import Flask, abort, request

app = Flask(__name__)

tasks = {}


@app.post("/tasks/<int:task_id>")
def create_task(task_id):
    data = request.get_json(silent=True)
    if not data or "title" not in data:
        abort(400, description="Pole title jest wymagane")
    tasks[task_id] = {"title": data["title"], "done": data.get("done", False)}
    return tasks[task_id], 201


@app.get("/tasks/<int:task_id>")
def get_task(task_id):
    if task_id not in tasks:
        abort(404, description="Nie ma takiego zadania")
    return tasks[task_id]

Co tu się dzieje:

  • <int:task_id> w ścieżce zamienia fragment adresu na liczbę całkowitą. Gdy ktoś poda tekst, Flask zwróci 404.
  • request.get_json(silent=True) odczytuje JSON z zapytania. Z silent=True zwraca None zamiast błędu, gdy treść nie jest poprawnym JSON-em, więc możesz sam zdecydować, co odpowiedzieć.
  • Walidację robisz ręcznie. W przeciwieństwie do FastAPI, Flask nie sprawdza typów danych sam.
  • return tasks[task_id], 201 zwraca dane z własnym kodem statusu.

Wyślij zapytanie:

curl -X POST http://127.0.0.1:5000/tasks/1 \
  -H "Content-Type: application/json" \
  -d '{"title": "Nauczyć się Flaska"}'

W odpowiedzi dostaniesz zadanie z done ustawionym na false.

Jak zwrócić listę jako JSON?

W aktualnych wersjach Flaska możesz zwrócić zarówno słownik, jak i listę, a framework zamieni je na JSON. Starsze poradniki używają jsonify(...), które nadal działa i bywa potrzebne, gdy chcesz zbudować odpowiedź w kilku krokach, ale nie jest już konieczne do prostego zwracania danych.

Jak wyświetlić dane w szablonie HTML?

Flask ma wbudowany silnik szablonów Jinja2. Utwórz katalog templates i plik templates/tasks.html:

<h1>Zadania</h1>
<ul>
  {% for task in tasks %}
    <li>{{ task.title }}{% if task.done %} (zrobione){% endif %}</li>
  {% else %}
    <li>Brak zadań</li>
  {% endfor %}
</ul>

Następnie dodaj widok, który przekazuje zmienną do szablonu:

from flask import render_template


@app.get("/lista")
def task_list():
    return render_template("tasks.html", tasks=tasks.values())

Zmienne przekazujesz jako argumenty render_template, a w szablonie używasz ich w podwójnych nawiasach klamrowych. Jinja2 domyślnie zamienia znaki specjalne na bezpieczne odpowiedniki, więc tytuł zadania <b> zostanie wyświetlony jako tekst, a nie wykonany jako HTML. To chroni przed atakami typu XSS.

Jak obsługiwać błędy we Flasku?

Domyślnie Flask zwraca błędy jako strony HTML. W API wolisz JSON. Jeden handler dla wszystkich błędów HTTP wystarczy:

from werkzeug.exceptions import HTTPException


@app.errorhandler(HTTPException)
def handle_http_error(error):
    return {"error": error.name, "message": error.description}, error.code

Teraz abort(404, description="Nie ma takiego zadania") zwraca {"error": "Not Found", "message": "Nie ma takiego zadania"} ze statusem 404, a brakujące pole title kończy się statusem 400 z odpowiednim komunikatem. Ten sam handler obsłuży także nieistniejące adresy.

Jakie błędy najczęściej pojawiają się na początku?

Co oznacza „The view function did not return a valid response”?

Funkcja widoku nic nie zwróciła. W Pythonie funkcja bez return zwraca None, a Flask oczekuje odpowiedzi. Najczęściej zdarza się to, gdy return znajduje się tylko wewnątrz if, a w pozostałych przypadkach kod „spada” na koniec funkcji. Sprawdź, czy każda ścieżka kodu zwraca dane lub wywołuje abort.

Co oznacza „Working outside of application context”?

Próbujesz użyć czegoś, co potrzebuje aplikacji (na przykład current_app albo rozszerzenia do bazy danych), poza obsługą zapytania, np. w osobnym skrypcie. Rozwiązaniem jest jawne otwarcie kontekstu:

with app.app_context():
    print(current_app.name)

Jak włączyć CORS, gdy frontend działa na innym adresie?

Jeśli aplikacja frontendowa (na przykład na localhost:3000) wysyła zapytania do Twojego API, przeglądarka je zablokuje, dopóki serwer nie zwróci odpowiednich nagłówków. Najprościej użyć biblioteki flask-cors:

pip install flask-cors
from flask_cors import CORS

CORS(app, origins=["http://localhost:3000"])

Wskazuj konkretne adresy zamiast zezwalać wszystkim, bo otwarte API bez ograniczeń to zbędne ryzyko.

Jak uruchomić Flaska poza komputerem programisty?

Serwer z flask run jest przeznaczony do pracy lokalnej. Na serwerze używa się serwera WSGI, na przykład Gunicorna:

pip install gunicorn
gunicorn app:app --workers 1 --threads 40

Liczba wątków ma znaczenie. Zmierzyliśmy to prostym testem, w którym widok odpowiada po 2 sekundach (jeden proces, laptop):

Konfiguracja20 zapytań200 zapytań
Gunicorn, jeden zwykły worker40,1 snie dokończył się w minutę
Gunicorn, jeden worker, 40 wątków2,0 s10,1 s

Zwykły worker obsługuje zapytania po kolei, więc 20 zapytań po 2 sekundy dało 40 sekund. Wątki rozwiązują problem do pewnej granicy: z 40 wątkami 200 zapytań zajęło 10 sekund. Wyniki z Twojego komputera będą inne, ale proporcje powinny być podobne. Porównanie z Django i FastAPI znajdziesz w osobnym artykule.

Kiedy wybrać Flaska?

Flask jest dobrym wyborem, gdy:

  • uczysz się, jak działa aplikacja webowa, i chcesz widzieć wszystkie elementy,
  • budujesz małą aplikację lub proste API,
  • potrzebujesz pełnej swobody w doborze bibliotek.

Rozważ Django, gdy potrzebujesz panelu administracyjnego, logowania i bazy danych od razu, a FastAPI, gdy budujesz API z automatyczną walidacją i dokumentacją.

Jakie błędy mentor poprawia najczęściej?

Uwaga mentora: najczęstszy błąd po pierwszych tygodniach z Flaskiem to uruchamianie aplikacji na serwerze poleceniem flask run z włączonym trybem debug. Tryb debug pokazuje w przeglądarce kod i pozwala wykonywać polecenia, więc nigdy nie wolno go włączać na publicznym adresie.

Druga uwaga: zacznij od jednego pliku app.py. Podział na moduły i blueprinty ma sens dopiero wtedy, gdy plik robi się trudny do czytania, a nie na starcie projektu.

Co dalej?

Masz aplikację z trasami, JSON-em, szablonem, obsługą błędów i CORS. Dalej warto połączyć ją z prawdziwą bazą danych (na przykład przez SQLAlchemy) i dodać testy. Jeśli chcesz uczyć się backendu w Pythonie z mentorem, który ocenia Twój kod, sprawdź kurs Python.

Konsultacja i warsztaty devmentor.pl

Masz pytania?