Skip to content

Commit 639a8e0

Browse files
authored
Plugin Configs (#32)
PluginVersion.configTemplate, PluginInstance.config, and tests of configurable plugins.
1 parent 3881d98 commit 639a8e0

5 files changed

Lines changed: 137 additions & 8 deletions

File tree

src/steamship/data/plugin_instance.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from dataclasses import dataclass
2+
from typing import Dict
23

34
from steamship.base import Client, Request
45
from steamship.base.response import Response
@@ -18,6 +19,7 @@ class CreatePluginInstanceRequest(Request):
1819
name: str = None
1920
handle: str = None
2021
upsert: bool = None
22+
config: Dict[str, any] = None
2123

2224

2325
@dataclass
@@ -34,6 +36,7 @@ class PluginInstance:
3436
pluginId: str = None
3537
pluginVersionId: str = None
3638
userId: str = None
39+
config: Dict[str, any] = None
3740
spaceId: str = None
3841

3942
@staticmethod
@@ -48,6 +51,7 @@ def from_dict(d: any, client: Client = None) -> "PluginInstance":
4851
handle=d.get('handle', None),
4952
pluginId=d.get('pluginId', None),
5053
pluginVersionId=d.get('pluginVersionId', None),
54+
config=d.get('config', None),
5155
userId=d.get('userId', None)
5256
)
5357

