4

My code currently takes in a file, and saves it to a preset directory, but is it possible to just use the file (read the file) and not save it?

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "yatta"
        else:
            return "file not allowed"

    return render_template("index.html")

I have tried both

file.read() and file.stream.read() but the return value of that is empty. I verify that the file exists in the uploaded directory and see that the file is not empty.

Stupid.Fat.Cat
  • 10,755
  • 23
  • 83
  • 144

2 Answers2

17

I know that this is very outdated but for the sake of people landing here for similar inquiry, here it is if you want to save AND read your file after wards. Seems like Werkzeug's FileStorage class (which is the class to handle uploaded file in Flask) pointing to end of file after every action (saving or reading). So we have to move the pointer up to the beginning of the file before doing any subsequent action. I am using python's pandas in my answer below because I usually read csv into dataframe.

import pandas as pd

@app.route('/', methods=['GET', 'POST'])
    def upload_file():
        if request.method == 'POST':
            file = request.files['file']
            if file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

                ## snippet to read code below
                file.stream.seek(0) # seek to the beginning of file
                myfile = file.file # will point to tempfile itself
                dataframe = pd.read_csv(myfile)
                ## end snippet

                return "yatta"
            else:
                return "file not allowed"

        return render_template("index.html")
addicted
  • 2,901
  • 3
  • 28
  • 49
  • 4
    invaluable - file.stream.seek(0) is a hidden gem - huge thanks! – jtlz2 Nov 10 '17 at 12:01
  • 2
    `file.stream.seek(0)` before `file.save(secure_filename(file.filename))` fixed my problem with empty file saving. Thanxs alot! – berrymorr Aug 11 '20 at 17:49
3

Make sure you're not saving the file with file.save() before you call file.read().

So, your function would be:

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            contents = file.read()
            # do something with file contents
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "yatta"
        else:
            return "file not allowed"

    return render_template("index.html")

Hope this helps!