Building Flask Web Apps: Advanced Features

Avatar

By squashlabs, Last Updated: Sept. 17, 2023

Building Flask Web Apps: Advanced Features

Flask Routing

Flask routing allows you to map URLs to specific functions in your Flask application. This is achieved using the @app.route() decorator, which is used to define routes in Flask.

Here's an example that demonstrates how to define a basic route in Flask:

from flask import Flask

app = Flask(__name__)

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

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

In this example, we import the Flask class from the flask module and create a new instance of the Flask class. We then use the @app.route() decorator to define a route for the root URL ("/"). The home() function is associated with this route and will be executed when the root URL is accessed. The function returns the string "Hello, World!", which will be displayed in the browser.

You can also pass variables through the URL using route parameters. Here's an example:

from flask import Flask

app = Flask(__name__)

@app.route('/user/')
def user_profile(username):
    return f'Hello, {username}!'

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

In this example, we define a route with a parameter . The value of this parameter will be passed as an argument to the user_profile() function. When the URL /user/john is accessed, the function will be called with the argument username='john', and it will return the string "Hello, john!".

Flask routing is a useful feature that allows you to create dynamic and interactive web applications. By defining routes, you can map different URLs to different functions and provide customized responses based on user input.

Related Article: How to Implement a Python Foreach Equivalent

Flask Templates

Flask templates are used to render dynamic content in Flask applications. Templates provide a way to separate the presentation logic from the application logic, making it easier to manage and update the user interface.

To use templates in Flask, you need to create a templates directory in your project and store your HTML templates in this directory. Here's an example of a simple Flask application that uses a template:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html', title='Home', message='Welcome to my Flask application!')

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

In this example, we import the render_template function from the flask module. The render_template function takes the name of the template file as its first argument and any additional keyword arguments that you want to pass to the template. In this case, we pass the title and message variables to the index.html template.

Here's an example of an index.html template:



    <title>{{ title }}</title>


    <h1>{{ message }}</h1>


In this template, we use the double curly braces ({{ }}) to indicate placeholders for variables. The values of these variables will be substituted when the template is rendered. In this case, the title and message variables will be replaced with the values passed from the Flask application.

Flask templates support a wide range of features, including template inheritance, conditionals, loops, and filters. They provide a flexible and useful way to generate dynamic HTML content in Flask applications.

Flask Forms

Flask forms allow you to handle user input in a structured and secure way. By using Flask forms, you can easily validate user input, generate HTML forms with CSRF protection, and handle form submissions.

To use Flask forms, you need to install the Flask-WTF extension. You can install it using pip:

pip install Flask-WTF

Once you have installed Flask-WTF, you can create a form class that inherits from the FlaskForm class. Here's an example:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

class MyForm(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def home():
    form = MyForm()
    if form.validate_on_submit():
        name = form.name.data
        return f'Hello, {name}!'
    return render_template('index.html', form=form)

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

In this example, we import the necessary modules and create a form class MyForm that inherits from FlaskForm. We define two form fields: a StringField for the name and a SubmitField for the submit button.

In the home() function, we create an instance of the form class and pass it to the template. When the form is submitted, we validate the input using the validate_on_submit() method. If the form is valid, we retrieve the value of the name field using form.name.data and return a personalized greeting. If the form is not valid or has not been submitted, we render the template with the form.

Flask forms provide a convenient way to handle user input and ensure that it meets your application's requirements. They help prevent common security vulnerabilities, such as cross-site request forgery (CSRF) attacks, and make it easier to work with user-submitted data.

Flask Extensions

Flask extensions are third-party packages that provide additional functionality to your Flask applications. These extensions cover a wide range of features, including database integration, authentication, API development, and more.

To use a Flask extension, you need to install it using pip and then import and initialize it in your Flask application. Here are a few popular Flask extensions:

- Flask-Login: provides user authentication and session management.

- Flask-SQLAlchemy: integrates SQLAlchemy, a useful and flexible ORM, with Flask.

- Flask-RESTful: simplifies the development of RESTful APIs in Flask.

- Flask-JWT: provides JSON Web Token (JWT) authentication for Flask applications.

- Flask-WTF: adds support for web forms and CSRF protection to Flask.

To demonstrate how to use a Flask extension, let's take a look at Flask-SQLAlchemy. First, install the extension using pip:

pip install Flask-SQLAlchemy

Next, import and initialize Flask-SQLAlchemy in your Flask application:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

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

# Define your database models here

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

In this example, we import the Flask class and the SQLAlchemy class from the respective modules. We create a new instance of the Flask class and configure the database URI for SQLAlchemy. Finally, we create an instance of the SQLAlchemy class and pass the Flask application to it.

With Flask-SQLAlchemy initialized, you can define your database models using SQLAlchemy's declarative syntax. For example, here's how you can define a simple User model:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

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)

    def __repr__(self):
        return f''

