How to use Flask for web development?

онлайн тренажер по питону
Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

What is Flask and Why Choose It?

Flask is a Python microframework for web development that has gained popularity due to its simplicity and flexibility. Python web development is becoming increasingly in demand, and Flask plays a key role in this as a lightweight but powerful tool.

The main advantage of Flask lies in its minimalism and extensibility. The framework does not impose a rigid architecture and allows developers to use only the necessary components. This makes Flask an ideal choice for creating both small websites and complex web applications.

Benefits of Flask for Web Development

Flask provides developers with numerous advantages:

  • Ease of learning and a low entry barrier for beginners.
  • Flexibility in choosing architectural solutions and components.
  • Active community and a rich ecosystem of extensions.
  • Ability to create both prototypes and production-ready applications.
  • Full control over the project structure.

Popular Flask extensions include Flask-WTF for working with forms, Flask-Login for authorization, Flask-Migrate for database migrations, and many others.

Installation and First Flask Application

Installing Flask

To get started with Flask, you need to install it via pip:

pip install Flask

Creating a Basic Application

The simplest Flask application might look like this:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, world!"

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

This code creates a web server that responds to GET requests to the root route. The debug=True parameter enables debug mode, which automatically reloads the application when the code is changed.

Flask Project Structure

Proper organization of the project structure is critical for maintaining and developing a web application. A well-structured project facilitates teamwork, testing, and scaling.

Recommended Directory Structure

my_flask_app/
├── app/
│   ├── __init__.py
│   ├── routes.py
│   ├── models.py
│   ├── forms.py
│   └── templates/
│       └── index.html
│   └── static/
├── config.py
└── run.py

Purpose of Files and Folders

  • __init__.py - application initialization file, contains the creation of the Flask instance.
  • routes.py - defines routes and request handlers.
  • models.py - contains data models for working with the database.
  • forms.py - describes forms using Flask-WTF.
  • templates/ - stores HTML templates for displaying pages.
  • static/ - contains static files (CSS, JavaScript, images).
  • config.py - application configuration file with settings.
  • run.py - entry point for running the application.

Application Initialization

In the app/__init__.py file, the creation and configuration of the Flask application usually take place:

from flask import Flask
from config import Config

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    from app.routes import bp
    app.register_blueprint(bp)
    
    return app

Working with Forms in Flask

Handling user input through forms is one of the main tasks of web development. Flask provides several ways to work with forms, but the most convenient and secure is to use the Flask-WTF extension.

Installing Flask-WTF

pip install flask-wtf

Creating Forms with Flask-WTF

Flask-WTF integrates WTForms with Flask and adds additional security features. Example of creating a login form:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6)])
    remember_me = BooleanField('Remember me')
    submit = SubmitField('Login')

Form Handling in Controllers

The controller handles both GET requests to display the form and POST requests to process data:

from flask import render_template, request, redirect, url_for, flash
from app.forms import LoginForm

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        
        # Here should be the user authentication logic
        if authenticate_user(username, password):
            flash(f'Welcome, {username}!', 'success')
            return redirect(url_for('dashboard'))
        else:
            flash('Incorrect username or password', 'error')
    
    return render_template('login.html', form=form)

Form Data Validation

Flask-WTF provides many built-in validators:

  • DataRequired() - the field is required to be filled.
  • Length(min, max) - string length check.
  • Email() - email address validation.
  • NumberRange(min, max) - numeric range check.
  • Regexp(regex) - regular expression check.

Working with Sessions in Flask

Sessions allow you to store information about the user between HTTP requests. Flask uses signed cookies to securely store session data on the client-side.

Session Configuration

To work with sessions, you need to set a secret key:

app.secret_key = 'your-secret-key-here'
# Or it is better to use an environment variable
import os
app.secret_key = os.environ.get('SECRET_KEY') or 'fallback-secret-key'

Basic Session Operations

from flask import session

@app.route('/set_session')
def set_session():
    session['username'] = 'admin'
    session['user_id'] = 123
    session.permanent = True  # The session will be permanent
    return 'Session data set!'

@app.route('/get_session')
def get_session():
    username = session.get('username', 'Guest')
    user_id = session.get('user_id')
    return f'User: {username}, ID: {user_id}'

@app.route('/clear_session')
def clear_session():
    session.pop('username', None)
    session.pop('user_id', None)
    # Or clear the entire session
    session.clear()
    return 'Session cleared!'

Setting Session Lifetime

from datetime import timedelta

app.permanent_session_lifetime = timedelta(minutes=30)

@app.route('/login')
def login():
    session.permanent = True
    session['username'] = 'user'
    return 'Login performed with a permanent session'

Session Security

Important security aspects when working with sessions:

  • Use a cryptographically strong secret key.
  • Do not store sensitive data in sessions.
  • Regularly update sessions to prevent attacks.
  • Clear sessions when the user logs out.

Working with Cookies in Flask

Cookies are small pieces of data that the web server sends to the user's browser. The browser saves them and sends them back to the server in subsequent requests.

Setting Cookies

from flask import make_response, request

@app.route('/set_cookie')
def set_cookie():
    resp = make_response('Cookie set!')
    resp.set_cookie('username', 'flask_user')
    return resp

@app.route('/set_secure_cookie')
def set_secure_cookie():
    resp = make_response('Secure cookie set!')
    resp.set_cookie('secure_data', 'secret_value', 
                   max_age=3600,  # Lifetime in seconds
                   secure=True,   # Only over HTTPS
                   httponly=True,  # Not available to JavaScript
                   samesite='Strict')  # CSRF protection
    return resp

Getting Cookies

