Flask – mikroframework Python do aplikacji webowych

⏱ ~18 minut czytania 📊 Poziom: Początkujący/Średni 📅 Luty 2026

Flask to lekki i elastyczny mikroframework dla Pythona, który od ponad dekady pozostaje jednym z najpopularniejszych wyborów do budowy aplikacji webowych. Stworzony przez Armina Ronachera w 2010 roku, Flask łączy prostotę z potężnymi możliwościami rozszerzeń. W tym artykule poznasz fundamenty frameworka i zbudujesz swoją pierwszą aplikację webową.

🎯 Czego się nauczysz:

  • Instalacja i konfiguracja Flask
  • Podstawowe koncepcje: routing, widoki, szablony
  • Obsługa formularzy i danych
  • Praca z bazą danych (SQLAlchemy)
  • Sesje i ciasteczka
  • Autentykacja użytkowników
  • Struktura projektu i best practices
  • Deployment aplikacji

TL;DR — Szybkie podsumowanie

Aspekt Django Flask
Rozmiar ⚠️ Duży (batteries included) ✅ Minimalny (mikroframework)
Elastyczność ⚠️ Sztywna struktura ✅ Pełna swoboda
Admin panel ✅ Built-in ❌ Brak (trzeba dodać)
Nauka ⚠️ Więcej do przyswojenia ✅ Prostszy start
Użycie Duże aplikacje Małe/średnie projekty, API

🐍 Czym jest Flask?

Flask nazywany jest “mikroframeworkiem” nie dlatego, że brakuje mu funkcjonalności, ale dlatego, że jego rdzeń jest minimalistyczny. W przeciwieństwie do Django, Flask nie narzuca struktury projektu – daje Ci swobodę decydowania, jak zorganizować kod.

Kluczowe cechy

  • Lekki rdzeń – minimalistyczny kod źródłowy, szybkie uruchomienie
  • Elaboratory – bogaty ekosystem rozszerzeń: SQLAlchemy, Flask-Login, Flask-WTF
  • Prosty routing – intuicyjny system dekoratorów do mapowania URL-i
  • Jinja2 Templates – potężny silnik szablonów z dziedziczeniem i makrami

⚙️ Instalacja

Terminal
# Tworzenie wirtualnego środowiska
python -m venv venv

# Aktywacja (Windows)
venv\Scripts\activate

# Aktywacja (Linux/Mac)
source venv/bin/activate

# Instalacja Flask
pip install flask

# Instalacja z dodatkowymi pakietami
pip install flask flask-sqlalchemy flask-wtf flask-login

# Sprawdzenie wersji
python -c "import flask; print(flask.__version__)"

🚀 Pierwsza aplikacja

Najprostsza aplikacja Flask składa się z zaledwie kilku linii kodu:

app.py
from flask import Flask

# Inicjalizacja aplikacji
app = Flask(__name__)

# Definicja trasy
@app.route('/')
def hello():
    return 'Witaj, świecie!'

# Uruchomienie serwera
if __name__ == '__main__':
    app.run(debug=True)

Zapisz kod w pliku app.py i uruchom:

Terminal
python app.py

Aplikacja będzie dostępna pod adresem http://127.0.0.1:5000.

🗺️ Routing i zmienne

Flask pozwala definiować dynamiczne trasy z parametrami:

Routing
from flask import Flask, abort

app = Flask(__name__)

# Statyczna trasa
@app.route('/about')
def about():
    return 'O nas'

# Trasa z parametrem
@app.route('/user/<username>')
def show_user(username):
    return f'Profil użytkownika: {username}'

# Parametr z typem
@app.route('/post/<int:post_id>')
def show_post(post_id):
    return f'Post numer: {post_id}'

# Wiele metod HTTP
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return 'Logowanie...'
    else:
        return 'Formularz logowania'

🎨 Szablony Jinja2

Flask używa silnika szablonów Jinja2. Szablony umieszczamy w folderze templates:

myapp/ ├── app.py ├── templates/ │ ├── base.html │ └── index.html └── static/ ├── css/ └── js/

Szablon bazowy

templates/base.html
<!DOCTYPE html>
<html>
<head>
    <title>{% raw %}{{ title }}{% endraw %} - Moja Aplikacja</title>
    <link rel="stylesheet" href="{% raw %}{{ url_for('static', filename='css/style.css') }}{% endraw %}">
</head>
<body>
    <nav>
        <a href="{% raw %}{{ url_for('index') }}{% endraw %}">Strona główna</a>
        <a href="{% raw %}{{ url_for('about') }}{% endraw %}">O nas</a>
    </nav>
    
    {% raw %}{% block content %}{% endblock %}{% endraw %}
    
    <footer>
        <p>© 2026 Moja Aplikacja</p>
    </footer>
</body>
</html>

Szablon rozszerzający

templates/index.html
{% raw %}{% extends "base.html" %}{% endraw %}

{% raw %}{% block content %}{% endraw %}
    <h1>Witaj, {% raw %}{{ username }}{% endraw %}!</h1>
    
    {% raw %}{% if posts %}{% endraw %}
        <ul>
        {% raw %}{% for post in posts %}{% endraw %}
            <li>
                <h2>{% raw %}{{ post.title }}{% endraw %}</h2>
                <p>{% raw %}{{ post.content | truncate(100) }}{% endraw %}</p>
            </li>
        {% raw %}{% endfor %}{% endraw %}
        </ul>
    {% raw %}{% else %}{% endraw %}
        <p>Brak postów do wyświetlenia.</p>
    {% raw %}{% endif %}{% endraw %}
{% raw %}{% endblock %}{% endraw %}

Renderowanie szablonu

app.py
from flask import render_template

