"""Generic class for plugin errors. This error is raised when a plugin raises an unexpected exception."""
pass
```
%% Cell type:markdown id: tags:
# Plugins
%% Cell type:markdown id: tags:
`PluginBase` is the base class of all Pymemri plugins. You can either build your plugin from scratch, or start with one of our [Plugins Templates](https://gitlab.memri.io/plugins/plugin-templates).
All inheriting classes should implement:
-`PluginBase.run`, which implements the logic of the plugin
-`PluginBase.add_to_schema`, for adding plugin specific item types to the Pod
Note that both the `pluginRun` and `client` arguments are mandatory for running a plugin. When using the `run_plugin` CLI, these are handled for you. For local development and testing, a plugin can be initialized with just a `client`, which results in a `RuntimeWarning`.
%% Cell type:markdown id: tags:
## Example plugin
%% Cell type:markdown id: tags:
Let's use the following plugin as an example of how we can define and run plugins.
%% Cell type:markdown id: tags:
```python
frompymemri.pod.clientimportDog
classExamplePlugin(PluginBase):
schema_classes=[Dog]
def__init__(self,dog_name:str="Bob",**kwargs):
super().__init__(**kwargs)
self.dog_name=dog_name
defrun(self):
print("Started plugin run...")
dog=Dog(self.dog_name,10)
self.client.create(dog)
print("Run success!")
```
%% Cell type:code id: tags:
``` python
# export
# hide
classExamplePlugin(PluginBase):
schema_classes=[Dog,Message]
def__init__(self,dog_name:str="Bob",**kwargs):
super().__init__(**kwargs)
self.dog_name=dog_name
defrun(self):
print("Started plugin run...")
dog=Dog(self.dog_name,10)
self.client.create(dog)
print("Run success!")
```
%% Cell type:code id: tags:
``` python
# hide
example_schema=ExamplePlugin.get_schema()
assertisinstance(example_schema,list)
assertlen(example_schema)
```
%% Cell type:markdown id: tags:
### Authentication
%% Cell type:markdown id: tags:
Many plugins use authentication for external services that require passwords or oauth authentication. Pymemri implements some common cases, see `OAuthAuthenticator` or `PasswordAuthenticator`.
%% Cell type:markdown id: tags:
# Helper methods -
%% Cell type:code id: tags:
``` python
# export
# hide
defwrite_run_info(plugin,id_):
try:
ifpluginisNone:
raiseValueError("Empty container")
run_path=PLUGIN_DIR/plugin/"current_run.json"
run_path.parent.mkdir(parents=True,exist_ok=True)
print(f"writing run info to {run_path}")
write_json({"id":id_},run_path)
exceptExceptionase:
print(f"""failed to write run info to {run_path}\n{e}""")
Plugins can be started using the pymemri `run_plugin` or `simulate_run_plugin_from_frontend` CLI. With `run_plugin` the plugin is invoked directly by spawning a new python process, while `simulate_run_plugin_from_frontend` requests the pod to spawn a new process, docker container, or kubernetes container, which in calls `run_plugin` (for more info see `simulate_run_plugin_from_frontend`. When using `run_plugin`, you can either pass your run arguments as parameters, or set them as environment variables. If both are set, the CLI will use the passed arguments.
%% Cell type:code id: tags:
``` python
# export
# hide
@call_parse
defstore_keys(path:Param("path to store the keys",str)=DEFAULT_POD_KEY_PATH,
database_key:Param("Database key of the pod",str)=None,
To start a plugin on your local machine, you can use the CLI. This will create a client for you, initialize the plugin, and run the code defined in the run method of your plugin.
%% Cell type:code id: tags:
``` python
!run_plugin--metadata"../example_plugin.json"
```
%% Cell type:markdown id: tags:
### Plugin configuration
Often, plugins require some configuration for a run. For example, our `ExamplePlugin` has a `dog_name` argument, which could be different for different runs.
Pymemri handles plugin configuration by passing a dictionary of configuration values to the `__init__` method of the plugin. A possible configuration for the `ExamplePlugin` could be:
```json
{"dog_name":"Alice"}
```
Configuration can be passed to the `run_plugin` CLI in two ways:
- Defined in the `PluginRun` item, as `config` property. This value should be a json serialized dictionary, which is deserialized and passed to the plugin by the CLI
- Defined in a json file and passed to `run_plugin` as a `--config_file` argument. If this option is used, the `config` property from the `PluginRun` is ignored.
%% Cell type:markdown id: tags:
## Run from pod
%% Cell type:markdown id: tags:
In production, we start plugins by making an API call to the pod, which in turn creates an environment for the plugin and starts it using docker containers, kubernetes containers or a shell script. We can start this process using the `simulate_run_plugin_from_frontend` CLI. **Note that when using docker, provided container name should be built within the Pod environment (e.g. `docker build -t pymemri .` for this repo), or available on the memri gitlab container repository.**
%% Cell type:markdown id: tags:

%% Cell type:code id: tags:
``` python
# export
@call_parse
defsimulate_run_plugin_from_frontend(
pod_full_address:Param("The pod full address",str)=DEFAULT_POD_ADDRESS,
database_key:Param("Database key of the pod",str)=None,
owner_key:Param("Owner key of the pod",str)=None,
container:Param("Pod container to run frod",str)=None,
plugin_path:Param("Plugin path",str)=None,
metadata:Param("metadata file for the PluginRun",str)=None,
config_file:Param(
"A plugin configuration, overwrites the configuration of the PluginRun",str
)=None,
account_id:Param("Account id to be used inside the plugin",str)=None,