Skip to content

Commit 2c2c61e

Browse files
committed
feat: packages refactor, added generic add function, plus a tests suite for configuring packages, readme.
1 parent c27ff74 commit 2c2c61e

4 files changed

Lines changed: 162 additions & 33 deletions

File tree

packages/polywrap-client-config-builder/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
These objects are needed to configure your python client's wrappers, pluggins, env variables, resolvers and interfaces.
66

7-
Look at [this file][./client_config_builder.py] to detail all of its functionality
8-
# Polywrap Python Client
9-
## This object allows you to build proper Polywrapt ClientConfig objects
7+
Look at [this file](./polywrap_client_config_builder/client_config_builder.py) to detail all of its functionality
8+
And at [tests](./tests/test_client_config_builder.py)
109

11-
These objects are needed to configure your python client's wrappers, pluggins, env variables, resolvers and interfaces.
10+
---
1211

13-
Look at [this file](./polywrap_client_config_builder/client_config_builder.py) to detail all of its functionality
14-
And at [tests](./tests/test_client_config_builder.py)
12+
The current implementation uses the `ClientConfig` as a dataclass to later create an Abstract Base Class of a `BaseClientConfigBuilder` which defines more clearly the functions of the module, like add_envs, set_resolvers, remove_wrappers, and so on.
13+
14+
This `BaseClientConfigBuilder` is later used in the class `ClientConfigBuilder` which only implements the build method, for now, and inherits all the abstract methods of the `BaseClientConfigBuilder`.

packages/polywrap-client-config-builder/polywrap_client_config_builder/client_config_builder.py

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from abc import ABC, abstractmethod
22
from dataclasses import dataclass
3-
from polywrap_core import Uri, IUriResolver, Env
3+
from polywrap_core import Uri, IUriResolver, Env, UriWrapper,UriPackage
4+
from polywrap_uri_resolvers import IUriResolver
45
from typing import Dict, Any, List, Optional, Union
56

67
@dataclass(slots=True, kw_only=True)
@@ -11,8 +12,9 @@ class ClientConfig():
1112
"""
1213
envs: Dict[Uri, Dict[str, Any]]
1314
interfaces: Dict[Uri, List[Uri]]
15+
packages: List[UriPackage]
1416
resolver: List[IUriResolver]
15-
wrappers: List[Uri]
17+
wrappers: List[UriWrapper]
1618

1719

1820
class BaseClientConfigBuilder(ABC):
@@ -22,13 +24,28 @@ class BaseClientConfigBuilder(ABC):
2224
"""
2325

2426
def __init__(self):
25-
self.config = ClientConfig(envs={}, interfaces={}, resolver=[], wrappers= [])
27+
self.config = ClientConfig(envs={}, interfaces={}, resolver=[], wrappers= [], packages=[])
2628

2729
@abstractmethod
2830
def build(self) -> ClientConfig:
2931
"""Returns a sanitized config object from the builder's config."""
3032
pass
3133

34+
@abstractmethod
35+
def add(self, new_config: ClientConfig) -> ClientConfig:
36+
"""Returns a sanitized config object from the builder's config after receiving a partial `ClientConfig` object."""
37+
if new_config.envs:
38+
self.config.envs.update(new_config.envs)
39+
if new_config.interfaces:
40+
self.config.interfaces.update(new_config.interfaces)
41+
if new_config.resolver:
42+
self.config.resolver.extend(new_config.resolver)
43+
if new_config.wrappers:
44+
self.config.wrappers.extend(new_config.wrappers)
45+
if new_config.packages:
46+
self.config.packages.extend(new_config.packages)
47+
return self.config
48+
3249
@abstractmethod
3350
def get_envs(self)-> Dict[Uri, Dict[str, Any]]:
3451
"""Returns the envs dictionary from the builder's config."""
@@ -37,13 +54,11 @@ def get_envs(self)-> Dict[Uri, Dict[str, Any]]:
3754
@abstractmethod
3855
def set_env(self, env: Env, uri: Uri):
3956
"""Sets the envs dictionary in the builder's config, overiding any existing values."""
40-
if (env or uri) is None:
41-
raise KeyError("Must provide both an env or uri")
4257
self.config.envs[uri] = env
4358
return self
4459

4560
@abstractmethod
46-
def add_env(self, env: Env = None , uri: Uri = None):
61+
def add_env(self, env: Env, uri: Uri):
4762
"""Adds an environment (in the form of an `Env`) for a given uri, without overwriting existing environments,
4863
unless the env key already exists in the environment, then it will overwrite the existing value"""
4964
if (env or uri) is None:
@@ -103,6 +118,39 @@ def remove_wrapper(self, wrapper_uri: Uri) :
103118
self.config.wrappers.remove(wrapper_uri)
104119
return self
105120

