openfeature-provider-flagd 0.1.4__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 +202 -8
- openfeature/contrib/provider/flagd/provider.py +89 -97
- openfeature/contrib/provider/flagd/resolvers/__init__.py +5 -0
- openfeature/contrib/provider/flagd/resolvers/grpc.py +354 -0
- openfeature/contrib/provider/flagd/resolvers/in_process.py +131 -0
- 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 +165 -0
- openfeature/contrib/provider/flagd/resolvers/process/flags.py +95 -0
- 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.4.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/METADATA +132 -14
- openfeature_provider_flagd-0.2.0.dist-info/RECORD +35 -0
- {openfeature_provider_flagd-0.1.4.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/WHEEL +1 -1
- {openfeature_provider_flagd-0.1.4.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_provider_flagd-0.1.4.dist-info/RECORD +0 -16
|
@@ -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: ...
|
{openfeature_provider_flagd-0.1.4.dist-info → openfeature_provider_flagd-0.2.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: openfeature-provider-flagd
|
|
3
|
-
Version: 0.
|
|
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
|
|
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,15 +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.
|
|
213
|
-
Requires-Dist:
|
|
214
|
-
Requires-Dist:
|
|
215
|
-
Requires-Dist:
|
|
212
|
+
Requires-Python: >=3.9
|
|
213
|
+
Requires-Dist: cachebox
|
|
214
|
+
Requires-Dist: grpcio>=1.68.1
|
|
215
|
+
Requires-Dist: mmh3>=4.1.0
|
|
216
|
+
Requires-Dist: openfeature-sdk>=0.6.0
|
|
217
|
+
Requires-Dist: panzi-json-logic>=1.0.1
|
|
218
|
+
Requires-Dist: protobuf>=4.29.2
|
|
219
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
220
|
+
Requires-Dist: semver<4,>=3
|
|
216
221
|
Description-Content-Type: text/markdown
|
|
217
222
|
|
|
218
223
|
# flagd Provider for OpenFeature
|
|
219
224
|
|
|
220
|
-
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.
|
|
221
226
|
|
|
222
227
|
## Installation
|
|
223
228
|
|
|
@@ -227,6 +232,14 @@ pip install openfeature-provider-flagd
|
|
|
227
232
|
|
|
228
233
|
## Configuration and Usage
|
|
229
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
|
+
|
|
230
243
|
Instantiate a new FlagdProvider instance and configure the OpenFeature SDK to use it:
|
|
231
244
|
|
|
232
245
|
```python
|
|
@@ -236,16 +249,121 @@ from openfeature.contrib.provider.flagd import FlagdProvider
|
|
|
236
249
|
api.set_provider(FlagdProvider())
|
|
237
250
|
```
|
|
238
251
|
|
|
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,
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
from openfeature import api
|
|
260
|
+
from openfeature.contrib.provider.flagd import FlagdProvider
|
|
261
|
+
from openfeature.contrib.provider.flagd.config import ResolverType
|
|
262
|
+
|
|
263
|
+
api.set_provider(FlagdProvider(
|
|
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,
|
|
290
|
+
offline_flag_source_path="my-flag.json",
|
|
291
|
+
))
|
|
292
|
+
```
|
|
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
|
+
|
|
239
298
|
### Configuration options
|
|
240
299
|
|
|
241
300
|
The default options can be defined in the FlagdProvider constructor.
|
|
242
301
|
|
|
243
|
-
| Option name
|
|
244
|
-
|
|
245
|
-
|
|
|
246
|
-
|
|
|
247
|
-
|
|
|
248
|
-
|
|
|
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
|
+
```
|
|
249
367
|
|
|
250
368
|
## License
|
|
251
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,,
|
|
@@ -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
|
|
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.
|