Skip to content

Commit d01e57a

Browse files
committed
Merge branch 'main' into feat/plugins-support
2 parents 69feeb7 + 6eb1b87 commit d01e57a

38 files changed

Lines changed: 756 additions & 152 deletions

packages/polywrap-client/polywrap_client/client.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,18 @@
22

33
from dataclasses import dataclass
44
from textwrap import dedent
5-
from typing import Any, List, Optional, Union, cast
5+
from typing import Any, Dict, List, Optional, Union, cast
66

77
from polywrap_core import (
88
Client,
99
ClientConfig,
10-
Env,
11-
GetEnvsOptions,
1210
GetFileOptions,
1311
GetManifestOptions,
14-
GetUriResolversOptions,
15-
InterfaceImplementations,
1612
InvokerOptions,
1713
IUriResolutionContext,
1814
IUriResolver,
1915
TryResolveUriOptions,
16+
Env,
2017
Uri,
2118
UriPackage,
2219
UriPackageOrWrapper,
@@ -46,29 +43,28 @@ def __init__(self, config: Optional[PolywrapClientConfig] = None):
4643
def get_config(self):
4744
return self._config
4845

49-
def get_uri_resolver(
50-
self, options: Optional[GetUriResolversOptions] = None
51-
) -> IUriResolver:
46+
def get_uri_resolver(self) -> IUriResolver:
5247
return self._config.resolver
5348

54-
def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]:
55-
return self._config.envs
49+
def get_envs(self) -> Dict[Uri, Env]:
50+
envs: Dict[Uri, Env] = self._config.envs
51+
return envs
5652

57-
def get_interfaces(self) -> List[InterfaceImplementations]:
58-
return self._config.interfaces
53+
def get_interfaces(self) -> Dict[Uri, List[Uri]]:
54+
interfaces: Dict[Uri, List[Uri]] = self._config.interfaces
55+
return interfaces
5956

60-
def get_implementations(self, uri: Uri) -> Result[List[Uri]]:
61-
if interface_implementations := next(
62-
filter(lambda x: x.interface == uri, self._config.interfaces), None
63-
):
64-
return Ok(interface_implementations.implementations)
57+
def get_implementations(self, uri: Uri) -> Result[Union[List[Uri], None]]:
58+
interfaces: Dict[Uri, List[Uri]] = self.get_interfaces()
59+
if interfaces.get(uri):
60+
return Ok(interfaces.get(uri))
6561
else:
6662
return Err.from_str(f"Unable to find implementations for uri: {uri}")
6763

6864
def get_env_by_uri(
69-
self, uri: Uri, options: Optional[GetEnvsOptions] = None
65+
self, uri: Uri
7066
) -> Union[Env, None]:
71-
return next(filter(lambda env: env.uri == uri, self.get_envs()), None)
67+
return self._config.envs.get(uri)
7268

