gofeatureflag-python-provider 0.1.0__tar.gz → 0.1.2__tar.gz

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 (12) hide show
  1. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/PKG-INFO +8 -8
  2. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/README.md +6 -6
  3. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/data_collector_hook.py +10 -6
  4. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/provider.py +30 -25
  5. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/pyproject.toml +5 -5
  6. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/__init__.py +0 -0
  7. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/metadata.py +0 -0
  8. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/options.py +0 -0
  9. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/provider_status.py +0 -0
  10. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/request_data_collector.py +0 -0
  11. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/request_flag_evaluation.py +0 -0
  12. {gofeatureflag_python_provider-0.1.0 → gofeatureflag_python_provider-0.1.2}/gofeatureflag_python_provider/response_flag_evaluation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gofeatureflag-python-provider
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: GO Feature Flag provider for OpenFeature
5
5
  Home-page: https://gofeatureflag.org
6
6
  License: Apache-2.0
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
17
17
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
18
  Requires-Dist: asyncio (>=3.4.3,<4.0.0)
19
- Requires-Dist: openfeature-sdk (>=0.4.1,<0.5.0)
19
+ Requires-Dist: openfeature-sdk (>=0.5.0,<0.6.0)
20
20
  Requires-Dist: pydantic (>=2.5.2,<3.0.0)
21
21
  Requires-Dist: pylru (>=1.2.1,<2.0.0)
22
22
  Requires-Dist: rel (>=0.4.9,<0.5.0)
@@ -58,27 +58,27 @@ from gofeatureflag_python_provider.options import GoFeatureFlagOptions
58
58
  from openfeature import api
59
59
  from openfeature.evaluation_context import EvaluationContext
60
60
 
61
- // ...
61
+ # ...
62
62
 
63
63
  goff_provider = GoFeatureFlagProvider(
64
64
  options=GoFeatureFlagOptions(endpoint="https://gofeatureflag.org/")
65
65
  )
66
66
  api.set_provider(goff_provider)
67
- client = api.get_client(name="test-client")
67
+ client = api.get_client(domain="test-client")
68
68
  ```
69
69
 
70
70
  ## Evaluate your flag
71
71
 
72
- This code block explain how you can create an `EvaluationContext` and use it to evaluate your flag.
72
+ This code block explains how you can create an `EvaluationContext` and use it to evaluate your flag.
73
73
 
74
74
 
75
75
  > In this example we are evaluating a `boolean` flag, but other types are available.
76
76
  >
77
77
  > **Refer to the [Open Feature documentation](https://docs.openfeature.dev/docs/reference/concepts/evaluation-api#basic-evaluation) to know more about it.**
78
78
 
79
- ```csharp
80
- // Context of your flag evaluation.
81
- // With GO Feature Flag you MUST have a targetingKey that is a unique identifier of the user.
79
+ ```python
80
+ # Context of your flag evaluation.
81
+ # With GO Feature Flag you MUST have a targetingKey that is a unique identifier of the user.
82
82
  evaluation_ctx = EvaluationContext(
83
83
  targeting_key="d45e303a-38c2-11ed-a261-0242ac120002",
84
84
  attributes={
@@ -28,27 +28,27 @@ from gofeatureflag_python_provider.options import GoFeatureFlagOptions
28
28
  from openfeature import api
29
29
  from openfeature.evaluation_context import EvaluationContext
30
30
 
31
- // ...
31
+ # ...
32
32
 
33
33
  goff_provider = GoFeatureFlagProvider(
34
34
  options=GoFeatureFlagOptions(endpoint="https://gofeatureflag.org/")
35
35
  )
36
36
  api.set_provider(goff_provider)
37
- client = api.get_client(name="test-client")
37
+ client = api.get_client(domain="test-client")
38
38
  ```
39
39
 
40
40
  ## Evaluate your flag
41
41
 
42
- This code block explain how you can create an `EvaluationContext` and use it to evaluate your flag.
42
+ This code block explains how you can create an `EvaluationContext` and use it to evaluate your flag.
43
43
 
44
44
 
45
45
  > In this example we are evaluating a `boolean` flag, but other types are available.
46
46
  >