@app.route('/get_cookie')
def get_cookie():
    username = request.cookies.get('username')
    if username:
        return f'Cookie username: {username}'
    else:
        return 'Cookie not found'

@app.route('/get_all_cookies')
def get_all_cookies():
    cookies = request.cookies
    return f'All cookies: {dict(cookies)}'

Deleting Cookies

@app.route('/delete_cookie')
def delete_cookie():
    resp = make_response('Cookie deleted!')
    resp.delete_cookie('username')
    return resp

Cookie Settings

When setting a cookie, you can set various parameters:

  • max_age - cookie lifetime in seconds.
  • expires - cookie expiration date.
  • domain - domain for which the cookie is valid.
  • path - path on the server for which the cookie is valid.
  • secure - transmit the cookie only over HTTPS.
  • httponly - the cookie is not available to JavaScript.
  • samesite - protection against CSRF attacks.

Full Project Example

Let's consider a comprehensive example demonstrating working with forms, sessions, and cookies in one application:

from flask import Flask, render_template, request, redirect, url_for, session, make_response, flash
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired
from datetime import timedelta

app = Flask(__name__)
app.secret_key = 'supersecretkey'
app.permanent_session_lifetime = timedelta(minutes=30)

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')

@app.route('/', methods=['GET', 'POST'])
def home():
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        
        # Simple check (use hashing in a real project)
        if username == 'admin' and password == 'secret':
            session.permanent = True
            session['username'] = username
            session['logged_in'] = True
            
            resp = make_response(redirect(url_for('profile')))
            resp.set_cookie('last_user', username, max_age=3600)
            
            flash('Login successful!', 'success')
            return resp
        else:
            flash('Incorrect username or password', 'error')
    
    return render_template('login.html', form=form)

@app.route('/profile')
def profile():
    if not session.get('logged_in'):
        flash('You must be logged in', 'error')
        return redirect(url_for('home'))
    
    username = session.get('username', 'Guest')
    last_user = request.cookies.get('last_user', 'Unknown')
    
    return render_template('profile.html', username=username, last_user=last_user)

@app.route('/logout')
def logout():
    session.clear()
    resp = make_response(redirect(url_for('home')))
    resp.delete_cookie('last_user')
    flash('You have logged out', 'info')
    return resp

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

Templates for the Example

login.html template

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    
    {% with messages = get_flashed_messages(with_categories=true) %}
        {% if messages %}
            {% for category, message in messages %}
                <div class="alert alert-{{ category }}">{{ message }}</div>
            {% endfor %}
        {% endif %}
    {% endwith %}
    
    <form method="POST">
        {{ form.hidden_tag() }}
        <div>
            {{ form.username.label }}
            {{ form.username(size=32) }}
            {% if form.username.errors %}
                <span style="color: red;">{{ form.username.errors[0] }}</span>
            {% endif %}
        </div>
        <div>
            {{ form.password.label }}
            {{ form.password(size=32) }}
            {% if form.password.errors %}
                <span style="color: red;">{{ form.password.errors[0] }}</span>
            {% endif %}
        </div>
        <div>
            {{ form.submit() }}
        </div>
    </form>
</body>
</html>

profile.html template

<!DOCTYPE html>
<html>
<head>
    <title>User Profile</title>
</head>
<body>
    <h1>Welcome, {{ username }}!</h1>
    <p>Last login: {{ last_user }}</p>
    <a href="{{ url_for('logout') }}">Logout</a>
</body>
</html>

Frequently Asked Questions

What is the difference between Flask and Django?

Flask and Django represent different approaches to web development:

Flask is suitable for:

  • Rapid prototyping
  • Small and medium-sized projects
  • APIs and microservices
  • Cases where full control over the architecture is needed

Django is better to choose for:

  • Large projects with an administrative panel
  • Applications with complex business logic
  • Projects where fast development with ready-made solutions is needed

How to ensure form security?

Flask-WTF automatically protects forms from CSRF attacks by adding special tokens. For additional security:

  • Use WTForms validators.
  • Sanitize user input.
  • Use HTTPS to transmit sensitive data.
  • Implement proper authentication and authorization.

How to limit the session lifetime?

from datetime import timedelta

app.permanent_session_lifetime = timedelta(minutes=30)

@app.route('/login')
def login():
    session.permanent = True
    session['username'] = 'user'
    return 'Session is active for 30 minutes'

Is it possible to store objects in sessions?

Flask sessions can only store serializable data (strings, numbers, lists, dictionaries). Complex objects need to be serialized to JSON or use other storage methods.

How to work with Jinja2 templates?

Jinja2 is built into Flask. Create HTML files in the templates/ folder and use render_template():

@app.route('/users/<username>')
def user_profile(username):
    user_data = {'name': username, 'email': f'{username}@example.com'}
    return render_template('user.html', user=user_data)

In the template, you can use variables and conditions:

<h1>Profile {{ user.name }}</h1>
{% if user.email %}
    <p>Email: {{ user.email }}</p>
{% endif %}

Best Practices for Flask Development

Code Organization

  • Use blueprints to organize routes.
  • Move the configuration to separate files.
  • Apply the factory pattern to create the application.
  • Separate the logic by modules.

Security

  • Never store secret keys in code.
  • Use environment variables for configuration.
  • Enable CSRF protection for all forms.
  • Use HTTPS in production.

Performance

  • Use caching for frequently requested data.
  • Optimize database queries.
  • Compress static files.
  • Set up proper logging.

Flask provides developers with powerful tools for creating web applications of any complexity. Thanks to the flexibility of the framework, you can start with a simple prototype and gradually develop it into a full-fledged production-ready application. Understanding how to work with forms, sessions, and cookies is essential for creating interactive and secure web applications.

News