The memri [pod](https://gitlab.memri.io/memri/pod) uses a plugin system to add features to the backend memri backend. Plugins can import your data (importers), change your data (indexers), or call other serivces. Users can define their own plugins to add new behaviour to their memri app. Let's use the following plugin as an example of how we can start plugins.
Memri plugins need to define at least 2 methods: `.run()` and `.add_to_schema()`. `.run()` defines the logic of the plugin. `.add_to_schema()` defines the schema for the plugin in the pod. Note that currently, `add_to_schema` requires all item to **have all properties defined that are used in the plugin**. In the future, we might replace add_to_schema, to be done automatically, based on a declarative schema defined in the plugin.
raise Exception('Missing parameter: {}'.format(e)) from None
```
%% Cell type:markdown id: tags:
## Running your plugin using the CLI
%% Cell type:markdown id: tags:
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.
> Note: The data that is created here should be in the pod in order for this to work
%% 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 "installed" within the Pod environemnt (e.g. `docker build -t pymemri .` for this repo) in order to start it.**
%% Cell type:markdown id: tags:

%% Cell type:code id: tags:
``` python
# export
from fastcore.script import call_parse, Param
import os
@call_parse
def simulate_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,
plugin_id:Param("Pod ID of the plugin",str)=None,
container:Param("Pod container to run frod", str)=None,
plugin_path:Param("Plugin path", str)=None,
account_id:Param("Account id to be used inside the plugin", str)=None,
"If a plugin with persistent and runtime states are going to be used, this includes the plugins with user interaction, then StatefulPlugin should be used.\n",
"\n",
"If a plugin needs views, an account to login or a last state to continue then a persistent state should be deployed into the pod."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Persistent state of a plugin"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# export\n",
"class PersistentState(Item):\n",
" \"\"\" Persistent state variables saved for plugin such as views, accounts, the last state to resume from etc. \"\"\"\n",
"stateful.set_state_str(client, \"the last state\")\n",
"assert stateful.get_state(client).state == \"the last state\""
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
%% Cell type:code id: tags:
``` python
%load_extautoreload
%autoreload2
# default_exp plugin.stateful
```
%% Cell type:code id: tags:
``` python
#export
frompymemri.data.schemaimportItem
frompymemri.plugin.pluginbaseimportPluginBase
importlogging
```
%% Cell type:code id: tags:
``` python
#hide
fromnbdev.showdocimport*
```
%% Cell type:markdown id: tags:
# Stateful Plugins
%% Cell type:markdown id: tags:
If a plugin with persistent and runtime states are going to be used, this includes the plugins with user interaction, then StatefulPlugin should be used.
If a plugin needs views, an account to login or a last state to continue then a persistent state should be deployed into the pod.
%% Cell type:markdown id: tags:
## Persistent state of a plugin
%% Cell type:code id: tags:
``` python
# export
classPersistentState(Item):
""" Persistent state variables saved for plugin such as views, accounts, the last state to resume from etc. """