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.
Files changed (43) hide show
  1. openfeature/.gitignore +2 -0
  2. openfeature/contrib/provider/flagd/config.py +193 -23
  3. openfeature/contrib/provider/flagd/provider.py +62 -12
  4. openfeature/contrib/provider/flagd/resolvers/__init__.py +1 -47
  5. openfeature/contrib/provider/flagd/resolvers/grpc.py +226 -17
  6. openfeature/contrib/provider/flagd/resolvers/in_process.py +40 -31
  7. openfeature/contrib/provider/flagd/resolvers/process/connector/__init__.py +11 -0
  8. openfeature/contrib/provider/flagd/resolvers/process/connector/file_watcher.py +106 -0
  9. openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py +192 -0
  10. openfeature/contrib/provider/flagd/resolvers/process/custom_ops.py +58 -19
  11. openfeature/contrib/provider/flagd/resolvers/process/flags.py +50 -6
  12. openfeature/contrib/provider/flagd/resolvers/process/targeting.py +35 -0
  13. openfeature/contrib/provider/flagd/resolvers/protocol.py +47 -0
  14. openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.py +72 -0
  15. openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.pyi +450 -0
  16. openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.py +358 -0
  17. openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.pyi +155 -0
  18. openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.py +50 -0
  19. openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.pyi +148 -0
  20. openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.py +186 -0
  21. openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.pyi +86 -0
  22. openfeature/schemas/protobuf/schema/v1/schema_pb2.py +72 -0
  23. openfeature/schemas/protobuf/schema/v1/schema_pb2.pyi +451 -0
  24. openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.py +358 -0
  25. openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.pyi +156 -0
  26. openfeature/schemas/protobuf/sync/v1/sync_service_pb2.py +47 -0
  27. openfeature/schemas/protobuf/sync/v1/sync_service_pb2.pyi +174 -0
  28. openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.py +143 -0
  29. openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.pyi +70 -0
  30. {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/METADATA +116 -15
  31. openfeature_provider_flagd-0.2.0.dist-info/RECORD +35 -0
  32. {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/WHEEL +1 -1
  33. {openfeature_provider_flagd-0.1.5.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/licenses/LICENSE +1 -1
  34. openfeature/contrib/provider/flagd/proto/flagd/evaluation/v1/evaluation_pb2.py +0 -62
  35. openfeature/contrib/provider/flagd/proto/flagd/evaluation/v1/evaluation_pb2_grpc.py +0 -267
  36. openfeature/contrib/provider/flagd/proto/flagd/sync/v1/sync_pb2.py +0 -40
  37. openfeature/contrib/provider/flagd/proto/flagd/sync/v1/sync_pb2_grpc.py +0 -135
  38. openfeature/contrib/provider/flagd/proto/schema/v1/schema_pb2.py +0 -62
  39. openfeature/contrib/provider/flagd/proto/schema/v1/schema_pb2_grpc.py +0 -267
  40. openfeature/contrib/provider/flagd/proto/sync/v1/sync_service_pb2.py +0 -37
  41. openfeature/contrib/provider/flagd/proto/sync/v1/sync_service_pb2_grpc.py +0 -102
  42. openfeature/contrib/provider/flagd/resolvers/process/file_watcher.py +0 -89
  43. openfeature_provider_flagd-0.1.5.dist-info/RECORD +0 -22
@@ -0,0 +1,174 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ *
5
+ DEPRECATED; use flagd.sync.v1
6
+ Flag definition sync API
7
+
8
+ This proto defines a simple API to synchronize a feature flag definition.
9
+ It supports establishing a stream for getting notifications about changes in a flag definition.
10
+ """
11
+
12
+ import builtins
13
+ import google.protobuf.descriptor
14
+ import google.protobuf.internal.enum_type_wrapper
15
+ import google.protobuf.message
16
+ import sys
17
+ import typing
18
+
19
+ if sys.version_info >= (3, 10):
20
+ import typing as typing_extensions
21
+ else:
22
+ import typing_extensions
23
+
24
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
25
+
26
+ class _SyncState:
27
+ ValueType = typing.NewType("ValueType", builtins.int)
28
+ V: typing_extensions.TypeAlias = ValueType
29
+
30
+ class _SyncStateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SyncState.ValueType], builtins.type):
31
+ DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
32
+ SYNC_STATE_UNSPECIFIED: _SyncState.ValueType # 0
33
+ """Value is ignored by the listening flagd"""
34
+ SYNC_STATE_ALL: _SyncState.ValueType # 1
35
+ """All the flags matching the request. This is the default response and other states can be ignored
36
+ by the implementation. Flagd internally replaces all existing flags for this response state.
37
+ """
38
+ SYNC_STATE_ADD: _SyncState.ValueType # 2
39
+ """Convey an addition of a flag. Flagd internally handles this by combining new flags with existing ones"""
40
+ SYNC_STATE_UPDATE: _SyncState.ValueType # 3
41
+ """Convey an update of a flag. Flagd internally attempts to update if the updated flag already exist OR if it does not,
42
+ it will get added
43
+ """
44
+ SYNC_STATE_DELETE: _SyncState.ValueType # 4
45
+ """Convey a deletion of a flag. Flagd internally removes the flag"""
46
+ SYNC_STATE_PING: _SyncState.ValueType # 5
47
+ """Optional server ping to check client connectivity. Handling is ignored by flagd and is to merely support live check"""
48
+
49
+ class SyncState(_SyncState, metaclass=_SyncStateEnumTypeWrapper):
50
+ """SyncState conveys the state of the payload. These states are related to flagd isync.go type definitions but
51
+ contains extras to optimize grpc use case. Refer - https://github.com/open-feature/flagd/blob/main/pkg/sync/isync.go
52
+ """
53
+
54
+ SYNC_STATE_UNSPECIFIED: SyncState.ValueType # 0
55
+ """Value is ignored by the listening flagd"""
56
+ SYNC_STATE_ALL: SyncState.ValueType # 1
57
+ """All the flags matching the request. This is the default response and other states can be ignored
58
+ by the implementation. Flagd internally replaces all existing flags for this response state.
59
+ """
60
+ SYNC_STATE_ADD: SyncState.ValueType # 2
61
+ """Convey an addition of a flag. Flagd internally handles this by combining new flags with existing ones"""
62
+ SYNC_STATE_UPDATE: SyncState.ValueType # 3
63
+ """Convey an update of a flag. Flagd internally attempts to update if the updated flag already exist OR if it does not,
64
+ it will get added
65
+ """
66
+ SYNC_STATE_DELETE: SyncState.ValueType # 4
67
+ """Convey a deletion of a flag. Flagd internally removes the flag"""
68
+ SYNC_STATE_PING: SyncState.ValueType # 5
69
+ """Optional server ping to check client connectivity. Handling is ignored by flagd and is to merely support live check"""
70
+ global___SyncState = SyncState
71
+
72
+ @typing.final
73
+ class SyncFlagsRequest(google.protobuf.message.Message):
74
+ """SyncFlagsRequest is the request initiating the sever-streaming rpc. Flagd sends this request, acting as the client"""
75
+
76
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
77
+
78
+ PROVIDER_ID_FIELD_NUMBER: builtins.int
79
+ SELECTOR_FIELD_NUMBER: builtins.int
80
+ provider_id: builtins.str
81
+ """Optional: A unique identifier for flagd(grpc client) initiating the request. The server implementations may
82
+ utilize this identifier to uniquely identify, validate(ex:- enforce authentication/authorization) and filter
83
+ flag configurations that it can expose to this request. This field is intended to be optional. However server
84
+ implementations may enforce it.
85
+ ex:- provider_id: flagd-weatherapp-sidecar
86
+ """
87
+ selector: builtins.str
88
+ """Optional: A selector for the flag configuration request. The server implementation may utilize this to select
89
+ flag configurations from a collection, select the source of the flag or combine this to any desired underlying
90
+ filtering mechanism.
91
+ ex:- selector: 'source=database,app=weatherapp'
92
+ """
93
+ def __init__(
94
+ self,
95
+ *,
96
+ provider_id: builtins.str = ...,
97
+ selector: builtins.str = ...,
98
+ ) -> None: ...
99
+ def ClearField(self, field_name: typing.Literal["provider_id", b"provider_id", "selector", b"selector"]) -> None: ...
100
+
101
+ global___SyncFlagsRequest = SyncFlagsRequest
102
+
103
+ @typing.final
104
+ class SyncFlagsResponse(google.protobuf.message.Message):
105
+ """SyncFlagsResponse is the server response containing feature flag configurations and the state"""
106
+
107
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
108
+
109
+ FLAG_CONFIGURATION_FIELD_NUMBER: builtins.int
110
+ STATE_FIELD_NUMBER: builtins.int
111
+ flag_configuration: builtins.str
112
+ """flagd feature flag configuration. Must be validated to schema - https://raw.githubusercontent.com/open-feature/schemas/main/json/flagd-definitions.json"""
113
+ state: global___SyncState.ValueType
114
+ """State conveying the operation to be performed by flagd. See the descriptions of SyncState for an explanation of
115
+ supported values
116
+ """
117
+ def __init__(
118
+ self,
119
+ *,
120
+ flag_configuration: builtins.str = ...,
121
+ state: global___SyncState.ValueType = ...,
122
+ ) -> None: ...
123
+ def ClearField(self, field_name: typing.Literal["flag_configuration", b"flag_configuration", "state", b"state"]) -> None: ...
124
+
125
+ global___SyncFlagsResponse = SyncFlagsResponse
126
+
127
+ @typing.final
128
+ class FetchAllFlagsRequest(google.protobuf.message.Message):
129
+ """FetchAllFlagsRequest is the request to fetch all flags. Flagd sends this request as the client in order to resync its internal state"""
130
+
131
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
132
+
133
+ PROVIDER_ID_FIELD_NUMBER: builtins.int
134
+ SELECTOR_FIELD_NUMBER: builtins.int
135
+ provider_id: builtins.str
136
+ """Optional: A unique identifier for flagd(grpc client) initiating the request. The server implementations may
137
+ utilize this identifier to uniquely identify, validate(ex:- enforce authentication/authorization) and filter
138
+ flag configurations that it can expose to this request. This field is intended to be optional. However server
139
+ implementations may enforce it.
140
+ ex:- provider_id: flagd-weatherapp-sidecar
141
+ """
142
+ selector: builtins.str
143
+ """Optional: A selector for the flag configuration request. The server implementation may utilize this to select
144
+ flag configurations from a collection, select the source of the flag or combine this to any desired underlying
145
+ filtering mechanism.
146
+ ex:- selector: 'source=database,app=weatherapp'
147
+ """
148
+ def __init__(
149
+ self,
150
+ *,
151
+ provider_id: builtins.str = ...,
152
+ selector: builtins.str = ...,
153
+ ) -> None: ...
154
+ def ClearField(self, field_name: typing.Literal["provider_id", b"provider_id", "selector", b"selector"]) -> None: ...
155
+
156
+ global___FetchAllFlagsRequest = FetchAllFlagsRequest
157
+
158
+ @typing.final
159
+ class FetchAllFlagsResponse(google.protobuf.message.Message):
160
+ """ FetchAllFlagsResponse is the server response containing feature flag configurations"""
161
+
162
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
163
+
164
+ FLAG_CONFIGURATION_FIELD_NUMBER: builtins.int
165
+ flag_configuration: builtins.str
166
+ """flagd feature flag configuration. Must be validated to schema - https://raw.githubusercontent.com/open-feature/schemas/main/json/flagd-definitions.json"""
167
+ def __init__(
168
+ self,
169
+ *,
170
+ flag_configuration: builtins.str = ...,
171
+ ) -> None: ...
172
+ def ClearField(self, field_name: typing.Literal["flag_configuration", b"flag_configuration"]) -> None: ...
173
+
174
+ global___FetchAllFlagsResponse = FetchAllFlagsResponse
@@ -0,0 +1,143 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+ import warnings
5
+
6
+ from openfeature.schemas.protobuf.sync.v1 import sync_service_pb2 as openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2
7
+
8
+ GRPC_GENERATED_VERSION = '1.70.0'
9
+ GRPC_VERSION = grpc.__version__
10
+ _version_not_supported = False
11
+
12
+ try:
13
+ from grpc._utilities import first_version_is_lower
14
+ _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
15
+ except ImportError:
16
+ _version_not_supported = True
17
+
18
+ if _version_not_supported:
19
+ raise RuntimeError(
20
+ f'The grpc package installed is at version {GRPC_VERSION},'
21
+ + f' but the generated code in openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.py depends on'
22
+ + f' grpcio>={GRPC_GENERATED_VERSION}.'
23
+ + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
24
+ + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
25
+ )
26
+
27
+
28
+ class FlagSyncServiceStub(object):
29
+ """FlagService implements a server streaming to provide realtime flag configurations
30
+ """
31
+
32
+ def __init__(self, channel):
33
+ """Constructor.
34
+
35
+ Args:
36
+ channel: A grpc.Channel.
37
+ """
38
+ self.SyncFlags = channel.unary_stream(
39
+ '/sync.v1.FlagSyncService/SyncFlags',
40
+ request_serializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsRequest.SerializeToString,
41
+ response_deserializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsResponse.FromString,
42
+ _registered_method=True)
43
+ self.FetchAllFlags = channel.unary_unary(
44
+ '/sync.v1.FlagSyncService/FetchAllFlags',
45
+ request_serializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsRequest.SerializeToString,
46
+ response_deserializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsResponse.FromString,
47
+ _registered_method=True)
48
+
49
+
50
+ class FlagSyncServiceServicer(object):
51
+ """FlagService implements a server streaming to provide realtime flag configurations
52
+ """
53
+
54
+ def SyncFlags(self, request, context):
55
+ """Missing associated documentation comment in .proto file."""
56
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
57
+ context.set_details('Method not implemented!')
58
+ raise NotImplementedError('Method not implemented!')
59
+
60
+ def FetchAllFlags(self, request, context):
61
+ """Missing associated documentation comment in .proto file."""
62
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
63
+ context.set_details('Method not implemented!')
64
+ raise NotImplementedError('Method not implemented!')
65
+
66
+
67
+ def add_FlagSyncServiceServicer_to_server(servicer, server):
68
+ rpc_method_handlers = {
69
+ 'SyncFlags': grpc.unary_stream_rpc_method_handler(
70
+ servicer.SyncFlags,
71
+ request_deserializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsRequest.FromString,
72
+ response_serializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsResponse.SerializeToString,
73
+ ),
74
+ 'FetchAllFlags': grpc.unary_unary_rpc_method_handler(
75
+ servicer.FetchAllFlags,
76
+ request_deserializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsRequest.FromString,
77
+ response_serializer=openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsResponse.SerializeToString,
78
+ ),
79
+ }
80
+ generic_handler = grpc.method_handlers_generic_handler(
81
+ 'sync.v1.FlagSyncService', rpc_method_handlers)
82
+ server.add_generic_rpc_handlers((generic_handler,))
83
+ server.add_registered_method_handlers('sync.v1.FlagSyncService', rpc_method_handlers)
84
+
85
+
86
+ # This class is part of an EXPERIMENTAL API.
87
+ class FlagSyncService(object):
88
+ """FlagService implements a server streaming to provide realtime flag configurations
89
+ """
90
+
91
+ @staticmethod
92
+ def SyncFlags(request,
93
+ target,
94
+ options=(),
95
+ channel_credentials=None,
96
+ call_credentials=None,
97
+ insecure=False,
98
+ compression=None,
99
+ wait_for_ready=None,
100
+ timeout=None,
101
+ metadata=None):
102
+ return grpc.experimental.unary_stream(
103
+ request,
104
+ target,
105
+ '/sync.v1.FlagSyncService/SyncFlags',
106
+ openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsRequest.SerializeToString,
107
+ openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.SyncFlagsResponse.FromString,
108
+ options,
109
+ channel_credentials,
110
+ insecure,
111
+ call_credentials,
112
+ compression,
113
+ wait_for_ready,
114
+ timeout,
115
+ metadata,
116
+ _registered_method=True)
117
+
118
+ @staticmethod
119
+ def FetchAllFlags(request,
120
+ target,
121
+ options=(),
122
+ channel_credentials=None,
123
+ call_credentials=None,
124
+ insecure=False,
125
+ compression=None,
126
+ wait_for_ready=None,
127
+ timeout=None,
128
+ metadata=None):
129
+ return grpc.experimental.unary_unary(
130
+ request,
131
+ target,
132
+ '/sync.v1.FlagSyncService/FetchAllFlags',
133
+ openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsRequest.SerializeToString,
134
+ openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2.FetchAllFlagsResponse.FromString,
135
+ options,
136
+ channel_credentials,
137
+ insecure,
138
+ call_credentials,
139
+ compression,
140
+ wait_for_ready,
141
+ timeout,
142
+ metadata,
143
+ _registered_method=True)
@@ -0,0 +1,70 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ *
5
+ DEPRECATED; use flagd.sync.v1
6
+ Flag definition sync API
7
+
8
+ This proto defines a simple API to synchronize a feature flag definition.
9
+ It supports establishing a stream for getting notifications about changes in a flag definition.
10
+ """
11
+
12
+ import abc
13
+ import collections.abc
14
+ import grpc
15
+ import grpc.aio
16
+ import openfeature.schemas.protobuf.sync.v1.sync_service_pb2
17
+ import typing
18
+
19
+ _T = typing.TypeVar("_T")
20
+
21
+ class _MaybeAsyncIterator(collections.abc.AsyncIterator[_T], collections.abc.Iterator[_T], metaclass=abc.ABCMeta): ...
22
+
23
+ class _ServicerContext(grpc.ServicerContext, grpc.aio.ServicerContext): # type: ignore[misc, type-arg]
24
+ ...
25
+
26
+ class FlagSyncServiceStub:
27
+ """FlagService implements a server streaming to provide realtime flag configurations"""
28
+
29
+ def __init__(self, channel: typing.Union[grpc.Channel, grpc.aio.Channel]) -> None: ...
30
+ SyncFlags: grpc.UnaryStreamMultiCallable[
31
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsRequest,
32
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsResponse,
33
+ ]
34
+
35
+ FetchAllFlags: grpc.UnaryUnaryMultiCallable[
36
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsRequest,
37
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsResponse,
38
+ ]
39
+
40
+ class FlagSyncServiceAsyncStub:
41
+ """FlagService implements a server streaming to provide realtime flag configurations"""
42
+
43
+ SyncFlags: grpc.aio.UnaryStreamMultiCallable[
44
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsRequest,
45
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsResponse,
46
+ ]
47
+
48
+ FetchAllFlags: grpc.aio.UnaryUnaryMultiCallable[
49
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsRequest,
50
+ openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsResponse,
51
+ ]
52
+
53
+ class FlagSyncServiceServicer(metaclass=abc.ABCMeta):
54
+ """FlagService implements a server streaming to provide realtime flag configurations"""
55
+
56
+ @abc.abstractmethod
57
+ def SyncFlags(
58
+ self,
59
+ request: openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsRequest,
60
+ context: _ServicerContext,
61
+ ) -> typing.Union[collections.abc.Iterator[openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsResponse], collections.abc.AsyncIterator[openfeature.schemas.protobuf.sync.v1.sync_service_pb2.SyncFlagsResponse]]: ...
62
+
63
+ @abc.abstractmethod
64
+ def FetchAllFlags(
65
+ self,
66
+ request: openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsRequest,
67
+ context: _ServicerContext,
68
+ ) -> typing.Union[openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsResponse, collections.abc.Awaitable[openfeature.schemas.protobuf.sync.v1.sync_service_pb2.FetchAllFlagsResponse]]: ...
69
+
70
+ def add_FlagSyncServiceServicer_to_server(servicer: FlagSyncServiceServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ...
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: openfeature-provider-flagd
3
- Version: 0.1.5
3
+ Version: 0.2.0
4
4
  Summary: OpenFeature provider for the flagd flag evaluation engine
5
5
  Project-URL: Homepage, https://github.com/open-feature/python-sdk-contrib
6
6
  Author-email: OpenFeature <openfeature-core@groups.io>
@@ -192,7 +192,7 @@ License: Apache License
192
192
  same "printed page" as the copyright notice for easier
193
193
  identification within third-party archives.
194
194
 
195
- Copyright The OpenTelemetry Authors
195
+ Copyright [yyyy] [name of copyright owner]
196
196
 
197
197
  Licensed under the Apache License, Version 2.0 (the "License");
198
198
  you may not use this file except in compliance with the License.
@@ -209,19 +209,20 @@ License-File: LICENSE
209
209
  Classifier: License :: OSI Approved :: Apache Software License
210
210
  Classifier: Programming Language :: Python
211
211
  Classifier: Programming Language :: Python :: 3
212
- Requires-Python: >=3.8
213
- Requires-Dist: grpcio>=1.60.0
212
+ Requires-Python: >=3.9
213
+ Requires-Dist: cachebox
214
+ Requires-Dist: grpcio>=1.68.1
214
215
  Requires-Dist: mmh3>=4.1.0
215
- Requires-Dist: openfeature-sdk>=0.4.0
216
+ Requires-Dist: openfeature-sdk>=0.6.0
216
217
  Requires-Dist: panzi-json-logic>=1.0.1
217
- Requires-Dist: protobuf>=4.25.2
218
+ Requires-Dist: protobuf>=4.29.2
218
219
  Requires-Dist: pyyaml>=6.0.1
219
220
  Requires-Dist: semver<4,>=3
220
221
  Description-Content-Type: text/markdown
221
222
 
222
223
  # flagd Provider for OpenFeature
223
224
 
224
- This provider is designed to use flagd's [evaluation protocol](https://github.com/open-feature/schemas/blob/main/protobuf/schema/v1/schema.proto).
225
+ This provider is designed to use flagd's [evaluation protocol](https://github.com/open-feature/schemas/blob/main/protobuf/schema/v1/schema.proto), or locally evaluate flags defined in a flagd [flag definition](https://github.com/open-feature/schemas/blob/main/json/flagd-definitions.json) via the OpenFeature Python SDK.
225
226
 
226
227
  ## Installation
227
228
 
@@ -231,6 +232,14 @@ pip install openfeature-provider-flagd
231
232
 
232
233
  ## Configuration and Usage
233
234
 
235
+ The flagd provider can operate in two modes: [RPC](#remote-resolver-rpc) (evaluation takes place in flagd, via gRPC calls) or [in-process](#in-process-resolver) (evaluation takes place in-process, with the provider getting a ruleset from a compliant sync-source).
236
+
237
+ ### Remote resolver (RPC)
238
+
239
+ This is the default mode of operation of the provider.
240
+ In this mode, `FlagdProvider` communicates with [flagd](https://github.com/open-feature/flagd) via the gRPC protocol.
241
+ Flag evaluations take place remotely at the connected flagd instance.
242
+
234
243
  Instantiate a new FlagdProvider instance and configure the OpenFeature SDK to use it:
235
244
 
236
245
  ```python
@@ -240,7 +249,11 @@ from openfeature.contrib.provider.flagd import FlagdProvider
240
249
  api.set_provider(FlagdProvider())
241
250
  ```
242
251
 
243
- To use in-process evaluation in offline mode with a file as source:
252
+ ### In-process resolver
253
+
254
+ This mode performs flag evaluations locally (in-process). Flag configurations for evaluation are obtained via gRPC protocol using [sync protobuf schema](https://buf.build/open-feature/flagd/file/main:sync/v1/sync_service.proto) service definition.
255
+
256
+ Consider the following example to create a `FlagdProvider` with in-process evaluations,
244
257
 
245
258
  ```python
246
259
  from openfeature import api
@@ -249,20 +262,108 @@ from openfeature.contrib.provider.flagd.config import ResolverType
249
262
 
250
263
  api.set_provider(FlagdProvider(
251
264
  resolver_type=ResolverType.IN_PROCESS,
265
+ ))
266
+ ```
267
+
268
+ In the above example, in-process handlers attempt to connect to a sync service on address `localhost:8013` to obtain [flag definitions](https://github.com/open-feature/schemas/blob/main/json/flags.json).
269
+
270
+ <!--
271
+ #### Sync-metadata
272
+
273
+ To support the injection of contextual data configured in flagd for in-process evaluation, the provider exposes a `getSyncMetadata` accessor which provides the most recent value returned by the [GetMetadata RPC](https://buf.build/open-feature/flagd/docs/main:flagd.sync.v1#flagd.sync.v1.FlagSyncService.GetMetadata).
274
+ The value is updated with every (re)connection to the sync implementation.
275
+ This can be used to enrich evaluations with such data.
276
+ If the `in-process` mode is not used, and before the provider is ready, the `getSyncMetadata` returns an empty map.
277
+ -->
278
+ ### File mode
279
+
280
+ In-process resolvers can also work in an offline mode.
281
+ To enable this mode, you should provide a valid flag configuration file with the option `offlineFlagSourcePath`.
282
+
283
+ ```python
284
+ from openfeature import api
285
+ from openfeature.contrib.provider.flagd import FlagdProvider
286
+ from openfeature.contrib.provider.flagd.config import ResolverType
287
+
288
+ api.set_provider(FlagdProvider(
289
+ resolver_type=ResolverType.FILE,
252
290
  offline_flag_source_path="my-flag.json",
253
291
  ))
254
292
  ```
255
293
 
294
+ Provider will attempt to detect file changes using polling.
295
+ Polling happens at 5 second intervals and this is currently unconfigurable.
296
+ This mode is useful for local development, tests and offline applications.
297
+
256
298
  ### Configuration options
257
299
 
258
300
  The default options can be defined in the FlagdProvider constructor.
259
301
 
260
- | Option name | Type & Values | Default |
261
- |----------------|---------------|-----------|
262
- | host | str | localhost |
263
- | port | int | 8013 |
264
- | schema | str | http |
265
- | timeout | int | 2 |
302
+ | Option name | Environment variable name | Type & Values | Default | Compatible resolver |
303
+ |--------------------------|--------------------------------|----------------------------|-------------------------------|---------------------|
304
+ | resolver_type | FLAGD_RESOLVER | enum - `rpc`, `in-process` | rpc | |
305
+ | host | FLAGD_HOST | str | localhost | rpc & in-process |
306
+ | port | FLAGD_PORT | int | 8013 (rpc), 8015 (in-process) | rpc & in-process |
307
+ | tls | FLAGD_TLS | bool | false | rpc & in-process |
308
+ | cert_path | FLAGD_SERVER_CERT_PATH | String | null | rpc & in-process |
309
+ | deadline | FLAGD_DEADLINE_MS | int | 500 | rpc & in-process |
310
+ | stream_deadline_ms | FLAGD_STREAM_DEADLINE_MS | int | 600000 | rpc & in-process |
311
+ | keep_alive_time | FLAGD_KEEP_ALIVE_TIME_MS | int | 0 | rpc & in-process |
312
+ | selector | FLAGD_SOURCE_SELECTOR | str | null | in-process |
313
+ | cache_type | FLAGD_CACHE | enum - `lru`, `disabled` | lru | rpc |
314
+ | max_cache_size | FLAGD_MAX_CACHE_SIZE | int | 1000 | rpc |
315
+ | retry_backoff_ms | FLAGD_RETRY_BACKOFF_MS | int | 1000 | rpc |
316
+ | offline_flag_source_path | FLAGD_OFFLINE_FLAG_SOURCE_PATH | str | null | in-process |
317
+
318
+ <!-- not implemented
319
+ | target_uri | FLAGD_TARGET_URI | alternative to host/port, supporting custom name resolution | string | null | rpc & in-process |
320
+ | socket_path | FLAGD_SOCKET_PATH | alternative to host port, unix socket | String | null | rpc & in-process |
321
+ | context_enricher | - | sync-metadata to evaluation context mapping function | function | identity function | in-process |
322
+ | offline_pollIntervalMs | FLAGD_OFFLINE_POLL_MS | poll interval for reading offlineFlagSourcePath | int | 5000 | in-process |
323
+ -->
324
+
325
+ > [!NOTE]
326
+ > Some configurations are only applicable for RPC resolver.
327
+
328
+ <!--
329
+ ### Unix socket support
330
+ Unix socket communication with flagd is facilitated by usaging of the linux-native `epoll` library on `linux-x86_64`
331
+ only (ARM support is pending the release of `netty-transport-native-epoll` v5).
332
+ Unix sockets are not supported on other platforms or architectures.
333
+ -->
334
+
335
+ ### Reconnection
336
+
337
+ Reconnection is supported by the underlying gRPC connections.
338
+ If the connection to flagd is lost, it will reconnect automatically.
339
+ A failure to connect will result in an [error event](https://openfeature.dev/docs/reference/concepts/events#provider_error) from the provider, though it will attempt to reconnect indefinitely.
340
+
341
+ ### Deadlines
342
+
343
+ Deadlines are used to define how long the provider waits to complete initialization or flag evaluations.
344
+ They behave differently based on the resolver type.
345
+
346
+ #### Deadlines with Remote resolver (RPC)
347
+
348
+ If the remote evaluation call is not completed within this deadline, the gRPC call is terminated with the error `DEADLINE_EXCEEDED`
349
+ and the evaluation will default.
350
+
351
+ ### TLS
352
+
353
+ TLS is available in situations where flagd is running on another host.
354
+
355
+
356
+ You may optionally supply an X.509 certificate in PEM format. Otherwise, the default certificate store will be used.
357
+
358
+ ```python
359
+ from openfeature import api
360
+ from openfeature.contrib.provider.flagd import FlagdProvider
361
+
362
+ api.set_provider(FlagdProvider(
363
+ tls=True, # use TLS
364
+ cert_path="etc/cert/ca.crt" # PEM cert
365
+ ))
366
+ ```
266
367
 
267
368
  ## License
268
369
 
@@ -0,0 +1,35 @@
1
+ openfeature/.gitignore,sha256=1ZPH4VtVL4bMQmBJXQJxeAyUa74LCtqV1a_yjeDIzSQ,8
2
+ openfeature/contrib/provider/flagd/__init__.py,sha256=WlrcPaCH31dEG1IvrvpeuhAaQ8Ni8LEzDpNM_x-qKOA,65
3
+ openfeature/contrib/provider/flagd/config.py,sha256=ObWUUMVaRf199AWjfg4xrTOR7qcx5venyTNPUJkSTmA,7024
4
+ openfeature/contrib/provider/flagd/flag_type.py,sha256=rZYfmqQEmtqVVTb8e-d8Wt8ZCnHtf7xPSmYxyU8w0R0,158
5
+ openfeature/contrib/provider/flagd/provider.py,sha256=n0sRslXEOhFkXZnFXQguC5HkC18ekTFLKEmj7WSTJ50,6795
6
+ openfeature/contrib/provider/flagd/resolvers/__init__.py,sha256=CzsnsfxJCaD_S1gBf15kkJBVD-gVLKIwDi4W1nE-dXw,181
7
+ openfeature/contrib/provider/flagd/resolvers/grpc.py,sha256=lVwznNS8WU41xIBjazxhhpJKfCLTEgnon4CHDh0DY-g,13470
8
+ openfeature/contrib/provider/flagd/resolvers/in_process.py,sha256=fUE6Q1dzwE4V7KYYpdp2_qKj7vrkL47fG906kyxubr8,4618
9
+ openfeature/contrib/provider/flagd/resolvers/protocol.py,sha256=Wc7oUH6ytPuKg8Lj_3y-_LLkQkuvsow9IiSfmlM8I2o,1402
10
+ openfeature/contrib/provider/flagd/resolvers/process/custom_ops.py,sha256=bZX1At0dRxhghhWz4g-8N-YPobcVfYSv9PTsYh-lZDc,4549
11
+ openfeature/contrib/provider/flagd/resolvers/process/flags.py,sha256=nDXkl80DiJBlSrz0l7xT-DAr6zzZSS0mwOSjvUAV2gY,3255
12
+ openfeature/contrib/provider/flagd/resolvers/process/targeting.py,sha256=qjYgfoJK9B1ghh19cUq7f-VEql7Hh1J7sh0BhnNc_h0,905
13
+ openfeature/contrib/provider/flagd/resolvers/process/connector/__init__.py,sha256=hyYYxRYEnSho5F28M2hbhhtkG4DQTwJjD36ddI0Xs7M,289
14
+ openfeature/contrib/provider/flagd/resolvers/process/connector/file_watcher.py,sha256=m_hscNJ0tHQgY5xuOriK20SiYKjz5FpLPoDfNJDDXKs,3889
15
+ openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py,sha256=ZTHLpMZSIMl7doK75-rZF64XfxGCNmocr4Vf8UhLHTY,7276
16
+ openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.py,sha256=YPBimdlVBCfnVqxq9uek3H4nyaIR0MhggCAaR0XtIt4,7527
17
+ openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.pyi,sha256=afh-fdsmyfS62C-iq7EQsqr_5yZP_QxJXp81Q0Lcllk,18333
18
+ openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.py,sha256=AFwLCOCunFSWGnlt8Asj3pxORfcx168r4jVmt9CLB0I,17189
19
+ openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.pyi,sha256=tQm-QOlsMdhdN_7i5LsrtLtBPu4qpL0qzTE7DbSvXFs,7731
20
+ openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.py,sha256=OIhVrNkhXtwuCdvbahXiOx-mQ3XVVPx5gh0UHzKN0_M,3528
21
+ openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.pyi,sha256=Qsqe0vz5AJRAAjARXhjiaPKyIFbLttr4gTWae2zyJfM,5967
22
+ openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.py,sha256=7sU7da4Sd8_Jg_TXuGLvNKmgzV98dBcMFKLb_EWQ0jU,8335
23
+ openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.pyi,sha256=APjDd-Yo6i6FE_kOusWhTqk-8B_0wIEMXcImCuGpQt8,3782
24
+ openfeature/schemas/protobuf/schema/v1/schema_pb2.py,sha256=dfGpiAYJ2VuRBrctH7s21KkdrIr9rzIaWibUZ3So3g4,7255
25
+ openfeature/schemas/protobuf/schema/v1/schema_pb2.pyi,sha256=14Z6i0kRpCAQO8aCpc4Qwre1OJ7_d_ZIPq8V1vTuYzU,18369
26
+ openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.py,sha256=4I0h1IXFzqAFX15J-h7yC7PQAu1CEcWEVwK4bhKLsog,16227
27
+ openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.pyi,sha256=EJ55jvso2Uzx50XryC7fsKGEOBi1bMOGCXaShl1TcJ4,7067
28
+ openfeature/schemas/protobuf/sync/v1/sync_service_pb2.py,sha256=Sw0kLvO0wIRXsaFic8qmTuScMdf1-1WOHGWP4FOIB_s,3327
29
+ openfeature/schemas/protobuf/sync/v1/sync_service_pb2.pyi,sha256=o3YpW_5iQJWjU7IFEsyspeqLyBDC4C_psBNErwziumE,7986
30
+ openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.py,sha256=cAbP4qfaS2Dpze8BH3w-PAJfL7LCA7xZYJfFro5b_2I,6185
31
+ openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.pyi,sha256=4NoAkGicVNxx4yVK5_JvvPn1OGlRdPhqM2wCpkwCjEI,3024
32
+ openfeature_provider_flagd-0.2.0.dist-info/METADATA,sha256=aWH2j09cJBu_IzuRgwufwnMUs9DA0jBhncib01UIOHg,21635
33
+ openfeature_provider_flagd-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
+ openfeature_provider_flagd-0.2.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
35
+ openfeature_provider_flagd-0.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.22.5
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright The OpenTelemetry Authors
189
+ Copyright [yyyy] [name of copyright owner]
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.