Skip to content

Commit c229dce

Browse files
authored
refactor: polywrap-client (#187)
1 parent f20df73 commit c229dce

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1552
-703
lines changed

packages/polywrap-client/poetry.lock

Lines changed: 19 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/polywrap-client/polywrap_client/client.py

Lines changed: 119 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,25 @@
33

44
import json
55
from textwrap import dedent
6-
from typing import Any, Dict, List, Optional, Union, cast
6+
from typing import Any, Dict, List, Optional, Union
77

88
from polywrap_core import (
99
Client,
1010
ClientConfig,
11-
Env,
12-
GetFileOptions,
13-
GetManifestOptions,
14-
InvokerOptions,
15-
IUriResolutionContext,
16-
TryResolveUriOptions,
1711
Uri,
1812
UriPackage,
1913
UriPackageOrWrapper,
14+
UriResolutionStep,
2015
UriResolver,
2116
UriWrapper,
2217
Wrapper,
18+
build_clean_uri_history,
19+
get_env_from_resolution_path,
2320
)
24-
from polywrap_manifest import AnyWrapManifest
21+
from polywrap_core import get_implementations as core_get_implementations
22+
from polywrap_manifest import AnyWrapManifest, DeserializeManifestOptions
2523
from polywrap_msgpack import msgpack_decode, msgpack_encode
26-
from polywrap_uri_resolvers import UriResolutionContext, build_clean_uri_history
24+
from polywrap_uri_resolvers import UriResolutionContext
2725

2826

2927
class PolywrapClient(Client):
@@ -59,13 +57,13 @@ def get_uri_resolver(self) -> UriResolver:
5957
"""
6058
return self._config.resolver
6159

62-
def get_envs(self) -> Dict[Uri, Env]:
60+
def get_envs(self) -> Dict[Uri, Any]:
6361
"""Get the dictionary of environment variables.
6462
6563
Returns:
66-
Dict[Uri, Env]: The dictionary of environment variables.
64+
Dict[Uri, Any]: The dictionary of environment variables.
6765
"""
68-
envs: Dict[Uri, Env] = self._config.envs
66+
envs: Dict[Uri, Any] = self._config.envs
6967
return envs
7068

7169
def get_interfaces(self) -> Dict[Uri, List[Uri]]:
@@ -77,146 +75,196 @@ def get_interfaces(self) -> Dict[Uri, List[Uri]]:
7775
interfaces: Dict[Uri, List[Uri]] = self._config.interfaces
7876
return interfaces
7977

80-
def get_implementations(self, uri: Uri) -> Union[List[Uri], None]:
81-
"""Get the implementations for the given interface URI.
78+
def get_implementations(
79+
self,
80+
uri: Uri,
81+
apply_resolution: bool = True,
82+
resolution_context: Optional[UriResolutionContext] = None,
83+
) -> Optional[List[Uri]]:
84+
"""Get implementations of an interface with its URI.
8285
8386
Args:
84-
uri (Uri): The interface URI.
87+
uri (Uri): URI of the interface.
88+
apply_resolution (bool): If True, apply resolution to the URI and interfaces.
8589
8690
Returns:
87-
Union[List[Uri], None]: The list of implementation URIs.
91+
Optional[List[Uri]]: List of implementations or None if not found.
8892
"""
8993
interfaces: Dict[Uri, List[Uri]] = self.get_interfaces()
90-
return interfaces.get(uri)
94+
if not apply_resolution:
95+
return interfaces.get(uri)
96+
97+
return core_get_implementations(uri, interfaces, self, resolution_context)
9198

92-
def get_env_by_uri(self, uri: Uri) -> Union[Env, None]:
99+
def get_env_by_uri(self, uri: Uri) -> Union[Any, None]:
93100
"""Get the environment variables for the given URI.
94101
95102
Args:
96103
uri (Uri): The URI of the wrapper.
97104
98105
Returns:
99-
Union[Env, None]: The environment variables.
106+
Union[Any, None]: The environment variables.
100107
"""
101108
return self._config.envs.get(uri)
102109

103-
async def get_file(self, uri: Uri, options: GetFileOptions) -> Union[bytes, str]:
110+
def get_file(
111+
self, uri: Uri, path: str, encoding: Optional[str] = "utf-8"
112+
) -> Union[bytes, str]:
104113
"""Get the file from the given wrapper URI.
105114
106115
Args:
107116
uri (Uri): The wrapper URI.
108-
options (GetFileOptions): The options for getting the file.
117+
(GetFile: The for getting the file.
109118
110119
Returns:
111120
Union[bytes, str]: The file contents.
112121
"""
113-
loaded_wrapper = await self.load_wrapper(uri)
114-
return await loaded_wrapper.get_file(options)
122+
loaded_wrapper = self.load_wrapper(uri)
123+
return loaded_wrapper.get_file(path, encoding)
115124

116-
async def get_manifest(
117-
self, uri: Uri, options: Optional[GetManifestOptions] = None
125+
def get_manifest(
126+
self, uri: Uri, options: Optional[DeserializeManifestOptions] = None
118127
) -> AnyWrapManifest:
119128
"""Get the manifest from the given wrapper URI.
120129
121130
Args:
122131
uri (Uri): The wrapper URI.
123-
options (Optional[GetManifestOptions]): The options for getting the manifest.
132+
(Optional[GetManifest): The for getting the manifest.
124133
125134
Returns:
126135
AnyWrapManifest: The manifest.
127136
"""
128-
loaded_wrapper = await self.load_wrapper(uri)
137+
loaded_wrapper = self.load_wrapper(uri)
129138
return loaded_wrapper.get_manifest()
130139

131-
async def try_resolve_uri(
132-
self, options: TryResolveUriOptions[UriPackageOrWrapper]
140+
def try_resolve_uri(
141+
self, uri: Uri, resolution_context: Optional[UriResolutionContext] = None
133142
) -> UriPackageOrWrapper:
134143
"""Try to resolve the given URI.
135144
136145
Args:
137-
options (TryResolveUriOptions[UriPackageOrWrapper]): The options for resolving the URI.
146+
(TryResolveUriUriPackageOrWrapper]): The for resolving the URI.
138147
139148
Returns:
140149
UriPackageOrWrapper: The resolved URI, package or wrapper.
141150
"""
142-
uri = options.uri
143151
uri_resolver = self._config.resolver
144-
resolution_context = options.resolution_context or UriResolutionContext()
152+
resolution_context = resolution_context or UriResolutionContext()
145153

146-
return await uri_resolver.try_resolve_uri(uri, self, resolution_context)
154+
return uri_resolver.try_resolve_uri(uri, self, resolution_context)
147155

148-
async def load_wrapper(
156+
def load_wrapper(
149157
self,
150158
uri: Uri,
151-
resolution_context: Optional[IUriResolutionContext[UriPackageOrWrapper]] = None,
152-
) -> Wrapper[UriPackageOrWrapper]:
159+
resolution_context: Optional[UriResolutionContext] = None,
160+
) -> Wrapper:
153161
"""Load the wrapper for the given URI.
154162
155163
Args:
156164
uri (Uri): The wrapper URI.
157-
resolution_context (Optional[IUriResolutionContext[UriPackageOrWrapper]]):\
165+
resolution_context (Optional[UriResolutionContext]):\
158166
The resolution context.
159167
160168
Returns:
161-
Wrapper[UriPackageOrWrapper]: initialized wrapper instance.
169+
Wrapper: initialized wrapper instance.
162170
"""
163171
resolution_context = resolution_context or UriResolutionContext()
164172

165-
uri_package_or_wrapper = await self.try_resolve_uri(
166-
TryResolveUriOptions(uri=uri, resolution_context=resolution_context)
173+
uri_package_or_wrapper = self.try_resolve_uri(
174+
uri=uri, resolution_context=resolution_context
167175
)
168176

169-
if isinstance(uri_package_or_wrapper, UriPackage):
170-
return await cast(
171-
UriPackage[UriPackageOrWrapper], uri_package_or_wrapper
172-
).package.create_wrapper()
173-
174-
if isinstance(uri_package_or_wrapper, UriWrapper):
175-
return cast(UriWrapper[UriPackageOrWrapper], uri_package_or_wrapper).wrapper
176-
177-
raise RuntimeError(
178-
dedent(
179-
f"""
180-
Error resolving URI "{uri.uri}"
181-
URI not found
182-
Resolution Stack: {
183-
json.dumps(
184-
build_clean_uri_history(
185-
resolution_context.get_history()
186-
), indent=2
177+
match uri_package_or_wrapper:
178+
case UriPackage(uri=uri, package=package):
179+
return package.create_wrapper()
180+
case UriWrapper(uri=uri, wrapper=wrapper):
181+
return wrapper
182+
case _:
183+
raise RuntimeError(
184+
dedent(
185+
f"""
186+
Error resolving URI "{uri.uri}"
187+
URI not found
188+
Resolution Stack: {
189+
json.dumps(
190+
build_clean_uri_history(
191+
resolution_context.get_history()
192+
), indent=2
193+
)
194+
}
195+
"""
187196
)
188-
}
189-
"""
190-
)
191-
)
197+
)
192198

193-
async def invoke(self, options: InvokerOptions[UriPackageOrWrapper]) -> Any:
199+
def invoke(
200+
self,
201+
uri: Uri,
202+
method: str,
203+
args: Optional[Any] = None,
204+
env: Optional[Any] = None,
205+
resolution_context: Optional[UriResolutionContext] = None,
206+
encode_result: Optional[bool] = False,
207+
) -> Any:
194208
"""Invoke the given wrapper URI.
195209
196210
Args:
197-
options (InvokerOptions[UriPackageOrWrapper]): The options for invoking the wrapper.
211+
(InvokerUriPackageOrWrapper]): The for invoking the wrapper.
198212
199213
Returns:
200214
Any: The result of the invocation.
201215
"""
202-
resolution_context = options.resolution_context or UriResolutionContext()
203-
wrapper = await self.load_wrapper(
204-
options.uri, resolution_context=resolution_context
216+
resolution_context = resolution_context or UriResolutionContext()
217+
load_wrapper_context = resolution_context.create_sub_history_context()
218+
wrapper = self.load_wrapper(uri, resolution_context=load_wrapper_context)
219+
wrapper_resolution_path = load_wrapper_context.get_resolution_path()
220+
wrapper_resolved_uri = wrapper_resolution_path[-1]
221+
222+
resolution_context.track_step(
223+
UriResolutionStep(
224+
source_uri=uri,
225+
result=UriWrapper(uri=uri, wrapper=wrapper),
226+
description="Client.load_wrapper",
227+
sub_history=load_wrapper_context.get_history(),
228+
)
205229
)
206-
options.env = options.env or self.get_env_by_uri(options.uri)
207230

208-
invocable_result = await wrapper.invoke(options, invoker=self)
231+
env = env or get_env_from_resolution_path(
232+
load_wrapper_context.get_resolution_path(), self
233+
)
234+
235+
wrapper_invoke_context = resolution_context.create_sub_history_context()
209236

210-
if options.encode_result and not invocable_result.encoded:
237+
invocable_result = wrapper.invoke(
238+
uri=wrapper_resolved_uri,
239+
method=method,
240+
args=args,
241+
env=env,
242+
resolution_context=wrapper_invoke_context,
243+
client=self,
244+
)
245+
246+
resolution_context.track_step(
247+
UriResolutionStep(
248+
source_uri=wrapper_resolved_uri,
249+
result=wrapper_resolved_uri,
250+
description="Wrapper.invoke",
251+
sub_history=wrapper_invoke_context.get_history(),
252+
)
253+
)
254+
255+
if encode_result and not invocable_result.encoded:
211256
encoded = msgpack_encode(invocable_result.result)
212257
return encoded
213258

214259
if (
215-
not options.encode_result
260+
not encode_result
216261
and invocable_result.encoded
217262
and isinstance(invocable_result.result, (bytes, bytearray))
218263
):
219264
decoded: Any = msgpack_decode(invocable_result.result)
220265
return decoded
221266

222267
return invocable_result.result
268+
269+
270+
__all__ = ["PolywrapClient"]

packages/polywrap-client/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ readme = "README.md"
1111

1212
[tool.poetry.dependencies]
1313
python = "^3.10"
14-
polywrap-uri-resolvers = {path = "../polywrap-uri-resolvers", develop = true}
1514
polywrap-manifest = {path = "../polywrap-manifest", develop = true}
1615
polywrap-msgpack = {path = "../polywrap-msgpack", develop = true}
1716
polywrap-core = {path = "../polywrap-core", develop = true}
@@ -21,6 +20,7 @@ pytest = "^7.1.2"
2120
pytest-asyncio = "^0.19.0"
2221
polywrap-plugin = {path = "../polywrap-plugin", develop = true}
2322
polywrap-client-config-builder = {path = "../polywrap-client-config-builder", develop = true}
23+
polywrap-test-cases = {path = "../polywrap-test-cases", develop = true}
2424
pylint = "^2.15.4"
2525
black = "^22.10.0"
2626
bandit = { version = "^1.7.4", extras = ["toml"]}
@@ -52,6 +52,7 @@ testpaths = [
5252

5353
[tool.pylint]
5454
disable = [
55+
"too-many-arguments",
5556
]
5657
ignore = [
5758
"tests/"
-5.32 KB
Binary file not shown.
-125 KB
Binary file not shown.
-724 Bytes
Binary file not shown.
-54.5 KB
Binary file not shown.

packages/polywrap-client/tests/cases/sha3/wrap.info

Lines changed: 0 additions & 1 deletion
This file was deleted.
-137 KB
Binary file not shown.
-629 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)