Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Plugin loading & reloading #16

Merged
merged 14 commits into from
Mar 28, 2024
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[tool.poetry]
classifiers = ["Environment :: Canvas :: Plugins"]
name = "{{ cookiecutter.project_name.lower().strip().replace(' ', '_') }}"
version = "{{ cookiecutter.version }}"
description = ""
authors = ["Beau Gunderson <beau@beaugunderson.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
27 changes: 27 additions & 0 deletions custom-plugins/my_first_plugin/CANVAS_MANIFEST.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"sdk_version": "0.1.4",
"plugin_version": "0.1.0",
"name": "My First Plugin",
"description": "A plugin to interact with a Canvas Instance",
"components": {
"protocols": [
{
"class": "my_first_plugin.protocols.protocol:Protocol",
"description": "A protocol that does xyz...",
"data_access": {
"event": "assess_condition_selected",
"read": [
"conditions"
],
"write": [
"commands"
]
}
}
],
"commands": [],
"content": [],
"effects": [],
"views": []
}
}
18 changes: 18 additions & 0 deletions custom-plugins/my_first_plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
===============
My First Plugin
===============

A plugin to interact with a Canvas Instance

## Structure

```
my_first_plugin/
├── commands/
├── content/
├── effects/
├── protocols/
├── views/
├── CANVAS_MANIFEST.json
└── README.md
```
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
22 changes: 22 additions & 0 deletions custom-plugins/my_first_plugin/protocols/protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import json


class Protocol:
RESPONDS_TO = "ASSESS_COMMAND__CONDITION_SELECTED"

NARRATIVE_STRING = "monkey"

def __init__(self, event) -> None:
self.event = event
self.payload = json.loads(event.target)

def compute(self):
return [
{
"effect_type": "ADD_PLAN_COMMAND",
"payload": {
"note": {"uuid": self.payload["note"]["uuid"]},
"data": {"narrative": self.NARRATIVE_STRING},
},
}
]
Empty file.
27 changes: 27 additions & 0 deletions custom-plugins/my_second_plugin/CANVAS_MANIFEST.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"sdk_version": "0.1.4",
"plugin_version": "0.1.0",
"name": "My Second Plugin",
"description": "A plugin to interact with a Canvas Instance",
"components": {
"protocols": [
{
"class": "my_second_plugin.protocols.protocol:Protocol",
"description": "A protocol that does xyz...",
"data_access": {
"event": "assess_condition_selected",
"read": [
"conditions"
],
"write": [
"commands"
]
}
}
],
"commands": [],
"content": [],
"effects": [],
"views": []
}
}
18 changes: 18 additions & 0 deletions custom-plugins/my_second_plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
================
My Second Plugin
================

A plugin to interact with a Canvas Instance

## Structure

```
my_second_plugin/
├── commands/
├── content/
├── effects/
├── protocols/
├── views/
├── CANVAS_MANIFEST.json
└── README.md
```
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
14 changes: 14 additions & 0 deletions custom-plugins/my_second_plugin/protocols/protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import json


class Protocol:
RESPONDS_TO = "SOMETHING_ELSE"

NARRATIVE_STRING = ""

def __init__(self, event) -> None:
self.event = event
self.payload = json.loads(event.target)

def compute(self):
return [{"effect_type": "ANOTHER_COMMAND_ADDITION", "payload": {}}]
Empty file.
28 changes: 28 additions & 0 deletions plugin_runner/generated/messages/plugins_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions plugin_runner/generated/messages/plugins_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Optional as _Optional

DESCRIPTOR: _descriptor.FileDescriptor

class ReloadPluginsRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...

class ReloadPluginsResponse(_message.Message):
__slots__ = ("success",)
SUCCESS_FIELD_NUMBER: _ClassVar[int]
success: bool
def __init__(self, success: bool = ...) -> None: ...
4 changes: 4 additions & 0 deletions plugin_runner/generated/messages/plugins_pb2_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

7 changes: 4 additions & 3 deletions plugin_runner/generated/services/plugin_runner_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions plugin_runner/generated/services/plugin_runner_pb2.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from generated.messages import events_pb2 as _events_pb2
from generated.messages import plugins_pb2 as _plugins_pb2
from google.protobuf import descriptor as _descriptor
from typing import ClassVar as _ClassVar

Expand Down
34 changes: 34 additions & 0 deletions plugin_runner/generated/services/plugin_runner_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import grpc

from generated.messages import events_pb2 as generated_dot_messages_dot_events__pb2
from generated.messages import plugins_pb2 as generated_dot_messages_dot_plugins__pb2


class PluginRunnerStub(object):
Expand All @@ -19,6 +20,11 @@ def __init__(self, channel):
request_serializer=generated_dot_messages_dot_events__pb2.Event.SerializeToString,
response_deserializer=generated_dot_messages_dot_events__pb2.EventResponse.FromString,
)
self.ReloadPlugins = channel.unary_stream(
'/canvas.PluginRunner/ReloadPlugins',
request_serializer=generated_dot_messages_dot_plugins__pb2.ReloadPluginsRequest.SerializeToString,
response_deserializer=generated_dot_messages_dot_plugins__pb2.ReloadPluginsResponse.FromString,
)


class PluginRunnerServicer(object):
Expand All @@ -30,6 +36,12 @@ def HandleEvent(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def ReloadPlugins(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')


def add_PluginRunnerServicer_to_server(servicer, server):
rpc_method_handlers = {
Expand All @@ -38,6 +50,11 @@ def add_PluginRunnerServicer_to_server(servicer, server):
request_deserializer=generated_dot_messages_dot_events__pb2.Event.FromString,
response_serializer=generated_dot_messages_dot_events__pb2.EventResponse.SerializeToString,
),
'ReloadPlugins': grpc.unary_stream_rpc_method_handler(
servicer.ReloadPlugins,
request_deserializer=generated_dot_messages_dot_plugins__pb2.ReloadPluginsRequest.FromString,
response_serializer=generated_dot_messages_dot_plugins__pb2.ReloadPluginsResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'canvas.PluginRunner', rpc_method_handlers)
Expand All @@ -64,3 +81,20 @@ def HandleEvent(request,
generated_dot_messages_dot_events__pb2.EventResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def ReloadPlugins(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/canvas.PluginRunner/ReloadPlugins',
generated_dot_messages_dot_plugins__pb2.ReloadPluginsRequest.SerializeToString,
generated_dot_messages_dot_plugins__pb2.ReloadPluginsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
Loading
Loading