Upref
Small, explicit user preferences for Python applications.
Upref stores per-user configuration in YAML for desktop applications, CLI tools, and scripts. Load and save preferences through a typed API, then optionally collect values through terminal prompts or wxPython dialogs. Your application decides when to ask and when to write.
Documentation · Installation · Quickstart · Examples · Contributing · Changelog
Why Upref?
User-specific storage: configuration directories follow Windows, macOS, and Linux conventions; an explicit directory enables portable mode.
Explicit persistence: loading defaults and collecting input do not write files.
save()andupdate()make persistence a deliberate step.Validated YAML: supported values are checked before writing; malformed files and duplicate keys produce configuration exceptions.
Atomic replacement: saves replace the destination file after writing a temporary file, so readers do not see a partially written YAML document.
Optional interfaces: terminal prompts are included; wxPython is loaded only when the GUI is requested. Type information ships with the package.
Installation
Requires Python 3.10 or later:
python -m pip install upref
For the optional graphical interface:
python -m pip install "upref[gui]"
The core runtime dependencies are platformdirs and PyYAML. The GUI extra
adds wxPython and requires a desktop session.
Quickstart
Create a store, load defaults, and save selected changes:
from upref import ConfigStore
store = ConfigStore("my-application")
settings = store.load(
defaults={"theme": "dark", "network": {"port": 8080}}
)
store.save(settings)
store.update({"network": {"port": 9000}})
print(store.load())
# {'theme': 'dark', 'network': {'port': 9000}}
print(store.path)
This example writes to your platform’s per-user configuration directory.
load() alone never creates a file. Nested mappings are merged; lists and
scalar values are replaced. exists() checks for a file and delete() removes
it. Try the portable example
to use an automatically cleaned temporary directory.
See the storage guide for supported values and the path guide for portable mode.
Optional interactive preferences
To edit the preferences from the quickstart, collect a draft and save only after successful completion:
from upref import Field, PromptCancelled, collect, parse_bool
schema = {"notifications": Field("Enable notifications", parser=parse_bool)}
try:
values = collect(schema, store.load(), interface="tty", mode="all")
except PromptCancelled:
print("Preferences unchanged.")
else:
store.update(values)
Use interface="gui" after installing upref[gui]. The
prompting guide covers
validation, optional fields, formatting, and custom interfaces.
Examples
The example catalog describes all 26 runnable programs, their difficulty, and their file effects. Start with one of these:
Scenario |
Runnable example |
|---|---|
Save, load, and merge in a temporary directory |
|
First-run preferences and subsequent startup |
|
Apply or discard an edited draft |
|
Temporary CLI overrides and explicit persistence |
|
Native dialogs with formatted current values |
|
Preview a legacy migration |
Clone the repository and install it with python -m pip install -e ., then run
an example with python examples/portable_store.py. The
preference walkthroughs
also cover resets, recent files, account settings, import/export, and backups.
Guarantees and limits
Upref is intended for small application preference files. Saves replace the complete YAML document; comments and original formatting are not preserved. Atomic replacement does not lock concurrent writers: coordinate read/modify/write operations externally when lost updates are unacceptable. Validate application rules after loading, and bound untrusted input before parsing it.
Saved values are plain text. Field(secret=True) hides input in compatible
interfaces; it does not encrypt storage. Keep credentials in an operating-system
keyring or secrets manager. Read the
security guide for the
full storage and input limits.
Status, compatibility, and releases
Upref uses the v2 API and is currently classified Beta on PyPI. Consult the release notes when upgrading; the version number does not change that maturity classification.
Python 3.10–3.14 are tested in CI, with platform checks on Windows, macOS, and Linux. The GUI has a separate native Windows test job.
Deprecated v1 wrappers remain available throughout 2.x and are scheduled for removal in 3.0. Explicit file migration remains supported; see the migration guide.
Read the changelog for behavior changes and the GitHub releases for published archives. Install published versions from PyPI.
Support and security reports
Maintained by Florent Tournois.
For usage questions, start with the troubleshooting guide. For bugs and feature requests, search the GitHub issues, then open an issue with your Upref and Python versions, operating system, and a minimal example. Remove credentials and personal configuration data from reproductions.
For vulnerabilities, use GitHub’s private reporting form and follow the security policy.
Contributing
Bug reports, documentation improvements, examples, and focused pull requests are welcome. Read the contribution guide for setup, reporting guidelines, and validation commands. The development guide contains the detailed Windows and POSIX workflows.
From a Windows checkout:
.\make.bat setup
.\make.bat check
.\make.bat test
.\make.bat docs
Git Bonsai
For optional Git branch maintenance on Windows x64:
.\make.bat bonsai-setup
git bonsai
Setup installs Git Bonsai 0.3.0 locally and protects master. Commit or stash
changes, including untracked files, before running it. The tool updates local
tracking branches and prompts before deletion. Use git bonsai -h for options;
see the development guide for setup details and other platforms.
License
Upref is distributed under the MIT license.