0

I developed a website that would take a user provided file and extract relevant data out of it, I used Python/Flask for the backend and the website is stored in Heroku.

The application is working fine on my local machine, but when I run it in Heroku, whenever I attempt to upload/process a file I get this message on Heroku's logs:

2022-02-14T17:27:48.000421+00:00 app[web.1]: FileNotFoundError: [Errno 2] No such file or directory: '/application/uploads/report.html'

My python code that goes around the file uploading is:

app.config['UPLOAD_PATH'] = './application/uploads'

@app.route('/read', methods=['GET', 'POST'])
def read():
    form = ReadForm()
    if form.validate_on_submit():
        if request.method == 'POST':
            files = request.files.getlist('read')
            for file in files:
                if file and allowed_file(file.filename):
                    filename = secure_filename(file.filename)
                    file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
            return redirect(url_for('show'))
    return render_template('read.html', form=form)

How do I make the uploaded files available to my application? After reading the file, the application just delete it.

I saw a question with a very similar title as mine, here: How to upload file on website hosted by Heroku?

And one of the answers there, suggests using Amazon's S3, is it the only solution?

ftani
  • 170
  • 1
  • 3
  • 12
  • *I saw a question with a very similar title as mine, here: How to upload file on website hosted by Heroku?* is not very similar. It's about having a docker volume (or whatever is on heroku) to store the media, so it won't be lost after redeploy – sudden_appearance Feb 14 '22 at 19:22
  • 1
    Check e.g. this one [Python Flask upload file to app folder on server (heroku)](https://stackoverflow.com/q/44718433/4046632) – buran Feb 14 '22 at 19:26

1 Answers1

0

@buran pointed me to another post here which helped me solving the issue: Python Flask upload file to app folder on server (heroku)

I added the following to my path definition:

base_path = os.path.dirname(__file__)

So the final one would be:

# Path for the files upload part
app.config['UPLOAD_PATH'] = '/uploads'
base_path = os.path.dirname(__file__)

Then when uploading a file I refer to the path like this:

if file and allowed_file(file.filename):
    filename = secure_filename(file.filename)
    file.save(os.path.join(base_path + "/" + app.config['UPLOAD_PATH'], filename))

So, instead of:

file.save(os.path.join(app.config['UPLOAD_PATH'], filename))

I used:

file.save(os.path.join(base_path + "/" + app.config['UPLOAD_PATH'], filename))
ftani
  • 170
  • 1
  • 3
  • 12
  • If I may comment - don't use concatenation to construct paths. i.e. you already using `os.path.join`. So instead of `os.path.join(base_path + "/" + app.config['UPLOAD_PATH'], filename)`, just do `os.path.join(base_path, app.config['UPLOAD_PATH'], filename)`. Or you can use `pathlib` module if prefer more OOP approach to paths. – buran Feb 15 '22 at 08:55