Python Flask File CheckSum
Muhammad Saim
Posted on August 20, 2022
Hello.! I hope you are doing great. Today we will learn how to make a small applictaion which will create checksum of file and evaluate the file with the checksum.
For the checksum I'll be using SHA256
you can use whatever hasing algo you want. You can find the code in this GitHub Repo.
Let's get started with the applictaion.
Make a new diretcory and step into it
mkdir flask-checksum && cd flask-checksum
Initialize the virtualenvironment
python -m venv vnev
OR
virtualenv venv
Activate the virtualenv
source venv/bin/activate
Now it time to install flask
pip install flask
Now its time to create the diretcory structure for our applictaion I'll make it simple.
📦flask-checksum
┣ 📂static
┃ ┣ 📂css
┃ ┣ 📂js
┃ ┗ 📂uploads
┣ 📂templates
┃ ┣ 📂includes
┃ ┣ 📂layouts
┃ ┗ 📂pages
┗ 📜app.py
Download and place CSS and Js files for this project in static/css
and static/js
respectively. After that your directory structure will look like this.
📦static
┣ 📂css
┃ ┗ 📜bootstrap.min.css
┣ 📂js
┃ ┗ 📜bootstrap.bundle.min.js
┗ 📂uploads
┃ ┗ 📜.gitignore
Now open app.py
start building our applictaion and these line of code this will show output of the hello, world in your browser.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello, World"
if __name__ == '__main__':
app.run()
Run this application.
python app.py
This will start a server and you can access the application on this URL 127.0.0.1:5000.
Its time to create templates for our applictaion in templates/layouts
create app.html
file this will be our master layout of the applictaion all these templates will extend this template.
app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
</head>
<body class="bg-white-500">
{% include 'includes/navbar.html' %}
<div class="container">
{% block content %}{% endblock %}
</div>
<script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script>
</body>
</html>
Create a file navbar.html
in templates/includes
.
navbar.html
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="{{ url_for('create_checksum') }}">File CheckSum</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link {% if request.endpoint == 'create_checksum' %} active {% endif %}" aria-current="page" href="{{ url_for('create_checksum') }}">Create</a>
</li>
<li class="nav-item">
<a class="nav-link {% if request.endpoint == 'verify_checksum' %} active {% endif %}" href="{{ url_for('verify_checksum') }}">Verify</a>
</li>
</ul>
</div>
</div>
</nav>
Now we need two more templates for our applictaion one for creating checksum and 2nd for verifing. Let's create two more files in templates/pages
first will be create.html
and 2nd will be verify.html
.
create.html
{% extends 'layouts/app.html' %}
{% block title %} Create CheckSum {% endblock %}
{% block content %}
<div class="row py-5">
<div class="col-md-8 offset-md-2 col-sm-12">
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">
Create CheckSum
</h5>
<form action="{{ url_for('create_checksum') }}" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label for="formFile" class="form-label">File</label>
<input class="form-control" type="file" id="formFile" name="file">
</div>
<div class="mb-3 float-end">
<button class="btn btn-primary" type="submit">create</button>
</div>
</form>
</div>
</div>
{% if checksum %}
<div class="card shadow mt-3">
<div class="card-body">
<h4 class="card-title">your CheckSum</h4>
<p class="bg-primary p-3 text-white">{{ checksum }}</p>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
verify.html
{% extends 'layouts/app.html' %}
{% block title %} Verify CheckSum {% endblock %}
{% block content %}
<div class="row py-5">
<div class="col-md-8 offset-md-2 col-sm-12">
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">
Verify CheckSum
</h5>
<form action="{{ url_for('verify_checksum') }}" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label for="formFile" class="form-label">File</label>
<input class="form-control" type="file" id="formFile" name="file">
</div>
<div class="mb-3">
<label for="checksum">CheckSum</label>
<input type="text" name="checksum" class="form-control" placeholder="CheckSum">
</div>
<div class="mb-3 float-end">
<button class="btn btn-primary" type="submit">Verify</button>
</div>
</form>
</div>
</div>
{% if status != None %}
<div class="card shadow mt-3">
<div class="card-body">
{% if status %}
<div class="alert alert-success">Your file is authentic.</div>
{% else %}
<div class="alert alert-danger">Your file is not authentic.</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
So after that your templates
directory structure will look like this.
📦templates
┣ 📂includes
┃ ┗ 📜navbar.html
┣ 📂layouts
┃ ┗ 📜app.html
┗ 📂pages
┃ ┣ 📜create.html
┃ ┗ 📜verify.html
Now create the main logic of our applictaion so we start with the creating checksum in app.py
and this function in the file.
@app.route('/', methods=['GET', 'POST'])
def create_checksum():
checksum = None
if request.method == 'POST':
file = request.files['file']
new_name = secure_filename(file.filename)
file.save('static/uploads/'+new_name)
checksum = sha256(new_name)
os.remove('static/uploads/'+new_name)
return render_template('pages/create.html', checksum=checksum)
After adding this function your app.py
will look like this.
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import hashlib
import os
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def create_checksum():
checksum = None
if request.method == 'POST':
file = request.files['file']
new_name = secure_filename(file.filename)
file.save('static/uploads/'+new_name)
checksum = sha256(new_name)
os.remove('static/uploads/'+new_name)
return render_template('pages/create.html', checksum=checksum)
if __name__ == '__main__':
app.run(debug=True)
Now create our 2nd function for verifying the checksum.
@app.route('/verify-checksum', methods=['GET', 'POST'])
def verify_checksum():
status = None
if request.method == 'POST':
file = request.files['file']
checksum = request.form.get('checksum')
new_name = secure_filename(file.filename)
file.save('static/uploads/' + new_name)
new_checksum = sha256(new_name)
status = checksum == new_checksum
os.remove('static/uploads/' + new_name)
return render_template('pages/verify.html', status=status)
After adding this function your app.py
will look like this.
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import hashlib
import os
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def create_checksum():
checksum = None
if request.method == 'POST':
file = request.files['file']
new_name = secure_filename(file.filename)
file.save('static/uploads/'+new_name)
checksum = sha256(new_name)
os.remove('static/uploads/'+new_name)
return render_template('pages/create.html', checksum=checksum)
@app.route('/verify-checksum', methods=['GET', 'POST'])
def verify_checksum():
status = None
if request.method == 'POST':
file = request.files['file']
checksum = request.form.get('checksum')
new_name = secure_filename(file.filename)
file.save('static/uploads/' + new_name)
new_checksum = sha256(new_name)
status = checksum == new_checksum
os.remove('static/uploads/' + new_name)
return render_template('pages/verify.html', status=status)
if __name__ == '__main__':
app.run(debug=True)
Now its time for the main and important function of the application which will be the responsible for the hasing.
def sha256(file_name):
hash_sha256 = hashlib.sha256()
with open('static/uploads/'+file_name, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_sha256.update(chunk)
return hash_sha256.hexdigest()
After adding this function your app.py
will look like this.
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import hashlib
import os
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def create_checksum():
checksum = None
if request.method == 'POST':
file = request.files['file']
new_name = secure_filename(file.filename)
file.save('static/uploads/'+new_name)
checksum = sha256(new_name)
os.remove('static/uploads/'+new_name)
return render_template('pages/create.html', checksum=checksum)
@app.route('/verify-checksum', methods=['GET', 'POST'])
def verify_checksum():
status = None
if request.method == 'POST':
file = request.files['file']
checksum = request.form.get('checksum')
new_name = secure_filename(file.filename)
file.save('static/uploads/' + new_name)
new_checksum = sha256(new_name)
status = checksum == new_checksum
os.remove('static/uploads/' + new_name)
return render_template('pages/verify.html', status=status)
def sha256(file_name):
hash_sha256 = hashlib.sha256()
with open('static/uploads/'+file_name, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_sha256.update(chunk)
return hash_sha256.hexdigest()
if __name__ == '__main__':
app.run(debug=True)
Now its time to run the application
python app.py
http://127.0.0.1:5000
Thanks for being with me.
If you want to learn Flask I have started my series Flask For Beginners Please do check out.
What you guys think and query and suggestion you have to feel free to write it down.
Thanks 🤗
Posted on August 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
August 27, 2024