Nick H
Nick H

Reputation: 41

Python - Creating an .ini or config file in the user's home directory

This is probably a simple answer but I'm really new when it comes to Python. I've been given existing code, and I'm trying to create a config file for it, whereas previously it had everything hardcoded. I want to have a default config that's with the source code, but then have the program create a copy of that config file in the user's home directory (ex. ~/.config) when they run it for the first time. That way they can edit the file in their home directory rather than edit the source code. (At least I've been told that's what's best.) I'm really bad with syntax and whatnot but I know it should be something like:

try import ~/.config/cfg.ini

except if file doesn't exist, import defaultconfig and create a copy of defaultconfig called cfg.ini in ~/.config (the directory ~/.config would have to be created then too)

Currently I just have config.py with my source code and then I use import config, and config.(variable name) when I need the value.

I know this is formatted poorly, sorry.

Upvotes: 4

Views: 10370

Answers (3)

Foxite
Foxite

Reputation: 11

I found useful the answer of Harald, anyway I found unnecessary to have a default_config.ini considering I already have the info of how the default file is inside my code. I then slightly modified the code to check if there is already a config file, and in case these is not it creates a new one with the default parameters. I also integrated everything in the main.

"main.py"

import os, shutil, configparser

config = configparser.ConfigParser()
config.add_section('settings')
config['settings']['param_1'] = "Hi"
config['settings']['param_2'] = "15"

user_config_dir = os.path.expanduser("~") + "/.config/Your_Forder"
user_config = user_config_dir + "/user_config.ini"

if not os.path.isfile(user_config):
    os.makedirs(user_config_dir, exist_ok=True)
    with open(user_config, 'w') as f:
        config.write(f)

config = configparser.ConfigParser()
config.read(user_config)

hope could help

Upvotes: 1

snowskeleton
snowskeleton

Reputation: 790

For other googlers looking for a way to safely/reliably place a file in the user's home directory across various operating systems, here ya go

import os

filePath = os.path.expanduser('~') + '/.configFile'

def write(text: str):
    with open(filePath, 'w+') as file:
        file.write(text)

def read():
    with open(filePath, 'r') as file:
        return file.read()

Put that in a file named config.py

Use it like so

from . import config

config.write('some stuff')
print(config.read())
>>> 'some stuff'

You'll want to flesh this out as suits your program. Note that by default this will completely overwrite the file every time.

Upvotes: 1

Harald Nordgren
Harald Nordgren

Reputation: 12381

It's generally not possible to import source code from a different directory structure in Python. You should use a configparser to read and write data.

I divided the program into two files, first you run write_default_config.py to generate the default config. Then on every invocation of main.py the script checks for the existence of a user config file, and otherwise copies it over from the source directory after creating the necessary folder.

write_default_config.py:

import configparser

config = configparser.ConfigParser()

config.add_section('section')
config['section']['setting_1'] = "hello"
config['section']['setting_2'] = "goodbye"

with open("default_config.ini", 'w') as f:
    config.write(f)

main.py:

import os, shutil, configparser

user_config_dir = os.path.expanduser("~") + "/.config/Nick_H"
user_config = user_config_dir + "/user_config.ini"

if not os.path.isfile(user_config):
    os.makedirs(user_config_dir, exist_ok=True)
    shutil.copyfile("default_config.ini", user_config)

config = configparser.ConfigParser()
config.read(user_config)

print(config['section']['setting_1'])
print(config['section']['setting_2'])

You always have read and write config data using sections. This is a hassle if you don't feel like you need section but there seems to be no way around it.

My example writes two strings and then prints them just to show how things works, you should replace this with your own information.

Upvotes: 9

Related Questions