使用pyinstaller构建的Flask应用程序不呈现index.html

Geo*_*rge 12 python jinja2 flask

我写了一个烧瓶应用程序,它工作得非常好.我想将它作为可执行文件分发.尝试使用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
Run Code Online (Sandbox Code Playgroud)

虽然它在执行python flaskScript.py时在开发设置中工作正常

ssa*_*ndo 13

这个问题现在有点旧了,但是当把它打包到一个文件时我遇到了同样的问题(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
Run Code Online (Sandbox Code Playgroud)

问题是,当该网站是在包装形式运行,模板是一个名为目录内_MEIxxxxxx temp目录(参见下将PyInstaller手册中),所以我们必须告诉大家,到瓶中.

这与做template_folder参数(这是我在这个答案发现了这里的,后来API文档).

最后,if确保我们仍然可以在开发时将其打包使用.如果是frozen,则打包脚本,我们必须告诉Flask在哪里找到模板; 否则我们在Python环境中运行它(从这里开始)并且默认值将起作用(假设您templates当然使用标准目录).


Eze*_*año 5

我刚刚写了一篇关于这个问题和其他类似问题的博客文章, 使用 PyInstaller 为 Flask 应用程序创建一个可执行文件

基本上,一个优雅的解决方案是执行以下操作:

视窗

pyinstaller -w -F --add-data "templates;templates" --add-data "static;static" app.py
Run Code Online (Sandbox Code Playgroud)

Linux(未测试)

pyinstaller -w -F --add-data "templates:templates" --add-data "static:static" app.py
Run Code Online (Sandbox Code Playgroud)


tot*_*ico 5

如果尝试创建--onefile可执行文件,则还需要在spec文件中添加目录。

  1. 在Python代码中,找到应用程序的运行位置,并将路径存储在中base_dir

    import os, sys
    base_dir = '.'
    if hasattr(sys, '_MEIPASS'):
        base_dir = os.path.join(sys._MEIPASS)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用`static_folder和template_folder参数将正确的路径传递到Flask应用程序:

    app = Flask(__name__,
            static_folder=os.path.join(base_dir, 'static'),
            template_folder=os.path.join(base_dir, 'templates'))
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在spec文件中,我们确实需要告诉pyinstaller 在pyinstaller 的Analysis部分中包含templatesstatic文件夹,其中包括相应的文件夹:

    a = Analysis(
         ...
         datas=[
           ('PATH_TO_THE_APP\\static\\', 'static'),
           ('PATH_TO_THE_APP\\templates\\', 'templates'),
         ],
         ...
    
    Run Code Online (Sandbox Code Playgroud)

一点解释:

使用pyinstaller打包后找不到文件的一般问题是文件将更改其路径。使用该--onefile选项,您的文件将在exe中压缩。当您执行exe时,它们将被解压缩并放在临时文件夹中。

每当您执行文件时,某个地方都会发生变化,但是可以在以下位置找到正在运行的应用程序(不是spec文件,而是您的主python文件main.py):

import os
os.path.join(sys._MEIPASS)
Run Code Online (Sandbox Code Playgroud)

因此,模板文件将不在中./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)
Run Code Online (Sandbox Code Playgroud)

这是有关pyinstaller中运行时信息的更多信息