openfeature-provider-flagd 0.1.5__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openfeature/.gitignore +2 -0
- openfeature/contrib/provider/flagd/config.py +193 -23
- openfeature/contrib/provider/flagd/provider.py +62 -12
- openfeature/contrib/provider/flagd/resolvers/__init__.py +1 -47
- openfeature/contrib/provider/flagd/resolvers/grpc.py +226 -17
- openfeature/contrib/provider/flagd/resolvers/in_process.py +40 -31
- openfeature/contrib/provider/flagd/resolvers/process/connector/__init__.py +11 -0
- openfeature/contrib/provider/flagd/resolvers/process/connector/file_watcher.py +106 -0
- openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py +192 -0
- openfeature/contrib/provider/flagd/resolvers/process/custom_ops.py +58 -19
- openfeature/contrib/provider/flagd/resolvers/process/flags.py +50 -6
- openfeature/contrib/provider/flagd/resolvers/process/targeting.py +35 -0
- openfeature/contrib/provider/flagd/resolvers/protocol.py +47 -0
- openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.py +72 -0
- openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.pyi +450 -0
- openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.py +358 -0
- openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.pyi +155 -0
- openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.py +50 -0
- openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.pyi +148 -0
- openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.py +186 -0
- openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.pyi +86 -0
- openfeature/schemas/protobuf/schema/v1/schema_pb2.py +72 -0
- openfeature/schemas/protobuf/schema/v1/schema_pb2.pyi +451 -0
- openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.py +358 -0
- openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.pyi +156 -0
- openfeature/schemas/protobuf/sync/v1/sync_service_pb2.py +47 -0
- openfeature/schemas/protobuf/sync/v1/sync_service_pb2.pyi +174 -0
- openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.py +143 -0
- openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.pyi +70 -0
- {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/METADATA +116 -15
- openfeature_provider_flagd-0.2.0.dist-info/RECORD +35 -0
- {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/WHEEL +1 -1
- {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/licenses/LICENSE +1 -1
- openfeature/contrib/provider/flagd/proto/flagd/evaluation/v1/evaluation_pb2.py +0 -62
- openfeature/contrib/provider/flagd/proto/flagd/evaluation/v1/evaluation_pb2_grpc.py +0 -267
- openfeature/contrib/provider/flagd/proto/flagd/sync/v1/sync_pb2.py +0 -40
- openfeature/contrib/provider/flagd/proto/flagd/sync/v1/sync_pb2_grpc.py +0 -135
- openfeature/contrib/provider/flagd/proto/schema/v1/schema_pb2.py +0 -62
- openfeature/contrib/provider/flagd/proto/schema/v1/schema_pb2_grpc.py +0 -267
- openfeature/contrib/provider/flagd/proto/sync/v1/sync_service_pb2.py +0 -37
- openfeature/contrib/provider/flagd/proto/sync/v1/sync_service_pb2_grpc.py +0 -102
- openfeature/contrib/provider/flagd/resolvers/process/file_watcher.py +0 -89
- openfeature_provider_flagd-0.1.5.dist-info/RECORD +0 -22
openfeature/.gitignore
ADDED
|
@@ -1,7 +1,54 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import os
|
|
2
3
|
import typing
|
|
3
4
|
from enum import Enum
|
|
4
5
|
|
|
6
|
+
|
|
7
|
+
class ResolverType(Enum):
|
|
8
|
+
RPC = "rpc"
|
|
9
|
+
IN_PROCESS = "in-process"
|
|
10
|
+
FILE = "file"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CacheType(Enum):
|
|
14
|
+
LRU = "lru"
|
|
15
|
+
DISABLED = "disabled"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
DEFAULT_CACHE = CacheType.LRU
|
|
19
|
+
DEFAULT_CACHE_SIZE = 1000
|
|
20
|
+
DEFAULT_DEADLINE = 500
|
|
21
|
+
DEFAULT_HOST = "localhost"
|
|
22
|
+
DEFAULT_KEEP_ALIVE = 0
|
|
23
|
+
DEFAULT_OFFLINE_SOURCE_PATH: typing.Optional[str] = None
|
|
24
|
+
DEFAULT_OFFLINE_POLL_MS = 5000
|
|
25
|
+
DEFAULT_PORT_IN_PROCESS = 8015
|
|
26
|
+
DEFAULT_PORT_RPC = 8013
|
|
27
|
+
DEFAULT_RESOLVER_TYPE = ResolverType.RPC
|
|
28
|
+
DEFAULT_RETRY_BACKOFF = 1000
|
|
29
|
+
DEFAULT_RETRY_BACKOFF_MAX = 120000
|
|
30
|
+
DEFAULT_RETRY_GRACE_PERIOD_SECONDS = 5
|
|
31
|
+
DEFAULT_STREAM_DEADLINE = 600000
|
|
32
|
+
DEFAULT_TLS = False
|
|
33
|
+
DEFAULT_TLS_CERT: typing.Optional[str] = None
|
|
34
|
+
|
|
35
|
+
ENV_VAR_CACHE_SIZE = "FLAGD_MAX_CACHE_SIZE"
|
|
36
|
+
ENV_VAR_CACHE_TYPE = "FLAGD_CACHE"
|
|
37
|
+
ENV_VAR_DEADLINE_MS = "FLAGD_DEADLINE_MS"
|
|
38
|
+
ENV_VAR_HOST = "FLAGD_HOST"
|
|
39
|
+
ENV_VAR_KEEP_ALIVE_TIME_MS = "FLAGD_KEEP_ALIVE_TIME_MS"
|
|
40
|
+
ENV_VAR_OFFLINE_FLAG_SOURCE_PATH = "FLAGD_OFFLINE_FLAG_SOURCE_PATH"
|
|
41
|
+
ENV_VAR_OFFLINE_POLL_MS = "FLAGD_OFFLINE_POLL_MS"
|
|
42
|
+
ENV_VAR_PORT = "FLAGD_PORT"
|
|
43
|
+
ENV_VAR_RESOLVER_TYPE = "FLAGD_RESOLVER"
|
|
44
|
+
ENV_VAR_RETRY_BACKOFF_MS = "FLAGD_RETRY_BACKOFF_MS"
|
|
45
|
+
ENV_VAR_RETRY_BACKOFF_MAX_MS = "FLAGD_RETRY_BACKOFF_MAX_MS"
|
|
46
|
+
ENV_VAR_RETRY_GRACE_PERIOD_SECONDS = "FLAGD_RETRY_GRACE_PERIOD"
|
|
47
|
+
ENV_VAR_SELECTOR = "FLAGD_SOURCE_SELECTOR"
|
|
48
|
+
ENV_VAR_STREAM_DEADLINE_MS = "FLAGD_STREAM_DEADLINE_MS"
|
|
49
|
+
ENV_VAR_TLS = "FLAGD_TLS"
|
|
50
|
+
ENV_VAR_TLS_CERT = "FLAGD_SERVER_CERT_PATH"
|
|
51
|
+
|
|
5
52
|
T = typing.TypeVar("T")
|
|
6
53
|
|
|
7
54
|
|
|
@@ -9,6 +56,14 @@ def str_to_bool(val: str) -> bool:
|
|
|
9
56
|
return val.lower() == "true"
|
|
10
57
|
|
|
11
58
|
|
|
59
|
+
def convert_resolver_type(val: typing.Union[str, ResolverType]) -> ResolverType:
|
|
60
|
+
if isinstance(val, str):
|
|
61
|
+
v = val.lower()
|
|
62
|
+
return ResolverType(v)
|
|
63
|
+
else:
|
|
64
|
+
return ResolverType(val)
|
|
65
|
+
|
|
66
|
+
|
|
12
67
|
def env_or_default(
|
|
13
68
|
env_var: str, default: T, cast: typing.Optional[typing.Callable[[str], T]] = None
|
|
14
69
|
) -> typing.Union[str, T]:
|
|
@@ -18,42 +73,157 @@ def env_or_default(
|
|
|
18
73
|
return val if cast is None else cast(val)
|
|
19
74
|
|
|
20
75
|
|
|
21
|
-
|
|
22
|
-
GRPC = "grpc"
|
|
23
|
-
IN_PROCESS = "in-process"
|
|
24
|
-
|
|
25
|
-
|
|
76
|
+
@dataclasses.dataclass
|
|
26
77
|
class Config:
|
|
27
78
|
def __init__( # noqa: PLR0913
|
|
28
79
|
self,
|
|
29
80
|
host: typing.Optional[str] = None,
|
|
30
81
|
port: typing.Optional[int] = None,
|
|
31
82
|
tls: typing.Optional[bool] = None,
|
|
32
|
-
|
|
33
|
-
|
|
83
|
+
selector: typing.Optional[str] = None,
|
|
84
|
+
resolver: typing.Optional[ResolverType] = None,
|
|
34
85
|
offline_flag_source_path: typing.Optional[str] = None,
|
|
35
|
-
|
|
86
|
+
offline_poll_interval_ms: typing.Optional[int] = None,
|
|
87
|
+
retry_backoff_ms: typing.Optional[int] = None,
|
|
88
|
+
retry_backoff_max_ms: typing.Optional[int] = None,
|
|
89
|
+
retry_grace_period: typing.Optional[int] = None,
|
|
90
|
+
deadline_ms: typing.Optional[int] = None,
|
|
91
|
+
stream_deadline_ms: typing.Optional[int] = None,
|
|
92
|
+
keep_alive_time: typing.Optional[int] = None,
|
|
93
|
+
cache: typing.Optional[CacheType] = None,
|
|
94
|
+
max_cache_size: typing.Optional[int] = None,
|
|
95
|
+
cert_path: typing.Optional[str] = None,
|
|
36
96
|
):
|
|
37
|
-
self.host = env_or_default(
|
|
38
|
-
|
|
39
|
-
env_or_default("FLAGD_PORT", 8013, cast=int) if port is None else port
|
|
40
|
-
)
|
|
97
|
+
self.host = env_or_default(ENV_VAR_HOST, DEFAULT_HOST) if host is None else host
|
|
98
|
+
|
|
41
99
|
self.tls = (
|
|
42
|
-
env_or_default(
|
|
100
|
+
env_or_default(ENV_VAR_TLS, DEFAULT_TLS, cast=str_to_bool)
|
|
101
|
+
if tls is None
|
|
102
|
+
else tls
|
|
43
103
|
)
|
|
44
|
-
|
|
45
|
-
self.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
104
|
+
|
|
105
|
+
self.retry_backoff_ms: int = (
|
|
106
|
+
int(
|
|
107
|
+
env_or_default(
|
|
108
|
+
ENV_VAR_RETRY_BACKOFF_MS, DEFAULT_RETRY_BACKOFF, cast=int
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
if retry_backoff_ms is None
|
|
112
|
+
else retry_backoff_ms
|
|
113
|
+
)
|
|
114
|
+
self.retry_backoff_max_ms: int = (
|
|
115
|
+
int(
|
|
116
|
+
env_or_default(
|
|
117
|
+
ENV_VAR_RETRY_BACKOFF_MAX_MS, DEFAULT_RETRY_BACKOFF_MAX, cast=int
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
if retry_backoff_max_ms is None
|
|
121
|
+
else retry_backoff_max_ms
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
self.retry_grace_period: int = (
|
|
125
|
+
int(
|
|
126
|
+
env_or_default(
|
|
127
|
+
ENV_VAR_RETRY_GRACE_PERIOD_SECONDS,
|
|
128
|
+
DEFAULT_RETRY_GRACE_PERIOD_SECONDS,
|
|
129
|
+
cast=int,
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
if retry_grace_period is None
|
|
133
|
+
else retry_grace_period
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
self.resolver = (
|
|
137
|
+
env_or_default(
|
|
138
|
+
ENV_VAR_RESOLVER_TYPE, DEFAULT_RESOLVER_TYPE, cast=convert_resolver_type
|
|
139
|
+
)
|
|
140
|
+
if resolver is None
|
|
141
|
+
else resolver
|
|
49
142
|
)
|
|
143
|
+
|
|
144
|
+
default_port = (
|
|
145
|
+
DEFAULT_PORT_RPC
|
|
146
|
+
if self.resolver is ResolverType.RPC
|
|
147
|
+
else DEFAULT_PORT_IN_PROCESS
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
self.port: int = (
|
|
151
|
+
int(env_or_default(ENV_VAR_PORT, default_port, cast=int))
|
|
152
|
+
if port is None
|
|
153
|
+
else port
|
|
154
|
+
)
|
|
155
|
+
|
|
50
156
|
self.offline_flag_source_path = (
|
|
51
|
-
env_or_default(
|
|
157
|
+
env_or_default(
|
|
158
|
+
ENV_VAR_OFFLINE_FLAG_SOURCE_PATH, DEFAULT_OFFLINE_SOURCE_PATH
|
|
159
|
+
)
|
|
52
160
|
if offline_flag_source_path is None
|
|
53
161
|
else offline_flag_source_path
|
|
54
162
|
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
163
|
+
|
|
164
|
+
if (
|
|
165
|
+
self.offline_flag_source_path is not None
|
|
166
|
+
and self.resolver is ResolverType.IN_PROCESS
|
|
167
|
+
):
|
|
168
|
+
self.resolver = ResolverType.FILE
|
|
169
|
+
|
|
170
|
+
if self.resolver is ResolverType.FILE and self.offline_flag_source_path is None:
|
|
171
|
+
raise AttributeError(
|
|
172
|
+
"Resolver Type 'FILE' requires a offlineFlagSourcePath"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
self.offline_poll_interval_ms: int = (
|
|
176
|
+
int(
|
|
177
|
+
env_or_default(
|
|
178
|
+
ENV_VAR_OFFLINE_POLL_MS, DEFAULT_OFFLINE_POLL_MS, cast=int
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
if offline_poll_interval_ms is None
|
|
182
|
+
else offline_poll_interval_ms
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
self.deadline_ms: int = (
|
|
186
|
+
int(env_or_default(ENV_VAR_DEADLINE_MS, DEFAULT_DEADLINE, cast=int))
|
|
187
|
+
if deadline_ms is None
|
|
188
|
+
else deadline_ms
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
self.stream_deadline_ms: int = (
|
|
192
|
+
int(
|
|
193
|
+
env_or_default(
|
|
194
|
+
ENV_VAR_STREAM_DEADLINE_MS, DEFAULT_STREAM_DEADLINE, cast=int
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
if stream_deadline_ms is None
|
|
198
|
+
else stream_deadline_ms
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
self.keep_alive_time: int = (
|
|
202
|
+
int(
|
|
203
|
+
env_or_default(ENV_VAR_KEEP_ALIVE_TIME_MS, DEFAULT_KEEP_ALIVE, cast=int)
|
|
204
|
+
)
|
|
205
|
+
if keep_alive_time is None
|
|
206
|
+
else keep_alive_time
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
self.cache = (
|
|
210
|
+
CacheType(env_or_default(ENV_VAR_CACHE_TYPE, DEFAULT_CACHE))
|
|
211
|
+
if cache is None
|
|
212
|
+
else cache
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
self.max_cache_size: int = (
|
|
216
|
+
int(env_or_default(ENV_VAR_CACHE_SIZE, DEFAULT_CACHE_SIZE, cast=int))
|
|
217
|
+
if max_cache_size is None
|
|
218
|
+
else max_cache_size
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
self.cert_path = (
|
|
222
|
+
env_or_default(ENV_VAR_TLS_CERT, DEFAULT_TLS_CERT)
|
|
223
|
+
if cert_path is None
|
|
224
|
+
else cert_path
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
self.selector = (
|
|
228
|
+
env_or_default(ENV_VAR_SELECTOR, None) if selector is None else selector
|
|
59
229
|
)
|
|
@@ -22,13 +22,14 @@
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
import typing
|
|
25
|
+
import warnings
|
|
25
26
|
|
|
26
27
|
from openfeature.evaluation_context import EvaluationContext
|
|
27
28
|
from openfeature.flag_evaluation import FlagResolutionDetails
|
|
29
|
+
from openfeature.provider import AbstractProvider
|
|
28
30
|
from openfeature.provider.metadata import Metadata
|
|
29
|
-
from openfeature.provider.provider import AbstractProvider
|
|
30
31
|
|
|
31
|
-
from .config import Config, ResolverType
|
|
32
|
+
from .config import CacheType, Config, ResolverType
|
|
32
33
|
from .resolvers import AbstractResolver, GrpcResolver, InProcessResolver
|
|
33
34
|
|
|
34
35
|
T = typing.TypeVar("T")
|
|
@@ -42,10 +43,19 @@ class FlagdProvider(AbstractProvider):
|
|
|
42
43
|
host: typing.Optional[str] = None,
|
|
43
44
|
port: typing.Optional[int] = None,
|
|
44
45
|
tls: typing.Optional[bool] = None,
|
|
46
|
+
deadline_ms: typing.Optional[int] = None,
|
|
45
47
|
timeout: typing.Optional[int] = None,
|
|
48
|
+
retry_backoff_ms: typing.Optional[int] = None,
|
|
49
|
+
selector: typing.Optional[str] = None,
|
|
46
50
|
resolver_type: typing.Optional[ResolverType] = None,
|
|
47
51
|
offline_flag_source_path: typing.Optional[str] = None,
|
|
48
|
-
|
|
52
|
+
stream_deadline_ms: typing.Optional[int] = None,
|
|
53
|
+
keep_alive_time: typing.Optional[int] = None,
|
|
54
|
+
cache: typing.Optional[CacheType] = None,
|
|
55
|
+
max_cache_size: typing.Optional[int] = None,
|
|
56
|
+
retry_backoff_max_ms: typing.Optional[int] = None,
|
|
57
|
+
retry_grace_period: typing.Optional[int] = None,
|
|
58
|
+
cert_path: typing.Optional[str] = None,
|
|
49
59
|
):
|
|
50
60
|
"""
|
|
51
61
|
Create an instance of the FlagdProvider
|
|
@@ -53,30 +63,70 @@ class FlagdProvider(AbstractProvider):
|
|
|
53
63
|
:param host: the host to make requests to
|
|
54
64
|
:param port: the port the flagd service is available on
|
|
55
65
|
:param tls: enable/disable secure TLS connectivity
|
|
56
|
-
:param
|
|
66
|
+
:param deadline_ms: the maximum to wait before a request times out
|
|
67
|
+
:param timeout: the maximum time to wait before a request times out
|
|
68
|
+
:param retry_backoff_ms: the number of milliseconds to backoff
|
|
69
|
+
:param offline_flag_source_path: the path to the flag source file
|
|
70
|
+
:param stream_deadline_ms: the maximum time to wait before a request times out
|
|
71
|
+
:param keep_alive_time: the number of milliseconds to keep alive
|
|
72
|
+
:param resolver_type: the type of resolver to use
|
|
57
73
|
"""
|
|
74
|
+
if deadline_ms is None and timeout is not None:
|
|
75
|
+
deadline_ms = timeout * 1000
|
|
76
|
+
warnings.warn(
|
|
77
|
+
"'timeout' property is deprecated, please use 'deadline' instead, be aware that 'deadline' is in milliseconds",
|
|
78
|
+
DeprecationWarning,
|
|
79
|
+
stacklevel=2,
|
|
80
|
+
)
|
|
81
|
+
|
|
58
82
|
self.config = Config(
|
|
59
83
|
host=host,
|
|
60
84
|
port=port,
|
|
61
85
|
tls=tls,
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
deadline_ms=deadline_ms,
|
|
87
|
+
retry_backoff_ms=retry_backoff_ms,
|
|
88
|
+
retry_backoff_max_ms=retry_backoff_max_ms,
|
|
89
|
+
retry_grace_period=retry_grace_period,
|
|
90
|
+
selector=selector,
|
|
91
|
+
resolver=resolver_type,
|
|
64
92
|
offline_flag_source_path=offline_flag_source_path,
|
|
65
|
-
|
|
93
|
+
stream_deadline_ms=stream_deadline_ms,
|
|
94
|
+
keep_alive_time=keep_alive_time,
|
|
95
|
+
cache=cache,
|
|
96
|
+
max_cache_size=max_cache_size,
|
|
97
|
+
cert_path=cert_path,
|
|
66
98
|
)
|
|
67
99
|
|
|
68
100
|
self.resolver = self.setup_resolver()
|
|
69
101
|
|
|
70
102
|
def setup_resolver(self) -> AbstractResolver:
|
|
71
|
-
if self.config.
|
|
72
|
-
return GrpcResolver(
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
if self.config.resolver == ResolverType.RPC:
|
|
104
|
+
return GrpcResolver(
|
|
105
|
+
self.config,
|
|
106
|
+
self.emit_provider_ready,
|
|
107
|
+
self.emit_provider_error,
|
|
108
|
+
self.emit_provider_stale,
|
|
109
|
+
self.emit_provider_configuration_changed,
|
|
110
|
+
)
|
|
111
|
+
elif (
|
|
112
|
+
self.config.resolver == ResolverType.IN_PROCESS
|
|
113
|
+
or self.config.resolver == ResolverType.FILE
|
|
114
|
+
):
|
|
115
|
+
return InProcessResolver(
|
|
116
|
+
self.config,
|
|
117
|
+
self.emit_provider_ready,
|
|
118
|
+
self.emit_provider_error,
|
|
119
|
+
self.emit_provider_stale,
|
|
120
|
+
self.emit_provider_configuration_changed,
|
|
121
|
+
)
|
|
75
122
|
else:
|
|
76
123
|
raise ValueError(
|
|
77
|
-
f"`resolver_type` parameter invalid: {self.config.
|
|
124
|
+
f"`resolver_type` parameter invalid: {self.config.resolver}"
|
|
78
125
|
)
|
|
79
126
|
|
|
127
|
+
def initialize(self, evaluation_context: EvaluationContext) -> None:
|
|
128
|
+
self.resolver.initialize(evaluation_context)
|
|
129
|
+
|
|
80
130
|
def shutdown(self) -> None:
|
|
81
131
|
if self.resolver:
|
|
82
132
|
self.resolver.shutdown()
|
|
@@ -1,51 +1,5 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from typing_extensions import Protocol
|
|
4
|
-
|
|
5
|
-
from openfeature.evaluation_context import EvaluationContext
|
|
6
|
-
from openfeature.flag_evaluation import FlagResolutionDetails
|
|
7
|
-
|
|
8
1
|
from .grpc import GrpcResolver
|
|
9
2
|
from .in_process import InProcessResolver
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class AbstractResolver(Protocol):
|
|
13
|
-
def shutdown(self) -> None: ...
|
|
14
|
-
|
|
15
|
-
def resolve_boolean_details(
|
|
16
|
-
self,
|
|
17
|
-
key: str,
|
|
18
|
-
default_value: bool,
|
|
19
|
-
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
20
|
-
) -> FlagResolutionDetails[bool]: ...
|
|
21
|
-
|
|
22
|
-
def resolve_string_details(
|
|
23
|
-
self,
|
|
24
|
-
key: str,
|
|
25
|
-
default_value: str,
|
|
26
|
-
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
27
|
-
) -> FlagResolutionDetails[str]: ...
|
|
28
|
-
|
|
29
|
-
def resolve_float_details(
|
|
30
|
-
self,
|
|
31
|
-
key: str,
|
|
32
|
-
default_value: float,
|
|
33
|
-
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
34
|
-
) -> FlagResolutionDetails[float]: ...
|
|
35
|
-
|
|
36
|
-
def resolve_integer_details(
|
|
37
|
-
self,
|
|
38
|
-
key: str,
|
|
39
|
-
default_value: int,
|
|
40
|
-
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
41
|
-
) -> FlagResolutionDetails[int]: ...
|
|
42
|
-
|
|
43
|
-
def resolve_object_details(
|
|
44
|
-
self,
|
|
45
|
-
key: str,
|
|
46
|
-
default_value: typing.Union[dict, list],
|
|
47
|
-
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
48
|
-
) -> FlagResolutionDetails[typing.Union[dict, list]]: ...
|
|
49
|
-
|
|
3
|
+
from .protocol import AbstractResolver
|
|
50
4
|
|
|
51
5
|
__all__ = ["AbstractResolver", "GrpcResolver", "InProcessResolver"]
|