47
47
  > **Refer to the [Open Feature documentation](https://docs.openfeature.dev/docs/reference/concepts/evaluation-api#basic-evaluation) to know more about it.**
48
48
 
49
- ```csharp
50
- // Context of your flag evaluation.
51
- // With GO Feature Flag you MUST have a targetingKey that is a unique identifier of the user.
49
+ ```python
50
+ # Context of your flag evaluation.
51
+ # With GO Feature Flag you MUST have a targetingKey that is a unique identifier of the user.
52
52
  evaluation_ctx = EvaluationContext(
53
53
  targeting_key="d45e303a-38c2-11ed-a261-0242ac120002",
54
54
  attributes={
@@ -47,9 +47,11 @@ class DataCollectorHook(Hook):
47
47
  # we don't collect data if the data collection is disabled or if the flag is not cached
48
48
  return
49
49
  feature_event = FeatureEvent(
50
- contextKind="anonymousUser"
51
- if hook_context.evaluation_context.attributes["anonymous"]
52
- else "user",
50
+ contextKind=(
51
+ "anonymousUser"
52
+ if hook_context.evaluation_context.attributes["anonymous"]
53
+ else "user"
54
+ ),
53
55
  creationDate=int(datetime.datetime.now().timestamp()),
54
56
  default=False,
55
57
  key=hook_context.flag_key,
@@ -66,9 +68,11 @@ class DataCollectorHook(Hook):
66
68
  return
67
69
 
68
70
  feature_event = FeatureEvent(
69
- contextKind="anonymousUser"
70
- if hook_context.evaluation_context.attributes["anonymous"]
71
- else "user",
71
+ contextKind=(
72
+ "anonymousUser"
73
+ if hook_context.evaluation_context.attributes["anonymous"]
74
+ else "user"
75
+ ),
72
76
  creationDate=int(datetime.datetime.now().timestamp()),
73
77
  default=True,
74
78
  key=hook_context.flag_key,
@@ -8,36 +8,41 @@ import pylru
8
8
  import urllib3
9
9
  import websocket
10
10
  from openfeature.evaluation_context import EvaluationContext
11
- from openfeature.exception import ErrorCode
12
11
  from openfeature.exception import (
12
+ ErrorCode,
13
13
  FlagNotFoundError,
14
- TypeMismatchError,
15
14
  GeneralError,
16
15
  OpenFeatureError,
16
+ TypeMismatchError,
17
17
  )
18
- from openfeature.flag_evaluation import FlagEvaluationDetails
19
- from openfeature.flag_evaluation import Reason
18
+ from openfeature.flag_evaluation import FlagResolutionDetails, Reason
20
19
  from openfeature.hook import Hook
21
20
  from openfeature.provider.metadata import Metadata
22
21
  from openfeature.provider.provider import AbstractProvider
23
- from pydantic import ValidationError, PrivateAttr
22
+ from pydantic import PrivateAttr, ValidationError
24
23
 
25
24
  from gofeatureflag_python_provider.data_collector_hook import DataCollectorHook
26
25
  from gofeatureflag_python_provider.metadata import GoFeatureFlagMetadata
27
- from gofeatureflag_python_provider.options import BaseModel
28
- from gofeatureflag_python_provider.options import GoFeatureFlagOptions
26
+ from gofeatureflag_python_provider.options import BaseModel, GoFeatureFlagOptions
29
27
  from gofeatureflag_python_provider.provider_status import ProviderStatus
30
28
  from gofeatureflag_python_provider.request_flag_evaluation import (
31
29
  RequestFlagEvaluation,
32
30
  convert_evaluation_context,
33
31
  )
34
32
  from gofeatureflag_python_provider.response_flag_evaluation import (
35
- ResponseFlagEvaluation,
36
33
  JsonType,
34
+ ResponseFlagEvaluation,
37
35
  )
38
36
 
37
+ AbstractProviderMetaclass = type(AbstractProvider)
38
+ BaseModelMetaclass = type(BaseModel)
39
39
 
40
- class GoFeatureFlagProvider(AbstractProvider, BaseModel):
40
+
41
+ class CombinedMetaclass(AbstractProviderMetaclass, BaseModelMetaclass):
42
+ pass
43
+
44
+
45
+ class GoFeatureFlagProvider(BaseModel, AbstractProvider, metaclass=CombinedMetaclass):
41
46
  options: GoFeatureFlagOptions
42
47
  _http_client: urllib3.PoolManager = PrivateAttr()
43
48
  _cache: pylru.lrucache = PrivateAttr()
@@ -124,7 +129,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
124
129
  flag_key: str,
125
130
  default_value: bool,
126
131
  evaluation_context: Optional[EvaluationContext] = None,
127
- ) -> FlagEvaluationDetails[bool]:
132
+ ) -> FlagResolutionDetails[bool]:
128
133
  return self.generic_go_feature_flag_resolver(
129
134
  bool, flag_key, default_value, evaluation_context
130
135
  )
@@ -134,7 +139,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
134
139
  flag_key: str,
135
140
  default_value: str,
136
141
  evaluation_context: Optional[EvaluationContext] = None,
137
- ) -> FlagEvaluationDetails[str]:
142
+ ) -> FlagResolutionDetails[str]:
138
143
  return self.generic_go_feature_flag_resolver(
139
144
  str, flag_key, default_value, evaluation_context
140
145
  )
@@ -144,7 +149,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
144
149
  flag_key: str,
145
150
  default_value: int,
146
151
  evaluation_context: Optional[EvaluationContext] = None,
147
- ) -> FlagEvaluationDetails[int]:
152
+ ) -> FlagResolutionDetails[int]:
148
153
  return self.generic_go_feature_flag_resolver(
149
154
  int, flag_key, default_value, evaluation_context
150
155
  )
