===================== Setting Up An Adapter ===================== The entry point of an Adapter is the Adapter Plugin. The Plugin is where you will register ActionModules, Resources, HealthChecks, and manage your Adapter's config. To set up an Adapter Plugin, you'll need to include following two files in the ``adapter/main`` directory of your development environment. .. code-block:: python :caption: :file:`adapter/main/__main__.py` import asyncio from artificial.adapter_common import Adapter from artificial.config import Config from .plugin import AdapterPlugin if __name__ == '__main__': # Parse the yaml config file to pass to the Adapter config = Config.from_env() # Run the plugin asyncio.run(Adapter.run_plugin(AdapterPlugin, config)) .. code-block:: python :caption: :file:`adapter/main/plugin.py` from dataclasses import dataclass from artificial.adapter_common import ActionModule, ActionModulePlugin, PluginContext, action_modules, plugin_config # Define the Adapter config schema # Typically this will be in a separate file (e.g. config.py) @dataclass class AdapterConfig: pass # Define an action module # Typically this will be in a separate file (e.g. actions.py) class MyActions(ActionModule): pass # Mark the Action Module for inclusion in the Action Stub generation process @action_modules(MyActions) class AdapterPlugin(ActionModulePlugin): # Register the config data class to be used for this adapter cfg = plugin_config(AdapterConfig) async def setup(self, pctx: PluginContext) -> None: # Register the action module self.add_module(MyActions()) .. note:: To make the Actions in an Action Module available to be called from a Workflow, you'll need to register the Action Module with the Adapter Plugin. To do this, override the :func:`setup ` method and call the :func:`add_module ` method for each Action Module you want to register. You'll also need to add the Action Module as a parameter to the :deco:`@action_modules ` decorator to make sure it's included in the Action Stub generation process. Monitor System Health --------------------- Artificial automatically monitors the health and connectivity of the overall Adapter and shows it in the LabOps UI. You may find it valuable to add additional health checks for various sub systems in your lab to help you get a clearer picture into your system status. To add health checks, you'll use :func:`add_monitor `. .. code-block:: python :caption: adapter/main/plugin.py from artificial.adapter_common.plugin import ActionModulePlugin, PluginContext, action_modules from artificial.adapter_common.apis import Health from .actions import MyActionModule @action_modules(MyActionModule) class MyAdapterPlugin(ActionModulePlugin): async def setup(self, pctx: PluginContext): self.add_module(MyActionModule()) # Add a health check pctx.lab.health.add_monitor('my_health_check', self.my_health_check) async def my_health_check(self) -> Health.Message: # Check the health of your system return Health.ok() Configuring the Adapter ----------------------- You can access the Adapter's config using :func:`plugin_config `. .. code-block:: python :caption: adapter/main/plugin.py from artificial.adapter_common.plugin import ActionModulePlugin, PluginContext, action_modules, plugin_config from .actions import MyActionModule # Adapter config schema is defined as a dataclass @dataclass class MyAdapterConfig: username: str password: str @action_modules(MyActionModule) class MyAdapterPlugin(ActionModulePlugin): # Pull in adapter configuration cfg = plugin_config(MyAdapterConfig) async def setup(self, pctx: PluginContext): # Pass the config to the Action Module. # The ActionModule __init__ must accept the config as a parameter. self.add_module(MyActionModule(self.cfg))