tars
tars

Reputation: 71

using flask, send_file a second time to get changed file with same path and name - caching problem?

On our flask website we implemented a "Download" button. This button invokes a function in flask which is providing the user with an zipped file via send_file(). The first time everything works fine. After clicking the button the second time, the user receives the exact same file again. Seems fine, but in the time the button is clicked again, the file that flask should send is changed and the old one is not existing anymore.

I tried to understand why this is happening with the PyCharm Debugger and noticed, that after pressing the download button a second time, the download routine is not even evoked anymore. So I think there is some kind of caching going on in the background. I even deleted the file to be send from the file system and then pressed the Download button a second time... I got the original file back.

Maybe you guys experienced something similar and can help me with your knowledge. Thank you in advance.

The download code:

@app.route('/download/<expID>')
def download(expID):

 experiment = dbc.getExperiment(int(expID))

# only execute, if owner of experiment calls it AND experiment is NOT running or in queue
 if experiment.getOwner() == cas.username and experiment.getStatus() != 1 and experiment.getStatus() != 2:
    ownerPath = dbc.getUser(experiment.getOwner()).getPath()
    fileName = cas.username + "_" + expID

    # remove old zip (if existing)
    try:
        os.remove(experiment.getPath() + "/" + fileName + ".zip")
    except FileNotFoundError:
        pass

    # create zip in owner folder to work around recursion problem
    make_archive(ownerPath + "/" + fileName, 'zip', root_dir=experiment.getPath(), base_dir=None)

    # move from owner folder to owner/experiment folder
    shutil.move(ownerPath + "/" + fileName + ".zip", experiment.getPath() + "/" + fileName + ".zip");

    # trigger download
    return send_file(
        experiment.getPath()+"/"+fileName + ".zip", as_attachment=True)
 return redirect('/dashboard')

the button:

<form action="/download/{{experiments[i][0]}}">
                <input type="submit" id="download" value="download" />
            </form>

Upvotes: 2

Views: 1781

Answers (1)

tars
tars

Reputation: 71

I found a solution in the documentation of send_file. Flask indeed caches files that you send via send_file and does not access the function you called previously for a certain amount of time. To limit this behavior you can use the cache_timeout argument. For me it looks like this:

return send_file(
            experiment.getPath()+"/"+fileName + ".zip", as_attachment=True, cache_timeout=0)

Upvotes: 3

Related Questions