In this article, we’ll explore the fundamentals of building a file upload and download system using Flask, a lightweight web framework for Python. We’ll walk through the code step-by-step, explaining its functionality and incorporating best practices for security and user experience.
Prerequisites:
- Basic understanding of Python
- Familiarity with web development concepts (optional)
Setting Up the Flask Application:
Project Creation:
- Create a new directory for your project.
- Initialize a virtual environment (recommended for managing dependencies):
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
Flask Installation:
- Install Flask using pip:
pip install Flask
Code Breakdown:
Imports:
from flask import Flask, request, jsonify
from flask import current_app, send_from_directory
import os
Flask
: The core web framework.request
,jsonify
: Tools for handling user requests and responses.current_app
: Provides access to the current application instance.send_from_directory
: Used to send files from a specific directory.os
: Used for interacting with the operating system (file system).
Flask App Initialisation:
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
Flask(__name__)
: Creates a Flask application instance with its name (__name__
is a special variable).app.config['UPLOAD_FOLDER'] = 'uploads'
: Configures the upload directory where uploaded files will be saved.
File Upload Functionality:
def allowed_file(filename):
ALLOWED_EXTENSIONS = set(['ips'])
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload_file', methods=['POST'])
def upload_file():
print("Reached file upload")
if request.method == 'POST':
# Check if the file part is present
if 'file' not in request.files:
return jsonify({'error': 'No file part'})
file = request.files['file']
# Check if user selected a file
if file.filename == '':
return jsonify({'error': 'No selected file'})
if file and allowed_file(file.filename):
filename = file.filename # Secure filename can be implemented here
print("File is ", filename)
# Create upload directory if it doesn't exist
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
# Call your document reading function here (optional)
# ReadDocumentsRAG.read_document(file_path)
return jsonify({'success': 'File Uploaded'})
else:
return jsonify({'error': 'Invalid file format'})
allowed_file(filename)
: Checks if the uploaded file has a supported extension (here, ‘.ips’).@app.route('/upload_file', methods=['POST'])
: Defines a route for handling file upload requests. It only accepts POST requests.- The function logic handles various scenarios:
- Checks if the request contains a file part (
'file' not in request.files
). - Ensures a file was selected (
file.filename == ''
). - Verifies the file format using
allowed_file
. - Creates the upload directory if it doesn’t exist (
os.makedirs
). - Saves the uploaded file to the specified path.
- Optionally, you can call your document reading function here to process the uploaded content.
- Returns success or error messages in JSON format (
jsonify
).
Example Usage:
If your Flask application is running on localhost:5000
and you want to upload a file named data.csv
, the command would be:
curl -X POST -F file=@your_file.txt http://your_flask_app_url/upload_file
Explanation:
-X POST
: Specifies that you’re making a POST request.-F file=@your_file.txt
: Tells cURL to upload the file namedyour_file.txt
as thefile
parameter in the POST request. Replaceyour_file.txt
with the actual path to your file.http://your_flask_app_url/upload_file
: The URL of your Flask application’s endpoint for file uploads.Replacehttp://your_flask_app_url
with the actual URL of your application.
Additional Notes:
- Make sure to replace
your_flask_app_url
with the correct URL of your Flask application. - You can use the
-v
flag with cURL to see more detailed output, including the HTTP response. - For more complex scenarios, you might need to adjust the command based on your specific requirements, such as adding headers or authentication information.
By following these steps and customizing the command to your needs, you can effectively use cURL to upload files to your Flask application.
Downloading Files in Flask
@app.route("/download/<path:filename>", methods=["GET"])
def download(filename):
downloads = os.path.join(current_app.root_path, "downloadable")
print(downloads + "/" + filename)
return send_from_directory(downloads, filename)
Explanation:
Route Definition:
@app.route("/download/<path:filename>", methods=["GET"])
: Defines a route for handling file download requests. The<path:filename>
part allows for dynamic filename parameters.
File Download Logic:
downloads = os.path.join(current_app.root_path, "downloadable")
: Constructs the path to the directory where downloadable files are stored.current_app.root_path
is the root directory of your Flask application.send_from_directory(downloads, filename)
: Uses thesend_from_directory
function to send the specified file from thedownloads
directory. This function automatically sets the appropriate content type and headers for file downloads.
Key Points:
- File Location: Ensure that the
downloadable
directory exists and contains the files you want to make available for download. - Dynamic Filenames: The route allows for dynamic filenames, making it flexible for various download scenarios.
- Content Type and Headers:
send_from_directory
handles the necessary content type and headers for file downloads, ensuring proper browser behavior.
Example Usage:
If your Flask application is running on localhost:5000
and you want to download a file named report.pdf
, the command would be:
curl -O http://localhost:5000/download/report.pdf
This will download the report.pdf
file from your Flask application and save it to a local file named report.pdf
in your current directory.
Additional Notes:
- You can customize the local filename by using the
-o
option instead of-O
. For example,-o my_downloaded_file.txt
would save the file asmy_downloaded_file.txt
. - If you want to see the downloaded content in the terminal instead of saving it to a file, omit the
-O
or-o
option. - You can use the
-v
flag with cURL to see more detailed output, including the HTTP response and the downloaded content.
By following these steps and customizing the command to your needs, you can effectively use cURL to download files from your Flask application.
Learn more [Python] Building a File Upload and Download System with Python Flask