Flask
Flask a microframework written in Python that makes it easy to get a simple web application up and running with some features that can be useful in the development process.
Install package Flask, create new application.py file with the code and set FLASK_APP=application.py
To start server: flask run

# Import the class `Flask` from the `flask` module from flask import Flask # Instantiate a new web application called `app`, with `__name__` representing the current file app = Flask(__name__) # A decorator; when the user goes to the route `/`, execute the function @app.route("/") def index(): return "Hello, world!"
A route is the part of the URL that determines which page is being requested. The route for the default page is simply “/”.


#when the user goes to the route `/Dmitry' @app.route("/Dmitry") def name(): return "Hello, Dmitry!"

#when the user goes to the route `/<any>` @app.route("/<string:user_name>") def name_variable(user_name): user_name1 = 'Mr ' + user_name.capitalize() return f"Hi, {user_name1}!"
HTML files
Separate HTML files can be rendered (render_template function from Flask module) with variables:
from flask import Flask, render_template app = Flask(__name__) @app.route("/<string:name>") def index(name): return render_template("index.html", var_name=name)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { text-align: center } </style> </head> <body> <h1>Hello, {{ var_name }} </h1> </body> </html>

These templates are rendered using a separate templating language called Jinja2.
Jinja2
Jinja is a modern and designer-friendly templating language for Python.
- In .py: return render_template(“index.html”, var_name=name)
- In html: <h1>Hello, {{ var_name }} </h1>
Jinja2 allows conditional statements:
{% if var_name %} <h2>Yes!</h2> <h3>Hello, {{ var_name }}</h3> <p></p> <a href="{{ url_for('loop') }}">See more...</a> {% else %} <a href="{{ url_for('index') }}">Go back</a> {% endif %}
- Loops:
<ul> {% for each in list %} <li>{{ each }}</li> {% endfor %} </ul>
If there are multiple routes on the Flask server, then one route can link to another as so:
<a href="{{ url_for('func_name') }}">See more...</a>
func_name is the name of a function associated with a route.
@app.route("/") def index(): name = True return render_template("index.html", var_name=name) @app.route("/looplist") def loop(): name = False my_list = ['AA', 'BB', 'CC'] return render_template("index.html", var_name=name, list=my_list)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { text-align: center } </style> </head> <body> <h1>This is constant!</h1> <p></p> <p></p> {% if var_name %} <h2>Yes!</h2> <h3>Hello, {{ var_name }}</h3> <p></p> <a href="{{ url_for('loop') }}">See more...</a> {% else %} <ul> {% for each in list %} <li>{{ each }}</li> {% endfor %} </ul> <a href="{{ url_for('index') }}">Go back</a> {% endif %} </body> </html>


Jinja2 ‘template inheritance’
Create some kind of layout with variables in blocks:
<!DOCTYPE html> <html> <head> <title>My Website!</title> <style> body { text-align: center} </style> </head> <body> <h1>{% block heading %}{% endblock %}</h1> {% block body %} {% endblock %} </body> </html>
In the different HTML files, just extend with the layout and fill blocks.
index.html:
{% extends "layout.html" %} {% block heading %} Index Page {% endblock %} {% block body %} <h2>Hello, {{ var_name }}</h2> <a href="{{ url_for('loop') }}">See more...</a> {% endblock %}
loop.html:
{% extends "layout.html" %} {% block heading %} Loop page {% endblock %} {% block body %} <ul> {% for each in list %} <li>{{ each }}</li> {% endfor %} </ul> <a href="{{ url_for('index') }}">Go back</a> {% endblock %}
application.py
@app.route("/") def index(): name ='User' return render_template("index.html", var_name=name) @app.route("/loop") def loop(): my_list = ['AA', 'BB', 'CC'] return render_template("loop.html", list=my_list)


Forms
the results from HTML forms can now be actually stored and used.
<form action="get-ip-address" method="post"> <input type="text" name="ip_address" placeholder="Enter IP Address"> <button>Add</button> <form>
- action attribute lists the route that should be ‘notified’ when the form is submitted
- method attribute is how the HTTP request to submit the form should be made
- name attribute of the input
The Python code to process this form: import request
from flask import Flask, render_template, request app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/get-ip-address", methods=["POST"]) def print_ip_address(): # take user request, access form, get var nam and store in ip_address ip_address = request.form.get("ip_address") return render_template("ip_address.html", ip_address=ip_address)


If there are multiple request methods: list of methods and ifelse
@app.route("/get-ip-address", methods=["POST", "GET"]) def print_ip_address(): if request.method == "GET": return "Please submit the form" else: ip_address = request.form.get("ip_address") return render_template("ip_address.html", ip_address=ip_address)

Sessions
Sessions are how Flask can keep track of data that pertains to a particular user: could be a global variable (access to all users) or per user(cookies). Install Flask-Session
from flask import Flask, render_template, request, session from flask_session import Session app = Flask(__name__) app.config["SESSION_PERMANENT"] = False app.config["SESSION_TYPE"] = "filesystem" Session(app) @app.route("/", methods=["GET", "POST"]) def index(): if session.get("ip_address") is None: session["ip_address"] = [] if request.method == "POST": ip_address = request.form.get("ip_address") session["ip_address"].append(ip_address) return render_template("index.html", ip_addresses=session["ip_address"])
{% extends "layout.html" %} {% block heading %} Index Page {% endblock %} {% block body %} <ul> {% for each in ip_addresses %} <li>{{ each }}</li> {% endfor %} </ul> <form action="/" method="post"> <input type="text" name="ip_address" placeholder="Enter IP Address"> <button>Add</button> <form> {% endblock %}

Run app from the script
from flask import Flask, render_template, request, session from flask_session import Session app = Flask(__name__) if __name__ == '__main__': app.debug = True app.run()
Debug mode
For every change in the files, the flask server must be restarted to apply those changes. With debug mode enabled – all changes are applied on the fly and no need to re-run flask
set FLASK_ENV=development

For more: Flask Documentation