diff --git a/packages/polywrap-client/polywrap_client/client.py b/packages/polywrap-client/polywrap_client/client.py index 0cb96ebe..b12368cb 100644 --- a/packages/polywrap-client/polywrap_client/client.py +++ b/packages/polywrap-client/polywrap_client/client.py @@ -2,21 +2,19 @@ from dataclasses import dataclass from textwrap import dedent -from typing import Any, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Union, cast from polywrap_core import ( Client, ClientConfig, - Env, - GetEnvsOptions, GetFileOptions, GetManifestOptions, GetUriResolversOptions, - InterfaceImplementations, InvokerOptions, IUriResolutionContext, IUriResolver, TryResolveUriOptions, + Env, Uri, UriPackage, UriPackageOrWrapper, @@ -51,24 +49,25 @@ def get_uri_resolver( ) -> IUriResolver: return self._config.resolver - def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]: - return self._config.envs + def get_envs(self) -> Dict[Uri, Env]: + envs: Dict[Uri, Env] = self._config.envs + return envs - def get_interfaces(self) -> List[InterfaceImplementations]: - return self._config.interfaces + def get_interfaces(self) -> Dict[Uri, List[Uri]]: + interfaces: Dict[Uri, List[Uri]] = self._config.interfaces + return interfaces - def get_implementations(self, uri: Uri) -> Result[List[Uri]]: - if interface_implementations := next( - filter(lambda x: x.interface == uri, self._config.interfaces), None - ): - return Ok(interface_implementations.implementations) + def get_implementations(self, uri: Uri) -> Result[Union[List[Uri], None]]: + interfaces: Dict[Uri, List[Uri]] = self.get_interfaces() + if interfaces.get(uri): + return Ok(interfaces.get(uri)) else: return Err.from_str(f"Unable to find implementations for uri: {uri}") def get_env_by_uri( - self, uri: Uri, options: Optional[GetEnvsOptions] = None + self, uri: Uri ) -> Union[Env, None]: - return next(filter(lambda env: env.uri == uri, self.get_envs()), None) + return self._config.envs.get(uri) async def get_file( self, uri: Uri, options: GetFileOptions @@ -139,9 +138,7 @@ async def invoke(self, options: InvokerOptions) -> Result[Any]: if wrapper_result.is_err(): return cast(Err, wrapper_result) wrapper = wrapper_result.unwrap() - - env = self.get_env_by_uri(options.uri) - options.env = options.env or (env.env if env else None) + options.env = options.env or self.get_env_by_uri(options.uri) result = await wrapper.invoke(options, invoker=self) if result.is_err(): diff --git a/packages/polywrap-client/tests/test_client.py b/packages/polywrap-client/tests/test_client.py index fcb3c8db..623195fc 100644 --- a/packages/polywrap-client/tests/test_client.py +++ b/packages/polywrap-client/tests/test_client.py @@ -1,9 +1,9 @@ from pathlib import Path - +import pytest from polywrap_client import PolywrapClient -from polywrap_core import Uri, InvokerOptions, InterfaceImplementations, Env +from polywrap_core import Uri, InvokerOptions from polywrap_uri_resolvers import BaseUriResolver, SimpleFileReader - +from polywrap_result import Ok from polywrap_client.client import PolywrapClientConfig @@ -31,7 +31,7 @@ async def test_subinvoke(): }, ) - client = PolywrapClient(config=PolywrapClientConfig(envs=[], resolver=uri_resolver)) + client = PolywrapClient(config=PolywrapClientConfig(resolver=uri_resolver)) uri = Uri( f'fs/{Path(__file__).parent.joinpath("cases", "simple-subinvoke", "invoke").absolute()}' ) @@ -48,19 +48,15 @@ async def test_interface_implementation(): redirects={}, ) + interface_uri = Uri("ens/interface.eth") impl_uri = Uri( f'fs/{Path(__file__).parent.joinpath("cases", "simple-interface", "implementation").absolute()}' ) client = PolywrapClient( config=PolywrapClientConfig( - envs=[], resolver=uri_resolver, - interfaces=[ - InterfaceImplementations( - interface=Uri("ens/interface.eth"), implementations=[impl_uri] - ) - ], + interfaces= {interface_uri : [impl_uri]} ) ) uri = Uri( @@ -71,10 +67,26 @@ async def test_interface_implementation(): uri=uri, method="moduleMethod", args=args, encode_result=False ) result = await client.invoke(options) - + assert client.get_implementations(interface_uri) == Ok([impl_uri]) assert result.unwrap() == {"str": "hello", "uint8": 2} +def test_get_env_by_uri(): + uri_resolver = BaseUriResolver( + file_reader=SimpleFileReader(), + redirects={}, + ) + uri = Uri(f'fs/{Path(__file__).parent.joinpath("cases", "simple-env").absolute()}') + env = {"externalArray": [1, 2, 3], "externalString": "hello"} + + client = PolywrapClient( + config=PolywrapClientConfig( + envs={uri: env}, + resolver=uri_resolver, + ) + ) + assert client.get_env_by_uri(uri) == env + async def test_env(): uri_resolver = BaseUriResolver( file_reader=SimpleFileReader(), @@ -86,13 +98,14 @@ async def test_env(): client = PolywrapClient( config=PolywrapClientConfig( - envs=[Env(uri=uri, env=env)], + envs={uri: env}, resolver=uri_resolver, ) ) options = InvokerOptions( - uri=uri, method="externalEnvMethod", args={}, encode_result=False + uri=uri, method="externalEnvMethod", args={}, encode_result=False, ) + result = await client.invoke(options) assert result.unwrap() == env diff --git a/packages/polywrap-client/tests/test_sha3.py b/packages/polywrap-client/tests/test_sha3.py index eb116fc9..4aa52ee9 100644 --- a/packages/polywrap-client/tests/test_sha3.py +++ b/packages/polywrap-client/tests/test_sha3.py @@ -19,7 +19,6 @@ async def test_invoke_sha3_512(): result = await client.invoke(options) s = hashlib.sha512() s.update(b"hello polywrap!") - print(result) assert result.result == s.digest() @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(): async def test_invoke_buffer_keccak_256(): options = InvokerOptions(uri=uri, method="buffer_keccak_256", args=args, encode_result=False) result = await client.invoke(options) - print(result) # TODO: Not sure exactly what this function `buffer_keccak_256` is doing in order to assert it properly assert result.result == False diff --git a/packages/polywrap-core/polywrap_core/types/__init__.py b/packages/polywrap-core/polywrap_core/types/__init__.py index ba6656d6..d49e4073 100644 --- a/packages/polywrap-core/polywrap_core/types/__init__.py +++ b/packages/polywrap-core/polywrap_core/types/__init__.py @@ -1,5 +1,4 @@ from .client import * -from .env import * from .file_reader import * from .invoke import * from .uri import * diff --git a/packages/polywrap-core/polywrap_core/types/client.py b/packages/polywrap-core/polywrap_core/types/client.py index 46845bac..dec9b712 100644 --- a/packages/polywrap-core/polywrap_core/types/client.py +++ b/packages/polywrap-core/polywrap_core/types/client.py @@ -2,31 +2,24 @@ from abc import abstractmethod from dataclasses import dataclass, field -from typing import List, Optional, Union +from typing import List, Optional, Union, Dict from polywrap_manifest import AnyWrapManifest, DeserializeManifestOptions from polywrap_result import Result -from .env import Env -from .interface_implementation import InterfaceImplementations from .invoke import Invoker from .uri import Uri +from .env import Env from .uri_resolver import IUriResolver from .uri_resolver_handler import UriResolverHandler - @dataclass(slots=True, kw_only=True) class ClientConfig: - envs: List[Env] = field(default_factory=list) - interfaces: List[InterfaceImplementations] = field(default_factory=list) + envs: Dict[Uri, Env] = field(default_factory=dict) + interfaces: Dict[Uri, List[Uri]] = field(default_factory=dict) resolver: IUriResolver -@dataclass(slots=True, kw_only=True) -class GetEnvsOptions: - pass - - @dataclass(slots=True, kw_only=True) class GetUriResolversOptions: pass @@ -45,16 +38,16 @@ class GetManifestOptions(DeserializeManifestOptions): class Client(Invoker, UriResolverHandler): @abstractmethod - def get_interfaces(self) -> List[InterfaceImplementations]: + def get_interfaces(self) -> Dict[Uri, List[Uri]]: pass @abstractmethod - def get_envs(self, options: Optional[GetEnvsOptions] = None) -> List[Env]: + def get_envs(self) -> Dict[Uri, Env]: pass @abstractmethod def get_env_by_uri( - self, uri: Uri, options: Optional[GetEnvsOptions] = None + self, uri: Uri ) -> Union[Env, None]: pass diff --git a/packages/polywrap-core/polywrap_core/types/env.py b/packages/polywrap-core/polywrap_core/types/env.py index ff1f914a..48dfa894 100644 --- a/packages/polywrap-core/polywrap_core/types/env.py +++ b/packages/polywrap-core/polywrap_core/types/env.py @@ -1,20 +1,3 @@ -from __future__ import annotations - -from dataclasses import dataclass, field from typing import Any, Dict -from .uri import Uri - - -@dataclass(slots=True, kw_only=True) -class Env: - """ - this type can be used to set env for a wrapper in the client - - Args: - uri: Uri of wrapper - env: env variables used by the module - """ - - uri: Uri - env: Dict[str, Any] = field(default_factory=dict) +Env = Dict[str, Any] diff --git a/packages/polywrap-core/polywrap_core/types/interface_implementation.py b/packages/polywrap-core/polywrap_core/types/interface_implementation.py deleted file mode 100644 index b46ae79d..00000000 --- a/packages/polywrap-core/polywrap_core/types/interface_implementation.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass -from typing import List - -from .uri import Uri - - -@dataclass(slots=True, kw_only=True) -class InterfaceImplementations: - interface: Uri - implementations: List[Uri] diff --git a/packages/polywrap-core/polywrap_core/types/invoke.py b/packages/polywrap-core/polywrap_core/types/invoke.py index 7c474cd8..47634396 100644 --- a/packages/polywrap-core/polywrap_core/types/invoke.py +++ b/packages/polywrap-core/polywrap_core/types/invoke.py @@ -7,6 +7,7 @@ from polywrap_result import Result from .uri import Uri +from .env import Env from .uri_resolution_context import IUriResolutionContext @@ -26,7 +27,7 @@ class InvokeOptions: uri: Uri method: str args: Optional[Union[Dict[str, Any], bytes]] = field(default_factory=dict) - env: Optional[Dict[str, Any]] = None + env: Optional[Env] = None resolution_context: Optional[IUriResolutionContext] = None @@ -55,7 +56,7 @@ async def invoke(self, options: InvokerOptions) -> Result[Any]: pass @abstractmethod - def get_implementations(self, uri: Uri) -> Result[List[Uri]]: + def get_implementations(self, uri: Uri) -> Result[Union[List[Uri], None]]: pass diff --git a/packages/polywrap-core/polywrap_core/utils/get_env_from_uri_history.py b/packages/polywrap-core/polywrap_core/utils/get_env_from_uri_history.py index dab39dd0..6c9ef177 100644 --- a/packages/polywrap-core/polywrap_core/utils/get_env_from_uri_history.py +++ b/packages/polywrap-core/polywrap_core/utils/get_env_from_uri_history.py @@ -1,10 +1,10 @@ -from typing import List, Union +from typing import List, Union, Dict, Any from ..types import Client, Env, Uri def get_env_from_uri_history( uri_history: List[Uri], client: Client -) -> Union[Env, None]: +) -> Union[Dict[str, Any], None]: for uri in uri_history: return client.get_env_by_uri(uri) diff --git a/packages/polywrap-msgpack/polywrap_msgpack/__init__.py b/packages/polywrap-msgpack/polywrap_msgpack/__init__.py index d3452640..af0fc63c 100644 --- a/packages/polywrap-msgpack/polywrap_msgpack/__init__.py +++ b/packages/polywrap-msgpack/polywrap_msgpack/__init__.py @@ -53,12 +53,7 @@ def sanitize(value: Any) -> Any: if isinstance(value, dict): dictionary: Dict[Any, Any] = value for key, val in dictionary.items(): - if isinstance(key, str): - dictionary[key] = sanitize(val) - else: - raise ValueError( - f"expected dict key to be str received {key} with type {type(key)}" - ) + dictionary[str(key)] = sanitize(val) return dictionary if isinstance(value, list): array: List[Any] = value