Flask Web Development: From Basics to Deployment

The text offers a comprehensive guide to constructing and deploying Flask web applications. It begins with the essentials of setting up a virtual environment and creating a basic “Hello, World!” application using Flask. The guide then demonstrates advanced features such as URL handling, request methods, response customization, and Jinja templating, which dynamically generates HTML content. Furthermore, the text details incorporating static files and integrating frameworks such as Bootstrap. The text advances to explore user authentication and databases and further enhances application structure through the implementation of blueprints. The explanation culminates in directions for using Docker to containerize applications for deployment on remote servers.

Flask Framework Mastery: A Comprehensive Study Guide

I. Quiz: Short Answer Questions

Answer each question in 2-3 sentences.

  1. What is the primary reason for creating a virtual environment when developing Flask applications?
  2. Explain the purpose of the requirements.txt file in a Flask project.
  3. Describe how to activate a virtual environment in a command line interface (CLI) on Linux or macOS.
  4. In Flask, what is a “route” and how is it defined?
  5. What does the debug=True parameter do when running a Flask application and why should it be turned off in production?
  6. Explain the difference between URL processors and URL parameters in Flask.
  7. How can you access URL parameters within a Flask route function?
  8. How can you specifically handle POST requests in Flask, and why is this useful?
  9. Explain how to return a custom status code along with a response in Flask. Give an example of a use case for this.
  10. What is Jinja2 and how is it used to generate dynamic web pages?

Answer Key

  1. Virtual environments isolate project dependencies, ensuring specific package versions don’t conflict with other projects or the system’s global packages. This isolation creates reproducible deployments.
  2. The requirements.txt file lists all the packages and their versions required for a Flask project. It enables others to easily replicate the project’s environment by installing these dependencies.
  3. To activate a virtual environment on Linux or macOS, use the command source venv/bin/activate. This command sets the environment variables to use the virtual environment’s Python interpreter and packages.
  4. A route in Flask maps a URL endpoint to a specific function that handles requests to that endpoint. It is defined using the @app.route() decorator.
  5. When debug=True, Flask automatically reloads the server on code changes and displays detailed error messages. It should be turned off in production to prevent security vulnerabilities and improve performance.
  6. URL processors are dynamic parts of the URL path captured as function arguments, like /greet/<name>. URL parameters are key-value pairs appended to the URL after a question mark, like /login?username=user.
  7. URL parameters can be accessed using the request.args object. The code example uses request.args.get(‘parameter_name’) or directly accesses request.args[‘parameter_name’].
  8. POST requests are handled by specifying methods=[‘POST’] in the @app.route() decorator. This is useful for submitting form data or sending data to the server to create or update resources.
  9. A custom status code can be returned as a second value in a return statement. For instance, return “Created”, 201 returns a 201 Created status. This is useful for indicating the success or failure of an operation to the client.
  10. Jinja2 is a templating engine that enables developers to embed dynamic content within HTML templates. It is used to generate dynamic web pages by combining data from the Flask application with HTML markup.

II. Essay Questions

  1. Discuss the advantages of using a modular structure, such as blueprints, in large Flask applications.
  2. Compare and contrast sessions and cookies in Flask, detailing their purposes, implementation, and security implications.
  3. Outline the steps involved in building a user authentication system in Flask, including hashing passwords and managing user sessions.
  4. Describe how static files (CSS, JavaScript, images) are served in Flask and explain how to structure your project to effectively manage them.
  5. Explain the process of deploying a Flask application using Docker, highlighting the benefits of containerization for deployment.

III. Glossary of Key Terms

  • Flask: A micro web framework for Python, designed to be lightweight and flexible.
  • Virtual Environment: An isolated environment for Python projects, managing dependencies and package versions.
  • requirements.txt: A text file listing all the Python packages required for a project, used to recreate the environment.
  • Route: A URL endpoint in a Flask application, mapped to a specific function that handles requests.
  • Decorator: A Python feature used to modify or extend a function’s behavior, often using the @ symbol (e.g., @app.route).
  • URL Processor: A dynamic part of a URL that captures values as function arguments (e.g., <int:id>).
  • URL Parameter: A key-value pair appended to a URL after a question mark (e.g., ?key=value).
  • POST Request: An HTTP method used to send data to a server to create or update a resource.
  • Status Code: A three-digit code returned by a server indicating the result of a request (e.g., 200 OK, 404 Not Found).
  • Jinja2: A templating engine for Python, used to embed dynamic content within HTML templates.
  • Template: A file containing HTML markup and Jinja2 syntax, used to generate dynamic web pages.
  • Session: Server-side storage used to persist user-specific data across multiple requests, using a cookie to maintain state.
  • Cookie: A small piece of data stored on the client-side, used to remember information about the user or track their activity.
  • Blueprint: A modular component in Flask, used to organize and encapsulate a set of related views, templates, and static files.
  • Docker: A platform for developing, shipping, and running applications inside containers, providing isolation and portability.
  • Container: A standardized unit of software that packages up code and all its dependencies, enabling applications to run quickly and reliably from one computing environment to another.
  • Docker Image: A read-only template with instructions for creating a Docker container.
  • pip: The package installer for Python, used to install and manage packages from the Python Package Index (PyPI).
  • flask-login: A Flask extension that provides user session management for login/logout functionality
  • bcrypt: A password-hashing function designed to be computationally intensive to prevent reverse engineering by brute-force attacks.
  • flask-sqlalchemy: A Flask extension that simplifies using SQLAlchemy, a powerful ORM (Object-Relational Mapper) for working with databases.
  • flask-migrate: A Flask extension that uses Alembic to handle database schema migrations in your Flask application

Flask Application Development and Deployment Guide

Okay, here’s a detailed briefing document summarizing the key themes and ideas from the provided source.

Briefing Document: Flask Application Development & Deployment

Overview:

This document synthesizes information from a series of tutorials on developing and deploying Flask applications. The tutorials cover core concepts, best practices, and practical steps for building, containerizing, and deploying Flask applications to a server. The emphasis is on modularity, maintainability, and security.

Main Themes & Ideas:

  1. Virtual Environments:
  • Theme: Isolating project dependencies.
  • Details: Creating a virtual environment ensures a project uses only the necessary packages and versions. This prevents conflicts and simplifies deployment.
  • Quote: “The reason you want to create a virtual environment is because you want to have an isolated uh project where you only have the packages and also the package versions that are relevant to this particular project.”
  • Process:Navigate to project directory in the command line.
  • Create the environment: python -m venv venv (or python3 -m venv venv).
  • Activate the environment: source venv/bin/activate (Linux/Mac).
  • Configure IDE (e.g., PyCharm) to use the virtual environment’s Python interpreter.
  1. Basic Flask Application Structure:
  • Theme: Building a minimal “Hello, World!” application.
  • Details: Creating a simple Flask application to demonstrate the core components and workflow. This covers importing Flask, creating an app instance, defining routes, and running the application.
  • Process:Import Flask: from flask import Flask
  • Create app instance: app = Flask(__name__)
  • Define a route: @app.route(“/”)
  • Create a function to handle the route, returning HTML or text.
  • Run the app: if __name__ == “__main__”: app.run(host=”0.0.0.0″, debug=True)
  1. Routes & Request Handling:
  • Theme: Defining and managing different URL endpoints.
  • Details: This covers static routes, dynamic URLs (using URL processors), URL parameters, and handling different HTTP methods (GET, POST).
  • Dynamic URLs:Use angle brackets to define variables in the route: /greet/<name>.
  • The function handling the route takes the variable as a parameter: def greet(name):.
  • Type casting parameters (e.g., <int:number>) to enforce data types in URLs.
  • URL Parameters:Access URL parameters using request.args: request.args.get(‘name’).
  • Check for the existence of parameters using if ‘name’ in request.args.keys():.
  • HTTP Methods:Specify allowed methods in the route decorator: @app.route(‘/login’, methods=[‘GET’, ‘POST’]).
  • Use request.method to differentiate between GET and POST requests.
  • GET requests are typically used to display forms, while POST requests handle form submissions.
  1. Templates:
  • Theme: Separating presentation logic from application code using Jinja2 templates.
  • Details: This covers rendering HTML templates, passing variables to templates, using loops and conditionals within templates, and template inheritance for creating reusable layouts.
  • Process:Store HTML templates in a “templates” directory.
  • Use render_template(‘index.html’, variable1=value1) to render a template.
  • Access variables in templates using double curly brackets: {{ variable1 }}.
  • Use Jinja2 syntax for loops ({% for item in list %}) and conditionals ({% if condition %}).
  • Use template inheritance to create reusable layouts with {% extends ‘base.html’ %} and {% block content %}.
  1. Filters:
  • Theme: Modifying data within templates using filters.
  • Details: Using built-in filters (e.g., upper, lower, replace) and creating custom filters to manipulate data before displaying it in the template.
  • Custom Filters:Define a filter function: def reverse_string(s): return s[::-1].
  • Register the filter: @app.template_filter(‘reverse_string’).
  • Use the filter in the template: {{ my_string | reverse_string }}.
  1. Static Files:
  • Theme: Serving static assets like CSS, JavaScript, and images.
  • Details: This covers how to serve static files from a dedicated “static” directory and referencing them in HTML templates.
  • Process:Store static files (CSS, JavaScript, images) in a “static” directory.
  • Reference static files in templates using the /static URL: <link rel=”stylesheet” href=”/static/style.css”>.
  1. File Uploads:
  • Theme: Handling file uploads from HTML forms.
  • Details: This covers creating a form for file uploads, accessing uploaded files using request.files, validating file types, and saving files to the server.
  • Process:Create an HTML form with enctype=”multipart/form-data”.
  • Access uploaded files using request.files[‘file_field_name’].
  • Validate file types using file.content_type.
  • Save files using file.save(‘path/to/save/file’).
  1. Downloads
  • Theme: Allowing users to download dynamically created files, such as CSV exports, through the web application.
  • Details: The process involves generating the file on the server, creating a unique filename to avoid conflicts, and using Flask’s send_from_directory function to securely serve the file for download. The tutorial demonstrates generating a CSV from an uploaded Excel file for download.
  1. Sessions & Cookies:
  • Theme: Managing user data and state across requests.
  • Details: This covers the difference between sessions (server-side storage) and cookies (client-side storage), setting and retrieving session data, setting and retrieving cookies, and the security implications of using each.
  • Sessions:Set app.secret_key to enable sessions.
  • Store data in the session dictionary: session[‘username’] = ‘value’.
  • Access data from the session dictionary: session.get(‘username’).
  • Clear the session using session.clear().
  • Cookies:Set cookies using response.set_cookie(‘key’, ‘value’).
  • Access cookies using request.cookies.get(‘key’).
  • Remove cookies by setting expires=0.
  1. Message Flashing:
  • Theme: Displaying temporary status messages to the user.
  • Details: This covers using the flash() function to store messages and retrieving them in templates using get_flashed_messages().
  1. Database Integration (SQLAlchemy):
  • Theme: Interacting with databases using Flask-SQLAlchemy.
  • Details: This covers setting up Flask-SQLAlchemy, defining database models, creating tables using Flask-Migrate, and performing basic database operations (CRUD – Create, Read, Update, Delete).
  • Models:Define models as classes inheriting from db.Model.
  • Define columns using db.Column(db.DataType, primary_key=True, nullable=False).
  • Migrations:Use Flask-Migrate to manage database schema changes: flask db init, flask db migrate, flask db upgrade.
  1. User Authentication (Flask-Login & Bcrypt):
  • Theme: Implementing a user authentication system.
  • Details: This covers using Flask-Login to manage user login and logout, using Flask-Bcrypt to hash passwords securely, creating user models, and protecting routes that require authentication.
  • Security:Hash passwords using bcrypt.generate_password_hash(password).
  • Verify passwords using bcrypt.check_password_hash(hashed_password, password).
  • Flask Login:Import and create a LoginManager instance, setting up user loading callbacks.
  • Implement a function @login_manager.user_loader to load users from the database based on their ID.
  • Protect views with login_required.
  1. Blueprints:
  • Theme: Organizing applications into modular components.
  • Details: This covers creating blueprints, defining routes and templates within blueprints, and registering blueprints with the main application.
  • Process:Create a Blueprint instance: blueprint_name = Blueprint(‘name’, __name__, template_folder=’templates’).
  • Define routes using @blueprint_name.route(‘/route’).
  • Register the blueprint with the application: app.register_blueprint(blueprint_name, url_prefix=’/prefix’).
  1. Deployment with Docker:
  • Theme: Containerizing and deploying Flask applications using Docker.
  • Details: The process involves creating a Dockerfile to define the environment and dependencies of the application, building a Docker image, and running the image on a server.
  • Docker File CommandsFROM defines base image
  • WORKDIR sets the working directory
  • COPY copies files from host to container
  • RUN executes commands to configure the environment
  • The process further involves building, saving, uploading, loading, and running the docker image on the server.
  • The importance of using pip freeze to export packages with exact versions is highlighted, making it easier to rebuild the container elsewhere.

Key Quotes:

  • “(Virtual Environment) the reason you want to create a virtual environment is because you want to have an isolated uh project where you only have the packages and also the package versions that are relevant to this particular project.”
  • “(For deploying you) need Docker on the server and that’s it.”

Conclusion:

This source provides a comprehensive guide to developing and deploying Flask applications, emphasizing modularity, security, and best practices. By following these tutorials, developers can build robust and scalable web applications using the Flask framework. The focus on using virtual environments, secure password handling, and containerization ensures that the applications are well-structured, secure, and easy to deploy.

Flask Development Essentials

General Flask Development

1. What is a virtual environment and why should I use one when developing Flask applications?

A virtual environment is an isolated project workspace that contains only the necessary packages and package versions specific to that project. This prevents conflicts with other projects and ensures that your application has consistent dependencies across different environments (development, testing, and production). Using a virtual environment also streamlines the process of creating a requirements.txt file for easy deployment and containerization.

2. How do I create and activate a virtual environment for a Flask project?

Open a command line (CMD on Windows, terminal on Linux/Mac) and navigate to your project directory. Create the environment using python -m venv venv (or python3 -m venv venv, depending on your system), where “venv” is the name of the environment directory. To activate it, use source venv/bin/activate (on Linux/Mac) or venv\Scripts\activate (on Windows). Your command line prompt will indicate the active environment.

3. How do I install Flask and save the project dependencies to a file?

With your virtual environment activated, use pip install flask (or pip3 install flask) to install Flask and its dependencies. To save the list of installed packages and their versions to a requirements.txt file, use pip freeze > requirements.txt (or pip3 freeze > requirements.txt). This file can then be used by others (or yourself on another system) to easily install the exact same dependencies by running pip install -r requirements.txt.

4. What is a route in Flask and how do I define one?

A route in Flask is a URL path that is associated with a specific function. When a user visits that URL, the corresponding function is executed. Routes are defined using the @app.route() decorator above a function definition. The decorator takes the URL path as an argument. For example:

from flask import Flask

app = Flask(__name__)

@app.route(“/”)

def index():

return “Hello, World!”

5. How do I pass and handle dynamic URLs in Flask?

Dynamic URLs can include variables that are passed as part of the URL path. You define these variables using angle brackets <> within the route. The variable name inside the angle brackets becomes an argument to the associated function. You can also specify the data type using <int:variable_name>.

@app.route(“/greet/<name>”)

def greet(name):

return f”Hello, {name}!”

@app.route(“/add/<int:num1>/<int:num2>”)

def add(num1, num2):

return str(num1 + num2)

6. What are URL parameters and how do I handle them in Flask?

URL parameters are key-value pairs appended to the end of a URL after a question mark (?). For example: /login?username=john&password=secret. You can access these parameters using the request.args object.

from flask import Flask, request

app = Flask(__name__)

@app.route(“/handle_params”)

def handle_params():

name = request.args.get(“name”)

greeting = request.args.get(“greeting”, “Hello”) #Default value if greeting is not provided

return f”{greeting}, {name}!”

7. How can I use HTML Templates in Flask?

To use HTML templates, you must first place your HTML files in a directory called “templates” within your project directory. The directory will be located in whatever file runs the application, commonly app.py. Use the render_template() function from Flask to load and render these templates, passing any necessary variables as keyword arguments. Use Jinja2 syntax ({{ variable_name }}) within the HTML templates to display these variables. This requires importing render_template from the flask package: from flask import render_template. Here is how you would return an HTML template in your app.py file:

from flask import Flask, render_template

app = Flask(__name__)

@app.route(“/”)

def index():

return render_template(“index.html”, message=”Welcome!”)

Within the index.html file you would have the following:

<!DOCTYPE html>

<html>

<head>

<title>My Webpage</title>

</head>

<body>

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

</body>

</html>

8. How do I deploy a Flask application using Docker?

  1. Create a Dockerfile: This file contains instructions to build a Docker image for your application.
  2. Define Base Image: Start with a Python base image (FROM python:3.10-slim-buster).
  3. Set Working Directory: Create a working directory inside the container (WORKDIR /app).
  4. Copy Requirements: Copy the requirements.txt file into the container (COPY requirements.txt .).
  5. Install Dependencies: Install Python dependencies using pip (RUN pip install -r requirements.txt).
  6. Copy Application Files: Copy the entire Flask application code into the container (COPY . .).
  7. Run database migrations: Change the working directory and run database migrations (WORKDIR /flaskapp/blueprintapp, then RUN flask db init, RUN flask db migrate, RUN flask db upgrade, then WORKDIR /flaskapp).
  8. Expose Ports: Specify the port that the Flask application will listen on (EXPOSE 5000).
  9. Set Entrypoint/Command: Define the command to start the application (CMD [“python3”, “run.py”]).
  10. Build the Docker Image: Use the command docker build -t <image_name> . from the directory containing the Dockerfile.
  11. Run the Docker Container: Use the command docker run -d -p <host_port>:<container_port> <image_name> to run the image as a container.

Understanding and Using Python Virtual Environments

A virtual environment is a tool used to create isolated project spaces containing only the packages and package versions relevant to that specific project. Here’s a breakdown of why and how to use them, according to the sources:

  • Purpose
  • Isolation: Virtual environments isolate projects, ensuring that each has its own dependencies without conflicts.
  • Dependency Management: They allow for specifying and managing exact package versions, which is crucial for consistent performance and avoiding compatibility issues.
  • Requirements File: Facilitates the creation of a requirements.txt file, which lists all project dependencies and their versions, simplifying deployment and containerization.
  • Creation & Activation
  • Command Line: Creation is typically done via the command line using python -m venv <environment_name>. For example, python -m venv venv.
  • Activation: Activating the environment makes it the current Python environment for the terminal session. On Linux and Mac, this is done using source <environment_name>/bin/activate.
  • Usage
  • Package Installation: Once activated, packages are installed using pip install <package_name>. For example, pip install flask.
  • Dependency Listing: The command pip freeze lists all installed packages within the active environment, which can then be saved to a requirements.txt file using pip freeze > requirements.txt.
  • Replicating Environments: Others can install the exact dependencies of a project by using the requirements.txt file and the command pip install -r requirements.txt.

