Configuration management in an app
Apps can persist user preferences and other data across restarts using the settings module. Settings are stored as JSON in /settings.json on the badge. The settings file store all badge settings, including Wi-Fi credentials and your display name.
The settings module
The module provides four functions:
| Function | Description |
|---|---|
settings.get(key, default=None) | Return the value for key, or default if it is not set. Loads the file on first use. |
settings.set(key, value) | Set key to value. Pass None to remove the key. |
settings.save() | Write changes to /settings.json. Only writes if something has changed since the last load or save. |
settings.load() | Reload settings from disk. You rarely need to call this directly. |
Because the file is JSON, values can be strings, numbers, booleans, lists, dictionaries, or null (None in Python).
Storing app configuration
Store your app's configuration under a single key whose value is a JSON object. Use a unique key for each app, such as "snake_OG" or "naomis_cool_app", so you do not overwrite badge or other app settings. This keeps your settings together and avoids clashes with badge-level keys such as name, wifi_ssid, or pattern.
import settings
CONFIG_KEY = "example_app" # set to a unique key
DEFAULT_CONFIG = {
"player_name": "Player",
"difficulty": "normal",
"high_score": 0,
}
def load_config():
config = settings.get(CONFIG_KEY)
if config is None:
return DEFAULT_CONFIG.copy()
merged = DEFAULT_CONFIG.copy()
merged.update(config)
return merged
def save_config(config):
settings.set(CONFIG_KEY, config)
settings.save()
load_config() returns the current config file. If later versions of your app change the config it will also merge the config to add any new fields from the DEFAULT_CONFIG.
save_config() writes the whole object back to disk. You must call settings.save() after you change values. Updates are not written to disk until you save.
View or edit settings.json
You can copy settings.json onto your computer by using mpremote cp :settings.json settings.json. You can also view or edit the file directly with mpremote edit settings.json. Make sure the JSON remains valid!
Example app
This app loads its configuration when it starts. Press C to increase the score; when it beats the saved high score, the new value is written to /settings.json:
import app
import settings
from events.input import Buttons, BUTTON_TYPES
CONFIG_KEY = "score_demo"
DEFAULT_CONFIG = {
"high_score": 0,
}
def load_config():
config = settings.get(CONFIG_KEY)
if config is None:
return DEFAULT_CONFIG.copy()
merged = DEFAULT_CONFIG.copy()
merged.update(config)
return merged
def save_config(config):
settings.set(CONFIG_KEY, config)
settings.save()
class ScoreDemoApp(app.App):
def __init__(self):
self.button_states = Buttons(self)
self.config = load_config()
self.score = 0
def update(self, delta):
if self.button_states.get(BUTTON_TYPES["CONFIRM"]):
self.score += 1
if self.score > self.config["high_score"]:
self.config["high_score"] = self.score
save_config(self.config)
if self.button_states.get(BUTTON_TYPES["CANCEL"]):
self.button_states.clear()
self.minimise()
def draw(self, ctx):
ctx.save()
ctx.rgb(0.2, 0, 0).rectangle(-120, -120, 240, 240).fill()
ctx.rgb(1, 1, 1).move_to(-80, -20).text(f"Score: {self.score}")
ctx.move_to(-80, 20).text(
f"High: {self.config['high_score']}"
)
ctx.restore()
__app_export__ = ScoreDemoApp
Building a settings screen
For a full in-app settings UI, use a Layout with DefinitionDisplay and TextDialog entries. Keep a dictionary in memory while the user edits values, then call save_config() when they confirm changes.
The layout menu demo in the UI elements reference shows this pattern with an in-memory app_settings dict. Replace that dict with load_config() on startup and save_config() when the user finishes editing.