Render dynamically changing images with same filenames in Flask

thebjorn's solution is valid. I have found multiple posts on Stack Overflow which suggest identical solutions. To view them, search for how to not cache images on Google. link link2 link3

Below is my solution to your problem. This will delete graph file and create new one with plot.savefig on every GET request to /myfunc. I was not sure on which request you wanted this behavior.

@app.route('/myfunc', methods = ['POST', 'GET'])
def myfunc():
    var = request.form["samplename"]
    selected_ecg=ecg.loc[ecg['Patient ID'].isin([var])]
    selected_ecg = selected_ecg.drop('Patient ID', 1)
    arr = np.array(selected_ecg)
    y = arr.T
    x=np.array(range(1,189))
    plot.plot(x,y)

    new_graph_name = "graph" + str(time.time()) + ".png"

    for filename in os.listdir('static/'):
        if filename.startswith('graph_'):  # not to remove other images
            os.remove('static/' + filename)

    plot.savefig('static/' + new_graph_name)

    return render_template("outputs.html", graph=new_graph_name)

Outputs.html

<html>
  <head>

  </head>
   <body>
     <h1>Output page</h1>

      <img src="{{ url_for('static', filename=graph) }}" />

   </body>

</html>

You're running into a caching issue. Static resources, like images, are cached at every point in the chain between your server and the browser. This is a good thing. Most reasonable systems are set up to cache images for at least 1 year at the server (and that's if they're not cached in the browser).

To bust through this cache issue, you'll need to either (i) give the files new names, (ii) reconfigure Vary headers to indicate they shouldn't be cached, or (iii) add a uniqueness fragment -- e.g. instead of using static/graph.png, add a timestamp 'static/graph.png?v=' + (new Date()).valueOf() or a md5 hash.

update: Dinko has given you a fine answer (do read the links he provides). To add cache-busting on the server side, without creating new files, you can calculate an md5 checksum (disadvantage: you'll need to read the entire file):

from hashlib import md5
fname = 'static/graph.png'
with open(fname, 'rb') as fp:
    checksum = md5.new(fp.read()).hexdigest()
fname += "?v" + checksum

or use the last-modified attribute (not always reliable):

from hashlib import md5
fname = 'static/graph.png'
modified_tstamp = str(int(os.stat(fname).st_mtime * 10**6))
fname += "?v" + checksum

both of these methods will serve a cached version as long as the file doesn't change.

Tags:

Python

Html

Flask