类似于这个问题,但是我有一些后续措施。 How to serve static files in Flask
我在调整上一篇文章中的解决方案时遇到的主要问题是,我需要使用matplotlib的.savefig()
函数,该函数只需要输入一个字符串即可保存到其中。所以我需要知道要传递什么字符串。
我记得在本地首次使用Flask应用程序时,静态文件存在很多问题。我不知道该如何正确地从我的app.py
/views.py
python文件引用静态文件的路径。我知道在html中使用url_for()
,但不是,但是在python中引用静态文件并不是那么简单。
我的烧瓶应用程序具有以下结构。根目录称为Neuroethics_Behavioral_Task
我有一个名为experiment.py
的文件,该文件基本上是views.py
或app.py
文件。但是我似乎找不到正确的引用静态文件的方法。
这里是experiment.py
代码。
import functools
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for, Flask
)
from werkzeug.security import check_password_hash, generate_password_hash
app = Flask(__name__, instance_relative_config=True, static_url_path='') # creates the flask instance
bp= Blueprint('experiment', __name__)
@app.route('/')
@app.route('/index')
def index():
return render_template("welcome.html")
@app.route('/experiment_app', methods=['GET', 'POST'])
def exp_js_psych_app():
total_trials = int(request.form['trials'])
import random
import string
user_id = ''.join([random.choice(string.ascii_letters
+ string.digits) for n in range(8)])
user_id = str(user_id)
stim_metadata = generate_stim_for_trials(total_trials, user_id)
return render_template("index.html", data={"user_id": str(user_id), "total_trials":total_trials, "lst_of_stim_jsons":stim_metadata})
def generate_stim_for_trials(trials, uid):
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import json
import os
json_dict = {}
json_dict["stimuli path info"] = []
lst_of_jsons_for_stimuli = []
# Unused but problematic static reference.
stim_metadata_path = "/static/textdata/stimulus_data" + str(uid) + ".json"
# Another problematic static reference.
stimuli_path = '/static/images/stimulus_img' + 1 + ".png"
df = pd.DataFrame({"Risk":[25], "No Effect" : [50], "Gain":[25]})
df.plot(kind='barh', legend = False, stacked=True, color=['#ed713a', '#808080', '#4169e1'])
plt.axis('off')
plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
plt.ylim(None,None)
plt.autoscale()
plt.margins(0,0)
plt.savefig(stimuli_path) # this fails
需要注意的是,将static_url_path
参数传递给Flask()
调用实际上并没有达到预期的效果,我认为这将为首先查找静态文件的地方建立根,但事实是由于我的/static/
目录显然位于根文件夹中,因此该代码仍然无法显示。
否则,就像我说的那样...我需要使用plt.savefig()
来接受路径,但仍然无法弄清楚应该如何编写此路径。
在此之前,我设法使静态文件能够正常工作。我不得不将上面对静态文件的两个引用更改为以下内容:
stimuli_path = 'Neuroethics_Behavioral_Task/static/images/stimulus_img' + "1" + ".png" stim_metadata_path = "Neuroethics_Behavioral_Task/static/textdata/stimulus_data" + str(uid) + ".json"
换句话说,我可以通过在路径中包含根目录来获取静态文件。
至少这使我不满意...直到我尝试将我的应用程序部署到Heroku上。然后我开始收到错误消息,提示Neuroethics_Behavioral_Task/static/images/
不是公认的路径...所以现在,我觉得我需要真正开始正确地引用静态文件,并且现在不知道该怎么做。
我已经尝试了变体(例如:images/stimulusimg1.png
)并尝试更改了static_url_path
参数(例如:static_url_path='/static/
),但是这些都导致我的Flask应用程序在本地崩溃,并显示FileNotFound。
我还有另一个重要的后续问题...
此应用程序将在Amazon Mechanical Turk上发布的在线实验中进行。图像应该由我使用的称为JsPsych的框架预先加载。但是像这样的帖子以及我第一次加入的帖子鼓励您使用NGINX What exactly does 'serving static files' mean?
提供文件我不知道Nginx或wsgi是如何工作的。我是否仍然应该尝试以这种方式提供所有静态文件,如果可以,如何开始?
总而言之,我要问的问题是
experiment.py
/views.py
/ apps.py
文件中,因此我需要弄清楚实际上表示我的静态图像路径的字符串。我怎么做?我实际上是否需要修改static_url_path
变量?编辑:url_for()
也不起作用。
stimuli_in_static = "images/stimulus_img" + "1" + ".png" stimuli_path = url_for('static', filename=stimuli_in_static)
[这仍然会在
.savefig()
调用时导致FileNotFound错误,
FileNotFoundError: [Errno 2] No such file or directory: '/static/images/stimulus_img1.png'
类似于这个问题,但是我有一些后续措施。如何在Flask中提供静态文件在适应上一篇文章中的解决方案时,我遇到的主要问题是我需要使用...
根据我的评论,由于Heroku不支持持久性文件系统存储,因此推荐的方法是使用S3。为此,您需要将plot.fig
写入Bytes IO缓冲区,然后将其上传到S3。此过程在this SO thread中介绍。
考虑烧瓶的文档,了解如何组织烧瓶应用程序。他们谈论的第一个文件结构是“简单模块”模式,第二个文件结构是更复杂的“包”模式。 https://flask.palletsprojects.com/en/1.1.x/tutorial/layout/