API Reference

July 31, 2026 · View on GitHub

hivemind_json_database.JsonDB

@dataclass
class JsonDB(AbstractDB):
    name: str = "clients"
    subfolder: str = "hivemind-core"
    password: Optional[str] = None

Backend implementation of hivemind_plugin_manager.database.AbstractDB on top of json_database.JsonStorageXDG.

Constructor parameters

ParamTypeDefaultEffect
namestr"clients"Basename of the JSON file (no extension).
subfolderstr"hivemind-core"XDG subfolder under $XDG_DATA_HOME.
passwordOptional[str]NoneIf set (non-empty), use EncryptedJsonStorageXDG (AES-GCM).

Construction is side-effecting: the file is opened (or created) at $XDG_DATA_HOME/<subfolder>/<name>.json, and _maybe_migrate() runs once to bring the on-disk shape up to AbstractDB.SCHEMA_VERSION.

See Configuration for full semantics.

add_item(client: Client) -> bool

Insert or overwrite a record keyed by client.client_id. Always returns True.

client.__dict__ is deep-copied before storage to break aliasing. Post-add_item mutations on the caller's Client do not leak into the stored record. See Architecture → Aliasing semantics.

Memory-only. Call commit() to persist.

delete_item(client: Client) -> bool

Inherited from AbstractDB. Replaces the record at client.client_id with a tombstone (Client(client_id=X, api_key="revoked")) and calls update_item. The slot stays allocated. client_ids are never reused. Returns whatever update_item returned.

update_item(client: Client) -> bool

Inherited from AbstractDB. Calls add_item.

replace_item(old_client: Client, new_client: Client) -> bool

Inherited from AbstractDB. Calls delete_item(old) then add_item(new). Note that this leaves a revoked tombstone at old.client_id and a fresh record at new.client_id. To edit a record in place, call add_item with the updated Client instead. It overwrites by client_id.

search_by_value(key: str, val) -> List[Client]

Return every stored client whose attribute named key equals val.

  • key="client_id" uses dict.get(val), which is O(1).
  • Every other key falls back to a linear scan, which is O(n).

The matching is exact equality (==). No substring, no regex, no case-folding.

__iter__() -> Iterable[Client]

Yield every stored record as a Client. Order matches insertion order. (Python dicts preserve insertion order, and so does the JSON store.) Includes tombstoned records (api_key="revoked"). Filter at the call site if you need only live ones.

__len__() -> int

Return the number of stored records, including tombstones. The <name>.schema_version sentinel does not count. It is a sibling file, not a record.

sync() -> None

Re-read the file from disk into memory. Use this if you suspect the file was modified out-of-band (e.g. by another process or a manual edit) and want to pick up the changes without restarting.

sync() does not write. Any uncommitted in-memory changes since the last commit() are discarded. Commit first if you have pending writes.

commit() -> bool

Persist the in-memory dict to disk. Returns True on success, False on any exception (which is also logged via ovos_utils.log.LOG).

Atomic on POSIX: writes to a temp file in the same directory, then os.replaces it over the target. Readers see either the old or new state, never a partial write.

migrate(from_version: int) -> None

Schema migration hook from AbstractDB. Called automatically by __post_init__ via _maybe_migrate() if the on-disk schema version is behind AbstractDB.SCHEMA_VERSION.

v1 -> v2: fold legacy top-level intent_blacklist / skill_blacklist into each record's metadata dict (setdefault). Purge message_blacklist outright (top-level and any residual metadata["message_blacklist"] from a prior migration run). Commit once at the end. Idempotent, so re-runs are no-ops.

You should not normally need to call this directly. See Migration for the full contract.

Private / internal

The following are implementation details, not part of the stable API:

  • _db: the underlying JsonStorage(XDG) instance.
  • _schema_version_path(): full path to the sentinel sibling file.
  • _read_schema_version() -> int: reads the sentinel, returns 1 on missing / unparseable.
  • _write_schema_version(version: int): writes the sentinel.
  • _maybe_migrate(): invokes migrate() if needed and bumps the sentinel.

These can change between releases.

hivemind_json_database.__version__

Standard __version__ string sourced from hivemind_json_database/version.py. Bumped automatically by the gh-automations release workflow from conventional-commit prefixes. Do not edit it by hand.

Entry point

[project.entry-points."hivemind.database"]
"hivemind-json-db-plugin" = "hivemind_json_database:JsonDB"

Discoverable via hivemind_plugin_manager.DatabaseFactory:

from hivemind_plugin_manager import DatabaseFactory
cls = DatabaseFactory.get_class("hivemind-json-db-plugin")
db = DatabaseFactory.create("hivemind-json-db-plugin",
                            name="clients",
                            subfolder="hivemind-core")

← Architecture · Home · Migration →