Skip to content

Commit a355db2

Browse files
committed
feat: plugin wrapper works as expected!
1 parent 04ecfaa commit a355db2

5 files changed

Lines changed: 79 additions & 49 deletions

File tree

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from abc import ABC
22
from typing import Any, Dict, TypeVar, Generic, List
3-
import inspect
43

54
from polywrap_core import Invoker
6-
from polywrap_result import Err, Ok
5+
from polywrap_result import Err, Ok, Result
76

87
TConfig = TypeVar('TConfig')
8+
TResult = TypeVar('TResult')
99

10-
class PluginModule(Generic[TConfig], ABC):
10+
class PluginModule(Generic[TConfig, TResult], ABC):
1111
env: Dict[str, Any]
1212
config: TConfig
1313

@@ -17,21 +17,15 @@ def __init__(self, config: TConfig):
1717
def set_env(self, env: Dict[str, Any]) -> None:
1818
self.env = env
1919

20-
async def _wrap_invoke(self, method: str, args: Dict[str, Any], client: Invoker):
21-
callable_method = self.get_method(method)
22-
if not method:
23-
return Err(Exception(f"Plugin missing method {method}"))
20+
async def _wrap_invoke(self, method: str, args: Dict[str, Any], client: Invoker) -> Result[TResult]:
21+
methods: List[str] = [name for name in dir(self) if name == method]
2422

25-
result = callable_method(args, client)
26-
print(result)
27-
return result
23+
if len(methods) == 0:
24+
return Err(Exception(f"{method} is not defined in plugin"))
2825

29-
def get_method(self, method: str):
30-
methods: List[str] = [name for name in dir(self) if name == method]
31-
callable_method = getattr(self, methods[0])
26+
callable_method = getattr(self, method)
3227

33-
# TODO: Change this to return Err instead of throwin
3428
if not callable(callable_method):
35-
raise Exception(f"Method {method} is an attribute, not a method")
36-
37-
return callable_method
29+
return Err(Exception(f"{method} is an attribute, not a method"))
30+
31+
return Ok(callable_method(args, client))
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
from typing import Generic
2+
13
from polywrap_manifest import AnyWrapManifest
2-
from polywrap_plugin import PluginModule
4+
from polywrap_plugin import PluginModule, TConfig, TResult
35

4-
class PluginPackage:
5-
module: PluginModule
6+
class PluginPackage(Generic[TConfig, TResult]):
7+
module: PluginModule[TConfig, TResult]
68
manifest: AnyWrapManifest
79

810
def __init__(
911
self,
10-
module: PluginModule,
12+
module: PluginModule[TConfig, TResult],
1113
manifest: AnyWrapManifest
1214
):
1315
self.module = module
14-
self.manifest = manifest
16+
self.manifest = manifest
17+

packages/polywrap-plugin/polywrap_plugin/wrapper.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,44 @@
1-
from typing import Union, Any, Dict
2-
3-
from polywrap_core import Wrapper, InvokeOptions, Invoker, InvocableResult, GetFileOptions
4-
from polywrap_plugin import PluginModule
5-
from polywrap_result import Result, Ok, Err
1+
from typing import Any, Dict, Union, cast, Generic
2+
3+
from polywrap_core import (
4+
GetFileOptions,
5+
InvocableResult,
6+
InvokeOptions,
7+
Invoker,
8+
Wrapper
9+
)
610
from polywrap_manifest import AnyWrapManifest
711
from polywrap_msgpack import msgpack_decode
12+
from polywrap_result import Err, Ok, Result
13+
14+
from polywrap_plugin import PluginModule, TConfig, TResult
815

9-
class PluginWrapper(Wrapper):
16+
class PluginWrapper(Wrapper, Generic[TConfig, TResult]):
17+
module: PluginModule[TConfig, TResult]
1018
manifest: AnyWrapManifest
11-
module: PluginModule
1219

13-
def __init__(self, manifest: AnyWrapManifest, module: PluginModule) -> None:
14-
self.manifest = manifest
20+
def __init__(self, module: PluginModule[TConfig, TResult], manifest: AnyWrapManifest) -> None:
1521
self.module = module
22+
self.manifest = manifest
1623

1724
async def invoke(
1825
self, options: InvokeOptions, invoker: Invoker
1926
) -> Result[InvocableResult]:
20-
21-
method = options.method
22-
if not self.module.get_method(method):
23-
return Err(Exception(f"PluginWrapper: method {method} not found"))
24-
2527
env = options.env if options.env else {}
2628
self.module.set_env(env)
2729

28-
decoded_args: Dict[str, Any] = options.args if options.args else {}
30+
decoded_args: Union[Dict[str, Any], bytes] = options.args if options.args else {}
2931

3032
if isinstance(decoded_args, bytes):
3133
decoded_args = msgpack_decode(decoded_args)
3234

33-
result = self.module._wrap_invoke(method, decoded_args, invoker)
35+
result: Result[TResult] = await self.module._wrap_invoke(options.method, decoded_args, invoker) # type: ignore
36+
37+
if result.is_err():
38+
return cast(Err, result.err)
39+
40+
return Ok(InvocableResult(result=result,encoded=False))
3441

35-
if result.ok:
36-
return Ok(InvocableResult(result=result,encoded=False))
3742

3843
async def get_file(self, options: GetFileOptions) -> Result[Union[str, bytes]]:
3944
return Err(Exception("client.get_file(..) is not implemented for plugins"))
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
from typing import TypeVar, Dict, Any
1+
from typing import Any, Dict
22

33
import pytest
44
from polywrap_client import PolywrapClient
55
from polywrap_core import Invoker
6+
from polywrap_result import Ok
67

78
from polywrap_plugin import PluginModule
89

9-
TConfig = TypeVar('TConfig')
1010

11-
class GreetingModule(PluginModule):
12-
def __init__(self, config: TConfig):
11+
class GreetingModule(PluginModule[Any, str]):
12+
def __init__(self, config: Any):
1313
super().__init__(config)
1414

1515
def greeting(self, args: Dict[str, Any], client: Invoker):
@@ -20,6 +20,5 @@ async def test_plugin_module():
2020
plugin = GreetingModule({})
2121

2222
client = PolywrapClient()
23-
result = await plugin._wrap_invoke("greeting", { "name": "Joe" }, client)
24-
print(result)
25-
assert result, "Greetings from: Joe"
23+
result = await plugin._wrap_invoke("greeting", { "name": "Joe" }, client) # type: ignore
24+
assert result, Ok("Greetings from: Joe")
Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,31 @@
1-
def test_plugin_wrapper_invoke():
2-
pass
1+
from typing import cast
2+
3+
import pytest
4+
from polywrap_core import InvokeOptions, Uri
5+
from polywrap_manifest import AnyWrapManifest
6+
from polywrap_plugin import PluginWrapper
7+
from polywrap_client import PolywrapClient
8+
from polywrap_result import Ok
9+
10+
from test_plugin_module import GreetingModule
11+
12+
@pytest.mark.asyncio
13+
async def test_plugin_wrapper_invoke():
14+
module = GreetingModule({})
15+
manifest = cast(AnyWrapManifest, {})
16+
17+
wrapper = PluginWrapper(module, manifest)
18+
19+
20+
args = {
21+
"name": "Joe"
22+
}
23+
options = InvokeOptions(
24+
uri=Uri("ens/greeting.eth"),
25+
method="greeting",
26+
args=args
27+
)
28+
29+
client = PolywrapClient()
30+
result = await wrapper.invoke(options, client)
31+
assert result, Ok("Greetings from: Joe")

0 commit comments

Comments
 (0)