@app.route('/')
def index():
    posts = [
        {'title': 'Pierwszy post', 'content': 'Treść pierwszego posta...'},
        {'title': 'Drugi post', 'content': 'Treść drugiego posta...'}
    ]
    return render_template('index.html', 
                         title='Strona główna', 
                         username='Jan', 
                         posts=posts)

📝 Formularze i walidacja

Do obsługi formularzy najlepiej użyć rozszerzenia Flask-WTF:

Terminal
pip install flask-wtf
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length

class LoginForm(FlaskForm):
    email = StringField('Email', validators=[
        DataRequired(),
        Email()
    ])
    password = PasswordField('Hasło', validators=[
        DataRequired(),
        Length(min=6, message='Hasło musi mieć min. 6 znaków')
    ])
    submit = SubmitField('Zaloguj się')
app.py
from flask import Flask, render_template, redirect, flash
from forms import LoginForm

app = Flask(__name__)
app.config['SECRET_KEY'] = 'twoj-tajny-klucz'

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    
    if form.validate_on_submit():
        flash(f'Zalogowano jako {form.email.data}', 'success')
        return redirect('/')
    
    return render_template('login.html', form=form)

💾 Baza danych z SQLAlchemy

Terminal
pip install flask-sqlalchemy
app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Definicja modelu
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    created_at = db.Column(db.DateTime, server_default=db.func.now())
    
    def __repr__(self):
        return f'<User {self.username}>'

# Tworzenie tabel
with app.app_context():
    db.create_all()

# CRUD operations
@app.route('/users')
def get_users():
    users = User.query.all()
    return {'users': [{'id': u.id, 'username': u.username} for u in users]}

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    user = User(username=data['username'], email=data['email'])
    db.session.add(user)
    db.session.commit()
    return {'message': 'Użytkownik utworzony', 'id': user.id}, 201

🔐 Autentykacja z Flask-Login

Terminal
pip install flask-login
app.py
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)
    password_hash = db.Column(db.String(128))
    
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

@app.route('/login', methods=['POST'])
def login():
    user = User.query.filter_by(username=request.form['username']).first()
    
    if user and user.check_password(request.form['password']):
        login_user(user, remember=True)
        return redirect(url_for('dashboard'))
    
    flash('Nieprawidłowe dane logowania')
    return redirect(url_for('login'))

@app.route('/dashboard')
@login_required
def dashboard():
    return f'Witaj, {current_user.username}!'

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('index'))

📁 Struktura projektu

Dla większych aplikacji zalecana jest struktura typu “application factory”:

myproject/ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── routes/ │ │ ├── __init__.py │ │ ├── auth.py │ │ └── main.py │ ├── templates/ │ └── static/ ├── config.py ├── requirements.txt └── run.py
app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

db = SQLAlchemy()
login_manager = LoginManager()

def create_app(config_name='default'):
    app = Flask(__name__)
    app.config.from_object(f'config.{config_name}Config')
    
    # Inicjalizacja rozszerzeń
    db.init_app(app)
    login_manager.init_app(app)
    
    # Rejestracja blueprintów
    from .routes.main import main_bp
    from .routes.auth import auth_bp
    
    app.register_blueprint(main_bp)
    app.register_blueprint(auth_bp, url_prefix='/auth')
    
    return app

🚀 Deployment

Do produkcji użyj WSGI servera, np. Gunicorn:

Terminal
# Instalacja
pip install gunicorn

# Uruchomienie
gunicorn -w 4 -b 0.0.0.0:8000 "app:create_app()"

# Z plikiem konfiguracyjnym
gunicorn -c gunicorn.conf.py "app:create_app()"
gunicorn.conf.py
bind = "0.0.0.0:8000"
workers = 4
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
errorlog = "-"
accesslog = "-"
loglevel = "info"
⚠️ Ważne: Nigdy nie używaj debug=True w produkcji! Tryb debug ujawnia poufne informacje i pozwala na zdalne wykonywanie kodu.

📊 Podsumowanie

Funkcja Kod Opis
Routing @app.route(‘/path’) Mapowanie URL na funkcję
Szablony render_template() Renderowanie HTML z Jinja2
Formularze FlaskForm Walidacja i obsługa formularzy
Baza danych SQLAlchemy ORM do pracy z bazą
Sesje session[‘key’] Przechowywanie danych użytkownika
Autentykacja Flask-Login Zarządzanie logowaniem
Blueprints Blueprint() Organizacja kodu w moduły

Kiedy używać Flask?

✅ Idealne dla:

  • Małych i średnich projektów
  • API REST
  • Mikroserwisów
  • Szybkich prototypów
  • Projektów wymagających elastyczności
  • Nauki web developmentu

❌ Rozważ alternatywę gdy:

  • Potrzebujesz wbudowanego admina (→ Django)
  • Duży projekt z wieloma modułami
  • Wymagasz ORM z migracjami out-of-the-box
  • Chcesz mniej decyzji architektonicznych
  • Projekt enterprise z rigidnymi wymaganiami
Wniosek: Flask to doskonały wybór dla developerów ceniących prostotę i elastyczność. Dzięki bogatemu ekosystemowi rozszerzeń możesz budować aplikacje dowolnej wielkości – od prostych API po rozbudowane platformy webowe.

📚 Bibliografia

  1. Pallets Projects. (2026). Flask Documentation. flask.palletsprojects.com
  2. Pallets Projects. (2026). Flask GitHub Repository. github.com/pallets/flask
  3. Pallets Projects. (2026). Jinja2 Documentation. jinja.palletsprojects.com
  4. Flask-SQLAlchemy. (2026). Flask-SQLAlchemy Documentation. flask-sqlalchemy.palletsprojects.com
  5. Flask-Login. (2026). Flask-Login Documentation. flask-login.readthedocs.io