Runner & config =============== The easiest way to get a host up is by running IMMP using the built-in runner: .. code-block:: console $ immp [-w] The expected configuration method is via a config file. Most file formats are understood, as long as the relevant parser libraries are installed (e.g. `PyYAML `_ for YAML files). Pass ``-w`` to have the runner write the current config back to the file on exit. This is useful for plugs and hooks that change their state at runtime (e.g. commands to manage their settings). Note that any comments in the file will be lost -- it will be regenerated from scratch. IMMP is config-driven: plugs and hooks are all created with a given configuration. This allows for a richer specification to suit each instance, and means all instances can be created in the same way with the same basic arguments. The examples below assume a YAML config file for succinctness. Plugs ----- Plug directives go under a root ``plugs`` section of the config. Each plug instance has a name, which can be referenced elsewhere in the config, and needs a ``path`` attribute to the corresponding Python module and class. A ``config`` subkey is generally needed to provide plug-specific options. A sample plug config may look like this: .. code-block:: yaml plugs: demo: path: demo.DemoPlug config: api-key: xyzzy Channels -------- Most networks will provide multiple "rooms" or "conversations" where messages come from, which are all handled by a single plug. A channel is used to specify which rooms are monitored. Channels are used to name and pair room identifiers with the plug they belong to: .. code-block:: yaml channels: foo: plug: demo source: 12345 bar: plug: demo source: 98765 Groups ------ A group defines a set of plugs, or a subset of their channels, and can be referenced by hooks to limit the scope of their actions, for example to provide features only in private or named channels. Each group can contain ``channels``, a list of individual channels to be included, or lists of certain categories of plugs: - ``private``: all private channels from this plug - ``shared``: all non-private channels from this plug - ``named``: all channels from this plug declared in the channels section above - ``anywhere``: all channels provided by this plug (i.e. ``private`` + ``shared``) You can also declare ``exclude`` alongside categories, to remove named channels individually. .. code-block:: yaml groups: secure: channels: [foo, bar] private: [demo-x, demo-y] named: [demo-z] Hooks ----- Hooks are configured in essentially the same way as plugs. A common idiom for hooks is to accept a list of group or channel names where the hook should apply: .. code-block:: yaml hooks: test: path: test.TestHook priority: 1 config: groups: [secure] args: [123, 456] Hooks accept an optional top-level property: ``priority``. If specified as an integer, it defines the order in which hooks receive each new message, lowest first. This will incur a performance penalty as prioritised hooks run in serial, so only apply to those that need it -- hooks without a priority will all run against each message in parallel. Search path ----------- During development, or when working with a third-party module, you may want to include plugs or hooks from Python modules outside the usual search path. You can do this by setting ``path`` to a list of additional paths, which will be added to :attr:`sys.path`. .. code-block:: yaml path: - /path/to/repo/a - /path/to/repo/b If you have a hook ``YourHook`` defined in */path/to/repo/a/module/file.py*, you would use ``module.file.YourHook`` as its path. Logging ------- By default, only startup and shutdown messages are displayed. To see what's going on under the hood, you can provide your own logging options, suitable for Python's :mod:`logging.config`: .. code-block:: yaml logging: version: 1 handlers: console: class: logging.StreamHandler level: INFO file: class: logging.FileHandler filename: debug.log level: DEBUG loggers: immp: level: DEBUG asyncio: level: ERROR root: level: WARNING handlers: [console, file] This example defines behaviour for both stdout (at info level) and a log file (debug level), with IMMP's full output and warnings/errors for external modules included.