Purpose
This application demonstrates how to build a simple Flask web application to upload and retrieve image files with additional fields like name and description. The goal is to provide an easy-to-understand, functional example of file uploads and database integration.
Prerequisites
- Python (>= 3.7)
- Flask framework
- MySQL database
- Basic understanding of Python and Flask
Requirements:
Before running the application, you need to install the necessary dependencies.
- Install Python 3.x (if not already installed).
- Installing and setting Flask.
- python -m venv vevn
- .\venv\Scripts\activate (these is to activate your virtual environment, if error occur you can manually open them usind cd command in the terminal)
- Select python interpretor (if you are using VScose à select view à command palette à python select interpreter à enter interpreter path à. à \your_project\venv\Scripts\python.exe)
- python -m pip install –upgrade pip (if needed to upgrade)
- python -m pip install flask (to install flask)
- create new app.py
- python -m flask –app .\app.py run OR python -m flask run (for running the flask application)
- Install the following packages using pip:
- pip install Flask
- pip install Flask-WTF
- pip install flask-mysqldb
- pip install bcrypt
Ensure that MySQL is installed and running on your local machine, and you have to created a database called mydatabase with a table users containing the following fields:
Steps to Implement
1. Install Required Libraries
Create a requirements.txt file with the following content:
Flask
Flask-MySQLdb
Flask-WTF
WTForms
Run the following command to install the dependencies:
pip install -r requirements.txt
2. MySQL Database Setup
Create a database named file_upload and a table images with the following structure:
CREATE DATABASE file_upload;
USE file_upload;
CREATE TABLE images (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
image_path VARCHAR(255) NOT NULL
);
3. Flask Application Code (app.py)
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_mysqldb import MySQL
import os
from werkzeug.utils import secure_filename
app = Flask(__name__)
# Configuration
app.config['UPLOAD_FOLDER'] = 'static/uploads'
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'}
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = '#A4yu5H#'
app.config['MYSQL_DB'] = 'file_upload'
app.secret_key = 'supersecretkey'
mysql = MySQL(app)
# Helper function to check allowed file extensions
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
@app.route('/')
def index():
cur = mysql.connection.cursor()
cur.execute("SELECT * FROM images")
images = cur.fetchall()
return render_template('index.html', images=images)
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
name = request.form['name']
description = request.form['description']
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
cur = mysql.connection.cursor()
cur.execute("INSERT INTO images (name, description, image_path) VALUES (%s, %s, %s)",
(name, description, filepath))
mysql.connection.commit()
cur.close()
flash('File uploaded successfully!', 'success')
return redirect(url_for('index'))
else:
flash('Invalid file format!', 'danger')
return render_template('upload.html')
if __name__ == '__main__':
app.run(debug=True)
Key Features:
1. File Upload Configuration:
- The app configures the UPLOAD_FOLDER to store files in static/uploads.
- The ALLOWED_EXTENSIONS ensures only specific file types (png, jpg, jpeg, gif) are uploaded, adding a layer of security to restrict unwanted file types.
2. MySQL Integration:
- The app uses flask_mysqldb to connect to a MySQL database (file_upload) for storing file metadata.
- The connection is configured with database credentials: MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, and MYSQL_DB.
- Images’ metadata (name, description, and file path) is stored in the images table of the MySQL database.
3. Helper Function for File Validation:
- allowed_file(filename): A utility function that checks if the uploaded file has an allowed extension. This helps to prevent users from uploading unsupported file types.
4. Routes:
- / (Home Route):
- This route retrieves and displays all uploaded images from the database using an SQL SELECT query.
- It renders the index.html template, passing the fetched images to it for display.
- /upload (Upload Route):
- This route handles both GET (showing the upload form) and POST (handling the form submission).
- On POST, it processes the form to retrieve the name, description, and file.
- If the file is valid, it saves it to the specified UPLOAD_FOLDER, stores the file details (name, description, path) in the database, and flashes a success message.
- If the file is invalid, it shows a danger message.
- / (Home Route):
5. Flash Messages:
- Flash messages are used to notify the user about the success or failure of the file upload. These messages are passed using flash() and are displayed in the templates via get_flashed_messages().
6. File Security:
- The secure_filename() function from werkzeug.utils ensures that the filename is sanitized and safe to use, preventing directory traversal and other security risks.
7. Directory Setup:
- The app expects the static/uploads directory to exist for saving the uploaded files. You should ensure that this directory exists on the server, or add a check to create it if it doesn’t.
4. HTML Templates
templates/index.html
Image Gallery
Uploaded Images
{% for image in images %}
-
{{ image[1] }}
{{ image[2] }}
{% endfor %}
Key features:-
- Dynamic Image List: Displays uploaded images with their name, description, and image.
- Upload Button: Links to the /upload page for new image uploads.
- CSS Styling: Links to the styles.css file for page styling.
templates/upload.html
Upload Image
Upload an Image
Key features:-
- Image Upload Form: Contains fields for name, description, and file selection, allowing users to upload an image.
- POST Method: Submits the form data to the /upload route using POST and multipart/form-data encoding.
- CSS Styling: Links to style.css for page styling.
5. Static Folder
static/styles.css
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}
.container {
width: 80%;
margin: 0 auto;
padding: 20px;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 20px;
}
.btn {
display: inline-block;
padding: 10px 15px;
background-color: #007BFF;
color: #fff;
text-decoration: none;
border-radius: 5px;
text-align: center;
margin-bottom: 20px;
}
.btn:hover {
background-color: #0056b3;
}
.image-list {
list-style: none;
padding: 0;
}
.image-item {
margin-bottom: 20px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #fafafa;
}
.image-item img {
max-width: 100%;
height: auto;
border-radius: 5px;
display: block;
margin: 10px 0;
}
label {
display: block;
margin-top: 10px;
font-weight: bold;
}
input, textarea {
width: 100%;
padding: 10px;
margin: 5px 0;
border: 1px solid #ccc;
border-radius: 5px;
}
button {
padding: 10px 20px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #218838;
}
Key features:-
- General Layout: The body has a clean, light background with a centered container that has padding, a white background, and a subtle shadow for a modern look.
- Buttons and Interactivity: The .btn class styles the upload and navigation buttons with a blue color, which turns darker on hover, while the button element is styled with a green color for the submit button, changing shade when hovered.
- Form and Image Display: The form inputs (input, textarea) and labels are styled for a uniform look, with padding, borders, and rounded corners. The image list has a clean, bordered layout for each image, with responsive sizing for images.
How to Run the Application
- Start your MySQL server and ensure the file_upload database is active.
- Run the Flask application: python app.py
- Open your browser and navigate to http://127.0.0.1:5000/.
Features
- Upload images with a name and description.
- Retrieve and display uploaded images.
- Store file paths and metadata in a MySQL database.
- Validate file types for secure uploads.
Retrieving the Images
1. For Retrieving the Images:
To fetch all the images from the images table:
Go to sql-
SELECT * FROM images;
This will return all rows from the images table, including the image id, name, description, and image_path.
2.Retrieve Image by ID:
To fetch a specific image by its id:
sql
SELECT * FROM images WHERE id = %s;
This query can be used if you want to display or process a single image by its unique identifier.
3.Retrieve Images by Name:
If you want to search for images by a specific name:
sql
SELECT * FROM images WHERE name LIKE '%search_term%';
This will return images whose names contain the search term (search_term). You can replace it with the actual value or pass it dynamically.
4.Retrieve Images Sorted by Date:
If you want to retrieve images ordered by their upload time (assuming you have a created_at timestamp column):
sql
SELECT * FROM images ORDER BY created_at DESC;
This will fetch the images ordered by the created_at field in descending order, showing the most recent uploads first.
Notes:
- Make sure the images table has the necessary fields such as id, name, description, image_path, and optionally created_at for timestamps.
- You can add conditions or use JOIN statements if you need to relate this data with other tables in your database.
Security Considerations
- Use a strong secret key for session management.
- Validate file extensions to prevent malicious uploads.
- Store uploaded files in a separate, restricted directory.