121+
@abstractmethod
122+
def set_package(self, uri_package: UriPackage):
123+
"""
124+
Sets the package in the builder's config, overiding any existing values.
125+
"""
126+
self.config.packages = [uri_package]
127+
return self
128+
129+
@abstractmethod
130+
def add_package(self, uri_package: UriPackage):
131+
"""
132+
Adds a package to the list of packages
133+
"""
134+
self.config.packages.append(uri_package)
135+
return self
136+
137+
@abstractmethod
138+
def add_packages(self, uri_packages: List[UriPackage]):
139+
"""
140+
Adds a list of packages to the list of packages
141+
"""
142+
for uri_package in uri_packages:
143+
self.add_package(uri_package)
144+
return self
145+
146+
@abstractmethod
147+
def remove_package(self, uri_package: UriPackage):
148+
"""
149+
Removes a package from the list of packages
150+
"""
151+
self.config.packages.remove(uri_package)
152+
return self
153+
106154
@abstractmethod
107155
def set_resolver(self, uri_resolver):
108156
"""
@@ -139,6 +187,13 @@ def build(self)-> ClientConfig:
139187
"""
140188
return self.config
141189

190+
def add(self, new_config: ClientConfig) -> ClientConfig:
191+
"""
192+
Returns a sanitized config object from the builder's config after receiving a partial `ClientConfig` object.
193+
"""
194+
super().add(new_config)
195+
return self.config
196+
142197
def get_envs(self) -> Dict[Uri, Dict[str, Any]]:
143198
return super().get_envs()
144199

@@ -170,6 +225,22 @@ def remove_wrapper(self, wrapper_uri: Uri)-> BaseClientConfigBuilder:
170225
super().remove_wrapper(wrapper_uri)
171226
return self
172227

228+
def set_package(self, uri_package: UriPackage)-> BaseClientConfigBuilder:
229+
super().set_package(uri_package)
230+
return self
231+
232+
def add_package(self, uri_package: UriPackage)-> BaseClientConfigBuilder:
233+
super().add_package(uri_package)
234+
return self
235+
236+
def add_packages(self, uri_packages: List[UriPackage])-> BaseClientConfigBuilder:
237+
super().add_packages(uri_packages)
238+
return self
239+
240+
def remove_package(self, uri_package: UriPackage)-> BaseClientConfigBuilder:
241+
super().remove_package(uri_package)
242+
return self
243+
173244
def set_resolver(self, uri_resolver: IUriResolver)-> BaseClientConfigBuilder:
174245
super().set_resolver(uri_resolver)
175246
return self

packages/polywrap-client-config-builder/tests/test_client_config_builder.py

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import List, Any, Dict, Union
22
from polywrap_core import Env
33
from polywrap_core import Uri
4-
from polywrap_core import IUriResolver
4+
from polywrap_core import IUriResolver, UriPackage, UriWrapper
55
from polywrap_client_config_builder import ClientConfigBuilder
66
import pytest
77
from pytest import fixture
@@ -27,33 +27,33 @@ def test_client_config_builder_set_env():
2727
envs = { env_uriX: env_varA }
2828
ccb = ccb.set_env( env_varA, env_uriX)
2929
client_config = ccb.build()
30-
assert asdict(client_config) == asdict(ClientConfig(envs=envs, interfaces={}, resolver = [], wrappers=[]))
30+
assert asdict(client_config) == asdict(ClientConfig(envs=envs, interfaces={}, resolver = [], wrappers=[], packages=[]))
3131

3232
def test_client_config_builder_add_env():
3333
ccb = ClientConfigBuilder() # instantiate new client config builder
3434
ccb = ccb.add_env(env = env_varA, uri = env_uriX) # add env to client config builder
3535
client_config: ClientConfig = ccb.build() # build a client config object
3636
print(client_config)
37-
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[]))
37+
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[], packages=[]))
3838

3939
def test_client_config_builder_add_env_updates_env_value():
4040
ccb = ClientConfigBuilder() # instantiate new client config builder
4141
ccb = ccb.add_env(env = env_varA, uri = env_uriX) # add env to client config builder
4242
client_config: ClientConfig = ccb.build() # build a client config object
43-
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[]))
43+
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[], packages=[]))
4444
ccb = ccb.add_env(env = env_varB, uri = env_uriX) # update value of env var on client config builder
4545
client_config: ClientConfig = ccb.build() # build a new client config object
46-
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varB}, interfaces={}, resolver = [], wrappers=[]))
46+
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varB}, interfaces={}, resolver = [], wrappers=[], packages=[]))
4747

