Skip to main content

SunsetSettings

Build Status Documentation Status PyPI - Version PyPI - Downloads codecov

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: int):
...     print("Pony count updated:", value)
>>> number_of_ponies.onValueChangeCall(callback)
>>> number_of_ponies.set(6)
Pony count updated: 6
True

Requirements

  • Python 3.10 or later.

Installation

Installing from PyPI (recommended)

SunsetSettings releases are available from PyPI and can be installed with the standard Python tooling.

Directly add SunsetSettings to your project's dependencies or, in order to manually install SunsetSettings and make it available in the current Python prefix, run:

pip install SunsetSettings

This will install the latest version of SunsetSettings, with its required dependencies, if any. The module can then be imported under the name sunset:

>>> import sunset
>>>

Installing from sources

  1. Download the code:

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

    cd SunsetSettings ; pip install .
    

That's it.

API documentation

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

Release files for SunsetSettings 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for SunsetSettings 0.7.1
File Size Uploaded
sunsetsettings-0.7.1.tar.gz 83.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for SunsetSettings 0.7.1
File Interpreter ABI Platform
sunsetsettings-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 145.7 kB

Release files / sunsetsettings-0.7.1.tar.gz

Download URL sunsetsettings-0.7.1.tar.gz
Size 83.9 kB
Tags Source
SHA-256 checksum
How to use checksums
001b89edf93d26f85f455fbd0136b1336e0eea02132fcb3e24a624546a050e22
BLAKE2b-256 checksum
How to use checksums
f2ec090e35640cc845ec8632630b498971d7644a6e1ff087b4baa7d0d61b7fe1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / sunsetsettings-0.7.1-py3-none-any.whl

Download URL sunsetsettings-0.7.1-py3-none-any.whl
Size 61.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ac642430457092faa912d295e1d983308f683dda1ff7bd97350a3fd23338827
BLAKE2b-256 checksum
How to use checksums
94d275162a350620bddfc5f5de2cf8d1de26eef373a0834ba9478482183798e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.7.1 This release

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page