Flask application built using pyinstaller not rendering index.html

前端 未结 5 646
面向向阳花
面向向阳花 2020-12-25 15:19

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

5条回答
  •  感动是毒
    2020-12-25 16:02

    If you are trying to create a --onefile executable you will also need to add the directories in the spec file.

    1. 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)
      
    2. 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'))
      
    3. 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'),
           ],
           ...
      

    A bit of explanation:

    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

提交回复
热议问题