In this example, we import the SQLAlchemy class and create a new instance of it. We then define a User model with three columns: id, username, and email. The __repr__() method is used to provide a string representation of the model object.

Flask extensions are a great way to extend the functionality of your Flask applications without reinventing the wheel. They provide ready-to-use solutions for common tasks and allow you to focus on the core logic of your application.

Related Article: How to Run External Programs in Python 3 with Subprocess

Flask Decorators

Flask decorators are a useful feature that allows you to modify the behavior of functions or methods in your Flask application. Decorators are functions that wrap other functions and can be used to add additional functionality, such as authentication, logging, or error handling, to your Flask views.

Here's an example that demonstrates how to define a custom decorator in Flask:

from functools import wraps
from flask import Flask, request

app = Flask(__name__)

def log_request(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        app.logger.info(f'Request: {request.method} {request.url}')
        return func(*args, **kwargs)
    return wrapper

@app.route('/')
@log_request
def home():
    return 'Hello, World!'

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

In this example, we import the wraps function from the functools module and the Flask and request objects from the respective modules. We define a custom decorator log_request that logs the details of each request before executing the wrapped function. The @wraps(func) decorator is used to preserve the metadata of the original function.

We then apply the log_request decorator to the home() function using the @ syntax. This means that the log_request decorator will be executed before the home() function is called. The decorator logs the details of the request and then calls the original function.

Flask decorators are a useful tool for adding reusable and modular functionality to your Flask views. They allow you to separate concerns and keep your code clean and organized.

Flask Middleware

Flask middleware is a way to add additional functionality to the request/response cycle of your Flask application. Middleware functions are executed before and after each request and can be used to perform tasks such as authentication, logging, error handling, or modifying the request or response.

To use middleware in Flask, you need to define a function that takes two arguments: the Flask application object and the Flask request object. This function should return the modified request object or None, depending on whether the request should be processed further or not.

Here's an example that demonstrates how to define a simple middleware function in Flask:

from flask import Flask, request

app = Flask(__name__)

@app.before_request
def log_request():
    app.logger.info(f'Request: {request.method} {request.url}')

@app.after_request
def add_custom_header(response):
    response.headers['X-Custom-Header'] = 'Hello, World!'
    return response

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

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

In this example, we define two middleware functions: log_request() and add_custom_header(). The @app.before_request decorator is used to register the log_request() function as a middleware function that will be executed before each request. The @app.after_request decorator is used to register the add_custom_header() function as a middleware function that will be executed after each request.

The log_request() function logs the details of each request, and the add_custom_header() function adds a custom header to the response.

Middleware functions can be used to perform a wide range of tasks, such as authentication, CSRF protection, caching, or modifying the response. They provide a flexible and useful way to extend the functionality of your Flask application.

Flask SQLAlchemy

Flask SQLAlchemy is a Flask extension that provides integration with SQLAlchemy, a popular Object-Relational Mapping (ORM) library. SQLAlchemy allows you to interact with databases using Python classes and objects, making it easier to manage and query data.

To use Flask SQLAlchemy, you need to install it using pip:

pip install Flask-SQLAlchemy

Once you have installed Flask SQLAlchemy, you can use it to define your database models and perform database operations. Here's an example that demonstrates how to use Flask SQLAlchemy:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

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

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)

    def __repr__(self):
        return f''

