|
| 1 | +"""This module provides a simple builder for building a ClientConfig object.""" |
| 2 | + |
| 3 | +from typing import Any, Dict, List, Optional, cast |
| 4 | + |
| 5 | +from polywrap_core import ( |
| 6 | + ClientConfig, |
| 7 | + Env, |
| 8 | + Uri, |
| 9 | + UriPackage, |
| 10 | + UriPackageOrWrapper, |
| 11 | + UriResolver, |
| 12 | + UriWrapper, |
| 13 | + WrapPackage, |
| 14 | + Wrapper, |
| 15 | +) |
| 16 | +from polywrap_uri_resolvers import ( |
| 17 | + ExtendableUriResolver, |
| 18 | + InMemoryWrapperCache, |
| 19 | + PackageToWrapperResolver, |
| 20 | + RecursiveResolver, |
| 21 | + RequestSynchronizerResolver, |
| 22 | + StaticResolver, |
| 23 | + UriResolverAggregator, |
| 24 | + WrapperCacheResolver, |
| 25 | +) |
| 26 | + |
| 27 | +from .types import BuilderConfig, BuildOptions |
| 28 | + |
| 29 | + |
| 30 | +class ClientConfigBuilder: |
| 31 | + """Defines a simple builder for building a ClientConfig object. |
| 32 | +
|
| 33 | + The ClientConfigBuilder is used to create a ClientConfig object,\ |
| 34 | + which is used to configure the Polywrap Client and its sub-components.\ |
| 35 | + ClientConfigBuilder provides a simple interface for setting\ |
| 36 | + the redirects, wrappers, packages, and other configuration options\ |
| 37 | + for the Polywrap Client. |
| 38 | + """ |
| 39 | + |
| 40 | + def __init__(self): |
| 41 | + """Initialize the builder's config attributes with empty values.""" |
| 42 | + self.config = BuilderConfig( |
| 43 | + envs={}, interfaces={}, resolvers=[], wrappers={}, packages={}, redirects={} |
| 44 | + ) |
| 45 | + |
| 46 | + def build(self, options: Optional[BuildOptions] = None) -> ClientConfig: |
| 47 | + """Build the ClientConfig object from the builder's config.""" |
| 48 | + resolver = ( |
| 49 | + options.resolver |
| 50 | + if options and options.resolver |
| 51 | + else RecursiveResolver( |
| 52 | + RequestSynchronizerResolver( |
| 53 | + WrapperCacheResolver( |
| 54 | + PackageToWrapperResolver( |
| 55 | + UriResolverAggregator( |
| 56 | + [ |
| 57 | + StaticResolver(self.config.redirects), |
| 58 | + StaticResolver(self.config.wrappers), |
| 59 | + StaticResolver(self.config.packages), |
| 60 | + *self.config.resolvers, |
| 61 | + ExtendableUriResolver(), |
| 62 | + ] |
| 63 | + ) |
| 64 | + ), |
| 65 | + options.wrapper_cache |
| 66 | + if options and options.wrapper_cache |
| 67 | + else InMemoryWrapperCache(), |
| 68 | + ) |
| 69 | + ) |
| 70 | + ) |
| 71 | + ) |
| 72 | + |
| 73 | + return ClientConfig( |
| 74 | + envs=self.config.envs, |
| 75 | + interfaces=self.config.interfaces, |
| 76 | + resolver=resolver, |
| 77 | + ) |
| 78 | + |
| 79 | + def add(self, config: BuilderConfig): |
| 80 | + """Add the values from the given config to the builder's config.""" |
| 81 | + if config.envs: |
| 82 | + self.config.envs.update(config.envs) |
| 83 | + if config.interfaces: |
| 84 | + self.config.interfaces.update(config.interfaces) |
| 85 | + if config.redirects: |
| 86 | + self.config.redirects.update(config.redirects) |
| 87 | + if config.resolvers: |
| 88 | + self.config.resolvers.extend(config.resolvers) |
| 89 | + if config.wrappers: |
| 90 | + self.config.wrappers.update(config.wrappers) |
| 91 | + if config.packages: |
| 92 | + self.config.packages.update(config.packages) |
| 93 | + return self |
| 94 | + |
| 95 | + def get_envs(self) -> Dict[Uri, Dict[str, Any]]: |
| 96 | + """Return the envs from the builder's config.""" |
| 97 | + return self.config.envs |
| 98 | + |
| 99 | + def set_env(self, uri: Uri, env: Env): |
| 100 | + """Set the env by uri in the builder's config, overiding any existing values.""" |
| 101 | + self.config.envs[uri] = env |
| 102 | + return self |
| 103 | + |
| 104 | + def set_envs(self, uri_envs: Dict[Uri, Env]): |
| 105 | + """Set the envs in the builder's config, overiding any existing values.""" |
| 106 | + self.config.envs.update(uri_envs) |
| 107 | + return self |
| 108 | + |
| 109 | + def add_env(self, uri: Uri, env: Env): |
| 110 | + """Add an env for the given uri. |
| 111 | +
|
| 112 | + If an Env is already associated with the uri, it is modified. |
| 113 | + """ |
| 114 | + if self.config.envs.get(uri): |
| 115 | + for key in self.config.envs[uri]: |
| 116 | + self.config.envs[uri][key] = env[key] |
| 117 | + else: |
| 118 | + self.config.envs[uri] = env |
| 119 | + return self |
| 120 | + |
| 121 | + def add_envs(self, uri_envs: Dict[Uri, Env]): |
| 122 | + """Add a list of envs to the builder's config.""" |
| 123 | + for uri, env in uri_envs.items(): |
| 124 | + self.add_env(uri, env) |
| 125 | + return self |
| 126 | + |
| 127 | + def add_interface_implementations( |
| 128 | + self, interface_uri: Uri, implementations_uris: List[Uri] |
| 129 | + ): |
| 130 | + """Add a list of implementation URIs for the given interface URI to the builder's config.""" |
| 131 | + if interface_uri in self.config.interfaces.keys(): |
| 132 | + self.config.interfaces[interface_uri].extend(implementations_uris) |
| 133 | + else: |
| 134 | + self.config.interfaces[interface_uri] = implementations_uris |
| 135 | + return self |
| 136 | + |
| 137 | + def add_wrapper(self, uri: Uri, wrapper: Wrapper[UriPackageOrWrapper]): |
| 138 | + """Add a wrapper by its URI to the builder's config.""" |
| 139 | + self.config.wrappers[uri] = wrapper |
| 140 | + return self |
| 141 | + |
| 142 | + def add_wrappers(self, uri_wrappers: List[UriWrapper[UriPackageOrWrapper]]): |
| 143 | + """Add a list of URI-wrapper pairs to the builder's config.""" |
| 144 | + for uri_wrapper in uri_wrappers: |
| 145 | + self.add_wrapper(cast(Uri, uri_wrapper), uri_wrapper.wrapper) |
| 146 | + return self |
| 147 | + |
| 148 | + def remove_wrapper(self, uri: Uri): |
| 149 | + """Remove a wrapper by its URI from the builder's config.""" |
| 150 | + del self.config.wrappers[uri] |
| 151 | + return self |
| 152 | + |
| 153 | + def remove_wrappers(self, uris: List[Uri]): |
| 154 | + """Remove a list of wrappers by its URIs.""" |
| 155 | + for uri in uris: |
| 156 | + self.remove_wrapper(uri) |
| 157 | + return self |
| 158 | + |
| 159 | + def add_package(self, uri: Uri, package: WrapPackage[UriPackageOrWrapper]): |
| 160 | + """Add a package by its URI to the builder's config.""" |
| 161 | + self.config.packages[uri] = package |
| 162 | + return self |
| 163 | + |
| 164 | + def add_packages(self, uri_packages: List[UriPackage[UriPackageOrWrapper]]): |
| 165 | + """Add a list of URI-package pairs to the builder's config.""" |
| 166 | + for uri_package in uri_packages: |
| 167 | + self.add_package(cast(Uri, uri_package), uri_package.package) |
| 168 | + return self |
| 169 | + |
| 170 | + def remove_package(self, uri: Uri): |
| 171 | + """Remove a package by its URI from the builder's config.""" |
| 172 | + del self.config.packages[uri] |
| 173 | + return self |
| 174 | + |
| 175 | + def remove_packages(self, uris: List[Uri]): |
| 176 | + """Remove a list of packages by its URIs from the builder's config.""" |
| 177 | + for uri in uris: |
| 178 | + self.remove_package(uri) |
| 179 | + return self |
| 180 | + |
| 181 | + def add_resolver(self, resolver: UriResolver): |
| 182 | + """Add a resolver to the builder's config.""" |
| 183 | + self.config.resolvers.append(resolver) |
| 184 | + return self |
| 185 | + |
| 186 | + def add_resolvers(self, resolvers_list: List[UriResolver]): |
| 187 | + """Add a list of resolvers to the builder's config.""" |
| 188 | + for resolver in resolvers_list: |
| 189 | + self.add_resolver(resolver) |
| 190 | + return self |
| 191 | + |
| 192 | + def add_redirect(self, from_uri: Uri, to_uri: Uri): |
| 193 | + """Add a URI redirect from `from_uri` to `to_uri`.""" |
| 194 | + self.config.redirects[from_uri] = to_uri |
| 195 | + return self |
| 196 | + |
| 197 | + def remove_redirect(self, from_uri: Uri): |
| 198 | + """Remove a URI redirect by `from_uri`.""" |
| 199 | + del self.config.redirects[from_uri] |
| 200 | + return self |
| 201 | + |
| 202 | + def add_redirects(self, redirects: Dict[Uri, Uri]): |
| 203 | + """Add a list of URI redirects to the builder's config.""" |
| 204 | + self.config.redirects.update(redirects) |
| 205 | + return self |
0 commit comments