Chapter 5 Python Web Framework
Chapter 5 Python Web Framework
<name of environment>\Scripts\activate
Step 4: Install Flask
Install Flask within the activated environment using pip:
pip install Flask
Flask is installed automatically with all the dependencies.
Step 5: Test the Development Environment
1. Create a simple Flask application to test the newly created development
environment.
2. Make a file in the Flask project folder called hello.py.
3. Edit the file using a text editor and add the following code to make an application
that prints "Hello world!":
from flask import Flask
app = Flask(__name__)
@app.route('/')
def helloworld():
return 'Hello world!'
For Windows:
setx FLASK_APP "hello.py"
7. Run the Flask application with:
flask run
8. Copy and paste the address into the browser to see the project running:
To View Video: https://www.youtube.com/watch?v=QjtW-wnXlUY
https://www.youtube.com/watch?v=QjtW
5.1.1 Web Server Gateway Interface
WSGI refers to Web Server Gateway Interface. WSGI plays a vital role at the
time when you deploy your Django or Flask application.
WSGI is a specification that describes the communication between web
servers and Python web applications or frameworks
frameworks.. It explains how a web server
communicates with python web applications/frameworks and how web
applications/frameworks can be chained for processing a request.
How does WSGI work?
Now, let’s have a look at how WSGI work. So, to obtain a clear understanding of
WSGI, let us assume a casee scenario where you have a web application developed in
Django or Flask application as shown in the figure
Since a web application is deployed in the web server. The figure below
represents the web server that obtains requests from various users.
The above web server can be apache, NGINX, etc. server which is responsible
for handling various static files and caching purposes. Furthermore, you can also use
the server as a load balancer if you are willing to scale multiple applications.
So, now a problem arises as a web server has to interact with a Python
application.
Hence, a mediator is required for carrying out the interaction between the web
servers and the Python application. So, the standard for carrying out communication
between the web server and Python application is WSGI(Web Server Gateway
Interface).
Now, web server is able to send requests or communicate with WSGI
containers. Likewise, Python application provides a ‘callable’ object which contains
certain functionalities that are invoked by WSGI application which are defined as per
the PEP 3333 standard. Hence, there are multiple WSGI containers available such as
Gunicorn, uWSGI, etc.
The figure below represents the communication that is carried out between
web server, WSGI, and Python application.
Communication between user, web server, WSGI, and Python application.
There are multiple WSGI containers that are available today. Hence, a WSGI
container is required to be installed in the project so that a web server can
communicate to a WSGI container which further communicates to the Python
application and provides the response back accordingly. Finally, when the web server
obtains the response, it is sent back to the web browser/users.
Why use the WSGI rather than directly pointing the web server to the Django or
Flask application?
If you directly point your web server to your application, it reduces
the flexibility of your application. Since your web server now directly points to your
web application, you are unable to swap out web stack components. Now, let’s have a
look at an example to make you clear about the applicability of WSGI. For instance,
today you have decided to deploy your application using Gunicorn but after some
years you decide to switch from Gunicorn to mod_wsgi. Now, in this case, you can
easily switch to mod_wsgi without making any changes in the application or
504 – Web Services and Framework (TYBCA Sem-V)
@app.route('/home')
def home():
return "hello, welcome to our website";
if __name__ =="__main__":
app.run(debug = True)
Flask facilitates us to add the variable part to the URL by using the section. We
can reuse the variable by adding that as a parameter into the view function. Consider
the following example.
Example
from flask import Flask
app = Flask(__name__)
@app.route('/home/<name>')
def home(name):
return "hello,"+name;
if __name__ =="__main__":
app.run(debug = True)
The converter can also be used in the URL to map the specified variable to the
particular data type. For example, we can provide the integers or float like age or
salary respectively.
Example
from flask import Flask
app = Flask(__name__)
@app.route('/home/<int:age>')
def home(age):
return "Age = %d"%age;
if __name__ =="__main__":
app.run(debug = True)
The following converters are used to convert the default string type to the associated
data type.
string: default
504 – Web Services and Framework (TYBCA Sem-V)
add_url_rule() function
There is one more approach to perform routing for the flask web application
that can be done by using the add_url() function of the Flask class. The syntax to use
this function is given below.
add_url_rule(<url rule>, <endpoint>, <view function>)
This function is mainly used in the case if the view function is not given and we
need to connect a view function to an endpoint externally by using this function.
Consider the following example.
Example
from flask import Flask
app = Flask(__name__)
def about():
return "This is about page";
app.add_url_rule("/about","about",about)
if __name__ =="__main__":
app.run(debug = True)
app = Flask(__name__)
@app.route('/admin')
def admin():
return 'admin'
@app.route('/librarion')
def librarion():
return 'librarion'
@app.route('/student')
def student():
return 'student'
@app.route('/user/<name>')
def user(name):
if name == 'admin':
return redirect(url_for('admin'))
if name == 'librarion':
return redirect(url_for('librarion'))
if name == 'student':
return redirect(url_for('student'))
if __name__ =='__main__':
app.run(debug = True)
The above script simulates the library management system which can be used
by the three types of users, i.e., admin, libraria
librarian,
n, and student. There is a specific
function named user() which recognizes the user the re redirect
direct the user to the exact
function which contains the implementation for this particular function.
504 – Web Services and Framework (TYBCA Sem-V)
<table>
<tr><td>Name</td>
<td><input type ="text" name ="uname"></td></tr>
<tr><td>Password</td>
<td><input type ="password" name ="pass"></td></tr>
<tr><td><input type = "submit"></td></tr>
</table>
</form>
</body>
</html>
Now, Enter the following code into the script named post_example.py.
post_example.py
from flask import *
app = Flask(__name__)
@app.route('/login',methods = ['POST'])
def login():
uname=request.form['uname']
passwrd=request.form['pass']
if uname=="ayush" and passwrd=="google":
return "Welcome %s" %uname
if __name__ == '__main__':
app.run(debug = True)
Now, start the development server by running the script using python
post_exmple.py and open login.html on the web browser as shown in the following
image.
Give the required input and click Submit, we will get the following result.
Hence, the form data is sent to the development server by using the post method.
GET Method
504 – Web Services and Framework (TYBCA Sem-V)
Sem
Let's consider the same example for the Get method. However, there are some
changes in the data retrieval syntax on the server side. First, create a form as
login.html.
login.html
<html>
<body>
<form action = "http://localhost:5000/login" method = "get">
<table>
<tr><td>Name</td>
<td><input type ="text" name ="uname"></td></tr>
<tr><td>Password</td>
<td><input type ="password" name ="pass"></td></tr>
<tr><td><input type = "submit"></td></tr>
</table>
</form>
</body>
</html>
@app.route('/login',methods = ['GET'])
def login():
uname=request.args.get('uname')
passwrd=request.args.get('pass')
if uname=="ayush" and passwrd=="google":
return "Welcome %s" %uname
if __name__ == '__main__':
app.run(debug = True)
Now, open the HTML file, login.html on the web browser and give the required input.
504 – Web Services and Framework (TYBCA Sem-V)
Sem
As we can check the result. The data sent using the get() method is retrieved on the
development server.
The data is obtained by using the following line of code.
uname = request.args.get('uname')
Here, the args is a dictionary object which contains the list of pairs of form parameter
and its corresponding value.
In the above image, we can also check the URL which also contains the data sent with
the request to the server. This is an important difference between the GET requests
and the POST requests as the data sent to the server is not shown in the URL on the
browser in the POST requests.
HEAD method
HEAD is a request method supported by HTTP used by the World Wide Web.
The HEAD method asks for a response identical to that of a GET request, but without
the response body. This is useful for retrieving meta
meta-information
information written in response
headers, without having to transport the entire content.
How to make HEAD request through Python Requests
Python’s
’s requests module provides in
in-built method called head() for making a
HEAD request to a specified URI.
Syntax
requests.head(url, params={key: value}, args)
Example
import requests
# Making a HEAD request
r = requests.head('https://httpbin.org/
https://httpbin.org/', data ={'key':'value'})
# check status code for response received
# success code - 200
print(r)
504 – Web Services and Framework (TYBCA Sem-V)
DELETE Method
DELETE is a request method supported by HTTP used by the World Wide Web. The
DELETE method deletes the specified resource. As with a PUT request, you need to
specify a particular resource for this operation. A successful response SHOULD be 200
(OK) if the response includes an entity describing the status, 202 (Accepted) if the
action has not yet been enacted, or 204 (No Content) if the action has been enacted
but the response does not include an entity.
How to make DELETE request through Python Requests
Python’s requests module provides in-built method called delete() for making a
DELETE request to a specified URI.
Syntax
Example
import requests
# Making a DELETE request
r = requests.delete('https://httpbin.org / delete', data ={'key':'value'})
# check status code for response received
# success code - 200
print(r)
# print content of request
print(r.json())
504 – Web Services and Framework (TYBCA Sem-V)
PUT Method
PUT is a request method supported by HTTP used by the World Wide Web. The PUT
method requests that the enclosed entity be stored under the supplied URI. If the URI
refers to an already existing resource, it is modified and if the URI does not point to an
existing resource, then the server can create the resource with that URI.
How to make PUT request through Python Requests
Python’s requests module provides in-built method called put() for making a PUT
request to a specified URI.
Syntax
requests.put(url, params={key: value}, args)
Example
import requests
# Making a PUT request
r = requests.put('https://httpbin.org / put', data ={'key':'value'})
# check status code for response received
# success code - 200
print(r)
# print content of request
print(r.content)
Output –
Generally, in practice, always use PUT for UPDATE Always use POST for CREATE operations.
operations.
web development framework using Python. Some of the most popular choices
include Flask, Django,, and FastAPI. One thing that is common among all these
frameworks is the use of templating engines.
Templating engines allow us to pass the data from the server-side
server side to HTML
pages (also support any text file and XML, CSV, LaTeX, etc) whenever the user makes
the request. This also allows us to build interactive websites with less effort plus the
support for the Object-Oriented
nted paradigm on the abstract level (inheritance) for web
pages nails it.
Jinja is one such template engine that is used extensively in Flask and FastAPI.
Django’s Templating engine is also very much similar to Jinja with a few
differences.Jinja templatingg comes pre-installed
pre installed with Flask and as an optional
requirement in FastAPI. The usage of the templating engine in both frameworks
remains the same.
We are able to use templates in flask for storing the non
non-changing
changing data, but we
can also use them dynamically
lly to show data using Jinja.. Jinja is used to write python-
python
like syntax in HTML files, which helps in using variables like functionality. In other
words, we can make dynamic templates also
also.
File structure
5.3.2.1Jinja2 Delimiters
Jinga 2 template engine provides some delimiters which can be used in the
HTML to make it capable of dynamic data representation. The template system
provides some HTML syntax which are placeholders for variables and expressions
that are replaced by their actual values when the template is rendered.
The jinga2 template engine provides the following delimiters to escape from
the HTML.
o {% ... %} for statements
o {{ ... }} for expressions to print to the template output
o {# ... #} for the comments that are not included in the template output
o # ... ## for line statements
Example
Consider the following example where the variable part of the URL is shown in
the HTML script using the {{ ... }} delimiter.
504 – Web Services and Framework (TYBCA Sem-V)
Sem
message.html
<html>
<head>
<title>Message</title>
</head>
<body>
<h1>hi, {{ name }}</h1>
</body>
</html>
script.py
from flask import *
app = Flask(__name__)
@app.route('/user/<uname>')
def message(uname):
return render_template('message.html',name=uname)
if __name__ == '__main__':
app.run(debug = True)
@app.route('/table/<int:num>')
def table(num):
return render_template('print-table.html',n=num)
table.html',n=num)
if __name__ == '__main__':
app.run(debug = True)
print-table.py
<html>
<head>
<title>print table</title>
</head>
<body>
<h2> printing table of {{n}}</h2>
{% for i in range(1,11): %}
<h3>{{n}} X {{i}} = {{n * i}} </h3>
{% endfor %}
</body>
</html>
504 – Web Services and Framework (TYBCA Sem-V)
message.html
<html>
<head>
<title>Message</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>hi, welcome to the website</h1>
</body>
</html>
style.css
body {
background-color: powderblue;
}
h1 {
color: blue;
}
p{
color: red;
}
allinone.py
from flask import Flask, render_template_string, request
class CustomFlask(Flask):
jinja_options = Flask.jinja_options.copy()
jinja_options.update(dict(
block_start_string='<%',
block_end_string='%>',
variable_start_string='%%',
variable_end_string='%%',
comment_start_string='<#',
comment_end_string='#>',
))
app = CustomFlask(__name__)
app.config['DEBUG'] = True
@app.route("/")
def index():
template = """
<# this is a jinja2 comment #>
<% block stuff %>
<h1>Jinja2</h1>
<% for i in range(5) %>
<p>Hello %% name %%!</p>
<% endfor %>
<h1>Mustache</h1>
<p>{{something}}</p>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
504 – Web Services and Framework (TYBCA Sem-V)
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
<% endblock %>
"""
return render_template_string(template, name=request.values.get('name', Viral'))
if __name__ == "__main__":
app.run(use_debugger=True, use_reloader=True)
Then index.html
<html>
<head>
<script type = "text/javascript"
src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayHello()" value = "Say Hello" />
</body>
</html>
SN Attribute Description
1 Methods By which data is sent from the client-side. i.e. get or post.
3 Cookies These are the temporary short files that hold the names and values of cookies, which
helps to track user session on the client-side.
4 Args Arguments are fetched from the URL address. It is part of the URL address that is
declared in the URL address just after the '?'.
return render_template('customer1.html')
@app.route('/success',methods = ['POST', 'GET'])
def render_datafunction():
if request.method == 'POST':
result = request.form
return render_template("result_data.html",result = result)
if __name__ == '__main__':
app.run(debug = True)
2. Customer1.html
<html>
<body>
<h3>Customer Registration</h3>
<p>Fill this form.</p>
<form action = "http://localhost:5000/success" method = "POST">
<p>Name <input type = "text" name = "entername" /></p>
<p>Email <input type = "email" name = "enteremail" /></p>
<p>Contact <input type = "text" name = "entercontact" /></p>
<p>Pin code <input type ="number" name = "pin" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
3. Result_data.html
<!doctype html>
<html>
<body>
<p><strong>Thanks for the registration. Confirm your details</strong></p>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
</table>
</body>
</html>
Firstly you must run the script.py file by using the command python script.py. This
will start the development server on the localhost:5000, which can be later accessed
on the browser, as given below:
Now click on the submit button, and output is shown in the given screenshot.
flask.render_template(template_name_or_list, **context)
Renders a template from the template folder with the given context.
Parameters
template_name_or_list (Union[str, jinja2.environment.Template, List[Union[str,
jinja2.environment.Template]]]) – the name of the template to be rendered, or
an iterable with template names the first one existing will be rendered
context (Any) – the variables that should be available in the context of the
template.
Return type
str
504 – Web Services and Framework (TYBCA Sem-V)
To remove a session variable, use the pop() method on the session object and
mention the variable to be removed.
Session.pop(key, None) // releases a session variable
Let's see a simple example to understand how we can set and get the session variable.
Session.py
from flask import *
app = Flask(__name__)
app.secret_key = "abc"
@app.route('/')
def home():
res = make_response("<h4>session variable is set, <a href='/get'>Get Variable</a></h4>")
session['response']='session#1'
return res;
@app.route('/get')
def getVariable():
if 'response' in session:
s = session['response'];
return render_template('getsession.html',name = s)
if __name__ == '__main__':
app.run(debug = True)
getsession1.html
<html>
<head>
app = Flask(__name__)
app.secret_key = "ayush"
@app.route('/')
def home():
return render_template("homepage2.html")
@app.route('/login')
def login():
return render_template("loginpage3.html")
@app.route('/success',methods = ["POST"])
def success():
if request.method == "POST":
session['email']=request.form['email']
return render_template('success3.html')
@app.route('/logout')
def logout():
if 'email' in session:
session.pop('email',None)
return render_template('logoutpage2.html');
else:
return '<p>user already logged out</p>'
@app.route('/profile')
def profile():
if 'email' in session:
email = session['email']
return render_template('profile.html',name=email)
else:
return '<p>Please login first</p>'
if __name__ == '__main__':
app.run(debug = True)
homepage2.html
<html>
<head>
<title>home</title>
</head>
<body>
<h3>Welcome to the website</h3>
<a href = "/login">login</a><br>
<a href = "/profile">view profile</a><br>
<a href = "/logout">Log out</a><br>
</body>
</html>
Loginpage3.html
<html>
<head>
<title>login</title>
</head>
<body>
<form method = "post" action = "http://localhost:5000/success">
<table>
<tr><td>Email</td><td><input type = 'email' name = 'email'></td></tr>
<tr><td>Password</td><td><input type = 'password' name = 'pass'></td></tr>
<tr><td><input type = "submit" value = "Submit"></td></tr>
</table>
</form>
</body>
</html>
Success.html
<html>
<head>
<title>success</title>
</head>
<body>
<h2>Login successful</h2>
<a href="/profile">View Profile</a>
</body>
</html>
Logoutpage2.html
<html>
<head>
<title>logout</title>
</head>
<body>
<p>logout successful, click <a href="/login">here</a> to login again</p>
</body>
</html>
Now lets run the loginpage1.py file from cmd as shown below
504 – Web Services and Framework (TYBCA Sem-V)
Now click on the login button, if you directly click on the view profile then it may show
some warning as shown below
We can easily understand the file uploading with the help of an example
In this example, we will provide a file selector (file_upload_form.html) to the
user where the user can select a file from the file system and send it to the server.
On the server-side, the file is retrieved using the request.files ['file'] object and
saved in the server location.
Fileuploadform1.html
<html>
<head>
<title>upload</title>
</head>
<body>
<form action = "/success4" method = "post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type = "submit" value="Upload">
</form>
</body>
</html>
Success4.html
<html>
<head>
<title>success</title>
</head>
<body>
<p>File has been uploaded successfully</p>
<p>File Name: {{name}}</p>
</body>
</html>
Uploladpagefile.py
from flask import *
app = Flask(__name__)
@app.route('/')
def upload():
return render_template("fileuploadform1.html")
@app.route('/success', methods = ['POST'])
def success():
if request.method == 'POST':
f = request.files['file']
f.save(f.filename)
return render_template("success4.html", name = f.filename)
if __name__ == '__main__':
app.run(debug = True)
Click on the Browse button so that we can explore the file system and search
the appropriate file.
Now we have to choose a file, as shown below.
504 – Web Services and Framework (TYBCA Sem-V)
Here click on the Upload button. Then user get a message of successful file uploading
as given below:-
We can confirm this by checking in the directory where upload.py is located, as shown
in the image below.
504 – Web Services and Framework (TYBCA Sem-V)
Sem
Here the first parameter is the location that is referred to as a target place
where the user is going to be redirected.
The second parameter is the status code. It is sent to the header of the
browser. The default code is 302, which stands for "found." And the third one is the
response, and it is used to instantiate the response.
We can understand this with the help of an example.
First of all,, we have to create three pages.
Homepage=home3.html
Login page =login3.html
Python script=redirect.py
Both html file must be saved in the template folder that we made earlier
flask_app/templates and .py file saved to the flask_app folder.
Home3.html
<html>
<head>
<title>home</title>
</head>
<body>
<h3>Welcome</h3>
<a href = "/login">login</a><br>
504 – Web Services and Framework (TYBCA Sem-V)
</html>
login3.html
<html>
<head>
<title>login</title>
</head>
<body>
<form method = "post" action = "http://localhost:5000/validate">
<table>
<tr><td>Email</td><td><input type = 'email' name = 'email'></td></tr>
<tr><td>Password</td><td><input type = 'password' name = 'pass'></td></tr>
<tr><td><input type = "submit" value = "Submit"></td></tr>
</table>
</form>
</body>
</html>
redirect.py
from
flask import *
app = Flask(__name__)
@app.route('/')
def home_page ():
return render_template("home3.html")
@app.route('/login')
def login_page():
return render_template("login3.html");
@app.route('/validate', methods = ["POST"])
def validate():
if request.method == 'POST' and request.form['pass'] == 'Akash':
return redirect(url_for("success"))
return redirect(url_for("login"))
@app.route('/success')
def success():
return "logged in successfully"
if __name__ == '__main__':
app.run(debug = True)
After clicking on the login button, a html form will appear. Fill this form and click on
the Submit button.
If the user enters the wrong details like an incorrect email id or password, then the
page is going to redirect to the same page again and again until the user enters the
correct details.
Example:
If the user enters an incorrect password, then it redirects the login page back again,
and it will show notification, i.e., You have entered incorrect Email or password.
504 – Web Services and Framework (TYBCA Sem-V)
401
403
504 – Web Services and Framework (TYBCA Sem-V)
404
406
415
504 – Web Services and Framework (TYBCA Sem-V)
We can understand the working of the abort() function with the help of an example.
Note:- In this example, we use both the html templates and the same files that we used
in the example of redirect() function, so we don't have to create new files.
Abort1.py
from flask import *
app = Flask(__name__)
@app.route('/')
def home_page ():
return render_template("home3.html")
@app.route('/login')
def login_page():
return render_template("login3.html");
@app.route('/validate', methods = ["POST"])
def validate_code():
if request.method == 'POST' and request.form['pass'] == 'Akash':
return redirect(url_for("success"))
else:
abort(400)
@app.route('/success')
def success():
return "logged in successfully"
if __name__ == '__main__':
app.run(debug = True)
Output
Click on the login.
Fill the correct Email because the code has validation. Click on the Submit button to
see how abort() function works.
504 – Web Services and Framework (TYBCA Sem-V)