Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data file saved only temporarily when using Pyinstaller executable

I have created an application with PyQt5 and bundled it using Pyinstaller. The application loads login info from a login.properties file that is stored in the same directory as the .py file that starts the app.

As suggested here I am modifying the path with the following function:

import os, sys
# Translate asset paths to useable format for PyInstaller

def resource_path(relative_path):
  if hasattr(sys, '_MEIPASS'):
      return os.path.join(sys._MEIPASS, relative_path)
  return os.path.join(os.path.abspath('.'), relative_path)

What it causes, is that it creates a temporary folder called _MEIPASS, that contains the files, like my login.properties.

In the app, I want to save the login.properties info with the following function:

self.loginFile = resource_path('./login.properties')    

def save_login_info(self):
        config = configparser.ConfigParser()
        config.read(self.loginFile)

        pw = self.login_ui.password_lineEdit.text()
        un = self.login_ui.username_lineedit.text()
        token = self.login_ui.token_lineEdit.text()
        alias = self.login_ui.gmail_alias_lineedit_2.text()
...     
            config.set('Login', 'password', pw )
            config.set('Login', 'username', un )
            config.set('Login', 'security_token', token )
            config.set('Login', 'alias', alias)

            with open(self.loginFile, 'w') as loginfile: 
                config.write(loginfile)

            print('Login info saved')

So the changed login info is saved to the temporary file/folder and it is not saved to the 'original' file.

Any ideas how to mitigate this problem?

like image 629
Peter Petocz Avatar asked Feb 19 '19 16:02

Peter Petocz


People also ask

Where does PyInstaller save EXE?

PyInstaller generates the executable that is a bundle of your game. It puts it in the dist\ folder under your current working directory.

How do I fix PyInstaller not working?

To Solve 'pyinstaller' is not recognized as an internal or external command operable program or batch file Error You just need to add python script in your path to solve this error.

Does PyInstaller obfuscate?

PyInstaller can follow import statements that refer to Cython C object modules and bundle them. Additionally, Python bytecode can be obfuscated with AES256 by specifying an encryption key on PyInstaller's command line.


1 Answers

_MEIPASS is a temporary folder, yes. The condition if hasattr(sys, '_MEIPASS') sometimes is used to know if application is running from sources or it's built.

Do not save your config files into _MEIPASS folder. It's a good practise to create your app's folder at users directory. If you run dev version (from sources), create a file at sources directory, otherwise at users directory.

def get_config_path():
    if hasattr(sys, "_MEIPASS"):
        abs_home = os.path.abspath(os.path.expanduser("~"))
        abs_dir_app = os.path.join(abs_home, f".my_app_folder")
        if not os.path.exists(abs_dir_app):
            os.mkdir(abs_dir_app)
        cfg_path = os.path.join(abs_dir_app, "login.properties")
    else:
        cfg_path = os.path.abspath(".%slogin.properties" % os.sep)
    return cfg_path
like image 172
stilManiac Avatar answered Oct 25 '22 16:10

stilManiac