@app.route('/')
def home():
    # Create a new user
    user = User(username='john', email='john@example.com')
    db.session.add(user)
    db.session.commit()

    # Retrieve all users
    users = User.query.all()

    # Update a user
    user = User.query.filter_by(username='john').first()
    user.email = 'newemail@example.com'
    db.session.commit()

    # Delete a user
    user = User.query.filter_by(username='john').first()
    db.session.delete(user)
    db.session.commit()

    return 'Hello, World!'

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

In this example, we import the necessary modules and create a Flask application and a SQLAlchemy instance. We define a User model using SQLAlchemy's declarative syntax. This model represents a table in the database and has three columns: id, username, and email.

In the home() function, we perform various database operations using SQLAlchemy. We create a new user, retrieve all users, update a user, and delete a user. SQLAlchemy provides a rich set of methods and query expressions that make it easy to perform complex database operations.

Flask SQLAlchemy simplifies the integration of SQLAlchemy with Flask and provides a convenient way to work with databases in Flask applications. It allows you to focus on the application logic and abstracts away the complexities of database management.

Flask RESTful

Flask RESTful is an extension for Flask that simplifies the development of RESTful APIs. RESTful APIs are a popular way to build web services that follow the principles of Representational State Transfer (REST).

To use Flask RESTful, you need to install it using pip:

pip install Flask-RESTful

Once you have installed Flask RESTful, you can use it to define resources and endpoints for your API. Here's an example that demonstrates how to use Flask RESTful:

from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class HelloWorld(Resource):
    def get(self):
        return {'message': 'Hello, World!'}

api.add_resource(HelloWorld, '/')

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

In this example, we import the necessary modules and create a Flask application and a RESTful API instance. We define a HelloWorld resource that inherits from the Resource class provided by Flask RESTful.

The HelloWorld resource defines a get() method that will be called when a GET request is made to the root URL ("/"). This method returns a dictionary with a single key-value pair containing the message "Hello, World!". Flask RESTful automatically converts this dictionary to JSON and sends it as the response.

Flask RESTful provides a clean and intuitive way to define resources and endpoints for your API. It handles request parsing, content negotiation, and response formatting, allowing you to focus on the business logic of your API.

Related Article: How To Check If Key Exists In Python Dictionary

Flask JWT

Flask JWT is a Flask extension that provides JSON Web Token (JWT) authentication for Flask applications. JWT is an open standard that defines a compact and self-contained way of securely transmitting information between parties as a JSON object.

To use Flask JWT, you need to install it using pip:

pip install Flask-JWT

Once you have installed Flask JWT, you can use it to secure your Flask routes and protect them from unauthorized access. Here's an example that demonstrates how to use Flask JWT:

from flask import Flask, jsonify
from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

class User:
    def __init__(self, id, username, password):
        self.id = id
        self.username = username
        self.password = password

    def __str__(self):
        return f'User(id={self.id}, username={self.username})'

users = [
    User(1, 'john', 'password'),
    User(2, 'jane', 'password')
]

def authenticate(username, password):
    for user in users:
        if user.username == username and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
            return user

def identity(payload):
    user_id = payload['identity']
    for user in users:
        if user.id == user_id:
            return user

jwt = JWT(app, authenticate, identity)

@app.route('/protected')
@jwt_required()
def protected():
    return jsonify(id=current_identity.id, username=current_identity.username)

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

In this example, we import the necessary modules and create a Flask application. We define a User class that represents a user in our application. We also define a list of users for simplicity, but in a real-world application, you would typically use a database.

We define an authenticate() function that takes a username and password and returns the corresponding user object if the credentials are valid. We also define an identity() function that takes a payload (decoded JWT) and returns the corresponding user object.

We create a JWT instance and pass the Flask application object and the authenticate() and identity() functions to it. This sets up JWT authentication for our application.

