11

I have a flask app where using one Flask route the server creates a csv file and saves it to the server. Using a generated button on the client page, another Flask route is triggered to get the most recent file, move it to a tmp folder and send that file to the user using send_file.

Right now, when I run the process the first time and download the file, all works as expected. However, the second time I run the process, it serves me the old CSV instead of the newly generated one. This continues until I hit the refresh button on my browser.

The following is my app code:

from flask import Flask, render_template, flash, redirect, request, url_for, Response, send_file
import os
import time
import shutil
import glob

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'

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


@app.route('/downloadcsv')
def downloadcsv():
    current = os.getcwd()
    try:
        list = glob.glob('{}/*.csv'.format(current))
    except:
        print('No file found')
    basename = os.path.basename(os.path.normpath(max(list, key=os.path.getctime)))
    shutil.move(basename, './tmp/{}'.format(basename))
    return send_file('./tmp/{}'.format(basename), as_attachment=True)

In case it is needed, the following is the JS code which "generates" the download button:

var download = '<div id="downloadsection" class="container-contact100-form-btn"><a href="/downloadcsv"><button id="download" class="contact100-form-btn"> <span>DOWNLOAD CSV</span></button></a></div>';

Please also let me know if I am over complicating the download process...

Thanks!!

Gugmi
  • 315
  • 1
  • 3
  • 9

2 Answers2

34

send_file has a caching timeout that you are not configuring. It will send the same file that has been cached unless you tell it not to cache the file like so:

send_file('./tmp/{}'.format(basename), as_attachment=True, cache_timeout=0)

See the following references for more information:

http://flask.pocoo.org/docs/1.0/api/#flask.send_file

http://flask.pocoo.org/docs/1.0/api/#flask.Flask.get_send_file_max_age

http://flask.pocoo.org/docs/1.0/config/#SEND_FILE_MAX_AGE_DEFAULT

ritlew
  • 1,622
  • 11
  • 13
  • That is EXACTLY what I was looking for. Thank you! – Gugmi Apr 04 '19 at 15:32
  • 1
    I would check Aaron's comment as well if this doesn't fix your issue. – ritlew Apr 04 '19 at 15:33
  • Thanks- your solution did actually fix the issue. – Gugmi Apr 04 '19 at 15:38
  • So using `cache_timeout=0` always will keep my file updated, as long my app is updated too?? – igorkf Dec 26 '19 at 23:21
  • @igorkf `cache_timeout=0` tells flask to cache the file for 0 seconds, where it normally defaults to 43200 seconds (12 hours) – ritlew Dec 27 '19 at 05:00
  • 4
    Is there a way to uncache now the previous file? I got all working by changing the download url and adding ```cache_timeout=0```, but the old link still gives me the old file (the new one lets me change the file). – Rusca8 May 17 '20 at 12:01
  • 1
    Hi I put cache_timeout = 0 but it is not working. any one can help? – CodeGirl Jul 14 '20 at 10:51
  • Hi, I faced the same issue, after adding cache_timeout, the server is still sending the old file. What happens to me, that browser save that file in cache and it is not going to flask server at all, either you can delete it from manually from the cache or you can change route url with above cache_timeout attribute – dheeraj Aug 02 '20 at 04:51
0

@ritlew pretty much answers the question, to add to his answer, After adding cache_timeout=0, clear the browser cache and hit the URL in incognito mode.

You can also try:

Disabling caching in Flask

Ayush Goyal
  • 1
  • 1
  • 1