Рендеринг динамически меняющихся изображений с одинаковыми именами файлов в Flask - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть функция просмотра колбы, как показано ниже:

@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)

    #Remove the old file
    os.remove("static\graph.png")
    #Now save the new image file
    plot.savefig("static\graph.png")

    return render_template("outputs.html")

Outputs.html:

<html>
  <head>

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

      <img src="static/graph.png" />

   </body>

</html>

Я использую функцию просмотра колбы для отображения изображения через файл output.html. Подвох в том, что обслуживаемый файл статического изображения постоянно меняется в зависимости от пользовательского ввода. Другими словами, я продолжаю перезаписывать файл изображения, основываясь на входах, выбранных пользователем.

Но проблема в том, что изменяющийся файл изображения не обслуживается. Старый файл изображения, который использовался для первого рендеринга, отображается только для каждого нового ввода пользователя.

Я уже ссылался на старые сообщения, касающиеся подачи динамического содержимого в колбу. Но ни одна из них не принесла пользы.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

thebjorn решение действительно. Я нашел несколько сообщений о переполнении стека, которые предлагают идентичные решения. Чтобы просмотреть их, выполните поиск how to not cache images в Google. ссылка ссылка2 ссылка3

Ниже мое решение вашей проблемы. Это удалит файл графика и создаст новый файл с plot.savefig при каждом запросе GET к / myfunc . Я не был уверен, по какому запросу вы хотели этого поведения.

@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>
0 голосов
/ 08 ноября 2018

Вы столкнулись с проблемой кеширования. Статические ресурсы, например изображения, кэшируются в каждой точке цепочки между вашим сервером и браузером. Это хорошая вещь. Наиболее приемлемые системы настроены для кэширования изображений на сервере не менее 1 года (и это если они не кэшируются в браузере).

Чтобы решить эту проблему с кешем, вам нужно (i) дать файлам новые имена, (ii) перенастроить заголовки Vary, чтобы указать, что они не должны кэшироваться, или (iii) добавить фрагмент уникальности - например вместо использования static/graph.png добавьте метку времени 'static/graph.png?v=' + (new Date()).valueOf() или хэш md5.

обновление: Динко дал вам хороший ответ (прочитайте ссылки, которые он предоставляет). Чтобы добавить кэш-очистку на стороне сервера, не создавая новые файлы, вы можете вычислить контрольную сумму md5 (недостаток: вам нужно прочитать весь файл):

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

или используйте последний измененный атрибут (не всегда надежный):

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

оба эти метода будут обслуживать кэшированную версию, пока файл не изменится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...