flagsmith 6.2.2__tar.gz → 6.3.0__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.
- {flagsmith-6.2.2 → flagsmith-6.3.0}/PKG-INFO +2 -1
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/analytics.py +2 -2
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/flagsmith.py +11 -3
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/models.py +24 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/version.py +2 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/pyproject.toml +1 -1
- {flagsmith-6.2.2 → flagsmith-6.3.0}/LICENSE +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/README.md +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/__init__.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/api/__init__.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/api/types.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/exceptions.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/mappers.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/offline_handlers.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/polling_manager.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/py.typed +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/streaming_manager.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/types.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/utils/__init__.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/utils/datetime.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/utils/identities.py +0 -0
- {flagsmith-6.2.2 → flagsmith-6.3.0}/flagsmith/webhooks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flagsmith
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.3.0
|
|
4
4
|
Summary: Flagsmith Python SDK
|
|
5
5
|
License: BSD3
|
|
6
6
|
License-File: LICENSE
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
18
19
|
Requires-Dist: flagsmith-flag-engine (>=11.0.0,<12.0.0)
|
|
19
20
|
Requires-Dist: iso8601 (>=2.1.0,<3.0.0) ; python_version < "3.11"
|
|
20
21
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
@@ -8,7 +8,7 @@ from datetime import datetime
|
|
|
8
8
|
|
|
9
9
|
from requests_futures.sessions import FuturesSession # type: ignore
|
|
10
10
|
|
|
11
|
-
from flagsmith.version import __version__
|
|
11
|
+
from flagsmith.version import DEFAULT_USER_AGENT, __version__
|
|
12
12
|
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
@@ -218,7 +218,7 @@ class EventProcessor:
|
|
|
218
218
|
headers={
|
|
219
219
|
"Content-Type": "application/json; charset=utf-8",
|
|
220
220
|
"X-Environment-Key": self._environment_key,
|
|
221
|
-
"Flagsmith-SDK-User-Agent":
|
|
221
|
+
"Flagsmith-SDK-User-Agent": DEFAULT_USER_AGENT,
|
|
222
222
|
},
|
|
223
223
|
)
|
|
224
224
|
except RuntimeError:
|
|
@@ -41,13 +41,12 @@ from flagsmith.types import (
|
|
|
41
41
|
TraitMapping,
|
|
42
42
|
)
|
|
43
43
|
from flagsmith.utils.identities import generate_identity_data
|
|
44
|
-
from flagsmith.version import
|
|
44
|
+
from flagsmith.version import DEFAULT_USER_AGENT
|
|
45
45
|
|
|
46
46
|
logger = logging.getLogger(__name__)
|
|
47
47
|
|
|
48
48
|
DEFAULT_API_URL = "https://edge.api.flagsmith.com/api/v1/"
|
|
49
49
|
DEFAULT_REALTIME_API_URL = "https://realtime.flagsmith.com/"
|
|
50
|
-
DEFAULT_USER_AGENT = f"flagsmith-python-sdk/{__version__}"
|
|
51
50
|
|
|
52
51
|
|
|
53
52
|
class Flagsmith:
|
|
@@ -369,7 +368,9 @@ class Flagsmith:
|
|
|
369
368
|
Resolve a flag for an identity and record an exposure event.
|
|
370
369
|
|
|
371
370
|
The exposure event's ``value`` is the flag's variant key. It is only
|
|
372
|
-
sent when the flag exists, is enabled and
|
|
371
|
+
sent when the flag exists, is enabled and the identity is enrolled in
|
|
372
|
+
the feature's experiment (``flag.experiment.in_experiment``) with a
|
|
373
|
+
variant; any
|
|
373
374
|
other outcome is logged and skipped to keep experimentation data
|
|
374
375
|
clean. A `DefaultFlag` served via the `default_flag_handler` counts
|
|
375
376
|
as the feature not existing.
|
|
@@ -389,6 +390,12 @@ class Flagsmith:
|
|
|
389
390
|
FLAG_EXPOSURE_EVENT,
|
|
390
391
|
feature_name,
|
|
391
392
|
)
|
|
393
|
+
elif not (flag.experiment and flag.experiment.in_experiment):
|
|
394
|
+
logger.debug(
|
|
395
|
+
"Not sending %s for feature %s: identity is not in a running experiment.",
|
|
396
|
+
FLAG_EXPOSURE_EVENT,
|
|
397
|
+
feature_name,
|
|
398
|
+
)
|
|
392
399
|
elif flag.variant is None:
|
|
393
400
|
logger.debug(
|
|
394
401
|
"Not sending %s for feature %s: flag has no variant.",
|
|
@@ -401,6 +408,7 @@ class Flagsmith:
|
|
|
401
408
|
identifier=identifier,
|
|
402
409
|
value=flag.variant,
|
|
403
410
|
traits=traits,
|
|
411
|
+
metadata={"experiment_id": flag.experiment.id},
|
|
404
412
|
)
|
|
405
413
|
return flag
|
|
406
414
|
|
|
@@ -41,6 +41,28 @@ def build_segment_overrides_index(
|
|
|
41
41
|
return index
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class ExperimentMetadata:
|
|
46
|
+
"""The running experiment a flag was evaluated under; identity evaluations only."""
|
|
47
|
+
|
|
48
|
+
id: int
|
|
49
|
+
name: str
|
|
50
|
+
in_experiment: bool
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_api_metadata(
|
|
54
|
+
cls,
|
|
55
|
+
metadata: typing.Optional[typing.Mapping[str, typing.Any]],
|
|
56
|
+
) -> typing.Optional[ExperimentMetadata]:
|
|
57
|
+
if not metadata or not (experiment := metadata.get("experiment")):
|
|
58
|
+
return None
|
|
59
|
+
return cls(
|
|
60
|
+
id=experiment["id"],
|
|
61
|
+
name=experiment["name"],
|
|
62
|
+
in_experiment=experiment["in_experiment"],
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
44
66
|
@dataclass
|
|
45
67
|
class BaseFlag:
|
|
46
68
|
enabled: bool
|
|
@@ -59,6 +81,7 @@ class Flag(BaseFlag):
|
|
|
59
81
|
variant: typing.Optional[str] = None
|
|
60
82
|
reason: typing.Optional[str] = None
|
|
61
83
|
is_default: bool = field(default=False)
|
|
84
|
+
experiment: typing.Optional[ExperimentMetadata] = None
|
|
62
85
|
|
|
63
86
|
@classmethod
|
|
64
87
|
def from_evaluation_result(
|
|
@@ -88,6 +111,7 @@ class Flag(BaseFlag):
|
|
|
88
111
|
feature_id=flag_data["feature"]["id"],
|
|
89
112
|
variant=flag_data.get("variant"),
|
|
90
113
|
reason=flag_data.get("reason"),
|
|
114
|
+
experiment=ExperimentMetadata.from_api_metadata(flag_data.get("metadata")),
|
|
91
115
|
)
|
|
92
116
|
|
|
93
117
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|