Flask Application Development: A Minimalist Python Web Framework

A Flask application is a web application built using the Flask framework, a Python microframework known for its simplicity and minimalism.

Key aspects of Flask applications, based on the sources:

  • Minimalistic Approach: Flask provides only the essential tools and features needed for web development, leaving developers to implement additional functionality as required or by installing extension packages.
  • File Structure: A simple Flask application can be created with just a single Python file. However, more complex applications typically use a directory structure that includes templates and possibly blueprints.
  • Virtual Environments: It is recommended to create a virtual environment to manage project-specific dependencies.

How to create a basic Flask application, according to the sources:

  1. Set up: First, import the Flask class from the flask library: from flask import Flask.
  2. Create an instance: Create an instance of the Flask class, which will be the WSGI application: app = Flask(__name__).
  3. Define routes: Use the @app.route() decorator to define routes, which map URL paths to Python functions. For example:
  4. @app.route(‘/’)
  5. def index():
  6. return ‘Hello, World!’
  7. Run the application: Use the app.run() method to start the development server. You can specify parameters such as the host, port, and debug mode.
  8. if __name__ == ‘__main__’:
  9. app.run(host=’0.0.0.0′, port=5000, debug=True)

Key components and concepts in Flask applications:

  • Routes: Routes define the different URLs that the application responds to and the functions that are executed when those URLs are accessed.
  • Templates: Flask uses Jinja2 templating engine to render HTML files dynamically.
  • Static Files: Flask applications can serve static files such as CSS, JavaScript, and images from a designated static directory.
  • Blueprints: Blueprints are a way to organize larger Flask applications into reusable components.
  • Requests and Responses: Flask handles HTTP requests and provides objects for accessing request data, such as URL parameters and form data. It also provides mechanisms for creating custom responses, including setting status codes and headers.
  • Sessions and Cookies: Flask supports sessions and cookies for managing user-specific data across multiple requests.
  • Database Integration: Flask can be integrated with databases using extensions like Flask-SQLAlchemy, allowing you to define data models and perform database operations.
  • User Authentication: Flask can be used to implement user authentication systems, using extensions like Flask-Login and Flask-Bcrypt to manage user sessions and password hashing.

Docker Containers: Application Standardization and Deployment

A Docker container is a standardized unit of software that packages up code and all its dependencies so the application runs reliably from one computing environment to another. Here’s a breakdown based on the sources:

  • Purpose
  • Consistency: Docker containers ensure applications run the same way regardless of the environment, eliminating “it works on my machine” problems.
  • Efficiency: Containers virtualize the operating system, allowing for smaller sizes and faster startup times compared to virtual machines.
  • Isolation: Docker containers isolate applications from one another and the underlying infrastructure, providing security and preventing conflicts.
  • Creation
  • Dockerfile: A Dockerfile is a text file that contains all the instructions needed to build a Docker image. This includes the base image, dependencies, environment variables, and startup commands.
  • Image: A Docker image is a read-only template used to create containers. It’s built from a Dockerfile and contains everything needed to run an application.
  • Build Command: The command docker build -t <image_name> . is used to build a Docker image from a Dockerfile in the current directory.
  • Deployment
  • Docker Hub: Docker images can be stored in and distributed from registries like Docker Hub.
  • Run Command: The command docker run -d -p <host_port>:<container_port> <image_name> is used to run a Docker image as a container. The -d flag runs the container in detached mode (in the background), and the -p flag maps a port on the host to a port in the container.
  • Docker Compose: For more complex applications, Docker Compose can be used to define and manage multi-container applications.
  • Key commands
  • docker build: Builds a Docker image from a Dockerfile.
  • docker run: Runs a Docker image as a container.
  • docker ps: Lists running containers.
  • docker stop: Stops a running container.
  • docker save: Saves a Docker image to a tar archive.
  • docker load: Loads a Docker image from a tar archive.
  • docker images: Lists Docker images.

To deploy a Flask application using Docker, the process generally involves the following steps:

  1. Create a Dockerfile that specifies the base image, installs dependencies, copies the application code, and defines the startup command.
  2. Build a Docker image from the Dockerfile using the docker build command.
  3. Run the Docker image as a container using the docker run command, mapping the host port to the container port.

By containerizing a Flask application with Docker, you can ensure it runs consistently across different environments, simplify deployment, and isolate it from other applications.

Flask Database Migrations with SQLAlchemy and Flask-Migrate

Database migration, specifically in the context of Flask applications, involves managing changes to the database schema in a structured and organized manner. It is a way to evolve the database schema over time as the application’s needs change.

Here’s a breakdown of database migrations using Flask-Migrate and SQLAlchemy, according to the sources:

  • Packages: Flask-Migrate and SQLAlchemy are essential packages.
  • SQLAlchemy is an Object Relational Mapper (ORM) that facilitates the interaction with databases using Python classes and objects, rather than raw SQL queries.
  • Flask-Migrate is an extension for Flask that uses Alembic to handle database migrations.
  • Avoiding Circular Imports: To avoid circular import issues when working with databases and models in Flask, a common approach is to use the factory pattern, where the application and database objects are created within a function.
  • Steps for Implementing Migrations:
  1. Initialization: Use the command flask db init to initialize the migration repository. This step is done only once.
  2. Migration Creation: Use the command flask db migrate to automatically generate a migration script based on the changes made to the models. Flask-Migrate detects the changes in the models and generates the necessary migration script.
  3. Applying Migrations: Use the command flask db upgrade to apply the migration to the database. This updates the database schema to match the current state of the models.
  • Workflow: The typical workflow involves making changes to the models (e.g., adding a new field, changing a data type), generating a migration, and then applying the migration to the database. This process ensures that the database schema is always in sync with the application’s models.
  • Database Types: Flask-Migrate and SQLAlchemy support various database types, including SQLite, MySQL, and PostgreSQL. To switch between databases, you only need to change the connection string in the application configuration. After changing the connection string, you need to migrate and upgrade the database.
  • Model Definition: Define database tables as classes that inherit from db.Model. Each attribute of the class represents a column in the database table. Specify the data type of each column using db.Column and the appropriate SQLAlchemy data type (e.g., db.Integer, db.String, db.Text). You can define the table name using the __tablename__ attribute. You can specify the primary key for a column using primary_key=True. You can specify whether a column can be empty using nullable=False.
  • Making Changes: To make changes to the database schema, modify the models, then generate and apply a migration.
  • Benefits:
  • Version Control: Database migrations provide a way to version control the database schema, allowing you to track changes and roll back to previous versions if necessary.
  • Collaboration: Migrations facilitate collaboration among developers by providing a standardized way to manage database changes.
  • Deployment: Migrations simplify deployment by ensuring that the database schema is automatically updated when the application is deployed to a new environment.

Flask Application Server Deployment Guide

Server deployment involves making a Flask application accessible on the internet. Here’s a breakdown of key aspects and methods, according to the sources:

  • Methods
  • Manual Deployment: This involves copying the application files to a Linux server, installing the necessary dependencies, and running the application.
  • Docker Containerization: This involves packaging the application and its dependencies into a Docker container, which can then be run on any server with Docker installed.
  • Cloud Services: Docker can be used in combination with cloud services.
  • Docker Containerization Deployment Steps
  1. Create a Dockerfile: A Dockerfile contains the instructions to build a Docker image. This includes specifying the base image, setting the working directory, copying the application files, installing dependencies, and defining the startup command.
  2. Build the Docker image: Use the command docker build -t <image_name> . to build the Docker image from the Dockerfile.
  3. Save the Docker image: Save the Docker image to a tar archive using the command docker save -o <image_name>.tar <image_name>.
  4. Upload the Docker image: Upload the Docker image to the server using a tool like SCP. For example: SCP <file_name> root@<host_name>:<path>.
  5. Load the Docker image: Load the Docker image on the server using the command docker load -i <image_name>.tar.
  6. Run the Docker image: Run the Docker image as a container using the command docker run -d -p <host_port>:<container_port> <image_name>.
  • Key Considerations for Docker Containerization
  • Virtual Environment: Use a virtual environment during development to manage project-specific dependencies and create a requirements.txt file.
  • Base Image: Specify a Python base image in the Dockerfile. For example: FROM python:3.10-slim-buster.
  • Working Directory: Define a working directory in the Dockerfile. For example: WORKDIR /app.
  • Install Dependencies: Copy the requirements.txt file to the container and install the dependencies using pip install -r requirements.txt.
  • Copy Application Files: Copy the application files to the container. For example: COPY . ..
  • Database Migrations: Run database migrations inside the container to ensure the database schema is up to date.
  • Port Mapping: Map the host port to the container port when running the Docker image. For example: docker run -d -p 5000:5000 <image_name>.

By using Docker, you can ensure that the Flask application runs consistently across different environments, simplify deployment, and isolate it from other applications.

Full Flask Course For Python – From Basics To Deployment

The Original Text