@@ -60,7 +64,8 @@ def create(
6064
pluginVersionHandle: str = None,
6165
name: str = None,
6266
handle: str = None,
63-
upsert: bool = None
67+
upsert: bool = None,
68+
config: Dict[str, any] = None
6469
) -> Response[PluginInstance]:
6570
req = CreatePluginInstanceRequest(
6671
name=name,
@@ -69,7 +74,8 @@ def create(
6974
pluginHandle=pluginHandle,
7075
pluginVersionId=pluginVersionId,
7176
pluginVersionHandle=pluginVersionHandle,
72-
upsert=upsert
77+
upsert=upsert,
78+
config=config
7379
)
7480

7581
return client.post(

src/steamship/data/plugin_version.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from dataclasses import dataclass
2-
from typing import List
2+
from typing import List, Dict
33

44
from steamship.base import Client, Request
55
from steamship.base.response import Response
@@ -16,6 +16,7 @@ class CreatePluginVersionRequest(Request):
1616
handle: str = None
1717
upsert: bool = None
1818
type: str = 'file'
19+
configTemplate: Dict[str, any] = None
1920

2021

2122
@dataclass
@@ -53,6 +54,7 @@ class PluginVersion:
5354
pluginId: str = None
5455
name: str = None
5556
handle: str = None
57+
configTemplate: Dict[str, any] = None
5658

5759
@staticmethod
5860
def from_dict(d: any, client: Client = None) -> "PluginVersion":
@@ -63,7 +65,8 @@ def from_dict(d: any, client: Client = None) -> "PluginVersion":
6365
client=client,
6466
id=d.get('id', None),
6567
name=d.get('name', None),
66-
handle=d.get('handle', None)
68+
handle=d.get('handle', None),
69+
configTemplate=d.get('configTemplate', None)
6770
)
6871

6972
@staticmethod
@@ -74,7 +77,8 @@ def create(
7477
name: str = None,
7578
filename: str = None,
7679
filebytes: bytes = None,
77-
upsert: bool = None
80+
upsert: bool = None,
81+
configTemplate: Dict[str, any] = None
7882
) -> Response[PluginVersion]:
7983

8084
if filename is None and filebytes is None:
@@ -90,7 +94,8 @@ def create(
9094
name=name,
9195
handle=handle,
9296
pluginId=pluginId,
93-
upsert=upsert
97+
upsert=upsert,
98+
configTemplate=configTemplate
9499
)
95100

96101
return client.post(

tests/client/helpers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def deploy_app(py_name: str, versionConfigTemplate : Dict[str, any] = None, inst
168168

169169

170170
@contextlib.contextmanager
171-
def deploy_plugin(py_name: str, plugin_type: str):
171+
def deploy_plugin(py_name: str, plugin_type: str, versionConfigTemplate : Dict[str, any] = None, instanceConfig : Dict[str, any] = None):
172172
client = _steamship()
173173
name = _random_name()
174174
plugin = Plugin.create(client, name=name, description='test', type=plugin_type, transport="jsonOverHttp",
@@ -182,7 +182,8 @@ def deploy_plugin(py_name: str, plugin_type: str):
182182
client,
183183
"test-version",
184184
pluginId=plugin.id,
185-
filebytes=zip_bytes
185+
filebytes=zip_bytes,
186+
configTemplate=versionConfigTemplate
186187
)
187188
# TODO: This is due to having to wait for the lambda to finish deploying.
188189
# TODO: We should update the task system to allow its .wait() to depend on this.
@@ -196,6 +197,7 @@ def deploy_plugin(py_name: str, plugin_type: str):
196197
client,
197198
pluginId=plugin.id,
198199
pluginVersionId=version.id,
200+
config=instanceConfig
199201
)
200202
instance.wait()
201203
assert (instance.error is None)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import json
2+
3+
from steamship import Block, DocTag, Tag
4+
from steamship.app import App, post, create_handler
5+
from steamship.plugin.tagger import Tagger
6+
from steamship.plugin.service import PluginResponse, PluginRequest
7+
from steamship.plugin.inputs.block_and_tag_plugin_input import BlockAndTagPluginInput
8+
from steamship.plugin.outputs.block_and_tag_plugin_output import BlockAndTagPluginOutput
9+
import re
10+
11+
12+
13+
class TestParserPlugin(Tagger, App):
14+
# For testing; mirrors TestConfigurableTagger in Swift
15+
16+
def run(self, request: PluginRequest[BlockAndTagPluginInput]) -> PluginResponse[BlockAndTagPluginOutput]:
17+
tagKind = self.config['tagKind']
18+
tagName = self.config['tagName']
19+
tagValue = json.dumps({'numberValue':self.config['numberValue'], 'booleanValue':self.config['booleanValue']})
20+
21+
if request.data is not None:
22+
file = request.data.file
23+
tag = Tag.CreateRequest(kind=tagKind, name= tagName, value=tagValue)
24+
if file.tags:
25+
file.tags.append(tag)
26+
else:
27+
file.tags = [tag]
28+
return PluginResponse(
29+
data=BlockAndTagPluginOutput(file)
30+
)
31+
32+
@post('tag')
33+
def parse(self, **kwargs) -> dict:
34+
parseRequest = Tagger.parse_request(request=kwargs)
35+
parseResponse = self.run(parseRequest)
36+
return Tagger.response_to_dict(parseResponse)
37+
38+
39+
handler = create_handler(TestParserPlugin)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import json
2+
3+
from steamship import PluginInstance
4+
from ..client.helpers import deploy_plugin, _steamship
5+
from tests.client.operations.test_tag_file import parse_file
6+
7+
__copyright__ = "Steamship"
8+
__license__ = "MIT"
9+
10+
11+
def test_e2e_parser():
12+
client = _steamship()
13+
14+
configTemplate = {"tagKind": {"type":"string"},
15+
"tagName": {"type":"string"},
16+
"numberValue": {"type":"number"},
17+
"booleanValue": {"type":"boolean"}}
18+
instanceConfig1 = {"tagKind": "testTagKind",
19+
"tagName": "testTagName",
20+
"numberValue": 3,
21+
"booleanValue": True}
22+
23+
with deploy_plugin("plugin_configurable_tagger.py", "tagger", versionConfigTemplate=configTemplate, instanceConfig=instanceConfig1) as (plugin, version, instance):
24+
test_doc = "Hi there"
25+
res = client.tag(doc=test_doc, pluginInstance=instance.handle)
26+
res.wait()
27+
assert (res.error is None)
28+
assert (res.data is not None)
29+
assert (len(res.data.file.blocks) == 1)
30+
assert (res.data.file.blocks[0].text == test_doc)
31+
32+
#Validate configured content
33+
assert (len(res.data.file.tags) == 1)
34+
tag = res.data.file.tags[0]
35+
assert (tag.name == instanceConfig1['tagName'])
36+
assert (tag.kind == instanceConfig1['tagKind'])
37+
tagValue = json.loads(tag.value)
38+
assert (tagValue['numberValue'] == instanceConfig1['numberValue'])
39+
assert (tagValue['booleanValue'] == instanceConfig1['booleanValue'])
40+
41+
instanceConfig2 = {"tagKind": "testTagKind2",
42+
"tagName": "testTagName2",
43+
"numberValue": 4,
44+
"booleanValue": False}
45+
46+
instance2 = PluginInstance.create(
47+
client,
48+
pluginId=plugin.id,
49+
pluginVersionId=version.id,
50+
config=instanceConfig2
51+
)
52+
instance2.wait()
53+
assert (instance2.error is None)
54+
assert (instance2.data is not None)
55+
instance2 = instance2.data
56+
57+
res = client.tag(doc=test_doc, pluginInstance=instance2.handle)
58+
res.wait()
59+
assert (res.error is None)
60+
assert (res.data is not None)
61+
assert (len(res.data.file.blocks) == 1)
62+
assert (res.data.file.blocks[0].text == test_doc)
63+
64+
# Validate configured content
65+
assert (len(res.data.file.tags) == 1)
66+
tag = res.data.file.tags[0]
67+
assert (tag.name == instanceConfig2['tagName'])
68+
assert (tag.kind == instanceConfig2['tagKind'])
69+
tagValue = json.loads(tag.value)
70+
assert (tagValue['numberValue'] == instanceConfig2['numberValue'])
71+
assert (tagValue['booleanValue'] == instanceConfig2['booleanValue'])
72+
73+
74+
75+
76+
77+

0 commit comments

Comments
 (0)