We define a protected route /protected and use the @jwt_required() decorator to protect it. This decorator ensures that the route can only be accessed with a valid JWT.

When a request is made to the /protected route with a valid JWT, the protected() function is called. This function returns a JSON response with the current user's ID and username.

Flask JWT provides a secure and convenient way to implement JWT authentication in Flask applications. It handles token generation, token validation, and user authentication, allowing you to focus on the core functionality of your application.

Flask Login

Flask Login is a Flask extension that provides user authentication and session management for Flask applications. It simplifies the process of handling user logins, logouts, and user sessions.

To use Flask Login, you need to install it using pip:

pip install Flask-Login

Once you have installed Flask Login, you can use it to manage user authentication and sessions in your Flask application. Here's an example that demonstrates how to use Flask Login:

from flask import Flask, render_template, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

login_manager = LoginManager()
login_manager.init_app(app)

class User(UserMixin):
    def __init__(self, id):
        self.id = id

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

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

@app.route('/login')
def login():
    user = User(1)
    login_user(user)
    return redirect(url_for('home'))

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

@app.route('/protected')
@login_required
def protected():
    return 'Protected route'

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

In this example, we import the necessary modules and create a Flask application. We configure the application with a secret key, which is used to encrypt the user session.

We create a User class that inherits from the UserMixin class provided by Flask Login. This class represents a user in our application and only requires an id attribute.

We create a login_manager instance and initialize it with the Flask application. This sets up Flask Login for our application.

We define a load_user() function that takes a user ID and returns the corresponding user object. This function is used by Flask Login to load the user from the user ID stored in the session.

We define three routes: a home route ("/"), a login route ("/login"), and a logout route ("/logout"). The home route does not require authentication. The login route logs in a user and redirects to the home route. The logout route logs out the user and redirects to the home route.

We define a protected route ("/protected") that requires authentication using the @login_required decorator. This decorator ensures that the route can only be accessed by authenticated users.

Flask Login provides a clean and intuitive way to handle user authentication and session management in Flask applications. It abstracts away the complexities of user authentication and allows you to focus on the core functionality of your application.

Additional Resources



- Flask Routing

- Flask Templates

- Flask Extensions

More Articles from the Python Tutorial: From Basics to Advanced Concepts series:

How to Use and Import Python Modules

Python modules are a fundamental aspect of code organization and reusability in Python programming. In this tutorial, you will learn how to use and i… read more

How to Handle Cookies and Cookie Outputs in Python

This guide provides a comprehensive overview of using Python to manipulate and manage HTTP cookies. With chapters covering web scraping, session mana… read more

Python Super Keyword Tutorial

Python's super keyword is a powerful tool that can enhance code functionality. In this tutorial, you will learn how to use the super method to improv… read more

How to Append to a Dict in Python

This article provides a guide on adding elements to a dictionary in Python. It covers an overview of Python dictionaries, key-value pairs, exploring … read more

Django 4 Best Practices: Leveraging Asynchronous Handlers for Class-Based Views

Optimize Django 4 performance with asynchronous handlers for class-based views. Enhance scalability and efficiency in your development process by lev… read more

How To Rename A File With Python

Renaming files with Python is a simple task that can be accomplished using either the os or shutil module. This article provides a guide on how to re… read more

How to Flatten a List of Lists in Python

Learn how to flatten a list of lists in Python using two simple methods: nested list comprehensions and itertools.chain.from_iterable(). Discover the… read more

Optimizing FastAPI Applications: Modular Design, Logging, and Testing

Learn best practices in FastAPI for designing modular applications, logging, and testing. This article dives into the key aspects of optimizing FastA… read more

How to Use Assert in Python: Explained

The assert statement in Python is a powerful tool for validating the correctness of your code. This article explains its syntax and provides examples… read more

How to Use Slicing in Python And Extract a Portion of a List

Slicing operations in Python allow you to manipulate data efficiently. This article provides a simple guide on using slicing, covering the syntax, po… read more