4848
def test_client_config_builder_set_env_and_add_env_updates_and_add_values():
4949
ccb = ClientConfigBuilder()
5050
ccb = ccb.set_env(env_varA, env_uriX) # set the environment variables A
5151
client_config: ClientConfig = ccb.build()
52-
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[]))
52+
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varA}, interfaces={}, resolver = [], wrappers=[], packages=[]))
5353

5454
ccb = ccb.set_env(env_varB, env_uriX) # set new vars on the same Uri
5555
client_config: ClientConfig = ccb.build()
56-
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varB}, interfaces={}, resolver = [], wrappers=[]))
56+
assert asdict(client_config) == asdict(ClientConfig(envs={env_uriX: env_varB}, interfaces={}, resolver = [], wrappers=[], packages=[]))
5757

5858
ccb = ccb.add_env(env_varM, env_uriY) # add new env vars on a new Uri
5959
client_config: ClientConfig = ccb.build()
@@ -62,14 +62,14 @@ def test_client_config_builder_set_env_and_add_env_updates_and_add_values():
6262
env_uriX: env_varB,
6363
env_uriY: env_varM
6464
},
65-
interfaces={}, resolver = [], wrappers=[]))
65+
interfaces={}, resolver = [], wrappers=[], packages=[]))
6666

6767
# add new env vars on the second Uri, while also updating the Env vars of dog and season
6868
ccb = ccb.add_envs([env_varN, env_varS], env_uriY)
6969
new_envs = {**env_varM, **env_varN, **env_varS}
7070
print(new_envs)
7171
client_config = ccb.build()
72-
assert asdict(client_config) == asdict(ClientConfig(envs = {env_uriX: env_varB, env_uriY: new_envs}, interfaces={}, resolver = [], wrappers=[]))
72+
assert asdict(client_config) == asdict(ClientConfig(envs = {env_uriX: env_varB, env_uriY: new_envs}, interfaces={}, resolver = [], wrappers=[], packages=[]))
7373

7474
# INTERFACES AND IMPLEMENTATIONS
7575

@@ -79,7 +79,58 @@ def test_client_config_builder_adds_interface_implementations():
7979
implementations_uris = [Uri("wrap://ens/eth.plugin.one"), Uri("wrap://ens/eth.plugin.two")]
8080
ccb = ccb.add_interface_implementations(interfaces_uri, implementations_uris)
8181
client_config = ccb.build()
82-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={interfaces_uri: implementations_uris}, resolver = [], wrappers=[]))
82+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={interfaces_uri: implementations_uris}, resolver = [], wrappers=[], packages=[]))
83+
84+
# PACKAGES
85+
86+
@pytest.mark.skip("Should implement UriPackage interface with package argument")
87+
def test_client_config_builder_set_package():
88+
ccb = ClientConfigBuilder()
89+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"), version="1.0.0")
90+
ccb = ccb.set_package(package)
91+
client_config = ccb.build()
92+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package]))
93+
94+
@pytest.mark.skip("Should implement UriPackage interface with package argument")
95+
def test_client_config_builder_add_package():
96+
ccb = ClientConfigBuilder()
97+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
98+
ccb = ccb.add_package(package)
99+
client_config = ccb.build()
100+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package]))
101+
102+
@pytest.mark.skip("Should implement UriPackage interface with package argument")
103+
def test_client_config_builder_add_package_updates_package():
104+
ccb = ClientConfigBuilder()
105+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
106+
ccb = ccb.add_package(package)
107+
client_config = ccb.build()
108+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package]))
109+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
110+
ccb = ccb.add_package(package)
111+
client_config = ccb.build()
112+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package]))
113+
114+
@pytest.mark.skip("Should implement UriPackage interface with package argument")
115+
def test_client_config_builder_add_packages():
116+
ccb = ClientConfigBuilder()
117+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
118+
package2 = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
119+
ccb = ccb.add_packages([package, package2])
120+
client_config = ccb.build()
121+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package, package2]))
122+
123+
@pytest.mark.skip("Should implement UriPackage interface with package argument")
124+
def test_client_config_builder_add_packages_removes_packages():
125+
ccb = ClientConfigBuilder()
126+
package = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
127+
package2 = UriPackage(Uri("wrap://ens/uni.wrapper.eth"))
128+
ccb = ccb.add_packages([package, package2])
129+
client_config = ccb.build()
130+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package, package2]))
131+
ccb = ccb.remove_package([package1])
132+
client_config = ccb.build()
133+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[package2]))
83134

