Application settings
Project description
Savor what you feel and what you see / Things that may not seem important now / But may be tomorrow
–Chuck Schuldiner
Nostalgic
A drop-in configuration module to save and restore end-user and application settings.
- No meta-files
- Built using only the Python standard library
- Handle syncing with UI elements
Install
pip install nostalgic
Motivation
Many configuration packages themselves require configuration files. This often is extraneous.
Others provide a non-Pythonic API which hinders comprehension. For example, QSettings looks like
self.settings.setValue("my_tracked_variable", value)
and
self.settings.value("my_tracked_variable", DEFAULT_SETTINGS["my_tracked_variable"])
How you work with a variable depends on whether or not it's been touched by Qt.
With Nostalgic, these calls look simply like
self.settings.my_tracked_value = value
and
self.settings.my_tracked_value
Furthermore, most applications probably require only a single configuration. Nostalgic uses a Configuration singleton for this reason. Instantiate a Configuration and the next time one is created, it will be a reference to the already extant Configuration. This means explicit reference to the Configuration doesn't need to be passed around.
Quick Start
A Configuration is a collection of Settings.
- Use a dot to get the Setting value (like an attribute)
- Settings can have a default initial value
write()
Settings to disk andread()
them back in.
# basic usage
import os # needed only for demonstration
import sys # needed only for demonstration
import nostalgic
if __name__ == '__main__':
# create configuration in current directory
cfg = nostalgic.Configuration("sample_config")
# declare a setting 'foo' with initial value
cfg.add_setting("foo", default="bar")
print(cfg.foo) # "bar"
# change the value
cfg.foo = "baz"
try:
# second run
cfg.read()
print("Config just read")
print(cfg.foo) # "baz"
os.remove(cfg.config_file)
if not os.path.exists(cfg.config_file):
print("Removed config file")
except FileNotFoundError:
# first run, no config yet
cfg.write()
print("Wrote config")
sys.exit()
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample1.py"
bar
Wrote config
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample1.py"
bar
Config just read
baz
Removed config file
Advanced: coordinate a configuration with the UI
Optional setter and getter functions handle updating other parts of your code.
# demonstrate getting on write() and setting on read()
import os # needed only for demonstration
import sys # needed only for demonstration
import nostalgic
class SettingsUI:
def __init__(self):
self.some_ui_thing_the_end_user_uses = 0
class Main:
def __init__(self):
self.cfg = nostalgic.Configuration("sample_config")
self.settings_ui = SettingsUI()
self.cfg.add_setting(
"ui_related_thing",
setter=self.custom_setter, # called on read()
getter=self.custom_getter) # called on write()
def custom_setter(self, value):
print(f"Setting some_ui_thing_the_end_user_uses")
self.settings_ui.some_ui_thing_the_end_user_uses = value
def custom_getter(self):
print(f"Getting some_ui_thing_the_end_user_uses")
return self.settings_ui.some_ui_thing_the_end_user_uses
if __name__ == '__main__':
main = Main()
print(f"some_ui_thing_the_end_user_uses: "
f"{main.settings_ui.some_ui_thing_the_end_user_uses}") # 0, the initial value
try:
# second run
main.cfg.read()
print("Config just read")
print(f"some_ui_thing_the_end_user_uses: "
f"{main.settings_ui.some_ui_thing_the_end_user_uses}")
os.remove(main.cfg.config_file)
if not os.path.exists(main.cfg.config_file):
print("Removed config file")
except FileNotFoundError:
# first run, no config yet
# user changed the UI thing
main.settings_ui.some_ui_thing_the_end_user_uses = 42
main.cfg.write()
print("Wrote config")
sys.exit()
The first run gets the end-user value before writing:
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample2.py"
some_ui_thing_the_end_user_uses: 0
Getting some_ui_thing_the_end_user_uses
Wrote config
The second run sets the end-user's previous value:
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample2.py"
some_ui_thing_the_end_user_uses: 0
Setting some_ui_thing_the_end_user_uses
Config just read
some_ui_thing_the_end_user_uses: 42
Removed config file
Notes
- Shadowing Configuration methods with Settings of the same name is possible, although not recommended. A warning will be given.
Development
Install as "editable" using pip
:
~$ cd Projects/nostalgic
~/Projects/nostalgic$ python3 -m venv venv
~/Projects/nostalgic$ source venv/bin/activate
(venv) ~/Projects/nostalgic$ pip install -e .
Testing
Run tests using:
(venv) ~/Projects/nostalgic$ python3 tests/test_nostalgic.py
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for nostalgic-1.0.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b4fd8e393f3d743d007f302975f3644d60d6c1bb90c216115db41306803d7d62 |
|
MD5 | 691babc986e4c7c85b0579f3d05644ca |
|
BLAKE2b-256 | 9e94b2bb0b9db8324c3158b00bc608108c096295fb8b46424e7408545609cced |