I have written a flask application and it works perfectly fine. I wanted to distribute it as an executable. Tried doing it using pyinstaller flaskScript.py dist folder got
If you are trying to create a --onefile executable you will also need to add the directories in the spec file.
In the Python code, find where the application is running and store the path in base_dir:
import os, sys
base_dir = '.'
if hasattr(sys, '_MEIPASS'):
base_dir = os.path.join(sys._MEIPASS)
Pass the proper paths to the Flask app 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'))
In the spec file, we do need to tell pyinstaller to include the templates and static folder including the corresponding folders in the Analysis section of the pyinstaller:
a = Analysis(
...
datas=[
('PATH_TO_THE_APP\\static\\', 'static'),
('PATH_TO_THE_APP\\templates\\', 'templates'),
],
...
The general problem with not finding files after packaging with pyinstaller is that the files will change its path. With the --onefile option your files will be compressed inside the exe. When you execute the exe, they are uncompressed and put in a temporal folder somewhere.
Tha somewhere changes everytime you execute the file, but the running application (not the spec file, but your main python file, say main.py) can be found here:
import os
os.path.join(sys._MEIPASS)
So, the templates files won't be in ./templates, but in os.path.join(os.path.join(sys._MEIPASS), templates). The problem now is that your code won't run unless it is packaged. Therefore, python main.py won't run.
Therefore a condition is required 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)
Here is more regarding runtime information in pyinstaller