Skip to content

Commit 0f1bade

Browse files
committed
refine typing by adding types-grpcio
Signed-off-by: gruebel <[email protected]>
1 parent fe8130a commit 0f1bade

File tree

6 files changed

+333
-299
lines changed

6 files changed

+333
-299
lines changed

providers/openfeature-provider-flagd/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ dev = [
4040
"pytest>=8.4.0,<9.0.0",
4141
"pytest-bdd>=8.1.0,<9.0.0",
4242
"testcontainers>=4.12.0,<5.0.0",
43+
"types-grpcio>=1.0.0,<2.0.0",
4344
"types-protobuf>=6.30.0,<7.0.0",
4445
"types-pyyaml>=6.0.0,<7.0.0",
4546
]
@@ -97,7 +98,6 @@ disallow_any_generics = false
9798

9899
[[tool.mypy.overrides]]
99100
module = [
100-
"grpc.*",
101101
"json_logic.*",
102102
]
103103
ignore_missing_imports = true

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/grpc.py

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from ..config import CacheType, Config
3131
from ..flag_type import FlagType
32+
from .types import GrpcMultiCallableArgs
3233

3334
if typing.TYPE_CHECKING:
3435
from google.protobuf.message import Message
@@ -121,15 +122,16 @@ def _generate_channel(self, config: Config) -> grpc.Channel:
121122
),
122123
]
123124
if config.tls:
124-
channel_args = {
125-
"options": options,
126-
"credentials": grpc.ssl_channel_credentials(),
127-
}
125+
credentials = grpc.ssl_channel_credentials()
128126
if config.cert_path:
129127
with open(config.cert_path, "rb") as f:
130-
channel_args["credentials"] = grpc.ssl_channel_credentials(f.read())
128+
credentials = grpc.ssl_channel_credentials(f.read())
131129

132-
channel = grpc.secure_channel(target, **channel_args)
130+
channel = grpc.secure_channel(
131+
target,
132+
credentials=credentials,
133+
options=options,
134+
)
133135

