I have a python program that must work on Windows and Linux. There are some configuration options I normally store in a file, in a subdirectory of the program's directory.
For Windows, I converted it to exe and created an Installer for it. And now I have the problem of dealing with the config file.
What is the best place to save the configuration file? I have read that for Windows os.environ['APPDATA']+'myAppName' is the path that must be used. Is it correct? Is it standard? Will it work in all versions of Windows at least from XP (and at least in English and Spanish)?
PD: I am not interested in using ConfigParser. Config file is in my own format and I have working code for reading/writing from it.
Storing settings in the user directory is usually a good idea.
These days, you should probably use something like the appdirs library to find a good path to store your configuration in.
Under most Unices, just store a (preferably dot-prefixed) file in the home directory. Under OS X, you'd want to create a directory for your application in the user's Library folder, and store your files there. Under Windows, APPDATA is a good place to build a directory in for your application. It should work on all Windows localizations, and it looks like it was also available in Windows XP.
platformdirs
There is a better solution now ... better than speculating about what is best on each platform, better than environment variables which may or may not be defined, and even better than appdirs: platformdirs (GitHub, PyPI Snyk).
import platformdirs
appname = 'OurGreatApp'
print(f"User config files should be stored in {platformdirs.user_config_dir(appname)}")
On Linux, it is common to store the configuration file in the users home directory, for instance ~/.myprogramrc. On windows Vista and up, users have a home directory as well (/Users/username) and a would recommend storing your settings there in a subfolder (/Users/useranem/myprogram). Storing the settings in the application folder will generate UAC warnings.
On Windows XP, users do not have a home folder. Some programs make the choice of putting configuration in the 'My Documents' folder which I guess is as good a place as any.
Related
I have a Tkinter app that uses images included in the same folder as the .py file. pyinstaller script.py produces an executable that runs but does not open any windows. This is because it is looking for images that don't exist in the same subdirectory. When I copy the important images to the dist folder Pyinstaller creates, the application runs correctly.
However, I would like to have a single executable that I can share with other users that doesn't also require them to have the images stored. The images should be bundled with the software somehow, like how commercial software (usually) doesn't require you to download assets separately from the program itself.
Is there a way to bundle Python programs and the assets they use into single-click applications?
Note that I am using Python 3 on Linux Mint. I am also something of a novice, so don't be surprised if I'm missing something obvious here.
It appears I've solved my own problem.
Instead of having the images included in the same folder as main.py and using the resulting short relative filepath to reach them, install the images in an appropriate space in the system directory tree (I used /home/$USER$/.$PROGRAMNAME$/) and have the program access the files using the absolute path to that directory. This will allow you to copy the program anywhere on your computer you want and have it run without a problem.
However, if you want to share it with someone else, you'll need to also include an installation script that places the assets in the correct directory on their computer.
I am creating a small application in Python that needs to read a configuration file.
I intend to save this file in a folder in /etc on Linux, but I would like my application to run on other operating systems.
The question is: Is there some kind of constant, variable, package, etc. that can tell me the path to the most sensible settings folder on an OS?
Maybe it is better to locate your configuration file(s) in a folder related to your actual module/application? Determine the location of your module might not be straight forward, but this thread should help.
One tool which maybe useful, configparser, has a function which actually looks for configuration files in some standard locations: RawConfigParser.read(filenames)
As far as I know there is no builtin constant for this, but it seems fairly easy to do it manually.
You could use sys.platform or os.name to get the OS, and then set the config folder according to this.
os_name = sys.platform
cfg_folder = {'linux2': '/etc', 'win32': 'folder', ...}[os_name]
You might want to check http://docs.python.org/library/os.html#os-file-dir .
After getting the root path you are able to select specific paths depending on the working OS.
I've been trying to figure this out for more than 2 days, screening the internet and the tutorial, but yet I don't have solved my problem. I'm a real newb and don't yet really know what I'm doing..
Software I use:
Mac OS X 10.6
Python v3.2.2
Interactive interpreter (IDLE)
Problem:
IDLE's default directory is /Users/ME/Documents/. Files with the extention .py can only be opened when located in this directory. However, I made a folder where I would like to save all the .py files etc that have to do with this software. Currently, IDLE cannot load .py files from the chosen directory by me.
What I did first was I added to IDLE:
import sys.
sys.path.append('Users/Mydir/')
sys.path
However, in an already existing thread from 2010 I read sys.path is for the Interpreter ONLY, and that if I am to change this I need to modify the PYTHONPATH environment variable:
PYTHONPATH="/Me/Documents/mydir:$PYTHONPATH"
export PYTHONPATH
However, I'm confused how to use this and cannot find answers to my following questions:
1) PYTHONPATH (.py?) is already existing on my computer when I installed the program?
If YES, where is it? I cannot find it anywhere.
If NO, I need to create one. But where and what should be the content so that IDLE can load files from a non-default directory? Should it contain only the words in bold?
I hope I made my problem clear.
Cheers
It's not totally clear to me what you mean by load. That could mean Open and Close files in the IDLE editor. Or it could mean being able to use the Python import statement to load existing Python modules from other files. I'll assume the latter, that by load you mean import.
There are two general ways to launch IDLE on Mac OS X. One is from the command line of a terminal session; if you installed Python 3.2 using the python.org installers, by default typing /usr/local/bin/idle3.2 will work. The other way is by launching IDLE.app from /Applications/Python 3.2, i.e. by double-clicking its icon. Because you say the default directory for files is your Documents folder, I'm assuming you are using the second method because IDLE.app sets Documents as its current working directory, which becomes the default directory for *Open*s and *Save*s and is automatically added as the first directory on Python's sys.path, the list of directories that Python uses to search for modules when importing.
If you want to add other directories to sys.path, as you've noted you can use the PYTHONPATH environment variable to do so. The standard way to do this is to add an export PYTHONPATH=... definition to a shell startup script, like .bash_profile. However, if you use IDLE.app, no shell is involved so commands in .bash_profile have no effect.
While there are ways to modify the environment variables for OS X GUI apps, in this case, a simpler solution is to use the other method to invoke IDLE, from the command line of a shell session, using either /usr/local/bin/idle3.2 or, if you've run the Update Shell Profile command in the /Applications/Python 3.2 folder (and opened a new terminal session), just idle3. Then, a PYTHONPATH environment variable you set up will be inherited by that IDLE.
BTW, there is no direct way to modify the initial current working directory of IDLE.app from Documents other than modifying the code in IDLE. If you start IDLE from a command
line, it inherits the current working directory of the shell.
[UPDATE] But rather than fooling around with defining PYTHONPATH, here is another even simpler, and probably better, approach that should work with either IDLE.app or the command line idle. It takes advantage of Python path configuration (.pth) files and user site-package directories. Assuming you are using a standard Python framework build of 3.2 (like from a python.org installer) on Mac OS X, create a path file for the directory you want to permanently add to sys.path. In a terminal session:
mkdir -p ~/Library/Python/3.2/lib/python/site-packages
cd ~/Library/Python/3.2/lib/python/site-packages
cat >my_paths.pth <<EOF
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_1
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_2
EOF
Now, whenever you run that Python 3.2 or IDLE under your user name, the directories you have added to the .pth file will automatically be added to sys.path.
BTW, the exact path location of the user site-packages directory for versions of Python earlier than 3.2 or 2.7 may be slightly different. Also, on other Unix-y systems, the default location for the user site-package directory is ~/.local/lib/python3.2/site-packages.
PYTHONPATH is an environment variable (see here and here). I don't have a Mac, but from the threads I have linked to you would type something like
launchctl setenv PYTHONPATH=/Me/Documents/mydir:$PYTHONPATH
on the command line to allow you to run Python scripts from /Me/Documents/mydir. Alternatively, put this line in a file called .bashrc in your home directory (~) and this path will be set each time each time you open a terminal. See here for a short introduction to .bashrc and other .bash* files. Hope that helps.
EDIT See also this question.
I am really new to packaging.
I have developed a music player using pyqt in ubuntu.
It has a gui and it uses sqlite database.
I have looked at distutil.
What I understood is how to place modules and scripts in right place.
What I don't understand is how to set paths for database, config files & log files.
How do I achieve it the way other applications do it in ubuntu by maintainig all this data in '.application_name' folder under home for a user ?
Can anyone suggest a good example application to learn from or point in some direction?
You can use QDir.home() to get the absolute path to a user's home path. You can use this path when generating/accessing your database, config files and log files. For example, on first startup you can do something like:
filePath = QDir.home() + "/.application_name"
if not QDir.exists(filepath)
QDir.mkdir(filepath)
Then you can use filePath when reading/writing to the files from there on out.
I'm creating one-click python installer (integrated with my application). Is there any way to force Python MSI installer to add python's path to SYSTEM PATH variable?
I'm using MSI installer because it is very easy to specify (using command line) how it should interact with the user.
User variables are stored in the Windows Registry under HKEY_CURRENT_USER\Environment
I would use winreg in a post install script to set or add to the PATH there.
http://docs.python.org/library/_winreg.html
There has to be a way, but what some people do is provide batch files that set up the environment before invoking Python. That's what BZR does, anyway. If you can write that batch file somewhere that's already normally in the path, so much the better.
If you're just worried about invoking Python, the normal Python installer does file associations, so you can work it that way.