K Hutch K Hutch - 2 months ago 17
Python Question

Using Flask to load a txt file through the browser and access its data for processing

I am making a data visualization tool that takes input from the user (choosing a file on the computer); processes it in Python with Pandas, Numpy, etc; and displays the data in the browser on a local server.

I am having trouble accessing the data once the file is selected using an HTML input form.

HTML form:

<form action="getfile" method="POST" enctype="multipart/form-data">
Project file path: <input type="file" name="myfile"><br>
<input type="submit" value="Submit">
</form>


Flask routing:

@app.route("/")
def index():
return render_template('index.html')

@app.route('/getfile', methods=['GET','POST'])
def getfile():
if request.method == 'POST':
result = request.form['myfile']
else:
result = request.args.get['myfile']
return result


This returns a "Bad Request The browser (or proxy) sent a request that this server could not understand." error. I have tried a number of different ways of getting the data out of the file and simply printing it to the screen to start, and have received a range of errors including "TypeError: 'FileStorage' object is not callable" and "ImmutableMultiDict' object is not callable". Any pointers on how to approach this task correctly are appreciated.

Answer

Try this. I've been working on saving and unzipping files for the last few days. If you have any trouble with this code, let me know :)

I'd suggest saving the file on disk and then reading it. If you don't want to do that, you needn't.

from flask import Flask, render_template, request
from werkzeug import secure_filename

@app.route('/getfile', methods=['GET','POST'])
def getfile():
    if request.method == 'POST':

        # for secure filenames. Read the documentation.
        file = request.files['myfile']
        filename = secure_filename(file.filename) 

        # os.path.join is used so that paths work in every operating system
        file.save(os.path.join("wherever","you","want",filename))

        # You should use os.path.join here too.
        with open("wherever/you/want/filename") as f:
            file_content = f.read()

        return file_content     


    else:
        result = request.args.get['myfile']
    return result

And as zvone suggested in the comments, I too would advise against using GET to upload files.

Uploading files
os.path by Effbot

Edit:-

You don't want to save the file.

Uploaded files are stored in memory or at a temporary location on the filesystem. You can access those files by looking at the files attribute on the request object. Each uploaded file is stored in that dictionary. It behaves just like a standard Python file object, but it also has a save() method that allows you to store that file on the filesystem of the server.

I got this from the Flask documentation. Since it's a Python file you can directly use file.read() on it without file.save().

Also if you need to save it for sometime and then delete it later, you can use os.path.remove to delete the file after saving it. Deleting a file in Python

Comments