what is going on guys welcome back this video today is a full flas course combined into a single video it covers everything from the very basics of flask like working with HTML files rendering templates handling post requests working with files working with static files integrating bootstrap two more advanced concepts like sessions and cookies database interaction user authentication up until stuff like blueprints and even deployment and Docker so this is a very comprehensive course and it consists of 10 individual videos compiled into one big course so often times you will hear me referring to the previous episode or to the next episode uh in this case I just mean earlier or future points in the video so don’t be confused by that and I do this because most of you guys prefer to have one big course instead of 10 individual episodes so this is now the full flas course uh on the neural 9 Channel as I said it’s quite comprehensive so you might want to split it up into multiple sessions but yeah let’s get right into it I hope you enjoy it not a g all right so we’re going to start in this first episode today by creating our first simple flask application a simple hello world application just to get to know the process of creating and running a flask app so it’s going to be very beginner friendly and simple now as I already mentioned flask is a python web development framework and it’s often times also referred to as a micro framework or a microw web framework because it’s so simple and minimalistic compared to something like Django when you create a new flask application you don’t have any functionality out of the box you don’t have an authentication system or anything like that you basically have to implement everything from scratch or you have to install additional packages that implement the functionality we’re not going to go into the advantages and disadvantages we’re not going to compare here Jango versus flask we’re going to go into flask but it’s important to know that flask is very simple and minimalistic you can basically built an application with a single file you don’t have some uh project structure that has to be in place in order to run a simple hello world project we’re going to see that this is the case in a second here so the first thing we’re going to do is we’re going to create a virtual environment and the reason you want to create a virtual environment is because you want to have an isolated uh project where you only have the packages and also the package versions that are relevant to this particular project there are many reasons you want to do that but one reason is that it’s very uh convenient to then create a requirements txt file to then deploy the application to containerize it and so on uh but there are also other benefits so what we’re going to do first is we’re going to open up a command line so on Windows CMD on Linux and Mac the terminal and we’re going to navigate to the directory that we’re going to be working in in my case this is the current directory and here now we’re going to create our flask uh project directory so we’re just going to create a directory I’m going to call it now first app and in this directory here in this first app directory we’re going to create a virtual environment for this you don’t need to install any python packages this is something that works with python out of the box it’s part of the core python uh installation and what we need to do is we need to say python or Python 3 depending on your operating system- mvmf and then the name of the virtual environment directory I like to call itvn which makes it a hidden directory and once you have this once this is um created you can see that we have this virtual environment here and depending on your IDE depending on the editor that you’re using you will have to configure that now the environment that is being used is this environment because by default it’s going to use the environment it always uses uh in my case here in py charm what I have to do is I have to click here um on the python interpreter and I have to oh actually I’m blocking this with my camera let me just move this for a second I have to click on the python version down here I have to add a new interpreter a local interpreter and then basically I have to go to Virtual n environment existing and then I basically have to look for this so I have to in this case I have my prepared projects here uh I have to go to python current VN bin and then I want to use Python 3 this is the executable or the binary I’m interested in I click on this I click okay and now my pie charm uses this virtual environment um in addition to that the terminal that I want to use I also want to activate this environment in so I want to say Source at least on Linux and Mac source and then vnf bin and then activate and now you can see it’s using the vmf environment how can you check if this is actually working you can just type pip or pip 3 freeze and you’re going to get a list of all the packages that are installed in this case no package is installed now once you have the virtual environment running and activated what you can do or what you have to do is you have to install flask so pip or pip 3 install flask and then this is going to install uh everything that’s needed for a basic flask application I can run pip freeze again and now you can see I have a couple of packages here installed in this environment so after this what we want to do is want to create a python file called app.py and this is actually all we’re going to need for this video today we don’t need any uh directory structure we don’t need models we don’t need anything like that we can just have a simple python file and this is going to be our whole application of course when you build more complex projects you still have a directory structure you have templates you have Blueprints and so on we’re going to talk about this in future episodes but for a simple flask application one file is enough so what we’re going to do here now is we’re going to import from flask flask with a capital f so from flask import flask and then we’re going to create the application by saying app equals flask ask and we’re going to pass here uncore name uncore uncore so this is how you create the application and now what we do with this application is we add end points or routes you could say we’re going to talk about routes in the next episode but for this video we’re going to just create a simple uh default route a simple index route so what we’re going to do is we’re going to use the decorator so at app. Route and we’re going to specify the rule so basically the path that this uh route is going to to belong to and the default is just slash so app route slash and then below that we want to create a function that is going to return something uh which is what we’re going to see the HTML code we’re going to see when we go to that endpoint so here we’re going to say now def to create a new function index and here you can return something now later on we’re going to render HTML templates we’re going to do it professionally but for now you can just return any text you can just return hello world for example and this is what you’re going to see when you go to that specific endpoint now this is now the endpoint to actually run the application what we’re going to do is we’re going to say if uncore name uncore equals uncore maincore that’s just a basic uh python main section um what we’re going to do here is we’re going to say app.run and we can provide a couple of parameters here the three important parameters that we’re going to provide here are the host the port and whether we want to run this in debug mode or not so we can say host equals and what you want to do is you always want to run the application on the Local Host so on the host of The Machine uh not necessarily on Local Host but on the local IP address so if you’re running this on a server you can provide the IP address that you can find with the terminal so for example something like 1 192 168 and so on um or you can provide Local Host if you just want to run this locally or you can provide both by passing 000000 this is going to basically use the local IP address and Local Host so you can keep it simple and just provide this and then you can also provide a port I’m not sure what the default Port is we can actually see what the default Port is um and then you want to provide debug equals true now you don’t want to provide debuck equals true when you’re actually running this on a server when you’re actually deploying this but while you’re developing this application you want to run it in debug mode because then you don’t have to constantly restart the server you can just keep it running change the code and it’s going to update automatically uh and you’re also going to see the error messages and stuff like that uh but you want to turn this to false once you deploy the application so um right now I can just run this I think the default Port is yeah 5,000 but we can also change this for example you can say Port equals 5555 if you want to then you can run this and you can see it’s running now on Local Host and also on the private IP address and when I click on this it will open up a web browser and this web browser goes automatically to the default route slash and I get hello world as an output here and you can of course also change this to be HTML code so you can say here H1 and then H1 um yeah and and then this is going to to when you save this it will update because you’re running this in debug mode I can click on it and you can see now I have a heading here so this is the basic idea of a simple flask application what we’re going to do now in the next episodes is we’re going to add more routes we’re going to handle different types of requests we’re going to add uh Dynamic routes we’re going to add post requests and Status codes and templates and blueprints and all that but this is where it all starts this is the simple basic hello world application uh in flask and of course what you can also do is you can run this in the terminal you can just say Python 3 app.py this also works and uh just as one thing up front you can now take all the packages let’s say this is now your application you want to deploy it somewhere all you have to do for example to push it to GitHub so that people can uh use it you want to do something like um pip 3 freeze and then you want to pipe this with uh with the greater than sign with the close closing angle bracket you want to uh feed this into a requirements.txt file and when you have that you have this requirements txt file and then people can just go ahead and say pip 3 install dasr requirements txt and they can install all the packages that you have installed in this particular virtual environment all right so let us briefly recap what we did up until this point we created a virtual environment for our application so that we only have the packages that are relevant to this project that we’re building here and we created this simple hello world application in flask the idea is we import from flask flask with a capital f we create an application and then we add this index function which just returns hello world as a heading this is just some HTML code here and then we map this index function to the default route slash and then all we have to do is we have to run the application with the host 000000 which is automatically local host and also the private local IP address then we also customized the port to be 5555 and we set debug to True which has the effect of us not having to constantly restart the application to make changes or to apply changes uh it happens when we change the code and we also see the error messages instead of something like internal server error without any context so what we’re going to do in this video is we’re going to learn about routes we’re going to learn how to handle different types of um URLs so how to handle Dynamic URLs also also how to handle URL parameters and we’re going to learn about the different types of requests like post and get and put and so on um and we’re going to also learn how to return custom status codes so let us start with a very simple thing first let’s just add another endpoint here which has a different route so we can say here another function let’s say hello and this function will also return just a simple hello world maybe not as a heading this time uh what we can do easily we can just say app. route and the route can be something like SL hello the important thing is every route want it has to start with a slash so we have to say slash and then something and you can call this route whatever you want you can call it hello you can call it hello world you can call it ABC it doesn’t matter and it doesn’t even have to match the name of the function so I can call the route XYZ and I can call the function hello this is also fine and by doing that you can basically add as many end points as you want so what you have to do is you have to run the application and then you can just say slash hello and then you will get to this end point uh that is mapped to the function or that the function is mapped to now this is all static so I can add a bunch of those and they’re always going to be the same however what I can also do is I can add certain or so-called URL processor so I can have variables in the URL itself that I can handle in the function so so for example what I can do is I can create an endpoint here a route uh which I can call slash greet and then what I can do is I can add uh a name here so I can say I want to greet a certain name and how I can do that is I can use angle brackets to specify name here so now it’s not greed and then slash angle brackets name this is not the endpoint but name is now a variable that can be dynamic so I can say greet Mike greet uh Bob or something like that this and the way I handle this is I create a function and the function takes the parameter name so in this case what I could do is I could say fstring hello and then name so the idea is now in the URL itself I have the parameter name and I can go to the route greet SL mik and I would get a different response then when I go to greet SLB for example and uh we can see that this is the case by just going to SLG greet SL Mike and there you go hello mik SLG greet SL Bop hello Bop so this is what is called a URL processor now there are certain things that we can add to these URL processors so for example if I have a route um let’s call it at so slash add and what I have here is number one and number two then what I can do is I can Define the function add which takes the parameters number one number two but you’re going to notice something if I return for example an FST string saying number one plus number two is equal to number one + number two what you will notice is that when we go to the application and I actually go to add sl10 sl20 you will see that the result is 1020 and of of course this is because what happens by default is that the parameters that we pass are considered to be strings so they’re just concatenated so the string 10 plus the string 20 is of course 1020 that’s a string concatenation if I actually want to do a calculation I have to typ cast these parameters so what I can do of course is I can say number one equals int number one but I can also just specify the data type of the parameter of the um of the it’s not a URL parameter of the um value that is passed here as part of the dynamic URL I can specify it here in the route already so I can say it’s an INT colon number one and it’s an INT colon number two so what happens here now is that this is considered to be uh an integer already so I can say at 1020 and you can see 10 + 20 is 30 what happens now is though when I pass something else so when I say 10 hello I get not found because this is now obviously a string it cannot be typ casted into an integer and this route is only for integers so if I pass something that’s not an integer it doesn’t even have the route it doesn’t find the mapping so those are or this is how you do Dynamic URLs those are URL processors what we can also do is we can pass actual URL parameters and maybe you’ve seen this or probably you’ve seen this um on a couple of websites you go to something like uh login now hopefully it’s not done like this this is very secure uh but you usually have something like login and then question mark username equals and then something and then you have an ant and then you have password equals and again hopefully it’s not in clear text in the URL but these are URL parameters if you see them somewhere so how can we handle those in flask what we can do is we can do the following app route and then maybe let’s call this handle uh the suggestions you see here are by the way from my prepared code it just thinks that I’m going to write all the stuff again and I actually am uh so handle query or handle URL params let’s call it that way uh handle URL parameters and the function is going to be handle PMS or something like this uh now we don’t need to pass anything here now as a parameter the parameters here are taken from the URL so if I have uh these URL processors year they’re going to be part of the function signature if I handle the actual URL parameters it’s happening by uh using a so-called uh or using the request instance so what I have to do is I have to say from flask import flask and also request and then it’s going to be part of the request uh object so I can do here or actually I can return uh the string version of request do arguments so I can just return this as a string version and then I can go to handle uh what was it handle URL params and you can see it’s an empty dictionary so it’s an empty immutable dictionary but if I add now some parameters so uh question mark name is equal to mic then you can see I have name and mik in here and if I say ant greeting is equal to hello you can see I have name mic greeting hello so what I can do here is I can say that I want to handle the following thing the greeting is going to be equal to request. ARs doget and I can say here greeting and the name is going to be the same thing with Name by the way this is a dictionary so you can also instead of saying get you can just do this this also works um and then we can return for example an F string that says greeting and then name so when I go back I can just go to slash handle your url parameters and then name mic greeting hello hello mic so this is how you handle the URL parameters now of course if one is missing this is going to give me a bat request key so it makes sense to check if we have all the parameters available we can do something like if greeting in request arguments. keys and name in request arguments. Keys then we do all this otherwise we return some parameters are missing uh so now if I do this I get some parameters are missing and if I go to this I get hello mic all right um so this is how you handle the uh URL parameters now if you have a post request you actually get uh a form we’re going to talk about this I think in the next video so we’re not going to handle the post parameters yet so not we’re not going to handle forms that actually um include uh include information that we pass with a post request however what we are going to do is we’re going to learn how to handle different types of requests because all these routes all these endpoints that we Define here are by default only handling get request so we can see that this is the case by opening up a terminal uh I’m not sure if this works out of the box on Windows it does work on Mac and Linux uh you can use the tool curl and if you don’t have curl just install curl using your package man manager uh and curl basically just sends a request so I can say HTTP colon sl/ uh then Local Host slash hello for example and of course I need to specify the port which is 5555 uh and you can see I get Hello World here uh as an answer so I can just send a simple get request to an endpoint and I get whatever this endpoint returns to me now what I can do is I can also specify the method so I can say curl – x so capital x and then post to specify that now I’m sending a post request to the same same endpoint and what you can see here is I get as a response 405 method not allowed so the post method is not supported by this endpoint now if we want to change this if we want to allow for post requests we need to Define this in the route definition so for example if I want to allow for post requests on the endpoint hello what I have to do is I have to say methods equals and then I have to pass a list of all the methods that I want to support on this endpoint by default this list looks like this it’s just get however I can also say it’s just post if I specify it like that get requests are no longer allowed so I can save this I can open up my terminal and I can say curl um HTTP colon1 27001 5555 and then SL hello you will see it now tells me method not allowed even though didn’t specify post or exactly because I didn’t specify post whereas if I say DX poost you will see I get hello world so if I want to support both I just have to say get and post and then I can run the same thing it works and I can also run just uh now the displaying is a little bit messed up there you go I can also do it with get and I also get the same response now the difference between get post put delete is not really uh a technical one primarily it’s primarily a convention you use get when you want to get a resource when you want to get information you use post when you want to submit information so when you want to create something uh you use put when you want to update information so when there is for example uh if you have a to-do list application you already have an existing to-do you want to change something about it you use put and if you want to delete it you use delete so those are the four main methods there are also others but we’re going to to focus on those four uh and you can basically just specify that you want to allow for put you want to allow for delete and so on maybe you only want to allow for delete but this is how you use them get to get information post to create information or to submit information put to change information delete to delete information um now let’s say you support multiple of these methods on the same endpoint how can you differentiate between the two uh or between the three or four let’s say I have get and post here what I can do is I can say if request. method is equal to get then I want to have a certain kind of behavior so then I want to return for example here um you made a get request then I can say l if request method is equal to post then I can just print you made a post request now you can also if you want to add an else Branch but this is not going to be relevant because the proper message here is you will never see this message because of course we cannot send a put request or a delete request or anything else to this endpoint you will always only get a get or a post request so I can go again into the terminal maybe let’s go ahead and also add a back sln Indian just so we have a line break so that we don’t have to constantly mess up the formatting in uh in the command line so I can send this request you made a get request I can send a post request you made a post request and what you usually do later on we’re going to learn about templating and using HTML files and so on uh what you usually do is you have one endpoint that does something and when you send a get request to that endpoint you get the HTML template so you get basically the form to fill out with maybe create a new to-do you get uh when you send a get request to this create to-do page you get the form that allows you to create a word top specify the new to-do and then when you click the submit button you send a post request to the same endpoint to actually create um the to-do so in the get Branch you would serf the HTML file and here you would actually process the information from the form um all right so this is how you handle the different methods now last but not least I want to show you how you can return a custom response so how you can uh specify the status code that you want to return and for this we’re going to actually also use the hello here let’s go back and just return hello world and let’s only allow for get again um what we can do here this is the simple way to do it we can just specify the status code by passing uh or by returning it as a second value here so I can just say comma 200 and this will return a 200 status code now I think 200 is the default we can see if that is the case by just going again into the terminal and let’s just add again here for formatting reasons back ACC in uh we can go ahead and say curl but I can also specify here Dash uh what was it I wrote it down here um I think it’s- i- capital I to get the response header so you get HTP 200 okay and then you get also the content type the content length you can see it’s text HTML uh it’s content a Content length of 12 and so on now I can change this by just saying comma 2011 which is created so usually use that after a post request I can just curl again and you can see here now I get 21 created I can also change this to 202 and then you get accepted I can also change this even though it doesn’t fit here I can also change this to 404 which is not found and you can see I get not found I can also change this to 500 which is I think internal server error there you go I can also change this to 51 which is something else not implemented and I can also change this to something like 936 uh which I don’t even know what it is unknown there you go or I can change this to something like this I’m not sure if this is going to be rejected uh yeah unsupported Response Code and HTTP response so I have a video on this channel where I explain the different status codes when to use which one and what they basically mean I’m not going to go through all this here just know 200s are basically to tell you that uh everything worked fine 300s are for redirection uh 400 is telling you you did something wrong and 500 is telling you the server messed up something that’s like the most important thing to know um now we can also go ahead and create a full custom response so we can go and say from flask import flask request and make response and then we can craft a full response we can say response is equal to make response and then we can do things like response do status code is equal to 202 for example and then we can also say response and I can actually or response. headers and I can actually manipulate things like content type is going to be equal to and I can change this to application SL octet stream for example or Json or text plane or something like this so I can go now and you can see we get actually we don’t get this because we were still returning hello world we need to of course return the response there you go you can see now 202 accepted content type application octet stream uh and of course now we we don’t have any text so we would have to add here hello world back sln to have the content there you go and we still have content length 12 and if I just do it like this I still get hello world um we can also change this here to text/plain which is more fitting I guess there you go text plane 202 accepted and this is the content so this is how you can craft custom responses all right so we’re going to cover a couple of different concepts in this video today as I already mentioned we’re going to learn how to render HTML files we’re going to learn how to work with templates in addition to that we’re also going to learn how to redirect we’re going to learn how to dynamically get the URLs for specific end points and we’re also going to learn how to work with the Ginger 2 templating engine how to use filters how to create custom filters so it’s going to be a quite comprehensive episode today now what we have here is a very basic hello world project we just have a simple index endpoint and that’s it and up until this point every time we had an endpoint we returned some string some Json object something like this but not an actual HTML file and this is the first thing that we’re going to change now so what we’re going to do is we’re going to create a directory full of templates full of HTML files and then we’re going to render them instead of just returning a text and the first step to do that is in the definition of our application we’re going to add a keyword argument called template folder and we’re going to call the folder in this case templates this is what it’s usually called now this folder this directory now needs to be created here in our app application so I can rightclick new directory and I can call this here templates now to keep it very simple what we can do now is we can just create an HTML file in here let’s call it index HTML and in my case here I already have some basic structure just doc type HTML HTML head uh characters set defined a title and then an empty body and we can say the title is flask app and uh then I can just you know have a heading here hello world or something like this this is now an HTML file in my templates directory a very simple one now in order to return the HTML file and not just some text I need to import a function or a method called render template and now what I do is I render the template instead of returning hello world so I say return render template and then just the name of the file we don’t need to specify the path because we already know that the template folder is templates so all I have to do is I have to say index HTML and in this case when I run the application when I go to the browser you’re going to see Hello World the HTML file has been rendered now the good thing is now we can do a lot of things here that we can usually not do with HTML files we can dynamically uh change what is happening in this HTML file we can change the content of this HTML file and we can do that for example in a very simple way by just passing certain keyword arguments so for example I might have uh my value here and my value can be hello world or let’s change this to something else like uh uh let’s just call this neural 9 and then I might have some calculation my my result is equal to 10 + 20 I do some stuff here in this method I call some functions I do some processing and then I want to put these two values these two resulting values I want to feed them into the HTML file and I want to dynamically render them in the HTML file what I can do for this is I can just pass keyword arguments whichever keyword arguments I want I can say my value equals my value I can say my result equals my result and of course they don’t have to be the same name I can also say uh XYZ equals my value this is not a problem the important thing is that the name that I choose for the keyword argument so the left one is the one that I have to access in the HTML file the right side doesn’t really matter this is just a value um so now I have these two values and I can easily just go into my HTML file and all I have to do to display them is I can use some tag so for example a paragraph and in order to access these variables these values I just have to use double curly brackets and I can uh now specify the variable name so my value for example and I can copy this and change this to my result by the way I think that if you’re working in pyrum you need to set up the templating language I think you need to go to settings um template is there something like template language yeah you have to go with template language and change this to Ginger 2 because this is the templating engine of uh of flash but I think this only works in the professional Edition I’m not sure about that uh but it’s only about syntax highlighting you can also do it without that so you have these two um things here now and what I have to do or what I can do now is I can just go reload the page and you can see I get the values in the page even though I didn’t explicitly say neural 930 I get whatever I passed from the function here so that is how you use values that you pass now you can also do some more advanced stuff so for example what I can do is I can say my list equals and then I can have some elements in here 10 20 30 40 50 and I can say that I want to pass the list so let’s just pass the list only my list equals my list let’s delete these two things um and what I can do now is of course I can go here and I can just say my list this is easy in this case um what would happen is I would just get the list but I can also uh use certain other structures of the templating language so I can go ahead and say I want to have an unordered list so ul and then I want to have certain list items and I want to list all the individual elements of the list how do I do that I can do that with a Ginger 2 full loop so I can use a single curly bracket not not double single and then percent and then I also close this with percent curly bracket and here I can say now four and I can call this whatever I want item in my list now I need to close this with curly bracket percent and for percent curly bracket and in between now for each element in the list I will do something so I can also just say hello then I’m going to do this five times uh this also works as you can see uh but it makes more sense to have a list item and to have the content of this list item be double curly brackets item so what we do here is percent so single curly bracket percent for a full loop also for if statements and so on and we use double quot uh not quotations double uh curly brackets for individual variables or values then you can see here I get a list of the values so this is what we can do here um what else can we do now we can do a lot of things we can um do conditions so for example I can say uh curly bracket percent if item is equal to 30 uh what I want to do then is again also here end if then I can say if that is the case I want to have a specific list item where the style is color red item and I also need an else branch and I can just copy this here there you go uh and in this case now this one is red because I have this condition in here uh now of course I can also take this and make it more efficient by just not doing it like this by just saying here uh within the the list item I can just go and say percent if item equals 30 then add the style and if and otherwise don’t this has the same effect it’s just uh another way of writing it so basically we have the if here and then this is what happens if the condition is met so this produces the same result as you can see um all right so that’s like the simple stuff um this is the basic idea of templating um or at least of of of using values in the templates now what we can also do and this is now very interesting is we can inherit templates so let’s say I want to have the same navigation I want to have the same uh header I want to have or the same head section I want to have the same Imports I want to have the same content on every single page I have on my page uh or on my uh application uh and I don’t want to rewrite it all the time so actually the only thing that’s different about this index HTML compared to all the other files in my application is this content here I don’t need the rest this is just what’s unique about this everything else should be the same everywhere else maybe the title not what we can do for this is we can create a so-called base template so I can go ahead I can I can create an HTML file base. HTML and in this base HTML file I can now Define the structure so I can say we have this doc type HTML again HTML language English uh we Define a character set I have a body and so on um and the title now we can make Dynamics so we can say if you inherit from this template you will be able to fill in certain blocks so you will have certain sections that you can change and as such a section can be defined as curly bracket percent block and then we can choose a name for this section so title for example and then I also need uh end block the idea now is that when we inherit from this template we’re going to see how to do that here in a second when we inherit from this template we can fill in this section so depending on which page you’re in you’re going to get a different title however I can also put a default value in between so I can say default value for example this is going to be the default title if I don’t actively fill in the title in the sub page that is inheriting from this template uh and then I can do another block here in body I can say um again curly bracket percent block content and I can close this here end block and then I have some content here so this is now the basic structure and of course if I want to I can have a navigation here on each page and this is now always the same it’s not part of the block it will always be there um or maybe just to show you that this is the case I can add a paragraph here this will always be here because it’s not part of the uh of the block content here or of the block content here um and now what we can do is we can go into our index file and we can extend from this template so I can go here I can delete all of this here and at the top of my index HTML file I can say now uh curly bracket percent extends and then base. HTML like this so now it extends from base HTML it has the same structure and I can fill in the blocks now I can do the same thing block and title and block and in title I’m going to say here just index page and then I can say block content then I have my content here and I can close this block there you go so now what I can do is I can refresh the page you can see this will always be there and I still have the same content and I can do this now with a different page as well I can copy this I can call this other HTML um I can change the title to other page and I can you know maybe just have a heading here other something like this then I also need an endpoint for this so let’s copy this let’s call this other let’s put around to other and then just render other HTML there you go and now when I rerun this you can see here first of all we have um again here index page and then I can go slash other and this is still here and we get other Pages a title here so this is very useful because you don’t have to constantly uh make all the changes everywhere imagine you don’t do that and you want to include a new CSS file or a new Javascript file or you want to import bootstrap or something you cannot just do it here once you have to do it at every single HTML file you have and chances are you have hundreds of them depending on the size of your application so it makes a lot of sense to have this base HTML file um for the basic structure and then to just extend it here uh with with the other HTML files all right so now let us move on to a concept uh called filters now I have a video on this channel separately a separate video about filters in ginger um and I’m just going to briefly go through them so I’m going to create here a new or actually let’s use the other page for that let’s call it filters here um what we’re going to do now is we’re going to explore the effect of filters so very basic here let’s say I have uh some text that I pass to this to this endpoint I have a text and let’s call this text just hell World Su text equals Su text now as we already saw I can just display this in a paragraph here in a very simple way by using double curly brackets some text just to see that this still works there you go hello world now what I can do is I can say I want to have certain operations applied to that a very simple one is I want to have everything in uppercase now what you do in Python is you call the Dot Upper function or you call other methods of the string this is not really possible here in ginger what what you do in ginger is you use templates and to use templates uh not templates sorry filters uh and to use filters you need to pipe the text through a filter so we use the pipe symbol and for example one filter is upper this is a built-in filter you need to to know that these exist there is a there’s a list of them in the documentation but this is a built-in filter and now if I go to the page you can see we get hell World in uppercase I can do the same thing in let’s maybe just keep all of them to compare them I can do the same thing with lower so now if I go here you can see it’s all lowercase and there are also other filters so for example I can do title I can do stuff like uh replace where I can also add parameters so I can say replace all the else by uppercase lse for example this works so here you can see title case is just default and then we have here the replace filter active um and then we can also do uh or actually you know there there’s a huge list of different filters that you can use but what I’m interested in showing you here is that you can also Define your own custom filter so you can say uh let’s say you want to have a a filter that reverses the string for example for some reason you want to do that um this is not a filter as far as I know that is available by default so you have to implement yourself and you can easily do that by going into your appy and importing from flask here um or actually I don’t even think we need to import anything sorry uh we can go down here and we can create now not a route so not app. route but app. template filter uh and we can call this filter for example reverse string then I can call the method reverse string and it takes something as a parameter um and this parameter is just our text so our string s and what I can do now is I can just return s and then I can reverse it like this colon colon1 this is just how you reverse the string in Python and now what I can do is I have this reverse string here I can go to my other HTML and I can say reverse string and now I can go here and you can see it reverses the string it’s my custom Behavior I get some input and I return some output this is my filter I can do other filters as well I can do a filter called uh what did I have here repeat is a very simple one repeat also takes additional parameters so I can say repeat um and repeat takes a string and I can also say it takes times and Times by default is two but it doesn’t have to be it can also be 10 and then I return just s * times so I can go here I I can copy this I can say repeat and I can say repeat five and then you can see Hello World hello world and then I get it five times as well um maybe another thing that we can do is we can alternate the case is just now one more example here we can go and say app template filter alternate case basically everything that’s uppercase will be made lower case and vice versa so alternate case of s and now we can return here MP string join I’m going to use a list comprehension character upper if I or actually uh no this would be swap case alternate case means uh you have uppercase lower case uppercase lower case uppercase lower case so what we’re going to do actually here is we’re going to say if the index is um modulo modulo 2 is zero so if it’s an odd uh if it’s an even number we’re going to do c. uper else C do lower for i c in enumerate s and then what we get is of course we need to apply it as well let’s go to other alternate case there you go we get this uppercase lower case uppercase lowercase uppercase and so on so this is how you use filters now one last thing or actually uh two things that I want to show you here now is uh one the redirect and two how you get Dynamic URLs so how you can get um Dynamic how you can get the the the URL of an endpoint dynamically without having to specified statically because of course it can change so first of all let’s do the redirect um or actually first of all let’s do the the dynamic URL because the redirect can then use the dynamic URL for the redirection uh now let’s say on my index page I want to have a link to other so I want to have a link to the endpoint other now the endpoint other might have actually this URL here but I might uh I might change this over time so I might say this is something else now I don’t want to manually Define that this is the endpoint uh or that this is the route to this endpoint so what I can do here in the index pages I can have a link I can have an A an anchor tag uh with the following destination and now I can use double cly brackets again and I can say URL or4 and then I just pass the function name other and then I can say here other now you can see I didn’t specify the route at all but if if I now go to to this and I reload the page you can see I have a link to other and you can see in the bottom left that it actually gets me to this page so you can see here that the link is going to this URL here to this endpoint dynamically if I change it it’s going to change as well so if I go here and I change this again back to other it will also change in index HTML without me having to do anything there you go still works uh now this can also be used for redirects and this can also be used in the python code not just in HTML not just in the templating engine so for example what I can do is I can say let’s add a new endpoint here app route redirect endpoint and then I can say redirect endp Point here uh what I can do now is I can return instead of returning a template or a text or something I can just return a redirect and for this I need to import the redirect function and I can just say return redirect and the location now I can of course say just slash other but I can also do and for this I need to also import URL 4 I can just call the URL 4 function here URL 4 and then other for example redirects me to other um so if I now run the application again and I go to slash redirect endpoint you can see I end up at the other page so yeah this is how you can do that this is how you work with templates this is how you render HTML files how you can use uh filters in ginger how you can extend templates and uh how you work in general with actual HTML content not just text all right so we’re going to cover a lot of different things in this video today primarily we’re going to focus on handling post requests in the back end in a more advanced way than we already did in episode two we’re going to learn about forms we’re going to learn how to handle forms data we’re going to learn how to send post requests using JavaScript with Json data we’re going to learn how to handle that Json data we’re going to learn how to upload files how to process uploaded files how to respond with a file download for the user uh and stuff like that and what we have here now for the beginning is a very basic flask application which just renders an index HTML file this index HTML file just has a heading hello world and it extends a base HTML template nothing too fancy here very simple we already know how all of this works I can run this so that you can see what this looks like again just a basic hell World page and what we want to do now is we want to handle a post request but we don’t want to do it the way we did it in episode to with curl with a command line tool we actually want to have an HTML form where I can input some data where I can press a button and then the post request is sent and something is done based on that post request so what we’re going to do here is a very simple example is a uh dummy login page so we’re just going to have username password and then we’re going to send a post request with username password and if they match some static string then we’re going to say success otherwise we’re going to say fail so this is of course not an authentication system it’s just a dummy page that you know processes username and password and Compares them to Strings but it’s a good start to understand what is happening here or how this works so we’re going to use index for that and what we need to do first is we need to specify that multiple methods are allowed here by default remember get is already allowed but we still need to specify it here if we want to change this uh and we now also want to allow for post requests here so the idea is with a get request we want to get the HTML page to display the form and then when we submit that form we want to send a post request and then we want to process the data that was sent so what we’re going to do here is first of all import request and we’re going to distinguish two cases between two cases if request. method is equal to get then what we want to do is we want to just render the index HTML file otherwise if request method is equal to post we want to do something else that we don’t have yet so I’m just going to return an empty string for now uh we’re going to implement that once we have the form so what we want to do now is we want to get into index HTML and we want to create a simple form so I’m just going to say here form and now we need to specify a couple of things we want to say method is equal to post this is a post request that we’re sending and the action is the target URL that we’re sending this to here for this we’re going to use again double curly bracket URL 4 and the endpoint that we’re sending the post request to in our case index now of course what you can also do if you want to you can also create a separate endpoint login that only accepts post requests and then index only accepts get get requests and then of course you can also send the action to another page you don’t have to send it to the same page you can also send it to a different endpoint uh but we’re going to do it like this now and in this form we’re going to have two basic fields in input type textt now the important thing here is the name we don’t need an ID this is more for CSS stuff or styling we don’t need a class we need a name the name is important because the name is what we’re going to get as a key uh for the key value pair in the backend so we’re going to say that the name is username here uh and then we’re going to define a placeholder username and then we’re going to copy this type password name is going to be password and placeholder is going to also be password like this and then finally want to have an input type submit with the value login and probably we should add some line breaks here so when I run this here you can see we have this basic form I can enter some stuff and I think if I just do something I’m going to get an empty response here because remember if we send a post request which we now did we just get uh an empty string as a as a result here so what we would actually want to do is we would want to compare the username and password to our quote unquote actual username and password so what we do here is we say username equals and now we have to get the username from the post request that was being sent so we’re going to say request. form now this is important if you get the request from a form the post request comes from a form we get request. form Dot and then get key or you use it as a dictionary however if you send a request with JavaScript and you send a Json object you have to use request Json we’re going to look at this here in a second request form and now I can access the key username like this or I can also say form. get usern name whatever you like it’s the same thing it’s just a different way of writing it then password request form get password so now we get these things from the post request and of of course if you have some optional stuff uh it makes sense to first of all check if it’s part of the form so you can say if and then before getting it because in this case you would get an exception if you have something that’s not part of the form that was submitted and you try to access it you’re going to get an exception it’s going to crash your application what you should do is something like if username in request form Keys only then get username but in this case there’s no way uh to not get to not get the username because we’re going to use the application properly so for now we’re going to ignore this but this is how you get the two things now from the form and now we can say if username is equal to let’s say neural 9 and password is equal to uh let’s say password then return now we’re just going to return a text success otherwise we’re going to return failure like this so I can go here again I can type some nonsense there you go failure and now I can go and I can say neural n password success so this is how you handle very basic form data now what we can also do is we can upload files this now gets a little bit more advanced because you need to consider a couple of things when you upload files you have to to uh provide specific types of in puts you also have to change stuff about the form itself and you have to also access the files in a different way so this right here is a very simple way you just have some input stuff you have some text password number whatever and you just name them and you just access them this is how you handle basic form data you can now add a bunch of other fields here with type number and stuff like this doesn’t really matter it’s the same way of handling it you just get the form dictionary and then you get the individual keys and again if something is optional you just say if whatever key you have some key in request form Keys then get it from there to keep it safe now we’re going to handle files and for this I want to actually create a new uh a new endpoint I want to create an endpoint file upload so we’re going to say app route slash file upload file upload and and here now we want to handle what happens when a file is being uploaded for now I’m just going to return an empty string because first of all again I want to handle this in the HTML file so we’re going to create another form here let’s maybe add a heading in between to know the different sections we’re going to add a new form here and we’re going to start the same way method is equal to post action is going to be equal to now of course different URL so URL for the method or for the function file upload and the important thing now is that we need to specify an encoding type we need to say that this is now uh we we need to add this parameter here en type is equal to multiart form data because we’re going to pass files now so it’s a different type of encoding that we have to use here multiart form data this is important then what we can do is we can say input and the type of the input is file however this is not all of it because file is very generic what kind of file are you expecting are you expecting any type are you expecting any kind of file or are you expecting maybe just plain text or just uh Excel files or just CSV files or something like this uh depending on that you’re going to have to specify uh a different keyword here or or a different uh parameter here in a second so we’re going to say the name is just file nothing too fancy uh and what we want to do now is we want to say accept equals and accept equals now you can specify certain uh content types now what these content types uh content content types are exactly you have to Google most of the time here in py charm I have uh all the suggestions which is very convenient but um if you have a certain file type that you want to uh allow for here you need to Google what the content type string is actually uh what I want to allow here now is I want to allow uh Excel files so basic Excel files XLS and xlsx and also plain text so how do I do that I have to know what the proper um content type is for Excel and I think it is um application vnd D and then we need open XML formats so you have to scroll for a while here oh actually I don’t think that we have it here so I have to type it out applications SLV and. openen XML formats Dash Office document uh do spreadsheet usually you want to copy that you want to you don’t want to type this out actually I’m going to copy this now because that that’s no uh there’s no value in uh in doing this here so let me just mark this and then copy this to my clipboard then I’m going to just paste this here so the idea is you get the content types in this case I have three content types this is one then I use a comma to separate them then I use another one and then I use a comma again another one so here I have uh Excel Excel again and then uh text PL so txt files so that’s basically it then I can also set this to required equals required even though I think required in of itself should be enough let’s do it like that and then I can use again input type submit or yeah submit and then the value of that is upload file so let’s go ahead I can browse the file I can use data xlsx I can upload the file and in this case it tells me method not allowed because in my file upload here I didn’t specify that the method that I want to allow here is equal to post let’s go again upload the file and I get nothing in return because of course we had return an empty string so now it’s about handling that file let’s say what we want to do here in this case is we just want to uh in the case of a text file we want to to return the content of the file so we just want to display the content of the text file in the case of an EXO file we want to uh render the table we want to load it into a data frame and we want to render the table um to the HTML file so we want to show an HTML table off the data frame for this of course we need pandas so if you don’t have pandas installed uh this is now just an example by the way if you don’t care about pandas you don’t want to process Excel files just skip this you don’t need to work with that that’s not part of the course but we’re going to do this here now as an example in this case you would have to install pandas like this pip or pip 3 install pandas uh and of course we need to also then import pandas SPD um and now what we would do here is we would first of all get the file so we would say that the file is equal to request do files this is now a separate field it’s not form it’s not Json it’s files specifically for files and here want to get file this is again the name here file uh what we now want to do is we want to look at the content type of the file and decide what we do with that file so we’re going to say if file. content type is equal to text/plain if that is the case all I want to do is I want to return file read read the content of the file decode it so that it’s a string because it’s binary data I think uh by default since we have uh the encoding type um and that happens when we have a text file otherwise if the file content type come on file content type is equal to the Excel stuff and I think for this I’m going to just do it like this or file. content type is equal to that so just a two different uh content type strings if it’s one of those then what we want to do is want to say data frame is equal to pandas read Excel and then uh the file like this and then what we want to return is just df2 HTML which is a method in pandas that allows us to turn the data frame into HTML so that we can easily just uh display it all right so that is it and we can actually see now hopefully that this works so I have data xlsx I can upload it and you can see I get the content of the Excel file this is the content of the Excel file uh as HTML here rendered now I can also go here now and I can create uh a text file let’s call this hello.txt and I can say hello world this is a text file with some text and then I can go here I can browse I can get hello txt upload file and there you go now the line braks are not displayed properly but that’s okay uh and you can see we can distinguish between content type and get different responses so this is how you handle file uploads you get a file from request files this is just whatever file you submit here is input type file you accept certain file formats you can check for them you can process them in different ways depending on what the content type is so that’s actually quite straightforward and simple let us now actually go and Implement uh a use case that might be interesting let’s go ahead and convert um an Excel file to a CSV file so we take an Excel file and we take the content that we displayed as a table here in HTML and we want to return so this is now also about a file download as a result of the request we don’t just want to display something we actually want to return a CSV file to the user that the user can download so how can we do that for this what we’re going to do is we’re going to create an endpoint app route we’re going to call this convert CSV by the way the reason you already always see uh the names that we’re going to use is because I have all the code prepared so it already knows what I want to call the functions or the routes at least so convert CSV is going to be the endpoint um and here now all we want to do is we want to take the file and we want to return the converted version so the csb file and for this now again we’re going to just copy this part going to paste it down below I’m going to change this to convert to C vsv and now we’re not going to allow for text plane we’re only going to allow for EXO so we have um and also we’re going to not send this to file upload we’re going to send this to convert CSV and it’s important of course to specify here again methods is equal to post we accept post requests on this endpoint and uh the idea is the same now we get the file we say file equals request files file and in this case it’s always going to be an Excel file we don’t even need to to check for this it’s always going to be an Excel file because those are the two things that we accept um by the way let me just I hope this can be run right now you can see which types are supported down here you can see now since I in the first form allowed for Excel Excel and text file these are the supported types and only these are actually displayed here uh whereas here now I only have Excel and Excel um all right so we know that this is going to be the file type what I can do now is I can load this into a data frame again pd. read Excel file and then I can craft a response that I can give to the user and in this response I’m actually returning a file how do I do that I import from flask response with a capital R and then I do the following thing response is equal to response and here I specify a couple of things first of all what am I responding with and what I’m responding with is a CSV file so df2 CSV I’m taking the data frame and turning it into a CSV file and since I’m not specifying a path here I’m getting the object itself as a result so df2 CSV then I specify the mime type which is the content type and the string for CSV is just text SL CSV and then what I do is I say header equals and here I pass now a dictionary with a key content disposition and we pass uh the value attachment and file name equals and now now you can choose the file name of the CSV file now this is important this optional but this is important because the file itself uh doesn’t have uh or actually I’m not sure if this is uh in this case is even optional maybe it’s even mandatory but the thing that you’re returning you need to also specify a file name for it and what you can do with this header field is you can specify what the download name is going to be because there’s also another use case which we’re going to look at in a second where you actually have the file stored on your system and the file might have a completely random file name but you want to return it as result CSV for example so this is why you need this header and now what we do is we just return the response itself so again we get the file we load it into pandas we turn it into a CSV file we specify the type we specify the header with a file name and that is it so now this should already work I load the Excel file upload file and now you can see that for this I’m going to now navigate to my uh directory here result CSV I don’t want to do that come on current save result CSV and now I have a CSV file with the information from the Excel file so this is one way to serve a file this is one way to return uh a file for download we can find a second way now or we can do a second way now uh which is you get the file you download the file from the user so the user uploads the file and um you you process the file and what you do is the result you don’t return it immediately you save it in a downloads directory and then what you do is you return to the user a download page with a separate button so the user uploads an EXO file clicks on convert and instead of just getting the file as a result he’s redirected to a download page and at this download page uh the file is then loaded from the system from the server uh and download it this is in my opinion more professional most of the time you don’t want to just return the file immed medely you want to have a download page uh and then you can download the file from there but of course it depends on the use case so we’re going to call this convert CSV 2 um and the function is going to also be called convert CSV 2 and of course this takes methods equals post and what we want to do now here is let’s copy this convert to CSV 2 convert CSV 2 uh we’re going to have to add a couple of things here because we need a download template in our application we need to have here a download HTML file which actually I’m going to just copy index I’m going to call it download HTML and for now we’re just going to have downloads as a heading here and actually nothing else I’m going to add the stuff later on um and in our convert to function now we’re going to do the same thing file equals request. files file then we’re going to load this into a data frame so PD read Excel file and now what we’re going to do is we’re going to see does the download directory that I want to store this in uh the CSV file in does it already exist if not we’re going to create it and then we’re going to place the CSV file there so that it can be downloaded later on uh for this we’re going to need the OS module or package so import OS uh and we’re going to say if OS do path. exists or actually if not OS path exists downloads we’re going to do OS make deers downloads and then we’re going to create a file name we’re going to say file name is equal to and the important thing now is we want to have some file name that’s completely random it doesn’t really matter but we want to make sure that we don’t use the same file name that’s maybe already there and for this we’re going to import another uh python Library uu ID which is basically generating a random ID which is almost certain to not be the same as one that you generated uh already so it’s very unlikely that you’re going to generate something that you already have so we’re going to say file name is equal to uuid uuid4 and then CSV so just some generated file name and now what we’re going to do is we’re going to save the file with this file name and then we’re going to return download HTML and we’re going to pass the file name as a parameter to the HTML file so that the HTML file when you press download knows which file to actually download um so we’re going to say df2 CSV and then um OS path join downloads and file name and then we return render template download HTML and the file name is equal to file name now the important thing about download is now it has to actually download from an endpoint so it actually needs to call an endpoint that makes the download that performs the download so we’re going to create this one app. route download slash download actually and then we’re going to just call this download and here what we’re going to do is we’re going to return and this is now a function that we need to import again from flask it’s called sent from directory so we send from directory and this is now the directory downloads the file name file name which uh we need to pass here or we want to pass here as a URL parameter so I’m going to just call this file name I’m going to pass this here as file name this is now again these uh URL processors we passed a file name here and then the downloador name is what we want the file actually to be called so again we have some random file name some numbers and letters mixed together CSV but the download name should be result CSV all right and then finally what we need to do is we need to go to download we need to create an anchor tag with the following url url 4 download and the file name is equal to file name then download file so if I’m not mistaken this should actually be it uh I need to run the application there you go now this is not the best styling I know uh let’s go ahead upload data xlsx upload file now I’m redirected to download we can see here behind the scenes a downloads directory was created with some random file name you can see here the uuid it’s the CSV file and now what I can do is I can download the file and and I get result CSV I can save it replace the existing file and I now have the same file here and if I do this again I’m going to get a different file so I can do this again upload file and now you can see I have a second file here and I’m going to download it and it’s going to be result CSV again and of course uh you should probably on a regular basis clean the downloads directory otherwise you’re going to get a lot of different files that you don’t need anymore maybe once a day you should clean it uh but yeah this is how you can do that um then finally I also want to cover how to post Json data with JavaScript so this is now no longer python in HTML now we’re going to actually use JavaScript to send a post request with a button click now why is this useful it’s useful because sometimes you’re going to have um some button or some chat or something that you want to use to send request to the backend so a very simple example of that is you have a chatbot you have a chat window and you have an AI model in the background answering uh the request you have an endpoint that you need to communicate with but you don’t want to actually send form data so to chat with a chat bot you don’t want to send you don’t want to fill out a form with your message send uh the request and then be redirected to another page to get the response you want to do this dynamically in the same window you want to just send a request using JavaScript get the response update the HTML and so on this is why you want to do that so for this let me just close all of this let’s go to index again we’re going to do down below H1 JavaScript Json request and all we’re going to do here now is we’re going to have a button and the button will have an ID this is now important the ID is important because now we’re working with JavaScript JavaScript works with ID and ID is a unique identifier for a specific element in HTML and we’re going to call this post button and we’re going to say send post request and what we need now is we need an endpoint that we’re going to send a request to this is going to be the endpoint that handles the Json data and for that we’re going to go to appy we’re going to create an endpoint app route let’s call this handle post which of course needs to take method post and we’ll post and what we do in this one here is we get the ad Json data we expect this post request to be a Json uh to have the content type Json so we say here um what we’re going to do is we’re going to have a greeting and a name and we’re going to process a greeting and Name by writing it into a file and then returning that the file was successfully written so we’re going to say greeting is equal to um to request. Json and then greeting I can copy this name equals request Json name and then I want to say with open file.txt in writing mode SF fite and then just greeting name and then we want to return just adjacent object saying that it was successfully written so key message and value successfully written so I can just do it like this message and then successfully written now the best practice way to do this is to jsonify this to make sure it’s actually ajacent object so you want to import jsonify from flask and you just want to call the function on this so jsonify on this dictionary that’s it so this is our endpoint and now we’re going to send a post request to that endpoint using JavaScript so script we’re going to create a script tag down here script type is text JavaScript and the functionality is going to be the following we’re going to get the con uh the button is a constant here so const uh post button is going to be equal to document. get element by ID now this is core JavaScript you probably want to use something like J query if you’re actually doing some JavaScript stuff but this is now core JavaScript get element by ID postore button uh then const Json data is going to be equal to and now let’s just go with name or actually we don’t need quotation marks your name is going to be equal to Mike and the greeting is going to be equal to hello and of course in the case of a chatbot you would not just statically Define adjacent data you would actually get it you would get the content off a text box that contains the data you would get the content from the chat window you would update the content of the chant window but we’re keeping it simple now we have some static Json dictionary here some static Json data and now we’re going to add an event to the post button we’re going to say post button. add event listener and the event listener that we’re targeting is Click so when you click on the button the following is going to happen we’re going to have an an anonymous function here just uh parentheses then equals and then the greatest uh greater than sign so an arrow basically then CI brackets and in here now we’re going to call the fetch function and the URL is again we can get it dynamically URL 4 and the URL 4 is going to be handle post so that is where the request is going then again k brackets to say the method that we’re using here is post and we need to specify the headers because of course what we’re sending is Json data but we need to also specify it’s Json data so we’re going to say content type is application SL Json then semicolon character set is equal to utf-8 encoding basically and the body this is now the content the body is equal to json. stringify Json data um this is basically sending the request what we want to do now also is we need to respond or we need to to we can respond so we can say here uh dot then what happens then response is response. Json and then do then we can say data console lock and we can lock that this was successful success is uh success data here so success colon data um and then finally we can say catch if there is an error we can also uh we can also come on not used to JavaScript I don’t like JavaScript so I have to constantly check my second screen console do error and we can just lock the error message yeah that’s basically it and uh I think this needs to be closed and this also needs to be no actually is this where is this closed this is actually closed here I think I messed up something in my code yeah of course because we need it like this all right so to just go over this again we Define the element post button to be the element in document that has the ID post button which is our button here we have some static Json data in an actual application you would read this from the text boxes then you add an event listener to the button when the button has the event click then the following thing happens we fetch to the URL of the handle post endpoint with a post request we have the content type Json we get the Json data we stringify it that’s the body then we get the response we get the data we lock the data if it was successful if there’s an error we lock the error message that is what we do here so let’s go ahead and go to the site let’s go ahead and open up the console let’s send a post request there you go success successfully written then I can see I have file txt hello mik so this is how you can handle Json data from JavaScript script post requests all right so we’re going to learn how to work with static files and flask in this video today which means we’re going to learn how to work with images CSS files javascripts and so on how can we load these things into our HTML files how can I specify the path to an image how can I link to a stylesheet how can I load a JavaScript from the respective directory how is this done in flask properly and how do I work with static files in general in addition to that we also going to use that knowledge to integrate bootstrap into our flask application just so you see how you can integrate something simple like a CSS framework uh and yeah this is what we’re going to do in this video today so this is our starting point we have a simple flask application just an index endpoint rendering the index HTML file which just extends the base HTML template we just have a simple hello world heading here and now let’s say my goal is to display an image here so let’s say I want to have an image Tech down here this is basic HTML I have an image the image has a source and uh the image also has an alternative text so something like this here um and that is basically our image here how do I do that now in flask so where do I put the images how do I link to the images because for our templates is very simple we have a template folder and we just specify the name of the HTML file so we have the templates all the HTML files here in the templates directory and then in order to load the HTML files I just have to specify the file name how do I do that now with static files the way you do that with static files is very simple to the way you do that with templates you define a static folder so you have to add an additional parameter here an additional keyword argument called Static folder equals and then you can choose the name of the static folder usually you call the static and then in addition to that we also want to specify a static URL path so how do we uh get there and what I like to do or what it’s usually done is you just pass slash so simple slash and then you can access all the different directories uh from the static directory just after the slash so in addition to templates now here we add an additional directory called Static and in this directory what I like to do and what is usually done is you have different directories for the different types of static files that you want to serve so you can have something like IMG or images you can call this whatever you want I like to call it IMG then you have maybe another one for uh CSS and then maybe you have another one for scripts or you can call it JavaScript or JS whatever you want to call it so CSS IMG JS again you can call this uh CSS images scripts something like this doesn’t really matter but now you have the static directory the static folder which is also defined here in the application and when I now uh put an image here so for example I have here the prepared logo. jpeg just in theal 9 logo I can just take it drag it into IMG and now this image is in the static folder and all I have to do to display it in the index HTML file is in the source I have to say SL IMG SL logo. jpack and it’s automatically going to recognize since I have static as the folder and the URL path is slash I can just go into slash IMG because I’m already in static when I go slash I can go IMG logo JPEG and that’s it so I can run this application and you’re going to see that we have the neural 9 logo here very simple and this now works of course with stylesheets with scripts whatever you want to do you can do that uh so for example I can go ahead and I can create a file called style.css and here maybe I can create a class special and this special class here I want to say that the color of the text in that class has to be red and the font size has to be I don’t know 18 PT and then I can go into my index HTML file I can create maybe uh span or something give it a class special and I can just add hello here then I can go to my application uh and of course we’re not going to see anything for uh first of all let’s let’s make this a paragraph uh but of course we also need to uh to include the stylesheet sheet into our uh HTML template so let me just show you again that we have hello down here so The Styling is not applied even though I had the class uh set to special of course we need to also include this CSS file and how you usually do that is you go to the Head section which is of course in our base template not in our index file uh and here I do a simple link Rel equals stylesheet type equals text CSS and The Source or the path is equal to/ CSS SL style CSS like this then I can load the page again and you can see the styling is applied because it loads the static files from the static directory um what else I can do is I can create a JavaScript so for example I can go and I can say um I want to have a simple JavaScript that displays some popup after 5 seconds so I can go ahead and I can say uh hello.js and I can Define window onload is equal to a function that is called when the window is loaded and this function what it does is it sets a timeout and there’s another function in here and what we basically do is we just alert which is just pop up the warning hello world and we do that after 5,000 milliseconds so after after 5 Seconds basically uh that is our JavaScript now this alone won’t do anything if I open the page and wait for 5 seconds nothing’s going to happen because of course the script is not loaded in the index HTML file I have to load the script again from the static directory uh for example here at the bottom I can just say script and then um source is equal to uh sljs hello JS like this not sure if I have to specify a type I don’t think so now we can wait for 5 seconds and we should get a popup after 5 Seconds there you go hello world and yeah this is the basic idea of how you load images and CSS files and JavaScript files everything that’s static can be just placed here and you can just access it because you defined in the app py file here in the definition of the app you define the static folder and the static URL path so we can use this now of course to also integrate bootstrap so we can go to the bootstrap website which is this one here um and basically you can just download the compiled CSS in JavaScript you can just uh download the zip file which I have here then we can go and open files I can just open this and here we can see we have Js and we have CSS so all I have to do is I have to go to static JS I can take all these files here I can extract them I can go back I can go to CS CS we can go up here CSS take all these files drag them in here and now we have bootstrap basically installed uh in our flask application that was already it the only thing that you need to do now to actually be able to use bootstrap is you have to of course uh link the stylesheet and uh load to JavaScript so I can say link real stylesheet type text CSS and then SL CSS slash and then bootstrap.css and then also here I can go and I can say script source is equal to sljs SL bootstrap.js there you go and now in index for example I can go ahead let’s remove the image uh I can go ahead and add a button or an anchor tack so I can just say going nowhere let’s just use a filler here um I want to have some button text here and I can go ahead and I can say class equals and now BTN BTN primary for example which is these two are bootstrap classes that Define uh The Styling of the button you can see this is now a bootstrap button and of course if I change this to button uh danger I will get a red button that is bootstrap as you can see loaded and working all right so we’re going to learn about session management and cookie management and flask in this video today and we’re also going to learn about message flashing now let us get started with the first two sessions and cookies the basic ideas here are quite similar because in both cases we want to keep track of information we want to store information that is relevant for multiple requests so we want to keep information across multiple requests because HTTP in general is stateless which means we have a request and a response and we don’t have a state that keeps track of information uh about the overall exchange so if you want to do that you have the two basic ideas or the two basic methods to have a session or to have cookies to use cookies on the client site or to keep track of session information on the server site that’s the major difference the location of the storing and also for security reasons if something is sensitive and you want to be able to trust it you want to keep it in the session you want to keep it on the server side and um if something doesn’t really matter it does really matter if it’s changed it doesn’t really matter if the user sees it you can store it in a cookie on the client side so in the browser because whatever you store in a cookie on the client side can of course be changed by the client can be seen by the client whereas if you just provide the client with an ID with a so-called session ID and then you store the information uh for that session ID on the server and you do all this with a secret key you sign it with secret key and so on uh this is more secure so these are the two things we’re going to talk about out here now this is again our basic starting application we have an index endpoint rendering the index HTML file quite simple and we have the base HTML template here uh that is extended by index HTML very simple now the first thing we want to do here in order to be able to use sessions is we need to set a secret key for the signing for the encryption basically so app. secret key has to be set to something now in practice you want to use a good secret key here um for learning purposes for testing purposes you can use whatever you want just some key here uh again if you have an actual application you want to definitely uh set this to something yeah proper but you have now this secret key and with this secret key now you can uh issue basically uh session IDs and you can keep track of information uh of individual users of individual clients on the server site so for example if I want to do this in the index endpoint or actually let’s create individual endpoints for all of these things we’re going to talk about here um let’s do slash set data and let’s call the function here set data as well and what we want to do here is in the session and for this we need to import from flask import session here uh in the session dictionary you could say we want to set now some field to something so for example I can go and say name equals mic now these are just examples you can of course do whatever you want here in reality in actual applications as I mentioned the session data is something that is usually sensitive or that should not be changed by the user that should not be seen by the user maybe something that is not um yeah something that you’re supposed to be able to trust on the server side that’s the basic idea so session name equals mik and then session maybe something else let’s call it other equals hello world whatever you want to call it so this is now information stored in the session dictionary in this case um and this will be associated with a specific session ID so what I can do here now is I can say return render template and I can you know return index HTML maybe what we’re going to do here is just so we see the difference because I’m going to return here a couple of times uh I’m going to add a paragraph here and in this paragraph we’re going to just have some mess message and the message will be passed uh here so I can say message equals index and here I can say message equals session data set or something like this uh and then maybe Also let’s go ahead and have a couple of anchor Texs here with URL 4 so that we can have some buttons to play around with URL 4 set data and then set session data so let’s run the application and let’s open this up there you go so now I can click on set session data and it says session data set and I can actually see that in my browser if I right click go to inspect and then I go to storage you can see that I have a cookie here so I have a cookie here uh in Firefox and the name of the cookie is session and the value is something that I cannot really read you can see I don’t have any information here I don’t see the actual values for name and other I just have a session cookie and the server has the information for name and for other and I can just get it the server can provide me the information if the server wants to but I don’t have the information here on the client side I just have this session cookie um that I can identify myself with basically so now I can make another end point I can create a route app route um get data and here now I could just go ahead and render the data as the message or into the message so I can say that the name is equal to session name that other is equal to session other and then I can just return render template index HTML and the message will be a formatted string and F string where I have this information so I can say something like name name and other other whatever and then of course I also want to add an anchor tag for this so that we can easily do these things interactively so here I have set session data get session data set get now the interesting thing is I can go now into my memory uh or actually storage and I can delete the session cookie so I can delete my identifier that the server needs to know who I am that the server needs to understand that this is the same session so I can just go ahead delete this and now if I go to get session data I get the key error name because there is no session for this I don’t have a session uh cookie I don’t have a session ID so there is no data that the server can provide me with so actually what would make sense is to say something like if name in session do keys and other in session. keys if that is the case do this else just return with the message uh no session found so in this case now get session data no session found set session data get session data there you go so again this is all happening on the server side this is for security reasons this is what you want to do if you have some sensitive information and you want information that the user cannot change now we can do the same thing now uh or actually before we go to cookies let me show how you can clear a session you can also create an endpoint um app route and then uh we can say clear session and then clear session is also the function what I can do here is I can say session. CLE and then this basically clears the session uh the sessions entirely so it clears all the session data and uh I can then again just copy this and return the uh the message session cleared so now when I run this I don’t have a link to this so let me just add this maybe also with a line break to get a better overview um clear session clear session data then I can clear it now when we look at the storage I don’t have anything here I can set it then I can look again I have a session cookie I can get it still still have the session cookie I can clear the session data and I don’t have the session cookie anymore uh and now I cannot get it because it tells me again no session found so that is how you work with sessions now cookies are quite similar the important thing again is cookies are um cookies are stored on the client side now actually one more thing before we get uh on you can also just pop individual Fields now I’m not going to run this now to not spend too much time on this but if you don’t want to clear the whole session but you only want to pop individual um individual Fields you can also do something like session pop and then name for example so you can pop the name key value pair from the session but then you would still have other so if you have some mechanism for only reading certain parts of it you can also only clear certain parts of it so let us move on to the cookies now let’s say we have a route we want to call this route uh set cookie and the method is also or the function is also so set cookie and what we do here now is we make a response the response instructs the browser to set a cookie again this is client side so now we cannot just set the cookie we need to instruct the browser to set the cookie on the client side and then the client has control over the cookie so I can say response is equal to and for this we need to import a function called make response I think we talked about this already uh make response and the response we make is just render template index.html with a message cookie set that is the response and to this response now we can attach a cookie or we can set a cookie so response set cookie and then we just pass the key and we pass the value so we pass a cookie name and a cookie value so in this case the name is Cookie name or the key is Cookie name and the value is Cookie value and then I can just return to response and then I can also just copy this paste this set cookie set cookie and I need to run the application there’s a problem because I didn’t use a slash there you go now we can rightclick inspect look at the storage look at the cookies we don’t have cookies I can also set a session cookie there you go and now I can set cookie and now you can see we have cookie name cookie value you can see that this is now clear text I can see the content of the cookie I can see cookie name cookie value it’s not like with a session where the server has the information I have it here in my browser um and now we can have an endpoint get cookie so I can copy this down here I can change this to get cookie get get cookie and now what we want to do is we want to say cookie value is equal to request now do we have request imported no we need to get from request we need to get the cookies and in in particular here we want to get the cookie with the name cookie name of course you can have multiple cookies you can set cookie name cookie value then something else uh but in this case we’re interested in this one cookie uh so we get the value and then we can return a response in this case it’s going to be render template index HTML and the message is going to be formatted string cookie value is equal to cookie value so let’s load this and of course we need to have a link here as well so just copy change S to G and now let’s go ahead and see get cookie cookie value so you can see again the cookie is still here now the thing is since I have control over it I can change it it’s my browser I can do with it whatever I want and now if I go to get cookie you can see that the value has changed which shows you why the session might be a better choice in certain cases if it’s my choice whatever I want to do with a cookie it’s my choice I can I can uh you know manipulate it maybe it’s not sensitive maybe it doesn’t really matter but if the server needs to have control about something or over something if the server needs to be able to trust the information uh then of course use the session uh and don’t use cookies because cookies I can do with them whatever I want I can set new ones I can change them I can do whatever I want with cookies because they’re on my system they’re in my browser where’s the session of course I can also change this but I cannot change it in a meaningful way I cannot uh change the value of name and other just because I changed this cookie uh session cookie here um all right what else can we do we can also invalidate cookies so we can remove cookies uh let’s copy this here remove cookie uh and the way we do that is we basically make a response and we instruct the browser to expire the cookie to say the cookie expires in uh immediately basically so we can actually copy this here it’s almost the same we say cookie removed and what we do here now is we set cookie cookie name but we don’t set a value to it because the default value is just an empty string we set expires equal to zero and then we just return the response let’s go and I always forget to add the new endpoint here it is remove cookie remove cookie there you go and if I go and get the cookie I have it here remove the cookie get cookie and there you go bad request so here also again you should check for the key um but we can see in the storage now we don’t have it then again we do have it then again we don’t have it so this is how you can remove a cookie you just let it expire now last but not least I want to show you message flashing which is something in Flash that we can do it is basically you you display a message um that can be flashed using the flash function which can be useful uh if you want to have the field up there on every page for specific status messages for example you locked in or some event happened and uh this is something you could add in the base template for example so the idea is that we have the base template and in the base template what I can do is I can add a section in the body and of course you should style the section properly I’m not going to style it now so it’s going to look uh bad but what we can do here is we can use ginger with Ki brackets percent and I can say with messages being equal to get flashed messages and I can also use an endwith in between what I can do is I can say if there are messages and then of course I have to close it off with an end if if there are messages I’m going to iterate over the messages and show them in an unordered list again this is going to look bad but if you style it properly you will have an info box at the top showing relevant messages that have been flashed so we can say here for message in messages and for we’re going to have a list item with the message so this is how you display the flashed messages now you can flash a me a message in flask by just using the flash function so you import Flash and then let’s go ahead now and create a login page let’s go ahead and say we have an app route SL login and what we do here is we return render template login HTML so this of course needs to be created login HTML there you go then we can or actually let’s go ahead and copy the content of index and just replace this stuff here login page and then the content is going to be a form so we’re going to have a heading One login and we’re going to have a simple form which is going to have an action equal to URL for login and a method being equal to post and then we have some basic input type text name is going to be username placeholder is going to be username then we’re going to copy that we’re going to say this is password this is password this is password then we’re going to have an input type submit that value login very simple that’s basically it that is our login page and what we want to do now is we want to go to index um when we successfully logged in but of course we want to flash the message that we’re now successfully logged in or that the login failed depending on what we do so what we’re going to do here now is we’re going to say if request method and of course we need to allow here for methods being equal to get and to post so if the method is equal to get that is the case just render login HTML otherwise if the method is equal to post then do the following get the value for the values username is equal to request. form doget username password is equal to request form get password and then if username equals noral 9 and password equals 1 2 3 4 5 if that is the case we return render template index HTML and the message will be uh yeah not going to have any message or actually let’s go ahead and say message is going to be empty like this and otherwise we can copy this and also redirect to index the only difference now is going to be our message flashing I’m going to flash in this case successful login and in this case I’m going to flash login failed so the flash function is the only difference here and this is what we display here in the base template at the top so I can go now of course one more time let’s go ahead and add here the login there you go login and now I can say neural 9 1 2 3 4 5 login successful login and now do something else login failed this is the message flashing again usually you want to style this you want to design this properly so that you can have just an info field at the top all right so we’re going to learn how to work with databases in flask in this video today and for this we’re going to create a new project or application from scratch because we’re going to slightly change the structure of the files and of the code because in this case here since we’re working with databases and with models we have to avoid circular Imports because the idea is if you have an application file an appy file for example and you define a database object and this database object is then used in the models file where you define all the models and then you also import the models back into the application file you can end up in an endless Circle in a circular import and that can cause some issues so we’re going to adjust the structure here we’re going to use a factory pattern uh we’re going to talk about this here in a second but first of all what we need to do is we need to install two packages that we need for working with databases and for this you can open up your terminal of course use your virtual environment in this case now for the sake of the tutorial I’m just going to use my base environment but you want to do pip or pip 3 install Flash and then SQL Alchemy and flask migrate these are the two packages that you need to install for this video today let me zoom in a little bit there you go these are the two packages and once you have them installed we can go ahead and we can create now a new application directory let’s call this DB application and let’s let’s create now an app py file now this app py file in order to avoid circular Imports we need to now change the idea a little bit because what we’re going to have here is we’re going to have a DB object now let’s say this DB object is now an empty string but this DB object will be needed in another file that we’re going to have called models.py now why do we need a models py file think about it that way in our flask application we don’t have database tables we have classes so for example what we’re going to do in this video is we’re going to define a person Class A person can have an ID a person can have a name an age uh and other attributes but this is all just a class in python in the database if you’re connecting to a sqlite database or to a postgress database or mySQL database you are connecting to database tables now what the omm does an object relational mapper which is SQL Alchemy in this case what it does is it converts it migrates so to say the class CL into database tables it connects it to Worlds so that you can work with classes and flask and you can basically translate all the actions all the updates all the Creations all the insertions and so on in database language so that it all ends up in tables and that you can also select tables and get uh python objects as an answer now in order to Define that what we need to do in the models file is we need to create a class and so on but we also need to import this DB object in the models file now however once we have the the model defined here we also need to define or we also need to import the model from the models file into the application and then what happens is you import models in app you import app and models and it creates this circular import so we’re going to use a design pattern uh I think it’s the factory pattern where we have a function that creates the application then we have a separate file called run py which is going to run the application so the basic idea here is we’re going to import from flask import flask from flask SQL Alchemy we’re going to import SQL Alchemy and from flask uh migrate we’re going to import migrate these are the Imports now and what we do now is we Define a database object we say DB equals SQL Alchemy so that we can import it in models but then what we do is we create a function which we call create app and this fun function creates the application and returns it as an object so that it’s not always executed when you import this um this appy file because when you import something you execute all of the code however if it’s a function you don’t call the function so what we’re going to do here now is I’m going to say um equals flask uncore uncore name uncore template folder equals templates as we did it before now what we need to do here is we need to configure the string for the SQL database so I need to say okay what am I going to connect to and we’re going to start here with a simple SQL light database because if it doesn’t exist it’s just going to create it it’s the most simple database if you want to connect this to mySQL or postgress you can do that I can show you how to do that with postgress I’m not going to go through the installation of postgress and setting up postgress if you don’t have postgress already running it’s not going to work but you can connect this to any type of database so you can say here app.config and then you have to say SQL Alchemy uncore database _ URI is equal to and then you need this string and in the case of a sqlite database you can use it out of the box already you can say sqlite and then colon SL SL slash and then the path to the database so if it exists the path to the database otherwise just the name of the database so in this case we can say current directory and in this current directory I want to have a test T db. DB for example so this would now create a database test dbdb in this directory here that is the config now what we also do is we say DB initialize application so DB init app app and then what we do now is uh we do a couple of imports now we we’re not going to do the Imports yet um because we don’t have uh the stuff written out yet but what we’re going to do here is we’re going to import the routes so the views that we had before like app route Index app route create something or so on uh and we’re going to have in these routes they’re going to import the models which is again where the circular input uh import would happen uh but for now we’re going to leave this empty so we’re going to say here Imports later on and then what we want to do is we want to say migrate is equal to migrate app and DB and in the end we return the application so what we want to do in our run file is quite simple all we do in our run file is we say from App import create app and then we say flask application here is equal to create app and then we just say if uncore uncore name uncore uncore is equal toore uncore maincore uncore if that is the case just do flask app run host is equal to 000000 and debug equals true that’s down this is how you run the application so now instead of running the appy file We Run The Run py file it’s as simple as that so let us move on now to the model uh the model is going to be whatever you want to have in the database so you can either create the database first and then connect uh your application to the database or you can also create the database tables using uh SQL Alchemy and flask migrate so what we’re going to do here is we’re going to say from App import DB and then we can define a class let’s call it person and this class has to inherit from db. model so we’re defining a database model now and we need to have a double under hcore variable here called table name like this and this is basically the name of the table in the database let’s call table in the database people and all you have to do now is you have to define the field so I can say p ID is equal to db. column and what I do here now is I specify the data type DB integer for example and then I can also do some stuff like primary key equals true which makes the P ID the primary key integer column in the database table um then I can do name equals DB column and then I can say DB and then text now it depends on the database type what you want to use here so for example in the case of sqlite I think there is only text you don’t have something like varar or something but if you’re working with postgress you might want to do something like string and then I don’t know 255 or something or 128 I don’t know whatever you want to do here but I’m going to keep it simple here with text and I can say nullable equals false so it’s not allowed to be empty then I can do something like age is equal to DB column DB integer and then maybe job is equal to DB column DB text like this then I can also Define a representation Dunder method here just what happens when I print this so I can see more information I can say person with name self. name and H self. H that is just a string that you get uh when you when you print a person object here all right now this is a model I have in my application what I need to do now is I need to somehow create a database but in order to do that I first need to use this model in my application and for this we’re going to create a fourth F python file which is going to be routes. py you can also call this views pii it doesn’t really matter and this routes py here is going to import from flask uh render template and request but it’s also going to import from Models the person class and in order again to avoid circular Imports we’re going to do this now with a function again so we’re going to say def register rout takes the parameter app and DB or the parameters app and DB and to this we pass now the application and here we can register the route so we can say app route and by the way this is not necessarily the the only way you can do that or even the best way it’s one way you can do that while avoiding circular Imports it’s not the only way and you can uh try different patterns and different approaches here well let’s just let’s just go ahead and say we have the index function and all we want to do here is we want to say people is equal to person query all then maybe I want to print the string version or actually not print I want to return the string version of this people result here that would be now using the model uh now we don’t use any of these but we’re going to use them here in a second uh let’s also maybe create here a templates directory but now what I can do is I can go into my application here and I can say in appy um in the function this is important now I want to do the Import in the function this is how I’m avoiding the circular import I’m not doing it all the time I’m doing it when I call the function so what I do here now is I say import or actually from routes import register routes and then I call register routes with app and DB like this so I think if I didn’t mess up anything I mean it’s not going to work because we didn’t uh create anything but I’m not sure if we can even run the application let’s see it should probably cause some issue though there you go because we don’t have a table people so what we need to do now is we need to somehow migrate this to a database for this we’re going to open up the terminal in the directory of our uh project for this I’m going to actually open up this terminal here I’m going to navigate to um to my working directory so to current here let me just zoom in a little bit and actually I’m going to go into DB application now here I’m going to run the following command flask DB init flask DB init and you can see that this worked and then I can do flask DB migrate and then you can see detected added table people and in order to now actually create the migration to actually upgrade it I can say flask DB upgrade there you go it’s running the upgrade now the important thing is you only do this flask DB in it once and you do the migrate and upgrade every time you make a change in the scheme add a new class add a new model change a field you can always do that here you have now the database I can always change something I can always say I want to have an additional field or I don’t want to have the job field anymore or or I want to change the nullable or the data type I can do all of that but I have to migrate and upgrade every single time so I can open open up here this sqlite database can open up a connection and I can say select everything from people and you will see that I have P name AG job in the database which is of course great so now what I can do is I can just run this application and you can see that I get an empty list but it loaded all the people from the database because we don’t have any people in the database now what I can do is I can open up again the connection here and I can say insert into people and I can specify the fields uh Fields name H for example values and I can say I want to have Mike being 25 years old and maybe Bob being 30 years old then I can run this and then I can say select everything from people again you can then see I have these entries in the database and now I can again go run my application actually it was running already I can open it up and you can see I have these two people loaded from the database into flask mapped into a class now I have the objects that I can work with that’s the most simple way to do that so you have again a run file you have an app file where you have a function that creates the application just in order to avoid circular Imports here because routes think about it routes import models models Imports uh from App Imports DB from app and app itself again Imports routes routes Imports models models app and so on if we don’t do this in a function here it’s going to cause issues so that’s the basic idea what we’re going to do now in this video is we’re going to Define um or we’re not going to Define we’re going to create a base template again we’re going to create an index and we’re going to create a uh Details page where we can actually create users we can or create people uh delete people and also show more details about the people so we’re going to say here base HTML and we’re going to have the same uh layout that we had before so for the title we’re going to have here a block which is going to be the title block end block and the default title is just going to be default and then here we’re going to have a block content and we’re going to end the block um yeah that’s basically it now for the index what we’re going to do is we’re going to have index HTML the index HTML is going to extend this template extends base. HTML and we’re going to fill first of all the block title with the value index and we’re going to have also the block content and in here we’re going to put our content which is going to be a heading index page and then we can have uh we can list all the people from the database so we can say give me an unordered list and I want to do for person in people and for I want to have a list item here and this list item will be just the person and of course for this to work I need to pass first of all I need to render the HTML render template index.html and I need to pass people come on need to pass people equals to people so then there you go we get all the people from the database now what we want to do is we want to provide a form that allows for the creation of a new person so I’m going to go down here I’m going to say now heading of size three new person I’m going to create a form I’m going to say that the action of the form is going to go to yourl for index HTML um and we’re going to have a post request so we’re going to say method equals post like this and of course for this we need to adjust a route to also accept post so methods is going to be equal to get and post this is all stuff we already covered nothing new and we’re going to go ahead now and say we’re going to have the following fields input type text which is going to be the name placeholder is also going to be name and it’s going to be required like this then I can copy this and I can say I want to have also a type number which is going to be H with a placeholder H not going to be required and we’re going to have also job with a placeholder job and it’s also not required and then I want to have an input type submit with a value create all right so that’s quite simple um and I also want to have line breaks here there you go so that will not work because we need to say URL for index not URL for HTML but now you can see we have this form here and all I have to do now to use the information of this form and create a new user is I have to go into the route I have to distinguish between the two cases so I can say um if request. method is equal to get then just do this and otherwise if the request method is equal to post then what I want to do is I want to create a new um a new entry in the database how do I do that first of all I get all the information from the form so request. form. getet name I do the same thing for age I do the same thing for job age job and then all I have to do is I have to create a new instance of person so I can say person is equal to person name is equal to name H is equal to H and job is equal to job like this uh what’s the problem here yeah of course we need to type cast this into an integer there you go and now this object here this python class instance this python object basically I can just add it to the database by saying db. session. add person and db. session. commit and that is it so I can just copy these two lines here as well so that I can get again the full database table and display it but that is all you need to create a new database instance so let me just rerun this run it open it and then I can say I want to have uh Sarah 29 programmer create there you go we have a new in in the database I can say uh John 89 clerk something like this there you go I can create Now new instances which are also of course in the database they’re not just in my flask application so I can actually select from people and you can see that they’re part of the database and this works not only with sqlite it works with um postgress so I can easily go ahead now since I have postgress configured I can say create uh DB Flash tutorial DB there you go created it and now I can change the connection string to be something else uh I can easily change it to let me just copy this comment this out and say that the string is now going to be postgress ql colon postgress the user postgress the password very creative at localhost Port 5432 SL flash tutorial DB now I can run the full application again or actually I need to first uh I think I need to to where is it I need to migrate so I need to say flask DB migrate class DB upgrades and then I can just uh run the application here so stop and rerun open of course it’s going to be an empty database but I can create new entries here as well there you go now I’m connected to my postgress database not to my sqlite database and I have a new database with a new table with new data um this is how easy it is to switch from one database to another one you can do the same thing with mySQL you just need to know how to configure the uh database of course installing post setting it up might be a little bit more complex but once you have a database running you can just easily change the connection string and everything St is the same I don’t need to adjust anything about the model here um yeah so that is the basic idea uh what we’re also going to do now is we’re going to get we’re going to create two more routes and the two more routes are going to be for getting details about a person and deleting a person so I’m going to say here down below Define delete and delete is going to be an app route which is going to be delete and then we’re going to pass a p ID so a person ID and this is only going to take the method want to keep it professional here delete so this endpoint will only accept the delete method and what we pass here is the PID so we delete a specific user with an ID and all we have to do in order to accompl accomplish this is we need to say person query filter and we need to specify which person are we looking for we’re looking for person with a p ID that is equal to P ID and for this person we want to delete it there you go that’s it and again the only thing we need to do is we need to commit the session like this and then we can return render template index HTML with uh probably we should go and say people equals person query all then we can say people equals people as simple as that so let me just reconnect to the MySQL not the MySQL to the sqlite database because we had some data there let me just rerun this um what I can do now is I can just go ahead and say slash delete one for example uh of course this doesn’t work because I’m using a get method when I’m doing it in the browser so we’re not going to do it in the browser we’re going going to do it directly uh as a JavaScript function so we have this method here uh this route here this function and what we need to do is we need to send a delete request from the front end so from the python uh from the HTML file so we’re going to index and for each entry that I have here I’m going to add a button or a link we could say and this button or link I’m actually going to do it I’m going to make it a button uh this button is going to call a JavaScript function that takes the ID of the specific person and deletes it so we’re going to say here button the onclick is going to be equal to delete person and the parameter here is going to be the person. PID that is what this button does and the text is going to be just delete so for every person we have a button that has an onclick event which calls delete person with the ID of the specific person in this row now we need to Define this function so we’re going to say script type text JavaScript and we’re going to define the function delete person with PID as a parameter and what we need to do here is we need to fetch so we need to send a request we’re going to say I want to send a request to URL for delete I think this is what we called it right where is it routes delete and we can say also that the uh or actually we should use quotation marks here uh we can also say that the PID is equal to P ID because that is a URL parameter we need to pass it here and then we’re going to say plus P ID um and I’m going to say here that the function is going to be or actually the method is going to be uh Delete now please excuse that I’m looking at my second monitor a couple of times I’m not a JavaScript fan so I have to double check my code here um but this is what we do we sent a delete request to this URL endpoint and what we do then is we if it was successful we get the response and we forward it to the if statement if response is okay then we’re going to just say window location reload so that we can reload the page and see what happens uh so we can see the changes and otherwise we’re going to log into the console an error message console error failed to delete item with PID and we’re going to display the P ID here and finally of course we’re going to say catch if we have any errors here we’re going to say what we want to do is console error error during fetching P ID or let’s just do it like this error during fetching and then we can print the error message as well so I hope this works let me just indent this properly but the whole Magic happens actually here we’re fetching the URL for delete and we’re sending uh we’re using a delete method to do that uh yeah so that’s basically it let’s see if this works now let’s open up the application and let’s press delete there you go it deletes the entries from the database I can create some entries here delete oh actually doesn’t work when I just posted so let me just load the page again delete there you go so the entries are now gone from the database and you can also right click inspect and see that the delete button actually contains the ID so delete person 4 delete person 2 depending on the row so this is how you delete the object now finally what we want to do is we want to also display some more details so we want to say app route details and want to get the details for a specific person so for this we’re going to also get here the p and we’re going to define the details method that takes the P ID and all we’re going to do here is we’re going to load the person object from the database and we’re going to show the information so we’re going to say person equals person query filter where the person P ID is equal to the P ID from the URL and we get the first of these it’s always going to be one since the p ID is unique but in case we have many we’re just going to do uh we’re just going to get the first one and we’re now going to render actually the details HTML which is going to be a new one and the person is going to be equal to person like this and here now we’re going to just copy paste the index we’re going to call it detail. HTML I think I use just detail right details actually okay let’s just call it detail then um and here now what I’m going to do is I’m just going to say [Music] person and then person P ID and I can list some information something like name going to be person name H is going to be person H and job is going to be person job like this and the only thing that we need to do now is we need to add a button or actually this time we’re going to use an anchor tag so we’re going to use a link uh for each individual person here we want to have a link to the details page so a ATF is going to be uh URL 4 details and the P ID is going to be equal to person uh person do p like this and we’re going to say that the text for this is going to be details that should be enough to go to The Details page of the respective person and that’s it basically this is how you work with databases in flask this is how you can migrate how you can use any database basically the important thing is again to avoid circular Imports this is one way to do it with a factory pattern you have a create app you have a register uh routes meth method but that is one way to do it you just have to swap out the connection string here and you can use any database you like as long as you set it up properly you define models you migrate them with flask DB migrate flask DB upgrade and that is how you work with databases in flask all right so we’re going to learn how to implement a user authentication system for our flask application in this video today and for this we’re going to continue working on the application from last time remember the structure was slightly different because we had a separate run file which calls the create app function which is defined in the app py file where we use this sort of factory pattern in order to avoid circular Imports and basically all we’re going to do in this video is we’re going to add a class or we’re going to replace the class depending on what you want to do uh you can either replace person and create a user class or you can just add a user class you can have multiple classes as well and we’re going to build an authentication system around this user class so we’re going to be able to log in a user we’re going to be able to register or sign up a user and we’re going to be able to keep a user logged in and see which user is sending a request so that we can um you know show different content depending on the type of user or depending on the exact user that is viewing a certain endpoint so for this we’re going to need an external python package called flask login and we’re also going to install another one called flask bcrypt and the reason we install flask bcrypt is because when you have a user uh and you have user information in the database like a username and a password usually you don’t want to store the password in clear text in the database you want to store a hash of the password in the database and the good thing about a hash is it’s a one-way street so you can take a password you can hash it you get something that is very hard uh to reproduce almost impossible to reproduce with a given input string but you cannot reverse it in any way so you cannot decrypt it it’s not encryption it’s hashing uh and this is what bcrypt basically does so what we’re going to do first now is we’re going to install the packages we’re going to open up the command line and we’re going to type pip or pip 3 install flask-login and flask Das bcrypt like this and once you have this installed we’re going to go to our appy file and we’re going to import from flask login we’re going to import the login manager on and from flask uncore bcrypt we’re going to import bcrypt now let’s go ahead and create a user class now in my case here just to keep it simple and to have a better overview I’m going to remove the person class however you can do everything we do in this video and keep the current functionality from last video so you can actually keep uh all the routes all the models that you have and you can just add a user model but for the sake of Simplicity I’m going to just have one class here so we’re going to say class user and this is obviously going to be a DB model but it’s also going to have something else and for this we need to import report from flask login the user mix in this is something that we’re going to add here to The Inheritance so we’re going to say user mixin here in the parenthesis and then we’re just going to do the same thing as with a person we’re going to say table name let me just zoom in table name is going to be equal to users and then we’re going to say uid is equal to DB column DB integer and primary key equals true and then username is going to be a DB column DB string nullable is going to be equal to false then we are going to say password is also a string nullable false the RO is also going to be a string I’m going to keep it simple here no enm or anything it’s going to be nullable though and then we can say something like description you can add whatever you want here this is basically a user profile so table name is users actually we don’t want to do a comparison here we want to actually assign this uh description is going to be equal to DB column DB string as well and then what we’re going to do is we’re going to Define again the representation Dunder method we’re just going to return here a formatted string maybe with some angle brackets here and we’re going to say user and the user is going to be actually sorry this is a string I want to do user and in in here what we want to do is we want to show the username so self. username and maybe the role as well self. roll all right and one more thing we want to implement a method get ID which is just going to return self U ID just so we can access users by ID easily so that is our user class now of course we need to do the same thing with migration and upgrading so we need to open up a terminal we need to navigate to the directory that we’re currently working at which is here and then I need to say flask DB init or actually this is going to actually not in it we need to use uh first of all we don’t need to use in it because we already did it we need to use um migrate and upgrade but also we need to First of course sanitize all the code we need to remove everything that uses the person uh model so we can replace this here by user uh we can basically get rid of all this so we can just say uh return something here we can also get rid of the detail HTML in the index we can get rid of almost everything actually let’s get rid of everything and then here we don’t really have anything here we have just a model so now it should probably work flash DB migrate then you can see here remove table people added table users and then flask DB upgrade to actually make changes there you go so one thing that you need to understand about flask login is it doesn’t Implement any login procedure it doesn’t Implement any logic whatsoever when it comes to how you want to log in whether you want to do it with a password whether you want to do it with a token whether you want to do it without any uh secret or any any security measure at all all that flask login does is it locks you in it keeps you locked in it handles the user that is currently locked in and it locks you out how exactly you do that is up to you so you basically just use the login manager to say now you’re logged in now you’re logged out and now this is the currently loged in user how or when you log in a user is up to you so you need to implement all the logic with comparing the password hashing the password and so on so we have this models py file now this is just a user and what we’re going to do now in the application so in the app why is first of all since we’re working with sessions here this is what we’re doing behind the scenes we’re working with sessions we need to again Define a secret key so app. secret key as we did it already in the session management is going to be equal to something of course here you want to generate a good secret key I’m just going to use some sample key here some key and then what we want to do is we want to create a login manager so the login manager is going to be equal to login manager and we also want to say login manager init application we pass the application and now what we want to do is we want to Define um a certain we want to Define for the login manager what it means to load a user so what we do is we say and here now we Define a method inside of a method so when you just say uh let’s say the the method or the function is going to be called load user based on a given ID the logic here is to say return user query get uid and for this of course we need to import up here from Models import user otherwise we cannot do that now the important thing is this is now just some function here we need to say that this function is actually how the login manager loads users so we need to give it an annotation here login manager. user loader like this this basically now means said when the login manager loads a user it does it like that it gives you a user based on a uid that is how it’s done um what we also want to do afterwards here is we want to create a bcrypt object so bcrypt is going to be equal to bcrypt and we’re going to pass app here um as a parameter and the important thing now is that we also want to pass the bcrypt object to the register route so we pass here bcrypt to register routes which is remember this function here uh so we pass bcrypt here and we need to do that because of course we need to Hash passwords when we create users and also hash them when we log in users so that is important now we’re going to leave appy for now we’re going to add something later on but now let’s go ahead and try to just Implement a very basic login so no password no fancy stuff just an endpoint where I can go and I can log in a user and another one where I can log out the currently logged in user very simple uh for this let’s go ahead and Define just a simple endpoint let’s call it login um and then a p ID or uid actually so I can just go to an endpoint and when I go to that endpoint I can just log in a user how do I do that uh well all I have to do basically is I have to call the login user function and this is a function provided by flask login so we can say from flask login import log in user I also have log out user which I’m going to import I can also get information about the currently locked in user so current user and I can later on this is I’m going to import it uh now but we’re going to use it later on we can also say that for certain endpoints a login is required so we’re going to import these four things login user logout user current user and login required so all we’re going to do here now is we’re going to Define this login function with pi ID or actually uid as a parameter here and this function will just log in a user so we’re going to say login user uid done that’s it that’s how you log in a user and then we can return success and let’s say for the index page what we’re going to do is we’re going to return current user username as a string so we just want to know what is the username of the current user this is what the index um endpoint gives us and then I can copy this and I can say I want to have also a log out log out endpoint lock out without any ID I’m just logging out the current user and for this we’re going to just say lock out user very simple nothing too fancy let’s run the application and see what happens so first of all I have of course the problem that there’s no uh logged in user so what we’re going to do is we’re going to say for the sake of Simplicity we’re just going to use a try except or actually let’s do it properly let’s say if current user is authenticated I think that is the proper Boolean here we’re going to do that otherwise we’re going to just return no user is logged in let’s do it like this let’s go back no user is logged in now let’s go to slash login oh actually I don’t have a user so let’s first of all before we do anything go to the database and select everything from users you can see we have no users so what we’re going to do is we’re going to say insert into users and here we want to have username password values and then I’m going to just say neural 9 the p password is going to be 1 2 3 4 5 I can run this then I can run this and you can see now I have this user so let’s go back let’s run this and then let’s go SL login one now what’s the problem here login user user is active string has no attribute is active what’s the problem here let me just double check l in user oh of course sorry uh what we need to do actually I didn’t uh write this properly what we need to do is we cannot just log in a user based on the ID we need to log in a user object so what we need to do is we cannot just pass the U ID we need to first get the user that has this uid so user query get uid and then we can pass the user and log in the user so let’s run this again or actually it’s still running Let’s Go slash login one success now let’s go back to index there you go neural 9 is logged in as you can see now I can go to SL logout success let’s go back and no user is logged in so this works you can see that there was no password checking there was no hashing all flask login does is it allows me to log in a user to log out a user and to work with a current user and do some stuff with it but it doesn’t say what the authentication process actually has to be this is what we have to implement ourself so what we’re going to do now is we’re going to just create a basic login system here so we’re going to return render template here I’m just going to say index HTML is going to be the start page nothing too fancy we’re also not going to do any post requests here so just a simple endpoint um and then what we want to do is we want to have a sign up we want to have a login and a log out so we’re going to say app route and here we’re going to say sign up methods are going to be obviously get and post because we need to get the form and then with the form we can sign up and here we’re going to do now if request method is equal to get then we’re going to return render template and the template is going to be be sign up. HTML we don’t have it yet otherwise if the method is equal to post we’re going to do some stuff uh same is going to be true for login so I’m going to just copy that and I’m going to replace this here I’m going to change this to login we’re going to change this to login and we’re going to also load the login HTML now login and signup are going to be very simple HTML files they’re just going to have some basic form with username and password and that’s basically it um of course you can also add for the sign up maybe the other fields if you want to I’m not going to do it here now it’s not really complicated to do that you just add more Fields uh the important thing you need to consider is the hashing so let’s say or actually let’s go ahead and first create the signup so for the sign up uh we literally just need sign up page we literally just need a form that has an action equal to URL for signup method is going to be equal to post and the fields here are just going to be type text name username placeholder username required equals required copy change the type to password change the name to password and change the placeholder to password and then a simple sign up button input type submit value sign up that’s quite simple and that’s also what we’re going to have in our log in page so actually this is when we copy pasted login HTML um this is going to be the same thing the only difference is we’re going to go to login here and the text is also going to be login and here login page now maybe you want to add some breaks here for design reasons here as well but that’s basically it we’re done with the HTML part the interesting part is now how do we actually create a user how do we actually have the password and for this we’re going to go to the routes again and here now if it’s a post request we’re going to get username and password from the form so request form get username request form get password password and now the important thing is you don’t want to store the password in the database you want to store the hash of the password in a database so what we do is we Hash a password we say hashed pass password is equal to bcrypt do generate password hash of password and then what we do is we say user equals user username is equal to username password is equal to hashed password now and then all we have to do is we have to say DB session at this new user and then DB session commit the session and then we can just redirect for this we need to import redirect of course we can just redirect to and we need URL 4 here as well can redirect to index for example um which is going to show the current user or you can also redirect to a profile page if you want to it doesn’t really matter you redirect somewhere where you’re going to see some uh information that is specific to the user in our casee the index HTML file uh will display the user so here what we’re going to do let’s do it right away we’re going to say um if current user is authenticated we don’t even need to pass it if that is the case we’re going to do something otherwise we’re going to do something else and then we’re going to do end if down here and what we’re going to do here is heading of size three hello current user username and otherwise I’m going to just do hello like this so we can easily see if there is a user locked in or locked out maybe we should add also two links here pointing to URL for [Music] login like this and then we should also have one for sign up and maybe also one for log out there you go all right so this is how you create a new user this is done this is the signup process now how do we log in very easy we do the same thing we get username and password from the form we hash the password so we can actually go and copy paste this so we get username and password from the form uh we hashed the password and then we compare the hashed password uh that was hashed now from the user input to the hashed password from the database and if it’s the same we’re going to log in the user so we’re going to say user equals user query uh and then we’re going to use filter because now we’re not going to just get the ID we’re going to say the username has to be equal to the username passed in the form I want to get the first um the first entry we’re going to assume it’s Unique maybe we should set that up in the model but I’m just going to get the first user now and we’re going to say okay if the password of this user the hash password is the same as the hash password here we’re going to lck in the user and we’re going to do that here by saying if bcrypt check uncore password hash user password and password actually we don’t need a password hash here I’m going to do it like this um if that is the case we’re going to say login user and we’re going to return render template index.html and otherwise we’re going to return failed just like this okay so that is the login process again just repeat we sign up by getting a form providing username password hashing the password creating a user with the hash password in a database committing the session showing the index uh maybe we should also redirect here and not just render template I think that’s better uh for the login what we do is we get again username password We compare is there already a user with this username if yes get him does the password hash match and if yes log in the user otherwise just say failed no user was logged in and then finally we’re going to have log out which is just going to log out user and we’re also going to just redirect to index here and keep it simple so I think this should already work let’s see if it works we’re going to run it and now I have sign up log and log out let’s go ahead sign up let’s say I want to have a user mic with password password sign up there you go now I’m not logged in as you can see I’m just getting a hello here I can log in now as Mike with password login hello Mike log out hello log in uh now for neural 9 it’s not going to work because we didn’t have a hash so maybe I want to create uh another one John here and John will have the password 1 2 3 4 5 sign up there you go log in John 1 2 3 4 5 there you go log out and now if I try for example John with some other password I’m going to get failed and if I look into the database you will see that except for the one that I created manually here in the database you can see that the password is always a hash not the clear text password so even if someone hacks a database they’re not going to see the passwords that is important of course for security reasons all right so that’s almost everything but I want to show you something else I want to show you how we can protect certain endpoints uh or at least require for certain endpoints that the user is authenticated so let’s say I have an endpoint Here app route let’s call it secret yeah let’s call it secret def secret is going to be the function and here we just going to return my secret message this is what we get at this end point nothing nothing uh fancy here and of course what you can also do is you can also check for roles you can say if the current user uh Ro is equal to and then you can say admin only then show that otherwise return no permission but I’m not going to implement this now this is very simple you just have to set the role when you sign up or on an edit page um but then you can also check for rle you can do whatever you want here but the only thing that we want to do is we want to require a login so what we can do is we can say add login required and you want to put this below the app definition uh before the route definition here so app route Secret login required and now we can also go to index and add a link here to secret secret and then let’s go and run this now I’m not logged in if I try to go to secret I get this default message unauthorized the server could not verify that you’re an authorized uh that you’re authorized to access this URL if I log in now as mik what was the password I think password log in I’m now Mike secret my secret message okay so when I’m logged in it works um now as you saw when I’m not logged in I get this default error message so I can log out secret unauthorized how can I change that how can I change the behavior of this redirection if I’m not authorized um it’s actually quite easy to do that we just have to go to appy here and we have to add a function and this function will be a call back for this uh unauthorized uh scenario so we’re going to say here that the method is called or the function is called unauthorized callback and we’re going to decide what happens when uh what happens when I’m not unauthorized when I’m not authorized when I’m unauthorized to uh visit an endpoint because I’m not logged in what I’m going to do in this case is I’m going to to do redirect URL for index like this and of course we need to import this redirect URL for and in order to associate this with a login manager we need to again add a decorator login manager unauthorized Handler and um yeah that’s basically it so now when I’m not logged in I’m going to be redirected to index so if I try to go to secret you can see I’m ending up at index if I log in mikic password login secret it works and I can of course also do something else I can also just return some string here custom Behavior so it’s really up to you what you want to do I can log out secret custom Behavior so you can decide that but yeah this is how you build an authentication system in Python flask using flask login and using flask bcrypt all right so we’re going to learn how to work with blueprints and flask in this video today and this is going to make our applications much more professional and much more modular the main idea behind blueprints is that we take the functionality of our program we take our application and we split it up into multiple different components or blueprints which are for the most part independent of one another now of course you can still reference them uh between each other you can still interact with them so you can redirect from one blueprint to another one for example but the idea is that I can work on blueprint a you can work on blueprint B and we don’t have to really uh change the same files we don’t have to constantly interact with one another to merge some uh differences because I’m working on the files of blueprint a you’re working on the files of blueprint B and maybe occasionally we have to adjust some things because I changed the function signature or the name of an ENT point or something but for the most part we can work on these separate Blueprints and then all of them are combined into a central application so you can have one blueprint for a to-do list application uh or a to-do list blueprint uh or section you could say you can have one for a calender you can have one for a habit tracker you can have one for a login page or for authentication in general uh that’s the basic idea and then you can merge All of These Blueprints into a central application and this is just much more structure and uh everything is much more modular and professional now because of that we’re going to do everything from scratch here because we’re going to have a different directory structure and the first thing we’re going to do is we’re going to create a directory I’m going to call this now blueprint app call this whatever you want this is going to be our flask application and outside of this directory I want to run or I want to create a run py file and this is important because we’re going to use this as a package so right away I’m going to say init dot soore nitpy is going to be placed in that directory to make it a package because in all the files we want to have absolute paths we want to say blueprint app do blueprint name do uh module do something whatever you want to import you always want to use the absolute name here of the package blueprint app this is going to be our application now inside of this application I’m going to have an appy file this is going to be our Central File where all of this stuff is going to be merged and created and here what we’re going to do is we’re going to say from flask import flask obviously we’re going to also import URL 4 or actually I don’t think we need that we don’t need URL 4 and I also don’t think that we need redirect we’re just going to import flask uh we’re going to also import from flask SQL Alchemy import SQL Alchemy because of course we’re also going to work with models here so each blueprint will have its own model file models file and also its own routes file so we’re going to have everything that we have in an application we’re going to have in a blueprint other than maybe the database connection itself uh and then from flask migrate we’re going to import migrate so we do the same thing as before we create our database uh object here and then we Define our create app uh function and what we’re going to do here is we’re going to do the same thing as before create a flash application let me just zoom in a little bit create a flask application uncore name uncore the template folder is going to be templates now this is another thing each blueprint will uh each blueprint will have its own template uh folder so app is going to be that app config even though I don’t think we need to have a secret key um but yeah we need to have of course a um a database connection so actually this is not like this app config like this and then the field is SQL Alchemy database URI I’m going to set this equal to sqlite and then three * SL current directory SL test db. DB or call this whatever you want we can call this for this video today blueprints do DB for example um and I don’t think we need the secret key so we’re going to skip that and we’re going to say DB init application app and what we want to do then is here in this section we’re going to uh import and register all blueprints which we don’t have yet so we don’t have any blueprints yet but here we’re going to merge everything together and once this is done we’re going to say migrate is equal to migrate app DB and we’re going to return the app and in our run file this is also not we’re just going to import that from blueprint app.app import create app and then flask app is going to be equal to create app and if uncore uncore uh name uncore is equal toore maincore uncore then we want to do flask app run poost is going to be 00 0 debug equals true there you go so this is our run file you can see we use the absolute path here as well from blueprint app app and um that is our app file here here we’re going to merge everything but we don’t have anything to merge yet so what we’re going to do is we’re going to create our first blueprint and let’s actually just use a uh to-do list blueprint as an example here so we’re going to create now a directory which I’m going to call uh todu this is going to be our to-do blueprint and our to-do blueprint will also or or actually will it be a package let me just double check yeah it will be a package um we’re going to also add an init file here as well to make it a package just keep it empty this is just a file that needs to be present and here now we can create the two files routes py and models py and this is going to be the structure of each blueprint so I can create another one here I can create the blueprint people for example and I will do the same thing I can copy these files I can put them in here uh of course the code is going to be a different one later on but we’re going to have models and routes and then I can make another one we’re going to do three blueprints in this video today uh which I’m going to call Core core basically to just be the homepage the default blueprint which just displays an index page um and here I’m not going to have any models but I’m going to have also routes and I’m going to have anit py file all right so these are now three blueprints but we don’t really have or these are going to be our three blueprints but we don’t have them yet so what we’re going to do first is we’re going to create uh the toce uh routes file here so we’re going to say from flask import request render template the usual stuff uh redirect URL 4 and then what’s new now blueprint with a capital B this is a class blueprint um and then we also want to sa from and now we need the absolute path now this is something important if for some reason your development environment doesn’t show you that this is possible so if I say from blueprint app import DB if that doesn’t work if it somehow um says that this is you know an invalid path or something chances are you have to right click your directory at least in pie charm for example and you have to mark the directory as sources rout then it should work um just if you have the problem in case you have the uh problem and then if if it doesn’t apply right away you might have to invalidate the caches and restart the application and maybe we will have to do this here as well but for now it works so from blueprint app. blueprints do too. models import and here now I’m going to create a uh to-do model so this is nothing new this is just from blueprint app. app import DB class is going to be to-do it’s going to be a DB model we did that already nothing new here table name is going to be equal to uh toos and the fields are going to be the T ID the to-do ID basically it’s going to be a column it’s going to be an integer and it’s going to be the primary key then we’re going to say um that the to-do title is going to be equal to a column it’s going to be a string and it’s not going to be nullable and then we’re going to just copy this I’m going to do the same thing for description but it’s going to be nullable and then maybe done is going to be DB column DB Boolean and it’s also not going to be nullable because it’s either going to be true or false uh and then we can just uh Define a representation Dunder method here so we can just return some stuff like angle brackets to do and then we can use it to do title and whether it’s done or not and of course you want to have this as an F FST string here uh and then we need also get ID even though I’m not sure if we need that or if this was just for the user not sure right now let’s just add it here won’t hurt um and this is now our to-do model which we want to import here to work with it and the functionality itself is not going to be too fancy we did all of the stuff that we’re going to do in this blueprint now we already did so I’m going to go through it quite uh quite quickly the new thing here is that we now are going to create this as a blueprint so we don’t say app equals flask what we do is we say Todo equals blueprint and now we have to name the blueprint it’s going to be todos we’re going to pass here uncore uncore name uncore uncore and we’re going to define a template folder which is going to be templates the same way we did it for um for the application so this is what we do for an application here we just add a blueprint name and this is what we’re going to register now later on in our app py file so this is the blueprint and I can do the same thing now to dece instead of app. route to do. Route and the default route here is going to be slash and we’re going to say that we want to have an index and uh all we want to do here is we want to get all the to-dos from the database so to-do query all and then return and we’re going to render a template now what’s important here is um the structure or the convention the best practice way to do it is to create a directory templates here like this and then inside of it to use the same name of the blueprint again so to-dos templates to-dos like this and here now we place our um index HTML file for example now this brings us to another point we have a base template now let’s let’s just return an empty string for now to not have an error here um we want to use a base template for all the different Blueprints and because of that we’re going to create Also let’s close the blueprints here we’re going to create here in the application itself a directory templates and this templates directory will contain the base HTML template base HTML now this one I’m going to copy because I don’t want to waste too much time writing code that we have already written before so that is that we have again just our simple uh actually we don’t need this because we don’t have bootstrap and we also don’t need this uh but this is basically our blueprint we have uh or not blueprint our template we have here the base uh template with the title and the content block and then we just fill it up with um the other HTML files and here now what I’m going to do is I’m going to just extend so I’m going to say here extends base HTML nothing new here we did that before also again I’m going to fill the block title end block the title is going to be todu and then we’re going to fill up the block content and we going to do end block and what we want to do now for the index routee is we just want to get all the to-dos and then we want to say return render template and here now we need to say to-do /index HTML because remember we have a todu directory in the templates directory itself and we pass people equals people uh sorry not people to-dos equals to do like this now this object we can now use again here and display so we can say unordered list and then I can do four to-do in [Music] todos and four and I can just use list items here to show all the toos individually of course so that is a simple index route and then uh just so we have another endpoint here as well we’re going to use a create endpoint so we’re going to say Tod do. route we’re going to say the endpoint is slash create and uh we’re going to allow for methods get and post we going to say create like this and we’re going to say if request method is equal to get we’re going to just return an HTML file otherwise if request. method is equal to post we going to do something else so here I’m just going to return uh render template and I’m going to return H2 do create. HTML which we don’t have yet so I’m going to copy paste the index HTML I’m going to call it create I’m going to delete all this here um and I’m going to have a simple form that I can use here so I’m going to say H1 create too form again I’m rushing through this because all of this we have already done this is just a repetition the new thing is the blueprints now so I’m going to say here URL 4 uh Tod do. create and method is equal to post and then we’re going to have our field here so we’re going to have input type text which is going to be the title of the to-do so the name is going to be title the placeholder is going to be title and required is going to be equal to required then we’re going to say here input type uh text [Music] description come on description description not required and then we’re going to have a check box with the name done and here we’re just going to say in the end done and finally input type submit and the value is going to be equal to create all right so this is going to be our form and all we have to do now is we have to get the attributes title is going to be equal to um request form get title it’s mandatory so we don’t have to check if it’s there or not and for the description we’re going to say um request. form get description and for done we’re going to say it’s true if done is in request form keys so if the checkbox is checked it’s going to be part of the keys otherwise wi not so we want to set it to false if not um and we want to set also the description to null if it’s empty so we’re going to say description is equal to description if description is not equal to an empty string otherwise it’s going to be none so that is that and then we’re just going to create a new to-do like this we’re going to say that the name is equal to name the description is equal to description and done is equal to done and then then all we have to do is DB session add Todo DB session commit and of course we don’t need name we need Title there you go and then we return a redirect to and now this is also important when we do URL 4 now we need to say it’s not index it’s Todo index because we might have another index and another blueprint and that’s a different one of course so everything you see here except for maybe this blueprint line is stuff that we already did I think in two videos and also this is not not new and this is also not new so all this is already something that we have done before also the model now what’s new is how to get this into the application and how we do that is we register the blueprints so we do that in the create app function we just go ahead and say from blueprint app.app uh not app sorry blueprints do toos routes import um Todo now Todo is not a file to-do is our to-do blueprint that we defined up here this is what we want to import and this is also what we want to register so we have to say now app. register blueprint and we register our to-do blueprint and the important thing now is you want to uh you want to uh associate a prefix with it so URL prefix because you will have multiple of those and what I want to do here for example is just SL toos what this means is that in order to get to my index here I don’t have to say just slash I have to say to-dos slash and to get to create I cannot just go to URL SLC create I have to go to URL SL tocreate that is what the prefix is for uh now I’m not going to run the application yet we’re going to finish all the blueprints before we look at this and the good thing is that all of this can be easily just copy pasted at least for the person uh or for the people blueprints I’m going to delete all this and I’m going to just copy paste everything here uh so from here to no just just this stuff here copy and paste now somehow it doesn’t work so let me do that into files Explorer toce seems to be a bit buggy now it works there you go um and all we have to do now is we have to adjust the obvious parts so for example the model is not going to be to-dos or to-do is going to be person the table name is going to be people it’s not going to be a t ID it’s going to be a p ID it’s going to be a name instead of a title um and it’s going to be an AG which is going to be an integer instead of the description and it’s going to be a job um it’s going to be a job instead of a done and it’s going to be a Str string and it’s going to be down here a person and the person will have a name and H like this and it’s going to be a return P ID so that is how we Chang the model for the routes of course what we need to do is we need to change that it’s not the todu blueprint it’s the people blueprint it’s not the name Todo it’s the name people um it’s also not import from to-do models it’s import from people models and it’s going to be import person let me just adjust my chair it’s making some noises here uh it’s going to be the person model uh it’s not going to be add to doce route it’s going to be add people route down here as well um and here it’s not going to be to doce equals to do query it’s going to be people equals person query all and it’s going to be not to do/ index it’s going to be people slash index and it’s going to be people equals people we of course also have to rename now here this name it’s not going to be people templates to do so it’s going to be people templates people and um I think this is now done down here we’re going to do also people create HTML and here of course we need to also get the different field so it’s going to be get name it’s going to be AG is equal to request form get H and we have to type gas this into an integer again rushing through it because we already did it job is going to be equal [Music] to job and we’re going to say that this is going to be job job is going to be job if job is not empty otherwise none here we’re going to say person is equal to person and here we’re going to say name equals name H equals H and job equals job I’m going to add the person and we’re not redirecting to todu index even though we could do that here um we will do to we will redirect to people index uh now this should already be okay now we only have to change these two things we need to change this to people here we need to change this to person in people we need to change this to person and then for create we have to adjust a little bit more first of all again people create person then people create and then here we want to have [Music] name name then we want to have input type number H H then we want to copy this which is going to be job job job and just submit there you go so this should be it now we have our second blueprint what do we do to register it we go to appy we say from blueprint app. blueprints people. routes import the people blueprint and then register to blueprint people with a prefix SL people so we have in both files here you can see we have index and create index and create and they have the same uh pattern here but they’re different because they have different prefixes now finally what I want to do is I want to um implement the core blueprint which is not going to be super fancy it’s just going to be a simple HTML file uh that is rendered by default um so we’re going to go here we’re going to create also here a uh templates directory with another core directory in it and we’re going to copy here the index and we’re going to also copy the routes just so we don’t have to write every basic stuff from scratch but what we’re going to do now is we’re going to say that the blueprint is called core for not people and we also don’t need to import any models here so we’re just going to call this core and we’re going to have core route which is going to be index and this is just going to render the core index HTML but we’re not going to pass any objects and that is going to be our blueprint that’s it we don’t even need a database so just like this and we also don’t need all the Imports we just need render template and blueprint and our index file will do nothing but just uh link to the two other Pages just so we have a landing page a homepage so a h reference is going to be URL 4 and here now we can say todos index toos like this and then we can say here people index for people and that is actually all I want to do here I think maybe we can add a heading H1 homepage or something and we can say here core something like this and now all we have to do is we have to register this and we’re done um so since this is going to be our default default page I’m going to say from blueprint app blueprints core uh routes we’re going to import core and now I’m going to register this and it’s going to have no URL prefix just a slash so this is going to be our default index so to say now of course what’s important is we need to create the database so let’s go ahead and navigate to our current directory let’s go to blueprint app let’s do flask DB init no module named blueprint app blueprints why is that the case oh I think this is one thing that I forgot to do I wanted to place all of them in into a blueprints directory just to have a little bit uh more of an overview so blueprints is going to be a directory and I’m going to copy or I’m going to move core people introduce into this directory now I did this in my prepared code which is why I did the Imports like that blueprint app um and then blueprints core routes and not just blueprint app core routes uh but now it should work so we do we do here flash DB init flash DB migrate Flash DB upgrade and once this is done we can go into our run py file we can run it we can go to our application here and we can uh click on to do now to do is empty uh oh one thing that I wanted to do maybe this would be um useful is we can go to templates we can go to index and we want to have a link that links to URL 4 todos create I can copy this into the people index as well just so we don’t have to use the URL bar to make these changes so let’s restart the application go here to doce create and now I can say test whatever done create stuff stuff not done create there you go then we can go back we can go to people create person there you go so you can see this works and this is how we connect All These Blueprints you can see the URL patterns here people create and then if I go back to dos and then to do create so this is how we integrate All These Blueprints and this is the core blueprint here so yeah this is how you work with blueprints and flas this is how you make your applications more modular and professional all right so finally we’re going to learn how to deploy our flask application to an actual server on the internet and we’re going to also learn how to containerize our application using Docker in order to do that now when it comes to deploying an application there are multiple ways in which it can can be done for example you can also just copy paste all the files upload them to a Linux server install all the dependencies and run the application this is also an option you can use Docker you can use Docker in combination with some cloud service there’s not one correct way to do it what we’re going to do in this video is we’re going to containerize our application using Docker we’re going to upload the docker image to a Linux server which I have rented for this video uh we’re then going to load the docker image on the server we’re going to run it there and then the application is running on the server without us having to install any dependencies without even having to install python we just need Docker on the server and that’s it now if you want to follow along you will need to have some or if you want to replicate the results you will need to have some server that you can work with so you can either do it locally you can open up a virtual machine if you don’t have an actual server on the internet you can rent a server maybe you can find some free alternative I’m using a paid server that I’m paying for monthly uh but you will need to have some SSH access to a Linux server if you want to follow along if you want to replicate otherwise you can just watch and and learn how it’s done so the application that I’m going to deploy today is going to be the blueprint uh the blueprint application from last video so we’re not going to add any new code here we’re just going to take this application and deploy it now since we didn’t do it properly in the last video since we didn’t use a virtual environment we’re going to create one now just so you see why it’s important to have a virtual environment here so I’m going to open up a terminal down here I’m going to navigate to current and I’m going to uh do the following here I’m going to say python 3-m vnf dovm I’m going to create a virtual environment called vnf then I’m going to say source. vnf bin and activate as you can see now I’m using the environment and if I try to see which packages I have installed you can see I have no pip packages installed here so what I’m going to do here because we need it for the application is I’m going to say pip 3 install flask flask um SQL Alchemy and flask migrate and then this is going to install all the packages now why do we need that because we don’t need the virtual environment for Docker we’re not going to uh to add this to Docker we’re not going to add the virtual environment to Docker why do we need that um because now if I have been working on this for maybe months I will have all the packages relevant for this project in this virtual environment and I can do pip three freeze and I can see all the packages with the versions that I have to make this work so I want to have these exact versions to have the exact behavior of my application so what I can do is I can say pip free uh pip three freeze and then requirements.txt and now what I have here is a requirements file with all all the packages and all the versions that I need uh to make it work on any system basically this is the exact configuration I have in my virtual environment with which it works now for the sake of Simplicity what I’m going to do is I’m going to delete um first while I’m going to delete this I’m going to delete the database itself and I’m going to delete the migrations just so I can start from scratch so the application is still here we still have all the blueprints all the files but we don’t have any data already in there so we’re going to deploy an empty application without a database um now what do we need to do in order to turn this into a dock container what we need is we need to have a so-called Docker file so I need to go up here to current I need to right click and I need to say Docker file and this Docker file now will have the instructions that are necessary um to to build the image to build the docker image so the first thing I want to do is I want to specify the python version so I’m going to say from and then I’m going to say python colon 3.10 I’m going to use slim and Buster here so this is the python version that I’m going to use here 3.10 this is the one that I used uh during deploy uh during development as well and now we need to say okay what exactly has to be done to make this application work first of all let’s define a working directory let’s call the working directory flask app like this um what we want to do here is we want to copy the requirements txt file so we want to say copy requirements txt and the file should be requirements txt in the container in the docker container as well once I have requirements txt uh in the container what I want to do is I want to run the following command pip3 install dasr requirements txt now if you don’t know that pip install – R installs the dependencies from a requirements txt file so it’s going to install all these packages with these versions with these exact versions now once I have all the dependencies installed I can just go ahead and copy all the files um of the application so I can just do copy everything to everything so or current directory to the current directory on the server so copy everything that’s in this directory um and place it on the server as well now we don’t need the virtual environment we can delete that I think it has read only so I need to delete it in my uh my files applications here application here uh but we copy out all the files all the blueprints templates uh run file and and all that also the requirements file we copy all this uh into the container and then we change the work directory to flask app and then slash blueprint app now why do we do that we do that because we need to run some commands remember since we’re working with databases and we don’t have the database here we need to run all these flask DB commands and we have to run them inside of this directory because if I run them here they’re not going to have any effect I have to run them in here where the appy file is located so I have to change the working directory and then I can say run flask DB init run flask DB migrate run flask DB upgrade and then I have to change back to flas because of course I need to run the following command Python 3 run py this is running our application and that is the docker file that we need to create our uh image for our application so what do we do we Define a python version We Define a working directory we install the requirements we copy all the files we go into the application we do all the flash DB commands we go back and we run the py file the the Run py file that’s basically what we need to do here now in order to actually turn this into an image now we need to use our command line so I’m going to open up my terminal here I’m going to navigate to the directory here where the docker file is located and now we need to use Docker in order to build um the image now the important thing is that you need to have doer installed you need to have Docker running in the background the docker Damon has to be active so in case of Docker desktop you just need to run the application then the docker Damon is going to be up I’m not going to spend any time here now uh going through the installation process of Docker or showing you how to uh you know get Docker onto your system first of all it’s not that complicated second of all I think I have a video on this channel already where I do that I’m only going to show you how you can actually uh go through the steps uh that are necessary for deployment so I expect you to have Docker already on your system um so what we’re going to do here is we’re going to say Docker built– Tac and we can call this for example blueprint Docker or something like this uh and we need to pass uh a a DOT here because this means that we’re using the current uh the current uh directory for this Docker um this Docker process so there you go you can see it did all the steps it ran all the commands and the docker image is written so what I can do now is I can list a Docker images that I have using Docker images but in my case I don’t need to do that because I know uh the docker image name that I provided Docker Tac which is blueprint Docker so I can say Docker run- d-p now this is important we want to map Port 5000 depending on which Port you used to Port 5000 so the port 5000 in the docker container should also be the port 5000 on this machine that I’m running this on and then blueprint docker so I run this and now as a result of that I should be able to go to Local Host 5,000 and see my application is running and I should be able to do all the stuff that I was able to do before as you can see my application is running and it’s running as a Docker container so I can now say uh Docker PS what is running you can see here old Lama seems to be running and this is also running so I can just say Docker stop and I have to provide the container ID which is this one I think it’s enough to just say something like this that it recognizes which one I’m talking about uh and now if I try to reload you can see it’s down it’s offline basically so we do have our Docker image um we do have our Docker image ready now what we need to do is we need to upload this Docker image to um to the server and for that we need to first save it somewhere we need to save the docker image into a tar file so what we’re going to do is we’re going to say Docker save – o and now let’s call this blueprint Docker doar and what I want to store here is the blueprint Dash Docker image so this is going to take a while and then we’re going to create this tar file there you go and this is now the file that I want to deploy or that I want to upload to my server this is the whole thing this is my whole whole application as a Docker image so in my case here I do already have an SSH connection to my virtual machine now how do you get this file onto the server it depends on how you want to do that maybe you have some FTP access uh the simplest way to do that is to do that is to use SCP so SCP is basically just let me just zoom in a little bit here SCP is this command here you can also use tldr to see what SCP does it basically can just upload a file it can upload whole directories uh all you have to do is you have to say SCP then the file that you want to upload in my case blueprint uh Docker dotar and then you have to specify the uh host and user so in my case it’s root at and then the server host uh I’m not sure if I’m going to show this here maybe you see it right now uh maybe I’m going to censor it but I’m going to just enter here um um I’m going to enter my host and then you want to specify after the host name colon and then slash uh the path where you want to store this now in my case I’m here on my server in the root directory so I want to store it at root and then slash and then also the same name Blue Print Docker tar so this is how you do that in my case it’s going to ask me for a password now and it’s going to upload the file as you can see see it’s uploading the file to the server now and once this is done I’m going to be able to use that file on the server so I think I should already be able to see it it’s being uploaded here um and then all we have to do is we have of course we need to have Docker installed on the server as well again go to Docker installation guide to see how to do that it’s just adding uh the repository and then installing some dependencies it’s not too complicated um and what you want to do now when this is uploaded let me just close this here what you want to do now is you want to say Docker load dasi blueprint doer. tar and then I have the blueprint Docker image on the system and I just have to say Docker run uh and then blueprint Docker or actually not not just run sorry we need to say Docker run and then what we did before we need to say Das d-p we want to map again 5,000 to 5,000 uh and then blueprint Docker like this and now you can see it’s running and I can go to my um to my server which is public which is on the internet now this is not local anymore and I can use the application I can create people there you go I can use the application the flask application is now deployed on an actual server using a Docker container and this is how you do that you just need to have have a server you need to have Docker as I said again what you could do is you can use SCP to just upload all the files and you can then install all the dependencies using Pip this would also work probably but that’s a more convenient way to do it so that’s it for today’s video I hope you enjoyed it and I hope you’ll learn something if so let me know by hitting a like button and leaving a comment in the comment section down below and of course don’t forget to subscribe to this Channel and hit the notification Bell to not miss a single future video for free other than that thank you much for watching see you in the next video and bye for

By Amjad Izhar
Contact: amjad.izhar@gmail.com
https://amjadizhar.blog


Discover more from Amjad Izhar Blog

Subscribe to get the latest posts sent to your email.

Comments

Leave a comment