Skip to main content

SunsetSettings: a type-safe, extensible settings system with inheritance.

Project description

SunsetSettings

Build Status Documentation Status

SunsetSettings is a library that provides facilities to declare and use settings for an interactive application in a type-safe manner, and load and save them in a simple INI-like format.

The settings can safely store arbitrary types, and can be structured in an arbitrarily deep hierarchy of subsections, which allows you to implement overrides per project, per folder, per user, etc.

It is mainly intended for software where the user can change settings on the fly, for instance with a settings dialog, and those settings need to be preserved between sessions.

Examples

Creating settings:

>>> from sunset import Bunch, Key, List, Settings

>>> class BackupToolSettings(Settings):
...
...     class UI(Bunch):
...
...         class Font(Bunch):
...             name = Key(default="Arial")
...             size = Key(default=12)
...
...         font  = Font()
...         theme = Key(default="") 
...
...     class Backup(Bunch):
...         folder      = Key(default="~")
...         destination = Key(default="/mnt/backups")
...         compress    = Key(default=True)
...
...     ui = UI()
...     backups = List(Backup())

Loading and saving settings:

>>> from sunset import AutoSaver

>>> def main_program_loop(settings: BackupToolSettings):
...     ...

>>> settings = BackupToolSettings()
>>> with AutoSaver(settings, "~/.config/backup.conf"):  # doctest: +SKIP
...    main_program_loop(settings)

Using settings values:

>>> def do_backup(source: str, destination: str, use_compression: bool):
...     ...

>>> def do_all_backups(settings: BackupToolSettings):
...     for backup in settings.backups:
...         do_backup(
...             source=backup.folder.get(),
...             destination=backup.destination.get(),
...             use_compression=backup.compress.get(),
...         )

>>> do_all_backups(settings)

Changing settings values:

>>> def update_font_settings(
...     font_name: str,
...     font_size: int,
...     font_settings: BackupToolSettings.UI.Font,
... ):
...     font_settings.name.set(font_name)
...     font_settings.size.set(font_size)

>>> update_font_settings("Verdana", 11, settings.ui.font)

Reacting to setting value changes:

>>> def apply_theme(new_theme_name: str):
...     ...

>>> def setup_theme_change_logic(ui_settings: BackupToolSettings.UI):
...     ui_settings.theme.onValueChangeCall(apply_theme)

>>> setup_theme_change_logic(settings.ui)

Features

Type safety

SunsetSettings is type-safe; that is to say, if you are holding it wrong, type checkers will tell you.

>>> from sunset import Key

>>> # Types can be inferred from the provided default value:
>>> number_of_ponies = Key(default=0)
>>> number_of_ponies
<Key[int]:(0)>
>>> number_of_ponies.set(6)  # Works!
True
>>> number_of_ponies.set("six")  # Type error!
False
>>> number_of_ponies.get()  # Value is unchanged.
6
>>> from typing import TYPE_CHECKING
>>> if TYPE_CHECKING:
...     reveal_type(number_of_ponies.get())
>>> # Revealed type is "builtins.int"

Extensibility

You can store arbitrary types in your SunsetSettings provided that you also provide a serializer for that type. (See the API reference.)

>>> import re
>>> from typing import Optional, TYPE_CHECKING

>>> class Coordinates:
...     def __init__(self, x: int, y: int) -> None:
...         self.x = x
...         self.y = y

>>> class CoordinatesSerializer:
...     def toStr(self, coord: Coordinates) -> str:
...         return f"{coord.x},{coord.y}"
...
...     def fromStr(self, string: str) -> Optional[Coordinates]:
...         x, y = string.split(",", 1)
...         if not x.isdigit() or not y.isdigit():
...             return None
...         return Coordinates(int(x), int(y))

>>> from sunset import Key
>>> coordinates = Key(
...     default=Coordinates(0, 0), serializer=CoordinatesSerializer()
... )
>>> if TYPE_CHECKING:
...     reveal_type(coordinates.get())
>>> # Revealed type is "Coordinates"
>>> print(repr(coordinates))
<Key[Coordinates]:(0,0)>

Inheritance

SunsetSettings lets the user have a general set of settings that can be partially overriden in subsections used in specific cases (much like your VSCode settings can be overriden by workspace, for instance). The hierarchy of subsections can be arbitrarily deep.

>>> from sunset import Key, Settings

>>> class Animals(Settings):
...     limbs: Key[int] = Key(default=4)
... 
>>> animals = Animals()
>>> octopuses = animals.newSection(name="octopuses")
>>> octopuses.limbs.get()
4
>>> octopuses.limbs.set(8)
True
>>> octopuses.limbs.get()
8
>>> animals.limbs.get()
4
>>> octopuses.limbs.clear()
>>> octopuses.limbs.get()
4

Callbacks

Each setting key can be given callbacks to be called when its value changes.

>>> from sunset import Key

>>> number_of_ponies = Key(default=0)
>>> def callback(value):
...     print("Pony count updated:", value)
>>> number_of_ponies.onValueChangeCall(callback)
>>> number_of_ponies.set(6)
Pony count updated: 6
True

Requirements

  • Python 3.9 or later.
  • If installing from sources:
    • The flit build tool.

Installation

Installing from PyPI (recommended)

Run:

pip install SunsetSettings

This will install the latest version of SunsetSettings, with its required dependencies.

Installing from sources

  1. Download the code:

    git clone https://github.com/pvaret/SunsetSettings
    
  2. Install the library:

    cd SunsetSettings ; flit install
    

That's it.

API documentation

The API documentation is available at https://sunsetsettings.readthedocs.io/.

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

sunsetsettings-0.5.5.tar.gz (65.7 kB view details)

Uploaded Source

Built Distribution

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

sunsetsettings-0.5.5-py3-none-any.whl (45.1 kB view details)

Uploaded Python 3

File details

Details for the file sunsetsettings-0.5.5.tar.gz.

File metadata

  • Download URL: sunsetsettings-0.5.5.tar.gz
  • Upload date:
  • Size: 65.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for sunsetsettings-0.5.5.tar.gz
Algorithm Hash digest
SHA256 29e2ee5d4a05ce09a4454a76430e010160aa042ecf32806a2d20cdf99196cf52
MD5 5a3de7f15ee00ced2e43cf435ea5641a
BLAKE2b-256 da5c55d05ef0a35435d8254931223c876f8ec07df782e1521e4afa6506cca6dc

See more details on using hashes here.

File details

Details for the file sunsetsettings-0.5.5-py3-none-any.whl.

File metadata

  • Download URL: sunsetsettings-0.5.5-py3-none-any.whl
  • Upload date:
  • Size: 45.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for sunsetsettings-0.5.5-py3-none-any.whl
Algorithm Hash digest
SHA256 d5bd43b68a7d7916e2372eb5b3c4854ede404950148b22ffb76590a07971a4d2
MD5 19a862852eb2d4d31d4cf1ab8324368d
BLAKE2b-256 527d8aff60fc729fdd8c8e43c119cfae1d508efa2cbef1439861c012b5466dd5

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