snowe
snowe

Reputation: 61

Upload, manipulate, and save files in python flask

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

Answers (2)

snowe
snowe

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

J&#252;rgen Gmach
J&#252;rgen Gmach

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

Related Questions