Categories
data science

Reading a file using Flask – Python

This took me ages to figure out, and it was tough getting a simple straightforward answer…

BTW – I’m assuming that you know all the Flask basics, so I won’t be covering that. If you don’t, I suggest you go through their amazing tutorial.

This is what I want:

  • I want my web app to read a file (not upload it) and do stuff with it in python.
  • Also, I am using Flask to build my web app

How did I do it?

Once you set up the flask app, go to your __init__.py file and add two app routes or pages. One for uploading and the other for displaying what has been uploaded.

This is what it should look like

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

@app.route('/upload')
def upload_file():
    return 'stuff to be uploaded'

@app.route('/display')
def display_content():
    return 'content to be displayed'

These are just place holders at the moments. Let’s sort out the HTML first.

First, we go for the upload page. This one doesn’t really have to be anything special, simple HTML will do.

I am going to use the following HTML for my upload page:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Upload file</title>
</head>
<body>
  <form action="/display" enctype="multipart/form-data" method="POST">
    <input type="file" name="inputfile">
    <input type="submit" value= "submit">
  </form>
</body>
</html>

There are several things here that are important. First, action has been set to the display page, enctype has been set to multipart/form-data which is important for handling files. Lastly, the input name for the file has been set to inputfile.

Next we create a simple HTML template to display the content of the file.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Display</title>
</head>
<body>
</body>
  {{ file_content }}
</html>

Now let’s go back to the __init__.py file and change our upload and display pages.

# add a couple more imports
from flask import Flask, render_template, request

# upload page displays HTML template file only
@app.route('/upload')
def upload_file():
    return render_template('upload.html')
  
# reader page is where it all happens
@app.route('/display', methods=['GET','POST'])
def display_content():
    results = request.files['inputfile'].read().decode('utf-8')
    return render_template('display.html', file_content=results)

The upload page now renders the upload HTML page with the form in it, not much to explain.

The display app.route is where all the magic happens. First we add the GET and POST methods to the app.route. Then get the relevant data with request, to which we add files (since we’re after the file itself) followed by the input name – in this case inputfile. Now that we have the file we can .read() it. But the data is binary, so we have to .decode('UTF-8') to turn it to string so we can then pass it through to our template.

Took me an entire morning to figure all of this out. Very upset with how easy it actually is.

A small waring: This does NOT include validation or security. I’m only using this myself locally. Don’t do this if you are genuinely thinking about deploying.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s