【问题标题】:Pyinstaller Jinja2 TemplateNotFoundPyinstaller Jinja2 TemplateNotFound
【发布时间】:2016-03-05 07:37:03
【问题描述】:

我正在使用pyinstaller 来构建我的烧瓶应用程序, 一切正常,除了 Jinja2 模板出现问题。

它给了我jinja2.exceptions.TemplateNotFound

我尝试将模板文件夹 from app import template 放入,但没有成功(我猜是因为它们不包含任何 py 文件)。

我还尝试更改 .spec 文件以包含 templates 文件夹

added_files = [
         ( '..\\CommerceApp\\app\\templates', 'templates' ),
         ( '..\\CommerceApp\\app\\static', 'static' )
        ]

a = Analysis(['..\\CommerceApp\\run.py'],
             pathex=['D:\\PythonProjects\\CommerceAppExe'],
             binaries=None,
             datas=added_files,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

但是也没用,效果和我自己手动复制文件夹一样。

有没有办法将模板与 .exe 捆绑在一起?


编辑

这是我的spec 文件

# -*- mode: python -*-

block_cipher = None

a = Analysis(['..\\CommerceApp_withPyInstaller\\run.py'],
             pathex=['D:\\PythonProjects\\CommerceAppExe'],
             binaries=None,
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='SupplyTracker',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='SupplyTracker')

编辑 2

已接受的答案更改为 gmas80,因为它解决了问题。

编辑 3

我也刚刚意识到,我可以用我的包名创建一个新文件夹并填写静态模板csshtml 等,它会起作用(类似于 gmas80 脚本的结果)

【问题讨论】:

标签: python templates flask jinja2 pyinstaller


【解决方案1】:

我认为问题不是https://stackoverflow.com/a/35816876/2741329 中描述的问题。我刚刚能够使用Jinja2 冻结应用程序。

在我的规范文件中,我使用这种方法来收集所有模板:

from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT, BUNDLE, TOC


def collect_pkg_data(package, include_py_files=False, subdir=None):
    import os
    from PyInstaller.utils.hooks import get_package_paths, remove_prefix, PY_IGNORE_EXTENSIONS

    # Accept only strings as packages.
    if type(package) is not str:
        raise ValueError

    pkg_base, pkg_dir = get_package_paths(package)
    if subdir:
        pkg_dir = os.path.join(pkg_dir, subdir)
    # Walk through all file in the given package, looking for data files.
    data_toc = TOC()
    for dir_path, dir_names, files in os.walk(pkg_dir):
        for f in files:
            extension = os.path.splitext(f)[1]
            if include_py_files or (extension not in PY_IGNORE_EXTENSIONS):
                source_file = os.path.join(dir_path, f)
                dest_folder = remove_prefix(dir_path, os.path.dirname(pkg_base) + os.sep)
                dest_file = os.path.join(dest_folder, f)
                data_toc.append((dest_file, source_file, 'DATA'))

    return data_toc

pkg_data = collect_pkg_data('<YOUR LIB HERE>')

然后将pkg_data 添加到COLLECT(1 个文件夹)或EXE(1 个文件).spec。

在 1 文件夹解决方案中,您应该能够在创建的子文件夹中找到所有模板。


编辑

这可能有效(假设您有一个包(即,您有一个 __init__.py),遵循以下建议:http://flask.pocoo.org/docs/0.10/patterns/packages/):

# -*- mode: python -*-

# <<< START ADDED PART    
from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT, BUNDLE, TOC


def collect_pkg_data(package, include_py_files=False, subdir=None):
    import os
    from PyInstaller.utils.hooks import get_package_paths, remove_prefix, PY_IGNORE_EXTENSIONS

    # Accept only strings as packages.
    if type(package) is not str:
        raise ValueError

    pkg_base, pkg_dir = get_package_paths(package)
    if subdir:
        pkg_dir = os.path.join(pkg_dir, subdir)
    # Walk through all file in the given package, looking for data files.
    data_toc = TOC()
    for dir_path, dir_names, files in os.walk(pkg_dir):
        for f in files:
            extension = os.path.splitext(f)[1]
            if include_py_files or (extension not in PY_IGNORE_EXTENSIONS):
                source_file = os.path.join(dir_path, f)
                dest_folder = remove_prefix(dir_path, os.path.dirname(pkg_base) + os.sep)
                dest_file = os.path.join(dest_folder, f)
                data_toc.append((dest_file, source_file, 'DATA'))

    return data_toc

pkg_data = collect_pkg_data('<yourapplication>')  # <<< Put the name of your package here
# <<< END ADDED PART    

block_cipher = None

a = Analysis(['..\\CommerceApp_withPyInstaller\\run.py'],
             pathex=['D:\\PythonProjects\\CommerceAppExe'],
             binaries=None,
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='SupplyTracker',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               pkg_data,  # <<< Add here the collected files
               strip=False,
               upx=True,
               name='SupplyTracker')

【讨论】:

  • 嘿抱歉,如果我不知道,您如何将pkg_data 属性放入spec 文件中的COLLECT?我尝试放置脚本的pathname (../path/to/pkg_data.py) 但它没有用。我应该import 我的主脚本中的脚本吗?或者把它放在Analysis 属性中的某个地方?谢谢
  • @kingathur61 :为什么不将整个规范文件放在问题正文中?这样我就可以按照我认为可行的方式对其进行编辑。
  • @kingathur61:在我的回答中添加了一个新部分
  • 哇,谢谢! collect_pkg_data('flask_appbuilder') 为我收集了很多魔法。
【解决方案2】:

Jinja2 包使用pkg_resources API,PyInstaller 不支持。 pkg_resources 模块是通过 setuptools 包提供的。

来自pyinstallerFAQ页面:

PyInstaller 目前不支持 pkg_resources。这意味着 使用使用 pkg_resources 的库的应用程序 API 可能无法开箱即用。唯一的情况 它在用于 .egg 文件时起作用(见上文)。为了 详细信息遵循问题 #183。

【讨论】:

  • 啊,我明白了,所以在更新 pyinstaller 之前,我无能为力吗?
  • @Forge 和@kingathur61:jinja2.exceptions.TemplateNotFoundpkg_resources 无关。否则,情况会有所不同:github.com/pyinstaller/pyinstaller/issues/1898
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多