DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a Secure File Sharing Web App with Python & Flask (Step-by-Step)

In this tutorial, we’ll build a simple but powerful file-sharing web app using Python and Flask.

Users will be able to:

Upload files

Download shared files

Delete files

View file metadata

Access a simple API endpoint

By the end, you'll have a mini Dropbox-style file sharing tool running locally.

Project source code:

👉 https://github.com/rogers-cyber/python-tiny-tools/tree/main/77-File-sharing-web-app

Final Result

Your app will include:

• File upload interface
• Download links
• File size + upload date
• Delete button
• REST API for file list

Step 1 — Install Dependencies

First install Flask.

pip install flask
Enter fullscreen mode Exit fullscreen mode

Flask is a lightweight Python framework perfect for building small web tools quickly.

Step 2 — Create the Project File

Create a file called:

fileshare_pro.py
Step 3 — Import Required Libraries

Start by importing the modules we need.

import os
import uuid
import hashlib
from datetime import datetime
Enter fullscreen mode Exit fullscreen mode

And import Flask components:

from flask import (
    Flask,
    render_template_string,
    request,
    redirect,
    url_for,
    send_from_directory,
    abort
)
Enter fullscreen mode Exit fullscreen mode

What these do
Module Purpose
os file operations
uuid generate unique IDs
hashlib create file hashes
datetime store upload time
Flask web server framework
Step 4 — App Configuration

Next we configure the app.

APP_NAME = "FileShare PRO"
APP_VERSION = "1.0.0"

UPLOAD_FOLDER = "shared_files"
MAX_FILE_SIZE = 1024 * 1024 * 500
Enter fullscreen mode Exit fullscreen mode

This sets:

App name

Version

Upload folder

500MB max file size

Create the folder if it doesn't exist:

os.makedirs(UPLOAD_FOLDER, exist_ok=True)

Initialize Flask:

app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
app.config["MAX_CONTENT_LENGTH"] = MAX_FILE_SIZE
Enter fullscreen mode Exit fullscreen mode

Step 5 — Create an In-Memory Database

We’ll store uploaded files in a Python dictionary.

files_db = {}
Enter fullscreen mode Exit fullscreen mode

Each file will store:

{
id
name
path
size
hash
date
}
Step 6 — Generate Unique File IDs

Each file gets a short unique ID.

def generate_id():
    return str(uuid.uuid4())[:8]
Enter fullscreen mode Exit fullscreen mode

Example ID:

a91b32f0

This makes file URLs shorter and easier to share.

Step 7 — Create File Hash Function

We generate a hash checksum for each file.

def hash_file(path):

    md5 = hashlib.md5()

    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            md5.update(chunk)

    return md5.hexdigest()
Enter fullscreen mode Exit fullscreen mode

Why?

• Detect duplicate files
• Verify file integrity

Step 8 — Calculate File Size

We display file sizes in MB.

def get_file_size(path):
    return round(os.path.getsize(path) / 1024 / 1024, 2)
Enter fullscreen mode Exit fullscreen mode

Example output:

12.45 MB
Step 9 — Create the Web Interface

Instead of separate HTML files, we embed the template directly.

PAGE = """
<!DOCTYPE html>
<html>
<head>
<title>{{app_name}}</title>
Enter fullscreen mode Exit fullscreen mode

The interface includes:

Upload form

File table

Download links

Delete buttons

Example upload form:

<form method="POST" enctype="multipart/form-data">
<input type="file" name="file" required>
<button type="submit">Upload File</button>
</form>

Enter fullscreen mode Exit fullscreen mode

Example file table:

<table>
<tr>
<th>Name</th>
<th>Size</th>
<th>Date</th>
<th>Download</th>
<th>Delete</th>
</tr>
Enter fullscreen mode Exit fullscreen mode

Flask will dynamically populate this using Jinja:

{% for id,file in files.items() %}
Enter fullscreen mode Exit fullscreen mode

Step 10 — Create the Main Route

Now we create the homepage.

@app.route("/", methods=["GET", "POST"])
def index():
Enter fullscreen mode Exit fullscreen mode

If a file is uploaded:

if request.method == "POST":

    f = request.files["file"]

    if not f:
        return redirect("/")
Enter fullscreen mode Exit fullscreen mode

Generate a unique ID.

file_id = generate_id()
Enter fullscreen mode Exit fullscreen mode

Save the file.

filename = f.filename
path = os.path.join(app.config["UPLOAD_FOLDER"], file_id + "_" + filename)

f.save(path)
Enter fullscreen mode Exit fullscreen mode

Store metadata.

files_db[file_id] = {
    "name": filename,
    "path": path,
    "size": get_file_size(path),
    "hash": hash_file(path),
    "date": datetime.now().strftime("%Y-%m-%d %H:%M")
}
Enter fullscreen mode Exit fullscreen mode

Reload the page.

return redirect("/")
Step 11 — Download Files

Next create a download route.

@app.route("/download/<file_id>")
def download(file_id):
Enter fullscreen mode Exit fullscreen mode

Get the file from our database.

file = files_db.get(file_id)

if not file:
    abort(404)
Enter fullscreen mode Exit fullscreen mode

Send the file to the browser.

return send_from_directory(directory, filename, as_attachment=True)
Enter fullscreen mode Exit fullscreen mode

This triggers a download prompt.

Step 12 — Delete Files

Users can remove files.

@app.route("/delete/<file_id>")
def delete(file_id):
Enter fullscreen mode Exit fullscreen mode

Locate the file.

file = files_db.get(file_id)

if not file:
    abort(404)
Enter fullscreen mode Exit fullscreen mode

Delete it from disk.

os.remove(file["path"])
Enter fullscreen mode Exit fullscreen mode

Remove it from memory.

files_db.pop(file_id, None)
Enter fullscreen mode Exit fullscreen mode

Redirect back to homepage.

Step 13 — Create an API Endpoint

You can also expose the data via API.

@app.route("/api/files")
def api_files():
Enter fullscreen mode Exit fullscreen mode

Return JSON.

return {
    "app": APP_NAME,
    "version": APP_VERSION,
    "files": files_db
}
Enter fullscreen mode Exit fullscreen mode

Example response:

{
  "app": "FileShare PRO",
  "version": "1.0.0",
  "files": {...}
}
Enter fullscreen mode Exit fullscreen mode

Step 14 — Run the Server

Start the application.

if __name__ == "__main__":

    print(f"{APP_NAME} v{APP_VERSION} starting...")
    print("Open browser: http://127.0.0.1:5000")

    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Run it:

python fileshare_pro.py
Enter fullscreen mode Exit fullscreen mode

Open your browser:

http://127.0.0.1:5000
Features Recap

Your app now supports:

• File uploads
• Download links
• File deletion
• Upload timestamps
• File hashing
• Simple REST API

All in ~150 lines of Python.

Possible Improvements

Want to turn this into a production-level SaaS tool?

Add:

• user authentication
• cloud storage (S3)
• file expiration
• shareable public links
• drag-and-drop upload
• database (SQLite/PostgreSQL)
• file previews

Source Code

Full project:

👉 https://github.com/rogers-cyber/python-tiny-tools/tree/main/77-File-sharing-web-app

Top comments (0)