Flask
Flask
Flask is a lightweight and flexible web framework for Python. It’s designed
to make getting started with web development quick and easy, while still
being powerful enough to build complex web applications.
Advantages of Flask
dependencies.
2. Flask is easy to learn because its simple and intuitive API makes it
flask:
● Package name.
● Used in installation and import statements.
Flask:
● Class name within the flask package.
● Used to create and configure your Flask application.
Request
def handle_request(environ):
request = Request(environ)
# Now request has all the details about the HTTP request
data = request.form.get('data')
return f"Received data: {data}"
request Object :
● request is a global object in Flask that you use to access the details of
the current HTTP request.
● It is essentially a proxy to the current Request instance.
request.method: This returns the HTTP method used in the request (e.g.,
GET, POST, PUT, DELETE).
request.data: This contains the raw data of the request payload. It's useful
for reading binary or JSON data.
raw_data = request.data
request.json: This parses and returns the JSON data in the request payload,
if the Content-Type is application/json.
json_data = request.json
request.files: This is a MultiDict containing file uploads. You can use this to
access files sent with a POST or PUT request.
file = request.files['file']
Flask.g
Using flask.g helps you keep your code clean and maintainable by avoiding
the use of global variables that persist across multiple requests. It ensures
that the data you store is only accessible during the processing of a specific
request, reducing the risk of unintended side effects.
@app.before_request
● To run a function before each request. This is typically used to set up
or initialize data in flask.g that will be needed throughout the request.
Example:
@app.before_request
def before_request():
● Purpose: To run a function after each request. This is used for tasks
that need to be done after the request has been processed but before
the response is sent to the client.
Example:
@app.after_request
def after_request(response):
return response
@app.teardown_request:
This decorator is used to execute a function after each request finishes. This
function runs after the request context is popped, making it ideal for
cleaning up resources like closing database connections, releasing file
handles, or performing any other clean-up activities.
@app.teardown_request
def teardown_request(exception):
@app.route('/')
def home():
response = Response("Hello, World!", status=200, mimetype='text/plain')
return response
Response is the data that the server sends back to the client (browser) after
processing a request. The response can include the HTML content, JSON
data, status code, headers, and more.
app = Flask(__name__)
@app.route('/')
def index():
@app.route('/data')
def data():
data={"key": "value"}
resp=Response(json.dumps(data), status=200, mimetype=’application/json’)
return resp
app = Flask(__name__)
@app.route('/')
def index():
response.headers['Content-Type'] = 'text/plain'
response.status_code = 200
return response
Returning a Tuple: You can return a tuple containing the response body,
status code, and headers.
app = Flask(__name__)
@app.route('/')
def index():
This method provides a concise way to specify the response data, status,
and headers.
Jsonify
is a convenient function provided by Flask to convert a Python dictionary
or other data structures into a JSON response. It sets the Content-Type
header to application/json, ensuring that the client interprets the response
correctly as JSON data.
@app.route('/custom_json')
def custom_json_response():
data = {"message": "Custom JSON response"}
response = jsonify(data)
response.headers['Custom-Header'] = 'Custom-Value'
return response, 202 # 202 Accepted
send_file
This function in Flask is used to send a file from the server to the client.
This is especially useful when you need to allow users to download files,
such as images, PDFs, or other documents. Let's dive into the details of how
to use send_file effectively in Flask.
Using Response class :
app = Flask(__name__)
@app.route('/sendfile')
def send_file_response():
file_path = 'path/to/your/file.txt'
file_content = file.read()
return response
if __name__ == '__main__':
app.run()
app = Flask(__name__)
@app.route('/download')
def download_file():
path = "path/to/your/file.txt"
return send_file(path, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True)
Ex:2
@app.route('/download_image')
def download_image():
path = "path/to/your/image.jpg"
return send_file(path, as_attachment=True,
attachment_filename="downloaded_image.jpg", mimetype='image/jpeg')
@app.route('/display_pdf')
def display_pdf():
path = "path/to/your/document.pdf"
return send_file(path, as_attachment=False, mimetype='application/pdf')
For large files, you might want to enable conditional responses to improve
performance.
@app.route('/download_large')
def download_large_file():
path = "path/to/your/large_file.zip"
return send_file(path, as_attachment=True, conditional=True)
import requests
if response.status_code == 200:
with open('downloaded_example.txt', 'wb') as f:
f.write(response.content)
print('File downloaded successfully')
else:
print('Failed to download file')
Python client to read the content of the file directly from the Flask server.
import requests
response = requests.get(url)
if response.status_code == 200:
file_content = response.text # Read the content of the file
print('File content:')
print(file_content)
else:
print('Failed to read file')
If you are dealing with binary files (like images or PDFs), you should use
response.content instead of response.text.
render_template
is used to render HTML templates and send them to the client. It's a
fundamental part of building dynamic web applications with Flask,
allowing you to separate the HTML structure from the application logic.
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
You can pass variables from your Flask application to the template. These
variables can then be used within the template.
@app.route('/')
def home():
title = "Home Page"
message = "Welcome to the Home Page"
return render_template('index.html', title=title, message=message)
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<p>This is a basic example of using render_template in Flask.</p>
</body>
</html>
@app.route('/')
def home():
title = "Home Page"
items = ["Item 1", "Item 2", "Item 3"]
return render_template('index.html', title=title, items=items)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
Template Inheritance
base.html:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>
<h1>Site Header</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>Site Footer</p>
</footer>
</body>
</html>
{% extends "base.html" %}
{% block content %}
<h1>Welcome to the Home Page</h1>
<p>This is a basic example of using render_template in Flask.</p>
{% endblock %}
cookies
Cookies are small pieces of data that websites store on a user's web browser.
They are used for various purposes, such as keeping track of a user's
session, storing user preferences, and tracking user behavior across
different pages and visits.
Setting Cookies: response.set_cookie('key', 'value', max_age=seconds)
to set a cookie with an optional expiration time.
Example:
from flask import*
app=Flask(__name__)
@app.route('/count')
def counter_value():
count=request.cookies.get('count')
if not count:
count=1
else:
count=int(count)+1
if __name__=="__main__":
app.run(port=9876, debug=True)
@app.route('/delete_cookie')
def delete_cookie():
resp = make_response("Deleting a cookie!")
resp.delete_cookie('username') # Delete the cookie named 'username'
return resp
if __name__ == '__main__':
app.run(debug=True)
session
Sessions in Flask are a way to store information about a user across multiple
requests. They can be useful for keeping track of user preferences, login
states, or other pieces of information that need to persist across different
pages of a web application.
if __name__=="__main__":
app.run(debug=True)
Ex:2
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'supersecretkey'
@app.route('/set_session')
def set_session():
session['username'] = 'john_doe'
return 'Session data set!'
@app.route('/get_session')
def get_session():
username = session.get('username')
if username:
return f'Hello, {username}!'
else:
return 'Hello, Guest!'
@app.route('/remove_session')
def remove_session():
session.pop('username', None)
return 'Session data removed!'
@app.route('/clear_session')
def clear_session():
session.clear()
return 'All session data cleared!'
if __name__ == "__main__":
app.run(port=9876, debug=True)
Session Expiration
By default, Flask sessions do not have an expiration time, which means they
last only as long as the browser is open. You can configure the session to
expire after a certain period by setting the
PERMANENT_SESSION_LIFETIME configuration variable.
When you want to store data in a session, set the session to be permanent.
This ensures the session respects the configured lifetime.
@app.route('/set_session')
def set_session():
session.permanent = True # Make the session permanent
session['username'] = 'john_doe'
return 'Session data set with expiration!'
flash
Flash messages are used to show one-time messages to users. These
messages are stored in the session and will be removed after they are
retrieved. They are useful for informing users about the results of actions
(e.g., success, failure, form submissions, errors, warnings).
Ex:
from flask import Flask, flash, render_template, redirect, url_for,
get_flashed_messages
app = Flask(__name__)
app.secret_key = 'supersecretkey'
@app.route('/')
def index():
return render_template('index.html')
@app.route('/flash_success')
def flash_success():
flash('Operation was successful!', 'success') # Flash a success message
return redirect(url_for('index'))
@app.route('/flash_error')
def flash_error():
flash('An error occurred.', 'error') # Flash an error message
return redirect(url_for('index'))
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flash Messages</title>
</head>
<body>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul>
{% for category, message in messages %}
<li class="{{ category }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
redirect
A redirect is used in the Flask class to send the user to a particular URL with
the status code.
if __name__ == '__main__':
app.run(debug=True)
url_for() Function
used to build URLs for specific functions defined in your Flask application.
It is particularly useful because it ensures that URLs are generated
dynamically, helping to avoid hardcoding URLs and making your code more
maintainable.
url_for(endpoint, **values)
app = Flask(__name__)
@app.route('/')
def home():
return 'Home Page'
@app.route('/user/<username>')
def profile(username):
return f'User: {username}'
with app.test_request_context():
print(url_for('home')) # Output: /
print(url_for('profile', username='JohnDoe')) # Output: /user/JohnDoe
URL Building with url_for
● Static Files: You can use url_for to generate URLs for static files as
well.
app = Flask(__name__)
@app.route('/admin')
# binding to hello_admin call
def hello_admin():
return 'Hello Admin'
@app.route('/guest/<guest>')
def hello_guest(guest):
return 'Hello %s as Guest' % guest
@app.route('/user/<name>')
def hello_user(name):
if __name__ == '__main__':
app.run(debug=True)
The add_url_rule() function – The URL mapping can also be done using the
add_url_rule() function. This approach is mainly used in case we are
importing the view function from another module. In fact, the app.route
calls this function internally.
Syntax: add_url_rule(<url rule>, <endpoint>, <view function>)
from flask import Flask
app = Flask(__name__)
def greet(name='World'):
return f"Hello, {name}!"
if __name__ == '__main__':
app.run()
Flasks Errors
If there is an error in the address or if there is no such URL then Flask has an
abort() function used to exit with an error code.
● code: int, The code parameter takes any of the following values
● message: str, create your custom message Error.
app = Flask(__name__)
@app.route('/<uname>')
def index(uname):
if uname[0].isdigit():
abort(400)
app=Flask(__name__)
employees=[
{'id':1,'name':'prakash'},
{'id':2,'name':'arun'}
]
@app.route('/get', methods=['GET'])
def get_data():
data = request.get_json()
if not data:
return jsonify(employees)
for e in employees:
if e['id'] == data['id']:
return jsonify(e)
@app.route('/create', methods=['POST'])
def create_record():
data=request.get_json()
for e in employees:
if e['id']==data['id']:
return jsonify('already exists')
employees.append(data)
return jsonify(employees)
@app.route('/update', methods=['PUT'])
def update_record():
data=request.get_json()
for e in employees:
if e['id']==data['id']:
e['name']=data.get('name', e['name'])
return jsonify(employees)
@app.route('/delete', methods=['DELETE'])
def delete_record():
data=request.get_json()
if not data:
employees.clear()
return jsonify(employees)
else:
for e in employees:
if e['id']==data['id']:
employees.remove(e)
return jsonify(employees)
if __name__=='__main__':
app.run(port=5678, debug=True)
Python client
import requests
url='http://127.0.0.1:5678/get'
data={'id':1}
resp=requests.get(url, json=data)
print(resp.json())
# url='http://127.0.0.1:5678/create'
# data={'id':3,'name':'arun'}
# resp=requests.post(url, json=data)
# print(resp.json())
# url='http://127.0.0.1:5678/update'
# data={'id':1,'name':'aruna'}
# resp=requests.put(url, json=data)
# print(resp.json())
# url='http://127.0.0.1:5678/delete'
# data={'id':1}
# resp=requests.delete(url, json=data)
# print(resp.json())
CSRF Protection
is an attack that tricks a user into making an unwanted action on a web
application where they are authenticated. For example, an attacker could
trick you into transferring money from your bank account without your
consent.
from flask import Flask, jsonify
from flask_wtf import CSRFProtect
from flask_wtf.csrf import generate_csrf
app = Flask(__name__)
app.secret_key = 'bvjrbeknfleknfkjrebtvkj'
csrf = CSRFProtect(app)
@app.route('/')
def index():
return jsonify({'csrf_token': generate_csrf()})
@app.route('/csrf/<name>', methods=['POST'])
def csrf_fun(name):
return jsonify(f'Hi, {name}')
if __name__=='__main__':
app.run(debug=True)
Python
import requests
url='http://127.0.0.1:5000/'
session=requests.session()
resp=session.get(url)
csrf_token=resp.json().get('csrf_token')
name='prakash'
url_post=f'http://127.0.0.1:5000/csrf/{name}'
response=session.post(url_post, headers={'X-CSRFToken': csrf_token})
print(response.text)
File Upload
from flask import Flask,request,render_template
import os
app=Flask(__name__)
app.config['UPLOADED_FOLDER']='uploads'
app.config['MAX_CONTENT_LENGTH']=16*1024*1024
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
file=request.files['file']
file.save(os.path.join(app.config['UPLOADED_FOLDER'],file.filename))
if __name__=='__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Upload a File</h1>
<form action="/upload" method="POST"
enctype="multipart/form-data">
<input type="file" name="file" required>
<input type="submit" value="Upload">
</body>
</html>
Python client
import requests
url = 'http://127.0.0.1:5000/upload'
file_path = 'path/to/your/file.jpg'
@app.route('/upload', methods=['POST'])
def upload():
if request.method == 'POST':
files = request.files.getlist("file")
for file in files:
file.save(file.filename)
return "<h1>Files Uploaded Successfully.!</h1>"
WTF Forms
WTForms is a library designed to make the processing of forms easier to
manage. It handles the data submitted by the browser very easily.
Advantages of WT-FORM:
app=Flask(__name__)
app.secret_key='hbfghuvbrib'
class ContactForm(FlaskForm):
name=TextAreaField('Name', validators=[DataRequired()])
gender=RadioField('gender', choices=[('M','Male'),('F','female')])
address=TextAreaField('address')
email=StringField('email', validators=[DataRequired()])
age=IntegerField('age')
language=SelectField('languages', choices=[('py','Python'),('ml','machine
learning')])
submit=SubmitField('Submit')
@app.route('/', methods=['GET','POST'])
def index():
form=ContactForm()
if form.validate_on_submit():
name=request.form['name']
@app.route('/success/<name>', methods=["GET"] )
def success(name):
if __name__=="__main__":
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Submit your Details</h1>
<form method="POST">
{{ form.hidden_tag() }}
<div>
{{ form.name.label }}: {{ form.name}}
<br><br>
{{ form.gender.label }}: {{ form.gender}}
<br><br>
{{ form.address.label }}: {{ form.address }}
<br><br>
{{ form.email.label }}: {{ form.email }}
<br><br>
{{ form.age.label }}: {{ form.age}}
<br><br>
{{ form.language.label }}: {{ form.language }}
<br><br>
{{ form.submit.label }}: {{ form.submit }}
</div>
</form>
</body>
</html>