Reputation: 61
I am trying to create a simple web application with Flask. The goal is for a user to be able to upload a file (a .csv in my case), which then gets processed, and in the end the processed file should be saved to the user's computer.
So far, I am able to choose files from the browser and upload it. I save it as a Python object and I can also directly save it to my personal Downloads folder. However, I do not understand how I can make the download path dynamic. If I deploy the app, everybody should be able to have the processed file directly downloaded to their individual folder. How does that work?
Below is my code:
from flask import Flask, render_template, request, redirect
import os
app = Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
@app.route("/upload-csv", methods=["GET", "POST"])
def uplaod_csv():
if request.method == "POST":
if request.files:
csv = request.files["csv"]
path = "this should be dynamic"
csv.save(os.path.join(path, csv.filename))
return redirect(request.url)
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
I am rather new to web development, any kind of help is greatly appreciated!
Upvotes: 3
Views: 13817
Reputation: 61
I managed to get a version that behaves the way I want to:
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
import os
import pandas as pd
app = Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
@app.route("/upload-csv", methods=["GET", "POST"])
def upload_csv():
if request.method == "POST":
if request.files:
csv_upload = request.files["csv"]
filename = csv_upload.filename
csv_upload.save(os.path.join("uploads", csv_upload.filename))
path = os.path.join("uploads", csv_upload.filename)
df = pd.read_csv(path)
new_column = range(12343)
df['new_column'] = new_column
df.to_csv(os.path.join("downloads", filename))
return redirect(url_for('uploaded_file', filename=filename))
return render_template("index.html")
@app.route("/uploads/<filename>")
def uploaded_file(filename):
filename_processed = 'processed' + '-' + filename
return send_from_directory("downloads", filename, as_attachment=True, attachment_filename=filename_processed)
if __name__ == "__main__":
app.run(debug=True)
I can now upload a csv, add a new column, and download it again. Pretty sure there are way better options to do that, but it works :) I first save the requested file in the folder "uploads", then read it from there as a pandas dataframe and do some basic manipulations for testing, then I save it as a csv to a folder called "downloads". From there, I can download it as an attachment.
Thank you for all the inputs!
Upvotes: 2
Reputation: 6093
I guess there is a misunderstanding.
csv.save(os.path.join(path, csv.filename))
- this saves the file on the server - when you develop the app, that is your computer.
This is not the path for the user
.
The user's path is a setting in the user's browser. Usually it is the "downloads" directory or the user gets asked where to save the download.
Upvotes: 1