Reputation: 169
I´m trying to pack my run.py
app into run.exe
, but not including html templates
and the static
folder files in the .exe file, so they can be easily changed and updated without the need to recompile the .exe file.
The app structure is:
run.py
/serversystem
/templates
/static
/main
/users
In "main" and "users" folders there are empty __init__.py
files, and routes.py
files with the actual code, in a Blueprint architecture.
I am using pyinstaller --onefile run.py
and copying the packaged dist\run.exe
file to the root folder where run.py
lives.
The error I get is that Jinja cannot find the template when I tell it to render it. This is from http://localhost:3000/about
:
Traceback (most recent call last):
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 2091, in __call__
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 2076, in wsgi_app
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 2073, in wsgi_app
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 1518, in full_dispatch_request
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 1516, in full_dispatch_request
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\app.py", line 1502, in dispatch_request
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\serversystem\main\routes.py", line 17, in about
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\templating.py", line 148, in render_template
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\jinja2\environment.py", line 1068, in get_or_select_template
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\jinja2\environment.py", line 997, in get_template
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\jinja2\environment.py", line 958, in _load_template
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\jinja2\loaders.py", line 125, in load
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\templating.py", line 59, in get_source
File "C:\Users\GP\AppData\Local\Temp\_MEI171402\flask\templating.py", line 95, in _get_source_fast
jinja2.exceptions.TemplateNotFound: about.html
The same code works well in the IDE.
I have added a chunk of code to /systemserver/__init__.py
that goes:
def create_app(config_class=Config):
if getattr(sys, 'frozen', False):
print("Starting in FROZEN Mode")
else:
print("Starting in NORMAL Mode")
app = Flask(__name__)
print("Instance Path = {}".format(app.instance_path))
print("Root Path = {}".format(app.root_path))
print("Templates Path = {}".format(app.template_folder))
print("Static Path = {}".format(app.static_folder))
print("Static URL Path = {}".format(app._static_url_path))
When running from IDE (VSCode), I get this:
Starting in NORMAL Mode
Instance Path = h:\MyProject\Alfa1D\instance
Root Path = h:\MyProject\Alfa1D\serversystem
Templates Path = templates
Static Path = h:\MyProject\Alfa1D\serversystem\static
Static URL Path = None
When running from exe file, this is the output:
Starting in FROZEN Mode
Instance Path = C:\Users\GP\AppData\Local\Temp\_MEI144962\var\serversystem-instance
Root Path = C:\Users\GP\AppData\Local\Temp\_MEI144962\serversystem
Templates Path = templates
Static Path = C:\Users\GP\AppData\Local\Temp\_MEI144962\serversystem\static
Static URL Path = None
As I haven´t used the template_folder=template_folder, static_folder=static_folder
options when creating the Flask app, the template and static files do not get packed so they don´t go to the temp MEI folder.
Is it possible to pack the EXE file and, when running it from where run.py is, make it use the template & static files from the fixed folders and not the temp one?
I use Python 3.10 and PyInstaller 4.7, on Windows 10.
Upvotes: 2
Views: 2283
Reputation: 169
Ok, the following approach worked out well with the --onefile
PyInstaller switch:
templatesDir = os.getcwd() + '/serversystem/templates'
staticDir = os.getcwd() + '/serversystem/static'
app = Flask(__name__, template_folder=templatesDir, static_folder=staticDir)
As I´m running my main script from a folder that has a "serversystem" folder, where "templates" and "static" in turn are located, that´s my way to get it. If you have templates and static in direct folders, you should use os.getcwd() + '/templates'
and the same for '/static'
.
This worked great in both normal (Python interpreter) and frozen (Pyinstaller packaged) modes.
This reference helped a lot, specially the little sample script at the end:
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html
Upvotes: 2