Skip to content
Daniel Flassig edited this page Jun 17, 2026 · 1 revision

The pymsg.* api functions let plugins cooperate by exchanging messages. A plugin can offer a service by registering a Message Handler Extension for a topic, and any plugin can discover and call those handlers at runtime — without a compile-time or load-time dependency between the plugins.

This is useful when one plugin wants to make use of functionality provided by another plugin if (and only if) that other plugin happens to be installed, while still working fine on its own when it is not.

Functions:

Topics and addresses

A topic is an agreed-upon string in the long form PUBLISHER-GUID/TOPIC, where PUBLISHER-GUID is the GUID of the plugin that defined the topic. Topics are matched case-insensitively.

Several plugins may register a handler for the same topic. To pick exactly one of them, pymsg.send_message takes an address: an opaque token, returned by pymsg.list_message_handlers, that identifies a single handler. Treat the address as a value you obtained from list_message_handlers and pass through to send_message — do not construct or parse it yourself, as its internal format is not documented and may change.

The address is a stable identifier: it is derived deterministically from the handler's plugin and the handler's own id, so it stays the same across PYTHA sessions and even when a newer version of the handler's plugin is installed. You may therefore store an address (for example to remember a user's choice of handler) and reuse it later. If the addressed handler is no longer installed, pymsg.send_message simply reports a failure, so a stored address can always be validated by attempting the call (or by checking whether it still appears in pymsg.list_message_handlers).

Transferring values

The subject and value passed to a handler, and the status and value it returns, are copied between the two plugins (the plugins do not share Lua state). The following value types are transferred:

  • nil, booleans, numbers and strings
  • tables (nested tables are copied recursively, and shared sub-tables or cycles within the transferred data are preserved)
  • element handles and path handles

Anything else (functions, for example) is transferred as nil. Tables are transferred the same way whether they appear as values or as keys (their contents are copied recursively in both cases). When a table key cannot be transferred — i.e. the key itself is of a non-transferable type — that key/value pair is dropped.

See also:

config.xml: Message Handler Extension, pytha, pyio

Clone this wiki locally