@@ -154,7 +159,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
154
159
  flag_key: str,
155
160
  default_value: float,
156
161
  evaluation_context: Optional[EvaluationContext] = None,
157
- ) -> FlagEvaluationDetails[float]:
162
+ ) -> FlagResolutionDetails[float]:
158
163
  return self.generic_go_feature_flag_resolver(
159
164
  float, flag_key, default_value, evaluation_context
160
165
  )
@@ -164,7 +169,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
164
169
  flag_key: str,
165
170
  default_value: dict,
166
171
  evaluation_context: Optional[EvaluationContext] = None,
167
- ) -> FlagEvaluationDetails[Union[list, dict]]:
172
+ ) -> FlagResolutionDetails[Union[list, dict]]:
168
173
  return self.generic_go_feature_flag_resolver(
169
174
  Union[dict, list], flag_key, default_value, evaluation_context
170
175
  )
@@ -175,7 +180,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
175
180
  flag_key: str,
176
181
  default_value: JsonType,
177
182
  evaluation_context: Optional[EvaluationContext] = None,
178
- ) -> FlagEvaluationDetails[JsonType]:
183
+ ) -> FlagResolutionDetails[JsonType]:
179
184
  """
180
185
  generic_go_feature_flag_resolver is a generic evaluations of your flag with GO Feature Flag relay proxy it works
181
186
  with all types.
@@ -184,12 +189,11 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
184
189
  :param flag_key: name of the flag
185
190
  :param default_value: default value of the flag
186
191
  :param evaluation_context: context to evaluate the flag
187
- :return: a FlagEvaluationDetails object containing the response for the SDK.
192
+ :return: a FlagResolutionDetails object containing the response for the SDK.
188
193
  """
189
194
  try:
190
195
  if self._status != ProviderStatus.READY:
191
- return FlagEvaluationDetails[original_type](
192
- flag_key=flag_key,
196
+ return FlagResolutionDetails[original_type](
193
197
  value=default_value,
194
198
  reason=Reason.ERROR,
195
199
  error_code=ErrorCode.PROVIDER_NOT_READY,
@@ -245,8 +249,7 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
245
249
  )
246
250
 
247
251
  if response_flag_evaluation.reason == Reason.DISABLED.value:
248
- return FlagEvaluationDetails[original_type](
249
- flag_key=flag_key,
252
+ return FlagResolutionDetails[original_type](
250
253
  value=default_value,
251
254
  reason=Reason.DISABLED,
252
255
  )
@@ -256,13 +259,12 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
256
259
  "flag {} was not found in your configuration".format(flag_key)
257
260
  )
258
261
 
259
- return FlagEvaluationDetails[original_type](
260
- flag_key=flag_key,
262
+ return FlagResolutionDetails[original_type](
261
263
  value=response_flag_evaluation.value,
262
264
  variant=response_flag_evaluation.variationType,
263
- reason=Reason.CACHED
264
- if is_from_cache
265
- else response_flag_evaluation.reason,
265
+ reason=(
266
+ Reason.CACHED if is_from_cache else response_flag_evaluation.reason
267
+ ),
266
268
  flag_metadata=response_flag_evaluation.metadata,
267
269
  )
268
270
  except ValidationError as exc:
@@ -334,3 +336,6 @@ class GoFeatureFlagProvider(AbstractProvider, BaseModel):
334
336
  :return: None
335
337
  """
336
338
  self._status = ProviderStatus.STALE
339
+
340
+ def __hash__(self):
341
+ return id(self)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "gofeatureflag-python-provider"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "GO Feature Flag provider for OpenFeature"
5
5
  license = "Apache-2.0"
6
6
  authors = [ "Thomas Poignant" ]
@@ -28,7 +28,7 @@ classifiers = [
28
28
 
29
29
  [tool.poetry.dependencies]
30
30
  python = "^3.9"
31
- openfeature-sdk = "^0.4.1"
31
+ openfeature-sdk = ">=0.5.0,<0.6.0"
32
32
  pydantic = "^2.5.2"
33
33
  urllib3 = "^2.1.0"
34
34
  pylru = "^1.2.1"
@@ -37,11 +37,11 @@ classifiers = [
37
37
  asyncio = "^3.4.3"
38
38
 
39
39
  [tool.poetry.group.dev.dependencies]
40
- pytest = "^7.4"
41
- black = "^23.10.1"
40
+ pytest = ">=7.4,<9.0"
41
+ black = ">=23.10.1,<25.0.0"
42
42
  requests = "^2.31.0"
43
43
  pyyaml = "^6.0.1"
44
- pytest-docker = "^2.0.1"
44
+ pytest-docker = ">=2.0.1,<4.0.0"
45
45
 
46
46
  [build-system]
47
47
  requires = [ "poetry-core>=1.0.0" ]