Runtime Configuration Guide¶
This guide shows how to modify TaskWarrior configuration at runtime in your
application — without restarting or recreating the TaskWarrior instance.
What changed¶
Prior to this feature, sync parameters and other taskrc settings were read once at construction time. Any change required recreating the adapter.
Now both adapters read configuration lazily from config_store on every
call. A single set_value() is enough — no restart needed.
Step 1 — Nothing changes at construction¶
Your existing initialization code stays exactly the same:
# Before — still valid, nothing to change
self._tw = TaskWarrior(taskrc_file="/path/to/.taskrc")
# Or with explicit data directory
self._tw = TaskWarrior(
taskrc_file="/path/to/.taskrc",
data_location="/path/to/task/data",
)
Step 2 — Modify config at runtime via config_store¶
TaskWarrior exposes a config_store attribute. Use it to read or write any
taskrc key at any point after construction.
Set a single key¶
The change is written to disk and the in-memory cache is refreshed immediately. The next adapter call picks it up automatically.
Delete a key¶
Read the current value¶
Step 3 — Replace sync configuration¶
Use set_sync_config() to replace all sync.* keys in one atomic
operation (existing keys not in the new dict are removed):
# Switch to remote sync
self._tw.config_store.set_sync_config({
"sync.server.origin": "https://taskchampion.example.com",
"sync.server.client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"sync.encryption.secret": "my-passphrase",
})
# Switch to local sync (previous remote keys are removed automatically)
self._tw.config_store.set_sync_config({
"sync.local.server_dir": "/mnt/shared/taskserver",
})
# Disable sync entirely
self._tw.config_store.set_sync_config({})
After any of the above, just call:
Step 4 — Real-world patterns¶
Pattern A — Configure sync from user input¶
class MyApp:
def __init__(self, taskrc: str):
self._tw = TaskWarrior(taskrc_file=taskrc)
def configure_sync(self, server_url: str, secret: str) -> None:
self._tw.config_store.set_sync_config({
"sync.server.origin": server_url,
"sync.encryption.secret": secret,
})
def sync(self) -> None:
if self._tw.is_sync_configured():
self._tw.synchronize()
Pattern B — Toggle sync on / off¶
def enable_sync(self, server_dir: str) -> None:
self._tw.config_store.set_value("sync.local.server_dir", server_dir)
def disable_sync(self) -> None:
self._tw.config_store.set_sync_config({}) # removes all sync.* keys
Pattern C — Read then modify¶
def rotate_secret(self, new_secret: str) -> None:
cfg = self._tw.config_store.get_sync_config()
if not cfg.get("sync.server.origin"):
raise RuntimeError("Remote sync is not configured")
self._tw.config_store.set_value("sync.encryption.secret", new_secret)
What you must NOT change at runtime¶
| Setting | Why |
|---|---|
rc.data.location |
The SQLite database (Replica) is opened once at construction; changing the path has no effect on the running adapter. |
If you need a different data directory, create a new TaskWarrior instance:
# Correct way to switch data directory
self._tw = TaskWarrior(
taskrc_file=self._taskrc,
data_location="/new/path",
)
Quick reference¶
| Goal | Method |
|---|---|
| Write a single key | tw.config_store.set_value(key, value) |
| Delete a single key | tw.config_store.delete_value(key) |
Replace all sync.* keys |
tw.config_store.set_sync_config({…}) |
| Read a value | tw.config_store.config.get(key) |
| Read all sync keys | tw.config_store.get_sync_config() |
| Reload from disk | tw.config_store.refresh() |
| Check sync active | tw.is_sync_configured() |