Keywords#

A keyword is a typed named value served over libby, with a uniform payload convention:

  • {} → show (return current value)

  • {"value": V} → modify (apply, then return it)

Types: BoolKeyword, IntKeyword, FloatKeyword, StringKeyword, TriggerKeyword. Access mode is inferred — pass a getter for read-only, a setter for write-only, both for read-write. Optional extras: units, description, nullable, validator, timeout_s (advertised in keys.describe; the CLI uses it to extend the modify timeout for slow operations like motion).

Each Libby peer carries a keyword_registry with typed builder methods. Build keywords by calling lib.keyword_registry.<type>(...), then flush them to the peer with register_keywords:

from libby import Libby

libby = Libby.rabbitmq(self_id="my-peer", rabbitmq_url="amqp://localhost")

state = {"position": 0.0}
libby.keyword_registry.bool("online", getter=lambda: True)
libby.keyword_registry.float("position",
                             getter=lambda: state["position"],
                             setter=lambda v: state.update(position=v),
                             units="mm")
libby.keyword_registry.trigger("halt", action=lambda: print("halted"))

libby.register_keywords(libby.keyword_registry.drain())

You can also build keywords directly via BoolKeyword(...) / FloatKeyword(...) etc. and pass a list to register_keywords. The registry is a convenience layer over the same type classes.

Clients call the keyword by name:

client = Libby.rabbitmq(self_id="client", rabbitmq_url="amqp://localhost")

client.rpc("my-peer", "position", {})               # show
client.rpc("my-peer", "position", {"value": 12.5})  # modify
client.rpc("my-peer", "halt", {"value": 1})         # fire

Two meta-services are auto-registered on every peer that uses the keyword registry:

  • keys.list — payload {"pattern": "..."} (default "%") → names, sorted. % wildcards within a single name.

  • keys.describe — payload {"name": "..."} → flat metadata dict. Exact lookup; no wildcards.

LibbyDaemon subclasses also get a lasterror keyword for free (not just any keyword-registry user, since it needs the daemon’s own logger): a nullable string holding the most recent self.logger.error(...) message, so a failure that only got logged locally is still visible to a remote libby show <peer>.lasterror. Write null to clear it.

See libby.keyword and libby.keyword_registry in the API reference for the full type and method signatures.