Flask application created using pyinstaller, not rendering index.html

I wrote a jar application and it works great. I wanted to distribute it as an executable file. Tried to do this with the pyinstaller flaskScript.py dist folder created. I went into the dist folder and double-clicked my executable flag, it started my server. When accessing the localhost url: 9090 it gives the following exception

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 

So far, it works fine in dev settings when executing python flaskScript.py

+11
source share
5 answers

This question is already outdated, but I had the same problem (Python 3.4.3, Flask 0.10.1 and PyInstaller 3.1.1) when packing it into one file.

I managed to solve this problem by adding the following to the initialization script ( 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 

The problem is that when the site is running in packaged form, the templates are located in a directory named _MEIxxxxxx in the temp directory (see This in the PyInstaller Manual), so we should inform Flask about this.

This is done using the template_folder argument (which I learned about in this answer here and later in the API documentation ).

Finally, there is an if to ensure that we can still use it without packaging during its development. If it is frozen , then the script is packaged, and we must tell Flask where to find the templates; otherwise, we run it in the Python environment (taken from here ), and the default settings will work (unless, of course, you use the standard templates directory).

+13
source
 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) 

copy this code and paste it into your file. now pyinstaller is looking for a static folder and a template folder in your dist directory. Now copy and paste the static and template folder into the dist folder. he will work

+3
source

If you are trying to create the --onefile executable, you also need to add directories to the specification file.

  1. In the Python code, find where the application works and save the path in base_dir :

     import os, sys base_dir = '.' if hasattr(sys, '_MEIPASS'): base_dir = os.path.join(sys._MEIPASS) 
  2. Pass the correct paths to the Flask application using the static_folder and template_folder parameters:

     app = Flask(__name__, static_folder=os.path.join(base_dir, 'static'), template_folder=os.path.join(base_dir, 'templates')) 
  3. In the spec file, we need to specify pyinstaller to include the templates and static folder, including the corresponding folders in the Analysis section of pyinstaller:

     a = Analysis( ... datas=[ ('PATH_TO_THE_APP\\static\\', 'static'), ('PATH_TO_THE_APP\\templates\\', 'templates'), ], ... 

A little explanation:

A common problem with not finding files after packing with pyinstaller is that the files will change their path. With --onefile your files will be compressed inside exe. When you run the executable, they are unpacked and placed in a temporary folder.

This changes somewhere somewhere every time you run the file, but a working application (not the spec file, but your main python file, say main.py ) can be found here:

 import os os.path.join(sys._MEIPASS) 

Thus, the template files will not be in ./templates , but in os.path.join(os.path.join(sys._MEIPASS), templates) . The problem is that your code will not work until it is packaged. Therefore python main.py will not work.

Therefore, a condition is necessary to find the files in the right place:

 import os, sys base_dir = '.' if hasattr(sys, '_MEIPASS'): # or, untested: if getattr(sys, 'frozen', False): base_dir = os.path.join(sys._MEIPASS) 

More runtime information in pyinstaller

+3
source

I just wrote a blog post about this problem and other similar ones. Create one executable for Flask application with PyInstaller

Basically an elegant solution is as follows:

Window

 pyinstaller -w -F --add-data "templates;templates" --add-data "static;static" app.py 

Linux (NOT TESTED)

 pyinstaller -w -F --add-data "templates:templates" --add-data "static:static" app.py 
+1
source

if you are building from a .spec file, this can easily be done without modification

 __int__.py 

1) add your templates and static folder to the data in .spec

2) be sure to add jinja2 to 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) ... 

this method directly from the pyinstaller documentation here

0
source

All Articles