flagsmith 6.2.3__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.3 → flagsmith-6.3.0}/PKG-INFO +2 -1
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/flagsmith.py +10 -1
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/models.py +24 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/pyproject.toml +1 -1
- {flagsmith-6.2.3 → flagsmith-6.3.0}/LICENSE +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/README.md +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/__init__.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/analytics.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/api/__init__.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/api/types.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/exceptions.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/mappers.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/offline_handlers.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/polling_manager.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/py.typed +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/streaming_manager.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/types.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/utils/__init__.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/utils/datetime.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/utils/identities.py +0 -0
- {flagsmith-6.2.3 → flagsmith-6.3.0}/flagsmith/version.py +0 -0
- {flagsmith-6.2.3 → 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)
|
|
@@ -368,7 +368,9 @@ class Flagsmith:
|
|
|
368
368
|
Resolve a flag for an identity and record an exposure event.
|
|
369
369
|
|
|
370
370
|
The exposure event's ``value`` is the flag's variant key. It is only
|
|
371
|
-
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
|
|
372
374
|
other outcome is logged and skipped to keep experimentation data
|
|
373
375
|
clean. A `DefaultFlag` served via the `default_flag_handler` counts
|
|
374
376
|
as the feature not existing.
|
|
@@ -388,6 +390,12 @@ class Flagsmith:
|
|
|
388
390
|
FLAG_EXPOSURE_EVENT,
|
|
389
391
|
feature_name,
|
|
390
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
|
+
)
|
|
391
399
|
elif flag.variant is None:
|
|
392
400
|
logger.debug(
|
|
393
401
|
"Not sending %s for feature %s: flag has no variant.",
|
|
@@ -400,6 +408,7 @@ class Flagsmith:
|
|
|
400
408
|
identifier=identifier,
|
|
401
409
|
value=flag.variant,
|
|
402
410
|
traits=traits,
|
|
411
|
+
metadata={"experiment_id": flag.experiment.id},
|
|
403
412
|
)
|
|
404
413
|
return flag
|
|
405
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
|
|
File without changes
|
|
File without changes
|