7369
async def get_file(
7470
self, uri: Uri, options: GetFileOptions
@@ -99,9 +95,9 @@ async def load_wrapper(
9995
result = await self.try_resolve_uri(
10096
TryResolveUriOptions(uri=uri, resolution_context=resolution_context)
10197
)
102-
if result.is_err() == True:
98+
if result.is_err():
10399
return cast(Err, result)
104-
if result.is_ok() == True and result.ok is None:
100+
if result.is_ok() and result.ok is None:
105101
# FIXME: add resolution stack
106102
return Err.from_str(
107103
dedent(
@@ -139,9 +135,7 @@ async def invoke(self, options: InvokerOptions) -> Result[Any]:
139135
if wrapper_result.is_err():
140136
return cast(Err, wrapper_result)
141137
wrapper = wrapper_result.unwrap()
142-
143-
env = self.get_env_by_uri(options.uri)
144-
options.env = options.env or (env.env if env else None)
138+
options.env = options.env or self.get_env_by_uri(options.uri)
145139

146140
result = await wrapper.invoke(options, invoker=self)
147141
if result.is_err():

packages/polywrap-client/tests/test_client.py

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,44 @@
1+
import pytest
12
from pathlib import Path
2-
3-
from polywrap_client import PolywrapClient
4-
from polywrap_core import Uri, InvokerOptions, InterfaceImplementations, Env
5-
from polywrap_uri_resolvers import BaseUriResolver, SimpleFileReader
6-
7-
from polywrap_client.client import PolywrapClientConfig
8-
9-
10-
async def test_invoke():
3+
import pytest
4+
from polywrap_client import PolywrapClient, PolywrapClientConfig
5+
from polywrap_manifest import deserialize_wrap_manifest
6+
from polywrap_core import Uri, InvokerOptions, UriWrapper
7+
from polywrap_uri_resolvers import BaseUriResolver, SimpleFileReader, StaticResolver
8+
from polywrap_result import Result, Ok, Err
9+
from polywrap_wasm import WRAP_MANIFEST_PATH, WRAP_MODULE_PATH, IFileReader, WasmWrapper
10+
11+
@pytest.fixture
12+
def simple_wrap_module():
13+
wrap_path = Path(__file__).parent / "cases" / "simple-invoke" / "wrap.wasm"
14+
with open(wrap_path, "rb") as f:
15+
yield f.read()
16+
17+
18+
@pytest.fixture
19+
def simple_wrap_manifest():
20+
wrap_path = Path(__file__).parent / "cases" / "simple-invoke" / "wrap.info"
21+
with open(wrap_path, "rb") as f:
22+
yield f.read()
23+
24+
@pytest.fixture
25+
def simple_file_reader(simple_wrap_module: bytes, simple_wrap_manifest: bytes):
26+
class FileReader(IFileReader):
27+
async def read_file(self, file_path: str) -> Result[bytes]:
28+
if file_path == WRAP_MODULE_PATH:
29+
return Ok(simple_wrap_module)
30+
if file_path == WRAP_MANIFEST_PATH:
31+
return Ok(simple_wrap_manifest)
32+
return Err.from_str(f"FileNotFound: {file_path}")
33+
34+
yield FileReader()
35+
36+
@pytest.mark.asyncio
37+
async def test_invoke(
38+
simple_file_reader: IFileReader,
39+
simple_wrap_module: bytes,
40+
simple_wrap_manifest: bytes
41+
):
1142
client = PolywrapClient()
1243
uri = Uri(
1344
f'fs/{Path(__file__).parent.joinpath("cases", "simple-invoke").absolute()}'
@@ -20,6 +51,29 @@ async def test_invoke():
2051

2152
assert result.unwrap() == args["arg"]
2253

54+
manifest = deserialize_wrap_manifest(simple_wrap_manifest).unwrap()
55+
56+
wrapper = WasmWrapper(
57+
file_reader=simple_file_reader,
58+
wasm_module=simple_wrap_module,
59+
manifest=manifest
60+
)
61+
uri_wrapper = UriWrapper(uri=Uri("ens/wrapper.eth"), wrapper=wrapper)
62+
resolver = StaticResolver.from_list([uri_wrapper]).unwrap()
63+
64+
config = PolywrapClientConfig(resolver=resolver)
65+
client = PolywrapClient(config=config)
66+
67+
args = {"arg": "hello polywrap"}
68+
options = InvokerOptions(
69+
uri=Uri("ens/wrapper.eth"),
70+
method="simpleMethod",
71+
args=args,
72+
encode_result=False
73+
)
74+
result = await client.invoke(options)
75+
76+
assert result.unwrap() == args["arg"]
2377

2478
async def test_subinvoke():
2579
uri_resolver = BaseUriResolver(
@@ -31,7 +85,7 @@ async def test_subinvoke():
3185
},
3286
)
3387

34-
client = PolywrapClient(config=PolywrapClientConfig(envs=[], resolver=uri_resolver))
88+
client = PolywrapClient(config=PolywrapClientConfig(resolver=uri_resolver))
3589
uri = Uri(
3690
f'fs/{Path(__file__).parent.joinpath("cases", "simple-subinvoke", "invoke").absolute()}'
3791
)
@@ -48,19 +102,15 @@ async def test_interface_implementation():
48102
redirects={},
49103
)
50104

105+
interface_uri = Uri("ens/interface.eth")
51106
impl_uri = Uri(
52107
f'fs/{Path(__file__).parent.joinpath("cases", "simple-interface", "implementation").absolute()}'
53108
)
54109

55110
client = PolywrapClient(
56111
config=PolywrapClientConfig(
57-
envs=[],
58112
resolver=uri_resolver,
59-
interfaces=[
60-
InterfaceImplementations(
61-
interface=Uri("ens/interface.eth"), implementations=[impl_uri]
62-
)
63-
],
113+
interfaces= {interface_uri : [impl_uri]}
64114
)
65115
)
66116
uri = Uri(
@@ -71,10 +121,26 @@ async def test_interface_implementation():
71121
uri=uri, method="moduleMethod", args=args, encode_result=False
72122
)
73123
result = await client.invoke(options)
74-
124+
assert client.get_implementations(interface_uri) == Ok([impl_uri])
75125
assert result.unwrap() == {"str": "hello", "uint8": 2}
76126

77127

128+
def test_get_env_by_uri():
129+
uri_resolver = BaseUriResolver(
130+
file_reader=SimpleFileReader(),
131+
redirects={},
132+
)
133+
uri = Uri(f'fs/{Path(__file__).parent.joinpath("cases", "simple-env").absolute()}')
134+
env = {"externalArray": [1, 2, 3], "externalString": "hello"}
135+
136+
client = PolywrapClient(
137+
config=PolywrapClientConfig(
138+
envs={uri: env},
139+
resolver=uri_resolver,
140+
)
141+
)
142+
assert client.get_env_by_uri(uri) == env
143+
78144
async def test_env():
79145
uri_resolver = BaseUriResolver(
80146
file_reader=SimpleFileReader(),
@@ -86,13 +152,14 @@ async def test_env():
86152

87153
client = PolywrapClient(
88154
config=PolywrapClientConfig(
89-
envs=[Env(uri=uri, env=env)],
155+
envs={uri: env},
90156
resolver=uri_resolver,
91157
)
92158
)
93159
options = InvokerOptions(
94-
uri=uri, method="externalEnvMethod", args={}, encode_result=False
160+
uri=uri, method="externalEnvMethod", args={}, encode_result=False,
95161
)
162+
96163
result = await client.invoke(options)
97164

98-
assert result.unwrap() == env
165+
assert result.unwrap() == env

packages/polywrap-client/tests/test_sha3.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ async def test_invoke_sha3_512():
1919
result = await client.invoke(options)
2020
s = hashlib.sha512()
2121
s.update(b"hello polywrap!")
22-
print(result)
2322
assert result.result == s.digest()
2423

2524
@pytest.mark.skip(reason="can't invoke sha3 wrapper due to an error related to wasmtime")
@@ -90,7 +89,6 @@ async def test_invoke_hex_keccak_256():
9089
async def test_invoke_buffer_keccak_256():
9190
options = InvokerOptions(uri=uri, method="buffer_keccak_256", args=args, encode_result=False)
9291
result = await client.invoke(options)
93-
print(result)
9492
# TODO: Not sure exactly what this function `buffer_keccak_256` is doing in order to assert it properly
9593
assert result.result == False
9694

packages/polywrap-core/polywrap_core/types/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from .client import *
2-
from .env import *
32
from .file_reader import *
43
from .invoke import *
54
from .uri import *
@@ -10,6 +9,7 @@
109
from .uri_resolver import *
1110
from .uri_resolver_handler import *
1211
from .uri_wrapper import *
12+
from .wrap_package import *
1313
from .wasm_package import *
1414
from .wrap_package import *
1515
from .wrapper import *

packages/polywrap-core/polywrap_core/types/client.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,24 @@
22

33
from abc import abstractmethod
44
from dataclasses import dataclass, field
5-
from typing import List, Optional, Union
5+
from typing import List, Optional, Union, Dict
66

77
from polywrap_manifest import AnyWrapManifest, DeserializeManifestOptions
88
from polywrap_result import Result
99

10-
from .env import Env
11-
from .interface_implementation import InterfaceImplementations
1210
from .invoke import Invoker
1311
from .uri import Uri
12+
from .env import Env
1413
from .uri_resolver import IUriResolver
1514
from .uri_resolver_handler import UriResolverHandler
1615

17-
1816
@dataclass(slots=True, kw_only=True)
1917
class ClientConfig:
20-
envs: List[Env] = field(default_factory=list)
21-
interfaces: List[InterfaceImplementations] = field(default_factory=list)
18+
envs: Dict[Uri, Env] = field(default_factory=dict)
19+
interfaces: Dict[Uri, List[Uri]] = field(default_factory=dict)
2220
resolver: IUriResolver
2321

2422

25-
@dataclass(slots=True, kw_only=True)
26-
class GetEnvsOptions:
27-
pass
28-
29-
30-
@dataclass(slots=True, kw_only=True)
31-
class GetUriResolversOptions:
32-
pass
33-
34-
3523
@dataclass(slots=True, kw_only=True)
3624
class GetFileOptions:
3725
path: str
@@ -45,23 +33,21 @@ class GetManifestOptions(DeserializeManifestOptions):
4533

4634
class Client(Invoker, UriResolverHandler):
4735
@abstractmethod
48-
def get_interfaces(self) -> List[InterfaceImplementations]:
36+
def get_interfaces(self) -> Dict[Uri, List[Uri]]:
4937
pass
5038

5139
@abstractmethod
52-
def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]:
40+
def get_envs(self) -> Dict[Uri, Env]:
5341
pass
5442

5543
@abstractmethod
5644
def get_env_by_uri(
57-
self, uri: Uri, options: Optional[GetEnvsOptions] = None
45+
self, uri: Uri
5846
) -> Union[Env, None]:
5947
pass
6048

6149
@abstractmethod
62-
def get_uri_resolver(
63-
self, options: Optional[GetUriResolversOptions] = None
64-
) -> IUriResolver:
50+
def get_uri_resolver(self) -> IUriResolver:
6551
pass
6652

6753
@abstractmethod
Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
from __future__ import annotations
2-
3-
from dataclasses import dataclass, field
41
from typing import Any, Dict
52

6-
from .uri import Uri
7-
8-
9-
@dataclass(slots=True, kw_only=True)
10-
class Env:
11-
"""
12-
this type can be used to set env for a wrapper in the client
13-
14-
Args:
15-
uri: Uri of wrapper
16-
env: env variables used by the module
17-
"""
18-
19-
uri: Uri
20-
env: Dict[str, Any] = field(default_factory=dict)
3+
Env = Dict[str, Any]

packages/polywrap-core/polywrap_core/types/interface_implementation.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)