Skip to main content

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 UI syncing

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

# bad
self.settings.setValue("my_tracked_variable", value)

and

# bad
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

# good
self.settings.my_tracked_value = value

and

# good
self.settings.my_tracked_value

Furthermore, most applications likely 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 references to the Configuration don'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 and read() 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

Use the sync parameter of read() and write() to toggle whether setters or getters are called.

Use Configuration.set() and Configuration.get() to apply or update settings en masse without accessing the hard disk.

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nostalgic-1.3.0.tar.gz (8.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nostalgic-1.3.0-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file nostalgic-1.3.0.tar.gz.

File metadata

  • Download URL: nostalgic-1.3.0.tar.gz
  • Upload date:
  • Size: 8.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.9

File hashes

Hashes for nostalgic-1.3.0.tar.gz
Algorithm Hash digest
SHA256 1008e554540ccd6955fe56efed1e7bad7fe770bc34925b93c20a176265203a0e
MD5 987d6a84f80e34933498a2aa32c3af1a
BLAKE2b-256 7b70df40885b06472400b76557e6c8bd2e1dd23513c8a34e9db8bf1e7a599ee3

See more details on using hashes here.

File details

Details for the file nostalgic-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: nostalgic-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 6.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.9

File hashes

Hashes for nostalgic-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 74f91b43f6437d810b4d61bdf4b36f9fd22e991f136f5290129c688c24fad3af
MD5 54f9432d2381887bd1bb7c297120f93d
BLAKE2b-256 187bfe426c4ca81299e651c31ecc59e15b9fe710eccb3e8bc536e2c5a46a7d02

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page