我已经写了一个烧瓶应用程序,它工作得很好。我想将它作为可执行文件分发。 尝试使用pyinstaller flaskScript.py来做它 dist文件夹生成了。 进入dist文件夹并双击我的可执行文件flaskScript,它启动我的服务器。 在访问url时,localhost:9090会出现以下异常
jinja2.exceptions.TemplateNotFound
TemplateNotFound: index.html
Traceback (most recent call last)
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1836, in __call__
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1820, in wsgi_app
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1403, in handle_exception
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1817, in wsgi_app
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1477, in full_dispatch_request
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1381, in handle_user_exception
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1475, in full_dispatch_request
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.app", line 1461, in dispatch_request
File "<string>", line 13, in index
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.templating", line 127, in render_template
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/jinja2.environment", line 851, in get_or_select_template
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/jinja2.environment", line 812, in get_template
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/jinja2.environment", line 774, in _load_template
File "/Users/george/Downloads/flaskApps/flaskScript/build/flaskScript/out00-PYZ.pyz/flask.templating", line 64, in get_source
TemplateNotFound: index.html
虽然在执行python flaskScript.py
时它在开发设置中工作正常答案 0 :(得分:12)
这个问题现在有点老了,但是当把它打包成一个文件时,我遇到了同样的问题(Python 3.4.3,Flask 0.10.1和PyInstaller 3.1.1)。
我设法通过在初始化脚本(app\__init__.py
)中添加以下内容来解决它:
import sys
import os
from flask import Flask
# Other imports
if getattr(sys, 'frozen', False):
template_folder = os.path.join(sys._MEIPASS, 'templates')
app = Flask(__name__, template_folder=template_folder)
else:
app = Flask(__name__)
# etc
问题是,当站点以打包的形式运行时,模板位于temp目录下名为 _MEIxxxxxx 的目录中(参见PyInstaller手册中的this),所以我们有告诉Flask。
这是通过template_folder
参数完成的(我在这个答案here和API docs中稍后发现)。
最后,if
确保我们在开发它时仍然可以使用它解压缩。如果是frozen
,则打包脚本,我们必须告诉Flask在哪里找到模板;否则我们在Python环境中运行它(取自here)并且默认值将起作用(假设您当然使用标准的templates
目录。)
答案 1 :(得分:2)
if getattr(sys, 'frozen', False):
template_folder = os.path.join(sys.executable, '..','templates')
static_folder = os.path.join(sys.executable, '..','static')
app = Flask(__name__, template_folder = template_folder,\
static_folder = static_folder)
复制此代码并粘贴到您的文件中。现在pyinstaller在你的dist目录中查找静态和模板文件夹。现在复制并粘贴dist文件夹中的static和template文件夹。它会起作用
答案 2 :(得分:2)
如果您尝试创建--onefile executable ,您还需要在spec文件中添加目录。
在Python代码中,找到运行应用程序的位置并将路径存储在base_dir
中:
import os, sys
base_dir = '.'
if hasattr(sys, '_MEIPASS'):
base_dir = os.path.join(sys._MEIPASS)
使用`static_folder和template_folder参数将正确的路径传递给Flask应用程序:
app = Flask(__name__,
static_folder=os.path.join(base_dir, 'static'),
template_folder=os.path.join(base_dir, 'templates'))
在spec文件中,我们需要告诉pyinstaller包含templates
和static
文件夹,包括pyinstaller的 Analysis 部分中的相应文件夹:
a = Analysis(
...
datas=[
('PATH_TO_THE_APP\\static\\', 'static'),
('PATH_TO_THE_APP\\templates\\', 'templates'),
],
...
使用pyinstaller打包后未找到文件的一般问题是文件将更改其路径。使用--onefile
选项,您的文件将在exe中压缩。当你执行exe时,它们是未压缩的并放在某个临时文件夹中。
每次执行文件时某处都会发生变化,但是运行的应用程序(不是spec
文件,而是主要的python文件,比如说main.py
)可以在这里找到:
import os
os.path.join(sys._MEIPASS)
因此,模板文件不会出现在./templates
中,而是出现在os.path.join(os.path.join(sys._MEIPASS), templates)
中。现在的问题是,除非打包,否则您的代码将无法运行。因此,python main.py
不会运行。
因此,需要在正确的位置找到文件的条件:
import os, sys
base_dir = '.'
if hasattr(sys, '_MEIPASS'): # or, untested: if getattr(sys, 'frozen', False):
base_dir = os.path.join(sys._MEIPASS)
的更多信息
答案 3 :(得分:1)
我刚刚写了一篇关于这个问题的博客文章和其他类似的问题, Create one executable file for a Flask app with PyInstaller
基本上优雅的解决方案是执行以下操作:
窗
pyinstaller -w -F --add-data "templates;templates" --add-data "static;static" app.py
Linux(未测试)
pyinstaller -w -F --add-data "templates:templates" --add-data "static:static" app.py
答案 4 :(得分:0)
如果您是从.spec文件构建的,则无需更改即可轻松实现
__int__.py
1)将模板和静态文件夹添加到.spec中的数据
2)确保将jinja2添加到hiddenimports
block_cipher = None
# add templates and static folders to a list
added_files =[
('templates/*.html', 'templates'),
('static/*.css', 'static'),
]
a = Analysis(['run.py'],
pathex=['/your/app/location'],
binaries=[],
datas = added_files, # set datas = added_files list
hiddenimports=['jinja2.ext'], # be sure to add jinja2
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
...
此方法直接来自pyinstaller文档here
答案 5 :(得分:0)
pyinstaller spec_an_API.py --onefile --add-data "templates";"templates" --add-data "static";"static"
对于使用 --onefile 的窗口