Search code examples
pythonflaskpyinstallercx-freezewerkzeug

ImportError on message for Flask package - cx_freeze and Pyinstaller


I'm currently trying to create a standalone windows executable for my Python-Flask website. I've tried cx_freeze and PyInstaller, but each time I've ran into an issue with imports. Specifically, I get the following traceback:

 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 941-349-200
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\cx_Freeze\initscripts\__startup__.py", line 12, in <module>
    __import__(name + "__init__")
  File "C:\Python27\lib\site-packages\cx_Freeze\initscripts\Console.py", line 24, in <module>
    exec(code, m.__dict__)
  File "runserver.py", line 7, in <module>
  File "C:\Python27\lib\site-packages\flask\app.py", line 841, in run
    run_simple(host, port, self, **options)
  File "C:\Python27\lib\site-packages\werkzeug\serving.py", line 706, in run_simple
    reloader_type)
  File "C:\Python27\lib\site-packages\werkzeug\_reloader.py", line 263, in run_with_reloader
    reloader.run()
  File "C:\Python27\lib\site-packages\werkzeug\_reloader.py", line 144, in run
    self.extra_files):
  File "C:\Python27\lib\site-packages\werkzeug\_reloader.py", line 22, in _iter_module_files
    filename = getattr(module, '__file__', None)
  File "C:\Python27\lib\site-packages\email\__init__.py", line 79, in __getattr__
    __import__(self.__name__)
ImportError: No module named message

Both of these tools have a method for specifying exact modules to include, in case the tool fails to detect everything it'll need. I've ran cx_freeze with the following command, among other ways:

python cxfreeze runserver.py --target-dir DB --include-modules=message,email

and pyinstaller with:

python pyinstaller.py runserver.py --debug --onedir --hidden-import=message --hidden-import=email 

but nothing has worked. Email and message .pyc files exist after cx_freeze has generated everything, and removing them causes other errors to occur, yet for some reason they are insufficient for this part of it.

I am able to successfully run the site through python on its own, and as you can see the error occurs after it's started to run the site.

I've been researching this bug, and there have been a few occurrences of it before mentioned, but whenever it's been brought up there never seems to be a solution for it - some have indicated that it could be an issue with the way werkzeug handles "lazy imports", but the conversations usually end with "Don't use flask if you want to do this". That's not a viable solution for me, so if anyone could help out it'd be greatly appreciated.


Solution

  • In hidden imports you have to specify email mime types. I did the following in the spec file and it worked

    hiddenimports=['email.mime.message', 'email.mime.image', 'email.mime.text', 'email.mime.multipart', 'email.mime.nonmultipart', 'email.mime.base', 'email.mime.audio']
    

    Or what also works is setting Debug to False