84135
# WRAPPERS AND PLUGINS
85136

@@ -88,24 +139,24 @@ def test_client_config_builder_add_wrapper():
88139
wrapper = Uri("wrap://ens/uni.wrapper.eth")
89140
ccb = ccb.add_wrapper(wrapper)
90141
client_config = ccb.build()
91-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[wrapper]))
142+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[wrapper], packages=[]))
92143

93144
def test_client_config_builder_adds_multiple_wrappers():
94145
ccb = ClientConfigBuilder()
95146
wrappers = [Uri("wrap://ens/uni.wrapper.eth"), Uri("wrap://ens/https.plugin.eth")]
96147
ccb = ccb.add_wrappers(wrappers)
97148
client_config = ccb.build()
98-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=wrappers))
149+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=wrappers, packages=[]))
99150

100151
def test_client_config_builder_removes_wrapper():
101152
ccb = ClientConfigBuilder()
102153
wrapper = Uri("wrap://ens/uni.wrapper.eth")
103154
ccb = ccb.add_wrapper(wrapper)
104155
client_config = ccb.build()
105-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[wrapper]))
156+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[wrapper], packages=[]))
106157
ccb = ccb.remove_wrapper(wrapper)
107158
client_config = ccb.build()
108-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[]))
159+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver = [], wrappers=[], packages=[]))
109160

110161
# RESOLVER
111162

@@ -114,9 +165,9 @@ def test_client_config_builder_set_uri_resolver():
114165
ccb = ClientConfigBuilder()
115166
resolver = IUriResolver()
116167
Uri("wrap://ens/eth.resolver.one")
117-
ccb = ccb.set_resolver()
168+
ccb = ccb.set_resolver(resolver)
118169
client_config = ccb.build()
119-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=resolver, wrappers=[]))
170+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=[resolver], wrappers=[], packages=[]))
120171

121172
def test_client_config_builder_add_resolver():
122173

@@ -125,18 +176,24 @@ def test_client_config_builder_add_resolver():
125176
resolverA = Uri("wrap://ens/eth.resolver.one")
126177
ccb: ClientConfigBuilder = ccb.set_resolver(resolverA)
127178
client_config: ClientConfig = ccb.build()
128-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=[resolverA], wrappers=[]))
179+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=[resolverA], wrappers=[], packages=[]))
129180

130181
# add a second resolver
131182
resolverB = Uri("wrap://ens/eth.resolver.two")
132183
ccb = ccb.add_resolver(resolverB)
133184
client_config: ClientConfig = ccb.build()
134-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=[resolverA, resolverB], wrappers=[]))
185+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=[resolverA, resolverB], wrappers=[], packages=[]))
135186

136187
# add a third and fourth resolver
137188
resolverC = Uri("wrap://ens/eth.resolver.three")
138189
resolverD = Uri("wrap://ens/eth.resolver.four")
139190
ccb = ccb.add_resolvers([resolverC, resolverD])
140191
client_config: ClientConfig = ccb.build()
141192
resolvers = [resolverA, resolverB, resolverC, resolverD]
142-
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=resolvers, wrappers=[]))
193+
assert asdict(client_config) == asdict(ClientConfig(envs={}, interfaces={}, resolver=resolvers, wrappers=[], packages=[]))
194+
195+
# TODO: add tests for the following methods
196+
197+
def test_client_config_builder_generic_add():
198+
# Test adding package, wrapper, resolver, interface, and env with the ccb.add method
199+
pass

packages/polywrap-client-config-builder/tests/test_clientconfig.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ def test_client_config_structure_starts_empty():
1010
envs={},
1111
interfaces={},
1212
resolver = [],
13-
wrappers = []
13+
wrappers = [],
14+
packages=[]
1415
)
1516
assert asdict(client_config) == asdict(result)
1617

@@ -24,5 +25,5 @@ def test_client_config_structure_sets_env():
2425
env = env
2526
)
2627
client_config = ccb.build()
27-
assert asdict(client_config) == asdict(ClientConfig(envs={uri: env}, interfaces={}, resolver = [], wrappers=[]))
28+
assert asdict(client_config) == asdict(ClientConfig(envs={uri: env}, interfaces={}, resolver = [], wrappers=[], packages=[]))
2829

0 commit comments

Comments
 (0)