134136
else:
135137
channel = grpc.insecure_channel(
@@ -220,20 +222,19 @@ def emit_error(self) -> None:
220222

221223
def listen(self) -> None:
222224
logger.debug("gRPC starting listener thread")
223-
call_args = (
225+
call_args: GrpcMultiCallableArgs = (
224226
{"timeout": self.streamline_deadline_seconds}
225227
if self.streamline_deadline_seconds > 0
226228
else {}
227229
)
230+
call_args["wait_for_ready"] = True
228231
request = evaluation_pb2.EventStreamRequest()
229232

230233
# defining a never ending loop to recreate the stream
231234
while self.active:
232235
try:
233236
logger.debug("Setting up gRPC sync flags connection")
234-
for message in self.stub.EventStream(
235-
request, wait_for_ready=True, **call_args
236-
):
237+
for message in self.stub.EventStream(request, **call_args):
237238
if message.type == "provider_ready":
238239
self.emit_provider_ready(
239240
ProviderEventDetails(
@@ -309,20 +310,72 @@ def resolve_object_details(
309310
]:
310311
return self._resolve(key, FlagType.OBJECT, default_value, evaluation_context)
311312

313+
@typing.overload
314+
def _resolve(
315+
self,
316+
flag_key: str,
317+
flag_type: FlagType,
318+
default_value: bool,
319+
evaluation_context: typing.Optional[EvaluationContext],
320+
) -> FlagResolutionDetails[bool]: ...
321+
322+
@typing.overload
323+
def _resolve(
324+
self,
325+
flag_key: str,
326+
flag_type: FlagType,
327+
default_value: int,
328+
evaluation_context: typing.Optional[EvaluationContext],
329+
) -> FlagResolutionDetails[int]: ...
330+
331+
@typing.overload
332+
def _resolve(
333+
self,
334+
flag_key: str,
335+
flag_type: FlagType,
336+
default_value: float,
337+
evaluation_context: typing.Optional[EvaluationContext],
338+
) -> FlagResolutionDetails[float]: ...
339+
340+
@typing.overload
341+
def _resolve(
342+
self,
343+
flag_key: str,
344+
flag_type: FlagType,
345+
default_value: str,
346+
evaluation_context: typing.Optional[EvaluationContext],
347+
) -> FlagResolutionDetails[str]: ...
348+
349+
@typing.overload
350+
def _resolve(
351+
self,
352+
flag_key: str,
353+
flag_type: FlagType,
354+
default_value: typing.Union[
355+
typing.Sequence[FlagValueType], typing.Mapping[str, FlagValueType]
356+
],
357+
evaluation_context: typing.Optional[EvaluationContext],
358+
) -> FlagResolutionDetails[
359+
typing.Union[typing.Sequence[FlagValueType], typing.Mapping[str, FlagValueType]]
360+
]: ...
361+
312362
def _resolve( # noqa: PLR0915 C901
313363
self,
314364
flag_key: str,
315365
flag_type: FlagType,
316-
default_value: T,
366+
default_value: FlagValueType,
317367
evaluation_context: typing.Optional[EvaluationContext],
318-
) -> FlagResolutionDetails[T]:
368+
) -> FlagResolutionDetails[FlagValueType]:
319369
if self.cache is not None and flag_key in self.cache:
320-
cached_flag: FlagResolutionDetails[T] = self.cache[flag_key]
370+
cached_flag: FlagResolutionDetails[FlagValueType] = self.cache[flag_key]
321371
cached_flag.reason = Reason.CACHED
322372
return cached_flag
323373

324374
context = self._convert_context(evaluation_context)
325-
call_args = {"timeout": self.deadline, "wait_for_ready": True}
375+
call_args: GrpcMultiCallableArgs = {
376+
"timeout": self.deadline,
377+
"wait_for_ready": True,
378+
}
326379
try:
327380
request: Message
328381
if flag_type == FlagType.BOOLEAN:

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
)
1818

1919
from ....config import Config
20+
from ...types import GrpcMultiCallableArgs
2021
from ..connector import FlagStateConnector
2122
from ..flags import FlagStore
2223

@@ -105,22 +106,23 @@ def _generate_channel(self, config: Config) -> grpc.Channel:
105106
options.append(("grpc.default_authority", config.default_authority))
106107

107108
if config.channel_credentials is not None:
108-
channel_args = {
109-
"options": options,
110-
"credentials": config.channel_credentials,
111-
}
112-
channel = grpc.secure_channel(target, **channel_args)
109+
channel = grpc.secure_channel(
110+
target,
111+
credentials=config.channel_credentials,
112+
options=options,
113+
)
113114

114115
elif config.tls:
115-
channel_args = {
116-
"options": options,
117-
"credentials": grpc.ssl_channel_credentials(),
118-
}
116+
credentials = grpc.ssl_channel_credentials()
119117
if config.cert_path:
120118
with open(config.cert_path, "rb") as f:
121-
channel_args["credentials"] = grpc.ssl_channel_credentials(f.read())
119+
credentials = grpc.ssl_channel_credentials(f.read())
122120

123-
channel = grpc.secure_channel(target, **channel_args)
121+
channel = grpc.secure_channel(
122+
target,
123+
credentials=credentials,
124+
options=options,
125+
)
124126

125127
else:
126128
channel = grpc.insecure_channel(
@@ -228,11 +230,12 @@ def _fetch_metadata(self) -> typing.Optional[sync_pb2.GetMetadataResponse]:
228230
raise e
229231

230232
def listen(self) -> None:
231-
call_args = (
233+
call_args: GrpcMultiCallableArgs = (
232234
{"timeout": self.streamline_deadline_seconds}
233235
if self.streamline_deadline_seconds > 0
234236
else {}
235237
)
238+
call_args["wait_for_ready"] = True
236239
request_args = self._create_request_args()
237240

238241
while self.active:
@@ -242,9 +245,7 @@ def listen(self) -> None:
242245
request = sync_pb2.SyncFlagsRequest(**request_args)
243246

244247
logger.debug("Setting up gRPC sync flags connection")
245-
for flag_rsp in self.stub.SyncFlags(
246-
request, wait_for_ready=True, **call_args
247-
):
248+
for flag_rsp in self.stub.SyncFlags(request, **call_args):
248249
flag_str = flag_rsp.flag_configuration
249250
logger.debug(
250251
f"Received flag configuration - {abs(hash(flag_str)) % (10**8)}"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import typing
2+
3+
4+
class GrpcMultiCallableArgs(typing.TypedDict, total=False):
5+
timeout: typing.Optional[float]
6+
wait_for_ready: typing.Optional[bool]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies = [
1515
[dependency-groups]
1616
dev = [
1717
"coverage[toml]>=7.10.0,<8.0.0",
18-
"mypy[faster-cache]>=1.17.0,<2.0.0",
18+
"mypy>=1.18.0,<2.0.0",
1919
"pytest>=8.4.0,<9.0.0",
2020
]
2121

0 commit comments

Comments
 (0)