devcycle-python-server-sdk 3.10.0__py3-none-any.whl → 3.11.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.
- devcycle_python_sdk/VERSION.txt +1 -1
- devcycle_python_sdk/bucketing-lib.release.wasm +0 -0
- devcycle_python_sdk/cloud_client.py +7 -0
- devcycle_python_sdk/devcycle_client.py +7 -0
- devcycle_python_sdk/local_client.py +11 -2
- devcycle_python_sdk/models/event.py +1 -1
- devcycle_python_sdk/models/platform_data.py +2 -0
- devcycle_python_sdk/models/user.py +5 -2
- devcycle_python_sdk/open_feature_provider/provider.py +26 -2
- {devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/METADATA +7 -7
- {devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/RECORD +14 -14
- {devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/WHEEL +1 -1
- {devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/LICENSE +0 -0
- {devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/top_level.txt +0 -0
devcycle_python_sdk/VERSION.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.11.0
|
|
Binary file
|
|
@@ -182,6 +182,13 @@ class DevCycleCloudClient(AbstractDevCycleClient):
|
|
|
182
182
|
except Exception as e:
|
|
183
183
|
logger.error(f"DevCycle: Error tracking event: {e}")
|
|
184
184
|
|
|
185
|
+
def close(self) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Closes the client and releases any resources held by it.
|
|
188
|
+
"""
|
|
189
|
+
# Cloud client doesn't need to release any resources
|
|
190
|
+
logger.debug("DevCycle: Cloud client closed")
|
|
191
|
+
|
|
185
192
|
|
|
186
193
|
def _validate_sdk_key(sdk_key: str) -> None:
|
|
187
194
|
if sdk_key is None or len(sdk_key) == 0:
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
import uuid
|
|
4
4
|
from numbers import Real
|
|
5
|
-
from typing import Any, Dict, Union
|
|
5
|
+
from typing import Any, Dict, Union, Optional
|
|
6
6
|
|
|
7
7
|
from devcycle_python_sdk import DevCycleLocalOptions, AbstractDevCycleClient
|
|
8
8
|
from devcycle_python_sdk.api.local_bucketing import LocalBucketing
|
|
@@ -50,12 +50,21 @@ class DevCycleLocalClient(AbstractDevCycleClient):
|
|
|
50
50
|
sdk_key, self.client_uuid, self.options, self.local_bucketing
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
self._openfeature_provider =
|
|
53
|
+
self._openfeature_provider: Optional[DevCycleProvider] = None
|
|
54
54
|
|
|
55
55
|
def get_sdk_platform(self) -> str:
|
|
56
56
|
return "Local"
|
|
57
57
|
|
|
58
58
|
def get_openfeature_provider(self) -> AbstractProvider:
|
|
59
|
+
if self._openfeature_provider is None:
|
|
60
|
+
self._openfeature_provider = DevCycleProvider(self)
|
|
61
|
+
|
|
62
|
+
# Update platform data for OpenFeature
|
|
63
|
+
self._platform_data.sdkPlatform = "python-of"
|
|
64
|
+
self.local_bucketing.set_platform_data(
|
|
65
|
+
json.dumps(self._platform_data.to_json())
|
|
66
|
+
)
|
|
67
|
+
|
|
59
68
|
return self._openfeature_provider
|
|
60
69
|
|
|
61
70
|
def is_initialized(self) -> bool:
|
|
@@ -18,7 +18,7 @@ class EventType:
|
|
|
18
18
|
class DevCycleEvent:
|
|
19
19
|
type: Optional[str] = None
|
|
20
20
|
target: Optional[str] = None
|
|
21
|
-
date: datetime = field(default_factory=lambda: datetime.
|
|
21
|
+
date: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
22
22
|
value: Optional[int] = None
|
|
23
23
|
metaData: Optional[Dict[str, str]] = None
|
|
24
24
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# ruff: noqa: N815
|
|
2
2
|
import platform
|
|
3
3
|
import socket
|
|
4
|
+
from typing import Optional
|
|
4
5
|
from dataclasses import dataclass
|
|
5
6
|
from devcycle_python_sdk.util.version import sdk_version
|
|
6
7
|
|
|
@@ -13,6 +14,7 @@ class PlatformData:
|
|
|
13
14
|
deviceModel: str
|
|
14
15
|
platform: str
|
|
15
16
|
hostname: str
|
|
17
|
+
sdkPlatform: Optional[str] = None
|
|
16
18
|
|
|
17
19
|
def to_json(self):
|
|
18
20
|
return {
|
|
@@ -16,7 +16,7 @@ class DevCycleUser:
|
|
|
16
16
|
appVersion: Optional[str] = None
|
|
17
17
|
appBuild: Optional[str] = None
|
|
18
18
|
customData: Optional[Dict[str, Any]] = None
|
|
19
|
-
createdDate: datetime = field(default_factory=lambda: datetime.
|
|
19
|
+
createdDate: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
20
20
|
privateCustomData: Optional[Dict[str, Any]] = None
|
|
21
21
|
lastSeenDate: Optional[datetime] = None
|
|
22
22
|
platform: Optional[str] = None
|
|
@@ -24,6 +24,7 @@ class DevCycleUser:
|
|
|
24
24
|
deviceModel: Optional[str] = None
|
|
25
25
|
sdkType: Optional[str] = None
|
|
26
26
|
sdkVersion: Optional[str] = None
|
|
27
|
+
sdkPlatform: Optional[str] = None
|
|
27
28
|
|
|
28
29
|
def to_json(self):
|
|
29
30
|
json_dict = {
|
|
@@ -50,7 +51,7 @@ class DevCycleUser:
|
|
|
50
51
|
data["createdDate"].replace("Z", "+00:00")
|
|
51
52
|
)
|
|
52
53
|
else:
|
|
53
|
-
created_date = datetime.
|
|
54
|
+
created_date = datetime.now(timezone.utc)
|
|
54
55
|
|
|
55
56
|
last_seen_date = None
|
|
56
57
|
if "lastSeenDate" in data:
|
|
@@ -75,6 +76,7 @@ class DevCycleUser:
|
|
|
75
76
|
deviceModel=data.get("deviceModel"),
|
|
76
77
|
sdkType=data.get("sdkType"),
|
|
77
78
|
sdkVersion=data.get("sdkVersion"),
|
|
79
|
+
sdkPlatform=data.get("sdkPlatform"),
|
|
78
80
|
)
|
|
79
81
|
|
|
80
82
|
@staticmethod
|
|
@@ -156,4 +158,5 @@ class DevCycleUser:
|
|
|
156
158
|
if private_custom_data:
|
|
157
159
|
user.privateCustomData = private_custom_data
|
|
158
160
|
|
|
161
|
+
user.sdkPlatform = "python-of"
|
|
159
162
|
return user
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import time
|
|
2
3
|
|
|
3
4
|
from typing import Any, Optional, Union, List
|
|
4
5
|
|
|
@@ -6,11 +7,16 @@ from devcycle_python_sdk import AbstractDevCycleClient
|
|
|
6
7
|
from devcycle_python_sdk.models.user import DevCycleUser
|
|
7
8
|
|
|
8
9
|
from openfeature.provider import AbstractProvider
|
|
10
|
+
from openfeature.provider.metadata import Metadata
|
|
9
11
|
from openfeature.evaluation_context import EvaluationContext
|
|
10
12
|
from openfeature.flag_evaluation import FlagResolutionDetails, Reason
|
|
11
|
-
from openfeature.exception import
|
|
13
|
+
from openfeature.exception import (
|
|
14
|
+
ErrorCode,
|
|
15
|
+
InvalidContextError,
|
|
16
|
+
TypeMismatchError,
|
|
17
|
+
GeneralError,
|
|
18
|
+
)
|
|
12
19
|
from openfeature.hook import Hook
|
|
13
|
-
from openfeature.provider.metadata import Metadata
|
|
14
20
|
|
|
15
21
|
logger = logging.getLogger(__name__)
|
|
16
22
|
|
|
@@ -26,6 +32,24 @@ class DevCycleProvider(AbstractProvider):
|
|
|
26
32
|
self.client = devcycle_client
|
|
27
33
|
self.meta_data = Metadata(name=f"DevCycle {self.client.get_sdk_platform()}")
|
|
28
34
|
|
|
35
|
+
def initialize(self, evaluation_context: EvaluationContext) -> None:
|
|
36
|
+
timeout = 2
|
|
37
|
+
start_time = time.time()
|
|
38
|
+
|
|
39
|
+
# Wait for the client to be initialized or timeout
|
|
40
|
+
while not self.client.is_initialized():
|
|
41
|
+
if time.time() - start_time > timeout:
|
|
42
|
+
raise GeneralError(
|
|
43
|
+
f"DevCycleProvider initialization timed out after {timeout} seconds"
|
|
44
|
+
)
|
|
45
|
+
time.sleep(0.1) # Sleep briefly to avoid busy waiting
|
|
46
|
+
|
|
47
|
+
if self.client.is_initialized():
|
|
48
|
+
logger.debug("DevCycleProvider initialized successfully")
|
|
49
|
+
|
|
50
|
+
def shutdown(self) -> None:
|
|
51
|
+
self.client.close()
|
|
52
|
+
|
|
29
53
|
def get_metadata(self) -> Metadata:
|
|
30
54
|
return self.meta_data
|
|
31
55
|
|
{devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/METADATA
RENAMED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: devcycle-python-server-sdk
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.11.0
|
|
4
4
|
Summary: DevCycle Python SDK
|
|
5
5
|
Home-page: https://github.com/devcycleHQ/python-server-sdk
|
|
6
6
|
Author-email:
|
|
7
7
|
Keywords: DevCycle
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: setuptools>=21.0.0
|
|
11
11
|
Requires-Dist: urllib3>=1.15.1
|
|
12
|
-
Requires-Dist: requests
|
|
13
|
-
Requires-Dist: wasmtime
|
|
12
|
+
Requires-Dist: requests>=2.32
|
|
13
|
+
Requires-Dist: wasmtime~=30.0.0
|
|
14
14
|
Requires-Dist: protobuf>=4.23.3
|
|
15
|
-
Requires-Dist: openfeature-sdk>=0.
|
|
16
|
-
Requires-Dist: launchdarkly-eventsource>=1.2.
|
|
17
|
-
Requires-Dist: responses
|
|
15
|
+
Requires-Dist: openfeature-sdk>=0.8.0
|
|
16
|
+
Requires-Dist: launchdarkly-eventsource>=1.2.1
|
|
17
|
+
Requires-Dist: responses>=0.23.1
|
|
18
18
|
Dynamic: description
|
|
19
19
|
Dynamic: home-page
|
|
20
20
|
Dynamic: keywords
|
{devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/RECORD
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
devcycle_python_sdk/VERSION.txt,sha256=
|
|
1
|
+
devcycle_python_sdk/VERSION.txt,sha256=0w8VIMa3CqY143oi3wMMFnI8Zet0gUxedR_kDu7ZW3o,7
|
|
2
2
|
devcycle_python_sdk/__init__.py,sha256=30TcYb9PbvVi97gwk16omCGG1UoUI9lmmU7xpvxNMvc,336
|
|
3
|
-
devcycle_python_sdk/bucketing-lib.release.wasm,sha256=
|
|
4
|
-
devcycle_python_sdk/cloud_client.py,sha256=
|
|
5
|
-
devcycle_python_sdk/devcycle_client.py,sha256=
|
|
3
|
+
devcycle_python_sdk/bucketing-lib.release.wasm,sha256=Kuw8UrGafeyB8Z1wyBgGQpuXIhP4NvPjXZcVQiNZzl8,215020
|
|
4
|
+
devcycle_python_sdk/cloud_client.py,sha256=VVV3O8Fbrp3LrhKp0BNCF-pMqOuCA6TEEABBmjpfpOY,7586
|
|
5
|
+
devcycle_python_sdk/devcycle_client.py,sha256=OqNza7OXOSRmMQq2kmyivljmH1GyN4dTiz0EhvDvt8w,1069
|
|
6
6
|
devcycle_python_sdk/exceptions.py,sha256=Et7fS8pEFbHkFY86T2pJoEUstwjh4_rzhJxVH8fzAns,1053
|
|
7
|
-
devcycle_python_sdk/local_client.py,sha256=
|
|
7
|
+
devcycle_python_sdk/local_client.py,sha256=cC9N144DY-WWatcSwVQh-e_07mnncjC3NG88Eo9wX0g,9814
|
|
8
8
|
devcycle_python_sdk/options.py,sha256=WOpeI9U_9Gsf3OFWvoRIBRgJVZEqFxuEYTII71r5L24,4939
|
|
9
9
|
devcycle_python_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
devcycle_python_sdk/api/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
@@ -20,13 +20,13 @@ devcycle_python_sdk/managers/sse_manager.py,sha256=aJKHPmvv8SR4DU9IOi-KrUSCxQoHd
|
|
|
20
20
|
devcycle_python_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
devcycle_python_sdk/models/bucketed_config.py,sha256=NsdT-6RbEuDy5QuK5qlr6UqNKQQnwjoXVYN-uQp0P-E,3999
|
|
22
22
|
devcycle_python_sdk/models/error_response.py,sha256=r_dRUDAbral9UGaMYcnBsZOr9Hmkyi1SQbhGmZilgpA,442
|
|
23
|
-
devcycle_python_sdk/models/event.py,sha256
|
|
23
|
+
devcycle_python_sdk/models/event.py,sha256=Sj3eEopuPp8QwQl_Oz8E6Y9Ph6nLG0HxU7eR7xSbA7g,3722
|
|
24
24
|
devcycle_python_sdk/models/feature.py,sha256=m3wxxIjC5jxhKpPLI4RcsBaNLuy-zsMqoAgc8ySPe0I,852
|
|
25
|
-
devcycle_python_sdk/models/platform_data.py,sha256=
|
|
26
|
-
devcycle_python_sdk/models/user.py,sha256
|
|
25
|
+
devcycle_python_sdk/models/platform_data.py,sha256=nyQsgI6pcTd1FL3Y2ACmpvTYb08R_UtWul25OWZstps,849
|
|
26
|
+
devcycle_python_sdk/models/user.py,sha256=-tt-LQV-sBxNNfAKAlbNkHpsS01Gi0w37ZJQDARtve8,6422
|
|
27
27
|
devcycle_python_sdk/models/variable.py,sha256=qp00SyCNyfYiMlTwnDSDJ4ZetRF35JHTbYZQOBxFIqY,1711
|
|
28
28
|
devcycle_python_sdk/open_feature_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
devcycle_python_sdk/open_feature_provider/provider.py,sha256=
|
|
29
|
+
devcycle_python_sdk/open_feature_provider/provider.py,sha256=nLqyW4n9_NrJqgaz6cUt3YHDoZQzorjTYPiyT4UjFdc,5255
|
|
30
30
|
devcycle_python_sdk/protobuf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
31
|
devcycle_python_sdk/protobuf/utils.py,sha256=zi-kVx6yvgS2c04cUobLd2IDc_ZqKkWduay9YcpjoGc,4684
|
|
32
32
|
devcycle_python_sdk/protobuf/variableForUserParams_pb2.py,sha256=Zf4-8n67UnulC0Sz90aqLYsXCFEgywOqfiSHuXZomLk,4244
|
|
@@ -61,8 +61,8 @@ test/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
61
61
|
test/util/test_strings.py,sha256=T5H5U0af7_ld1yJC8IdDmay_Mx-iJQ5Fi5fbvKcAc7A,862
|
|
62
62
|
test/util/test_utils.py,sha256=tVBJm_qnqg-4PssLpXIxqlk0JehuiAIPs4zpi2oNVnY,6671
|
|
63
63
|
test/util/test_version.py,sha256=3Xg0_84m0bdHXz6pxd2Z85Oz9DoUC1T0Ol_WqEH_jac,335
|
|
64
|
-
devcycle_python_server_sdk-3.
|
|
65
|
-
devcycle_python_server_sdk-3.
|
|
66
|
-
devcycle_python_server_sdk-3.
|
|
67
|
-
devcycle_python_server_sdk-3.
|
|
68
|
-
devcycle_python_server_sdk-3.
|
|
64
|
+
devcycle_python_server_sdk-3.11.0.dist-info/LICENSE,sha256=tHQMqu-Jic2UpMGqb-vNFbGygysl8IG4l1clnnh0OFo,1071
|
|
65
|
+
devcycle_python_server_sdk-3.11.0.dist-info/METADATA,sha256=WuckfvN8mewEHEAzhXLThQEXSmj2_C1ydFpNQUAdgqE,701
|
|
66
|
+
devcycle_python_server_sdk-3.11.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
67
|
+
devcycle_python_server_sdk-3.11.0.dist-info/top_level.txt,sha256=34f8zDzihAHoH7siAFlmscyO_QLNWWq9HApFlwtYL4k,33
|
|
68
|
+
devcycle_python_server_sdk-3.11.0.dist-info/RECORD,,
|
{devcycle_python_server_sdk-3.10.0.dist-info → devcycle_python_server_sdk-3.11.0.dist-info}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|