flagsmith-common 3.1.0__tar.gz → 3.2.1__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_common-3.1.0 → flagsmith_common-3.2.1}/PKG-INFO +3 -2
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/pyproject.toml +3 -2
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/utils.py +2 -2
- flagsmith_common-3.2.1/src/flagsmith_schemas/api.py +217 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/dynamodb.py +4 -5
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/types.py +13 -26
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/models.py +17 -1
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/views.py +2 -2
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/LICENSE +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/README.md +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/app.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/cli/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/cli/healthcheck.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/constants.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/logging.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/main.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/docgen.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/start.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/waitfordb.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/metrics.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/middleware.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/templates/docgen-metrics.md +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/urls.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/utils.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/views.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/environments/permissions.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/multivariate/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/multivariate/serializers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/serializers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/versioning/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/versioning/serializers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/conf.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/constants.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/logging.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/metrics.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/gunicorn/middleware.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/migrations/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/migrations/helpers/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/migrations/helpers/postgres_helpers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/organisations/permissions.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/projects/permissions.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/prometheus/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/prometheus/utils.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/py.typed +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/test_tools/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/test_tools/plugin.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/test_tools/types.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/test_tools/utils.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/types.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/constants.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/py.typed +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/pydantic_types.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/flagsmith_schemas/validators.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/admin.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/apps.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/decorators.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/exceptions.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/health.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/managers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/metrics.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0001_initial.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0002_healthcheckmodel.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0003_add_completed_to_task.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0004_recreate_task_indexes.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0005_update_conditional_index_conditions.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0006_auto_20230221_0802.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0007_add_is_locked.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0008_add_get_task_to_process_function.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0009_add_recurring_task_run_first_run_at.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0010_task_priority.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0011_add_priority_to_get_tasks_to_process.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0012_add_locked_at_and_timeout.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0013_add_last_picked_at.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/0008_get_recurring_tasks_to_process.sql +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/0008_get_tasks_to_process.sql +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/0011_get_tasks_to_process.sql +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/0013_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/__init__.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/monitoring.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/processor.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/py.typed +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/routers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/serializers.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/task_registry.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/task_run_method.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/tasks.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/threads.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/types.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/urls.py +0 -0
- {flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flagsmith-common
|
|
3
|
-
Version: 3.1
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Flagsmith's common library
|
|
5
5
|
Author: Matthew Elwell, Gagan Trivedi, Kim Gustyr, Zach Aysan, Francesco Lo Franco, Rodrigo López Dato, Evandro Myller, Wadii Zaim
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -13,8 +13,8 @@ Requires-Dist: django>4,<6 ; extra == 'common-core'
|
|
|
13
13
|
Requires-Dist: django-health-check ; extra == 'common-core'
|
|
14
14
|
Requires-Dist: djangorestframework-recursive ; extra == 'common-core'
|
|
15
15
|
Requires-Dist: djangorestframework ; extra == 'common-core'
|
|
16
|
+
Requires-Dist: drf-spectacular>=0.28.0,<1 ; extra == 'common-core'
|
|
16
17
|
Requires-Dist: drf-writable-nested ; extra == 'common-core'
|
|
17
|
-
Requires-Dist: drf-yasg>=1.21.10,<2.0.0 ; extra == 'common-core'
|
|
18
18
|
Requires-Dist: environs<15 ; extra == 'common-core'
|
|
19
19
|
Requires-Dist: gunicorn>=19.1 ; extra == 'common-core'
|
|
20
20
|
Requires-Dist: prometheus-client>=0.0.16 ; extra == 'common-core'
|
|
@@ -22,6 +22,7 @@ Requires-Dist: psycopg2-binary>=2.9,<3 ; extra == 'common-core'
|
|
|
22
22
|
Requires-Dist: requests ; extra == 'common-core'
|
|
23
23
|
Requires-Dist: simplejson>=3,<4 ; extra == 'common-core'
|
|
24
24
|
Requires-Dist: typing-extensions ; extra == 'flagsmith-schemas'
|
|
25
|
+
Requires-Dist: flagsmith-flag-engine>6 ; extra == 'flagsmith-schemas'
|
|
25
26
|
Requires-Dist: backoff>=2.2.1,<3.0.0 ; extra == 'task-processor'
|
|
26
27
|
Requires-Dist: django>4,<6 ; extra == 'task-processor'
|
|
27
28
|
Requires-Dist: django-health-check ; extra == 'task-processor'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flagsmith-common"
|
|
3
|
-
version = "3.1
|
|
3
|
+
version = "3.2.1"
|
|
4
4
|
description = "Flagsmith's common library"
|
|
5
5
|
requires-python = ">=3.11,<4.0"
|
|
6
6
|
dependencies = []
|
|
@@ -12,8 +12,8 @@ optional-dependencies = { test-tools = [
|
|
|
12
12
|
"django-health-check",
|
|
13
13
|
"djangorestframework-recursive",
|
|
14
14
|
"djangorestframework",
|
|
15
|
+
"drf-spectacular (>=0.28.0,<1)",
|
|
15
16
|
"drf-writable-nested",
|
|
16
|
-
"drf-yasg (>=1.21.10,<2.0.0)",
|
|
17
17
|
"environs (<15)",
|
|
18
18
|
"gunicorn (>=19.1)",
|
|
19
19
|
"prometheus-client (>=0.0.16)",
|
|
@@ -27,6 +27,7 @@ optional-dependencies = { test-tools = [
|
|
|
27
27
|
"prometheus-client (>=0.0.16)",
|
|
28
28
|
], flagsmith-schemas = [
|
|
29
29
|
"typing_extensions",
|
|
30
|
+
"flagsmith-flag-engine>6",
|
|
30
31
|
] }
|
|
31
32
|
authors = [
|
|
32
33
|
{ name = "Matthew Elwell" },
|
|
@@ -6,7 +6,7 @@ from typing import Any
|
|
|
6
6
|
from django.core.handlers.wsgi import WSGIHandler
|
|
7
7
|
from django.core.wsgi import get_wsgi_application
|
|
8
8
|
from django.http import HttpRequest
|
|
9
|
-
from
|
|
9
|
+
from drf_spectacular.generators import EndpointEnumerator
|
|
10
10
|
from environs import Env
|
|
11
11
|
from gunicorn.app.wsgiapp import ( # type: ignore[import-untyped]
|
|
12
12
|
WSGIApplication as GunicornWSGIApplication,
|
|
@@ -77,7 +77,7 @@ def get_route_template(route: str) -> str:
|
|
|
77
77
|
`"^api/v1/environments/(?P<environment_api_key>[^/.]+)/api-keys/$"` ->
|
|
78
78
|
`"/api/v1/environments/{environment_api_key}/api-keys/"`
|
|
79
79
|
"""
|
|
80
|
-
route_template: str = EndpointEnumerator().get_path_from_regex(route)
|
|
80
|
+
route_template: str = EndpointEnumerator().get_path_from_regex(route) # type: ignore[no-untyped-call]
|
|
81
81
|
return route_template
|
|
82
82
|
|
|
83
83
|
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The types in this module describe Flagsmith SDK API request and response schemas.
|
|
3
|
+
The docstrings here comprise user-facing documentation for these types.
|
|
4
|
+
|
|
5
|
+
The types are used by:
|
|
6
|
+
- SDK API OpenAPI schema generation.
|
|
7
|
+
- Flagsmith's API and SDK implementations written in Python.
|
|
8
|
+
|
|
9
|
+
These types can be used with for validation and serialization
|
|
10
|
+
with any library that supports TypedDict, such as Pydantic or typeguard.
|
|
11
|
+
|
|
12
|
+
When updating this module, ensure that the changes are backwards compatible.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from flag_engine.engine import ContextValue
|
|
16
|
+
from flag_engine.segments.types import ConditionOperator, RuleType
|
|
17
|
+
from typing_extensions import NotRequired, TypedDict
|
|
18
|
+
|
|
19
|
+
from flagsmith_schemas.types import FeatureType, FeatureValue, UUIDStr
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Feature(TypedDict):
|
|
23
|
+
"""Represents a Flagsmith feature, defined at project level."""
|
|
24
|
+
|
|
25
|
+
id: int
|
|
26
|
+
"""Unique identifier for the feature in Core."""
|
|
27
|
+
name: str
|
|
28
|
+
"""Name of the feature. Must be unique within a project."""
|
|
29
|
+
type: FeatureType
|
|
30
|
+
"""Feature type."""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MultivariateFeatureOption(TypedDict):
|
|
34
|
+
"""Represents a single multivariate feature option in the Flagsmith UI."""
|
|
35
|
+
|
|
36
|
+
value: str
|
|
37
|
+
"""The feature state value that should be served when this option's parent multivariate feature state is selected by the engine."""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class MultivariateFeatureStateValue(TypedDict):
|
|
41
|
+
"""Represents a multivariate feature state value."""
|
|
42
|
+
|
|
43
|
+
id: int | None
|
|
44
|
+
"""Unique identifier for the multivariate feature state value in Core. Used for multivariate bucketing. If feature state created via `edge-identities` APIs in Core, this can be missing or `None`."""
|
|
45
|
+
mv_fs_value_uuid: UUIDStr | None
|
|
46
|
+
"""The UUID for this multivariate feature state value. Should be used for multivariate bucketing if `id` is null."""
|
|
47
|
+
percentage_allocation: float
|
|
48
|
+
"""The percentage allocation for this multivariate feature state value. Should be between or equal to 0 and 100; total percentage allocation of grouped `MultivariateFeatureStateValue` must not exceed 100."""
|
|
49
|
+
multivariate_feature_option: MultivariateFeatureOption
|
|
50
|
+
"""The multivariate feature option that this value corresponds to."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class FeatureSegment(TypedDict):
|
|
54
|
+
"""Represents data specific to a segment feature override."""
|
|
55
|
+
|
|
56
|
+
priority: int | None
|
|
57
|
+
"""The priority of this segment feature override. Lower numbers indicate stronger priority. If null or not set, the weakest priority is assumed."""
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class FeatureState(TypedDict):
|
|
61
|
+
"""Used to define the state of a feature for an environment, segment overrides, and identity overrides."""
|
|
62
|
+
|
|
63
|
+
feature: Feature
|
|
64
|
+
"""The feature that this feature state is for."""
|
|
65
|
+
enabled: bool
|
|
66
|
+
"""Whether the feature is enabled or disabled."""
|
|
67
|
+
feature_state_value: FeatureValue
|
|
68
|
+
"""The value for this feature state."""
|
|
69
|
+
featurestate_uuid: UUIDStr
|
|
70
|
+
"""The UUID for this feature state."""
|
|
71
|
+
feature_segment: FeatureSegment | None
|
|
72
|
+
"""Segment override data, if this feature state is for a segment override."""
|
|
73
|
+
multivariate_feature_state_values: list[MultivariateFeatureStateValue]
|
|
74
|
+
"""List of multivariate feature state values, if this feature state is for a multivariate feature."""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class Trait(TypedDict):
|
|
78
|
+
"""Represents a key-value pair associated with an identity."""
|
|
79
|
+
|
|
80
|
+
trait_key: str
|
|
81
|
+
"""Key of the trait."""
|
|
82
|
+
trait_value: ContextValue
|
|
83
|
+
"""Value of the trait."""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SegmentCondition(TypedDict):
|
|
87
|
+
"""Represents a condition within a segment rule used by Flagsmith engine."""
|
|
88
|
+
|
|
89
|
+
operator: ConditionOperator
|
|
90
|
+
"""Operator to be applied for this condition."""
|
|
91
|
+
value: str
|
|
92
|
+
"""Value to be compared against in this condition. May be `None` for `IS_SET` and `IS_NOT_SET` operators."""
|
|
93
|
+
property_: str
|
|
94
|
+
"""The property (context key) this condition applies to. May be `None` for the `PERCENTAGE_SPLIT` operator.
|
|
95
|
+
|
|
96
|
+
Named `property_` for legacy reasons.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class SegmentRule(TypedDict):
|
|
101
|
+
"""Represents a rule within a segment used by Flagsmith engine. Root rules usually contain nested rules."""
|
|
102
|
+
|
|
103
|
+
type: RuleType
|
|
104
|
+
"""Type of the rule, defining how conditions are evaluated."""
|
|
105
|
+
rules: "list[SegmentRule]"
|
|
106
|
+
"""Nested rules within this rule."""
|
|
107
|
+
conditions: list[SegmentCondition]
|
|
108
|
+
"""Conditions that must be met for this rule, evaluated based on the rule type."""
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class Segment(TypedDict):
|
|
112
|
+
"""Represents a Flagsmith segment. Carries rules and feature overrides."""
|
|
113
|
+
|
|
114
|
+
id: int
|
|
115
|
+
"""Unique identifier for the segment in Core."""
|
|
116
|
+
name: str
|
|
117
|
+
"""Segment name."""
|
|
118
|
+
rules: list[SegmentRule]
|
|
119
|
+
"""List of rules within the segment."""
|
|
120
|
+
feature_states: NotRequired[list[FeatureState]]
|
|
121
|
+
"""List of segment overrides."""
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class Project(TypedDict):
|
|
125
|
+
"""Represents a Flagsmith project. For SDKs, this is mainly used to convey segment data."""
|
|
126
|
+
|
|
127
|
+
segments: list[Segment]
|
|
128
|
+
"""List of segments."""
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class IdentityOverride(TypedDict):
|
|
132
|
+
"""Represents an identity override, defining feature states specific to an identity."""
|
|
133
|
+
|
|
134
|
+
identifier: str
|
|
135
|
+
"""Unique identifier for the identity."""
|
|
136
|
+
identity_features: list[FeatureState]
|
|
137
|
+
"""List of identity overrides for this identity."""
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class TraitInput(TypedDict):
|
|
141
|
+
"""Represents a key-value pair trait provided as input when creating or updating an identity."""
|
|
142
|
+
|
|
143
|
+
trait_key: str
|
|
144
|
+
"""Trait key."""
|
|
145
|
+
trait_value: ContextValue
|
|
146
|
+
"""Trait value. If `null`, the trait will be deleted."""
|
|
147
|
+
transient: NotRequired[bool | None]
|
|
148
|
+
"""Whether this trait is transient (not persisted). Defaults to `false`."""
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class V1Flag(TypedDict):
|
|
152
|
+
"""Represents a single flag (feature state) returned by the Flagsmith SDK."""
|
|
153
|
+
|
|
154
|
+
feature: Feature
|
|
155
|
+
"""The feature that this flag represents."""
|
|
156
|
+
enabled: bool
|
|
157
|
+
"""Whether the feature is enabled or disabled."""
|
|
158
|
+
feature_state_value: FeatureValue
|
|
159
|
+
"""The value for this feature state."""
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
### Root request schemas below. ###
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class V1IdentitiesRequest(TypedDict):
|
|
166
|
+
"""`/api/v1/identities/` request.
|
|
167
|
+
|
|
168
|
+
Used to retrieve flags for an identity and store its traits.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
identifier: str
|
|
172
|
+
"""Unique identifier for the identity."""
|
|
173
|
+
traits: NotRequired[list[TraitInput] | None]
|
|
174
|
+
"""List of traits to set for the identity. If `null` or not provided, no traits are set or updated."""
|
|
175
|
+
transient: NotRequired[bool | None]
|
|
176
|
+
"""Whether the identity is transient (not persisted). Defaults to `false`."""
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
### Root response schemas below. ###
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class V1EnvironmentDocumentResponse(TypedDict):
|
|
183
|
+
"""`/api/v1/environment-documents/` response.
|
|
184
|
+
|
|
185
|
+
Powers Flagsmith SDK's local evaluation mode.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
api_key: str
|
|
189
|
+
"""Public client-side API key for the environment, used to identify it."""
|
|
190
|
+
feature_states: list[FeatureState]
|
|
191
|
+
"""List of feature states representing the environment defaults."""
|
|
192
|
+
identity_overrides: list[IdentityOverride]
|
|
193
|
+
"""List of identity overrides defined for this environment."""
|
|
194
|
+
name: str
|
|
195
|
+
"""Environment name."""
|
|
196
|
+
project: Project
|
|
197
|
+
"""Project-specific data for this environment."""
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
V1FlagsResponse = list[V1Flag]
|
|
201
|
+
"""`/api/v1/flags/` response.
|
|
202
|
+
|
|
203
|
+
A list of flags for the specified environment."""
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class V1IdentitiesResponse(TypedDict):
|
|
207
|
+
"""`/api/v1/identities/` response.
|
|
208
|
+
|
|
209
|
+
Represents the identity created or updated, along with its flags.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
identifier: str
|
|
213
|
+
"""Unique identifier for the identity."""
|
|
214
|
+
flags: list[V1Flag]
|
|
215
|
+
"""List of flags (feature states) for the identity."""
|
|
216
|
+
traits: list[Trait]
|
|
217
|
+
"""List of traits associated with the identity."""
|
|
@@ -9,18 +9,17 @@ Otherwise, they serve as documentation for the structure of the data stored in D
|
|
|
9
9
|
|
|
10
10
|
from typing import Annotated, Literal
|
|
11
11
|
|
|
12
|
+
from flag_engine.segments.types import ConditionOperator, RuleType
|
|
12
13
|
from typing_extensions import NotRequired, TypedDict
|
|
13
14
|
|
|
14
15
|
from flagsmith_schemas.constants import PYDANTIC_INSTALLED
|
|
15
16
|
from flagsmith_schemas.types import (
|
|
16
|
-
ConditionOperator,
|
|
17
17
|
DateTimeStr,
|
|
18
18
|
DynamoContextValue,
|
|
19
19
|
DynamoFeatureValue,
|
|
20
20
|
DynamoFloat,
|
|
21
21
|
DynamoInt,
|
|
22
22
|
FeatureType,
|
|
23
|
-
RuleType,
|
|
24
23
|
UUIDStr,
|
|
25
24
|
)
|
|
26
25
|
|
|
@@ -99,9 +98,9 @@ class Trait(TypedDict):
|
|
|
99
98
|
"""Represents a key-value pair associated with an identity."""
|
|
100
99
|
|
|
101
100
|
trait_key: str
|
|
102
|
-
"""
|
|
101
|
+
"""Trait key."""
|
|
103
102
|
trait_value: DynamoContextValue
|
|
104
|
-
"""
|
|
103
|
+
"""Trait value."""
|
|
105
104
|
|
|
106
105
|
|
|
107
106
|
class SegmentCondition(TypedDict):
|
|
@@ -138,7 +137,7 @@ class Segment(TypedDict):
|
|
|
138
137
|
"""Name of the segment."""
|
|
139
138
|
rules: list[SegmentRule]
|
|
140
139
|
"""List of rules within the segment."""
|
|
141
|
-
feature_states: list[FeatureState]
|
|
140
|
+
feature_states: NotRequired[list[FeatureState]]
|
|
142
141
|
"""List of segment overrides."""
|
|
143
142
|
|
|
144
143
|
|
|
@@ -4,6 +4,8 @@ from typing import TYPE_CHECKING, Annotated, Literal, TypeAlias
|
|
|
4
4
|
from flagsmith_schemas.constants import PYDANTIC_INSTALLED
|
|
5
5
|
|
|
6
6
|
if PYDANTIC_INSTALLED:
|
|
7
|
+
from pydantic import WithJsonSchema
|
|
8
|
+
|
|
7
9
|
from flagsmith_schemas.pydantic_types import (
|
|
8
10
|
ValidateDecimalAsFloat,
|
|
9
11
|
ValidateDecimalAsInt,
|
|
@@ -15,6 +17,9 @@ elif not TYPE_CHECKING:
|
|
|
15
17
|
# This code runs at runtime when Pydantic is not installed.
|
|
16
18
|
# We could use PEP 649 strings with `Annotated`, but Pydantic is inconsistent in how it parses them.
|
|
17
19
|
# Define dummy types instead.
|
|
20
|
+
def WithJsonSchema(_: object) -> object:
|
|
21
|
+
return ...
|
|
22
|
+
|
|
18
23
|
ValidateDecimalAsFloat = ...
|
|
19
24
|
ValidateDecimalAsInt = ...
|
|
20
25
|
ValidateDynamoFeatureStateValue = ...
|
|
@@ -36,7 +41,11 @@ DynamoDB represents all numbers as `Decimal`.
|
|
|
36
41
|
`DynamoFloat` indicates that the value should be treated as a float.
|
|
37
42
|
"""
|
|
38
43
|
|
|
39
|
-
UUIDStr: TypeAlias = Annotated[
|
|
44
|
+
UUIDStr: TypeAlias = Annotated[
|
|
45
|
+
str,
|
|
46
|
+
ValidateStrAsUUID,
|
|
47
|
+
WithJsonSchema({"type": "string", "format": "uuid"}),
|
|
48
|
+
]
|
|
40
49
|
"""A string representing a UUID."""
|
|
41
50
|
|
|
42
51
|
DateTimeStr: TypeAlias = Annotated[str, ValidateStrAsISODateTime]
|
|
@@ -49,7 +58,7 @@ DynamoFeatureValue: TypeAlias = Annotated[
|
|
|
49
58
|
DynamoInt | bool | str | None,
|
|
50
59
|
ValidateDynamoFeatureStateValue,
|
|
51
60
|
]
|
|
52
|
-
"""Represents the value of a Flagsmith feature. Can be stored a boolean, an integer, or a string.
|
|
61
|
+
"""Represents the value of a Flagsmith feature stored in DynamoDB. Can be stored a boolean, an integer, or a string.
|
|
53
62
|
|
|
54
63
|
The default (SaaS) maximum length for strings is 20000 characters.
|
|
55
64
|
"""
|
|
@@ -65,27 +74,5 @@ Here's how we store different types:
|
|
|
65
74
|
This type does not include complex structures like lists or dictionaries.
|
|
66
75
|
"""
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"GREATER_THAN",
|
|
71
|
-
"LESS_THAN",
|
|
72
|
-
"LESS_THAN_INCLUSIVE",
|
|
73
|
-
"CONTAINS",
|
|
74
|
-
"GREATER_THAN_INCLUSIVE",
|
|
75
|
-
"NOT_CONTAINS",
|
|
76
|
-
"NOT_EQUAL",
|
|
77
|
-
"REGEX",
|
|
78
|
-
"PERCENTAGE_SPLIT",
|
|
79
|
-
"MODULO",
|
|
80
|
-
"IS_SET",
|
|
81
|
-
"IS_NOT_SET",
|
|
82
|
-
"IN",
|
|
83
|
-
]
|
|
84
|
-
"""Represents segment condition operators used by Flagsmith engine."""
|
|
85
|
-
|
|
86
|
-
RuleType = Literal[
|
|
87
|
-
"ALL",
|
|
88
|
-
"ANY",
|
|
89
|
-
"NONE",
|
|
90
|
-
]
|
|
91
|
-
"""Represents segment rule types used by Flagsmith engine."""
|
|
77
|
+
FeatureValue: TypeAlias = int | bool | str | None
|
|
78
|
+
"""Represents the value of a Flagsmith feature. Can be stored a boolean, an integer, or a string."""
|
|
@@ -180,7 +180,23 @@ class RecurringTask(AbstractBaseTask):
|
|
|
180
180
|
# If we have never run this task, then we should execute it only if
|
|
181
181
|
# the time has passed after which we want to ensure this task runs.
|
|
182
182
|
# This allows us to control when intensive tasks should be run.
|
|
183
|
-
|
|
183
|
+
if not self.first_run_time:
|
|
184
|
+
return True
|
|
185
|
+
first_run_today = now.replace(
|
|
186
|
+
hour=self.first_run_time.hour,
|
|
187
|
+
minute=self.first_run_time.minute,
|
|
188
|
+
second=self.first_run_time.second,
|
|
189
|
+
microsecond=self.first_run_time.microsecond,
|
|
190
|
+
)
|
|
191
|
+
# Handle midnight boundary using 12-hour window heuristic.
|
|
192
|
+
time_difference = (now - first_run_today).total_seconds()
|
|
193
|
+
if time_difference > 12 * 3600:
|
|
194
|
+
# first_run_today appears far in the past; it refers to tomorrow.
|
|
195
|
+
return False
|
|
196
|
+
if time_difference < -12 * 3600:
|
|
197
|
+
# first_run_today appears far in the future; it refers to yesterday.
|
|
198
|
+
return True
|
|
199
|
+
return now >= first_run_today
|
|
184
200
|
|
|
185
201
|
# if the last run was at t- run_every, then we should execute it
|
|
186
202
|
if (timezone.now() - last_task_run.started_at) >= self.run_every:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from drf_spectacular.utils import extend_schema
|
|
4
4
|
from rest_framework.decorators import api_view, permission_classes
|
|
5
5
|
from rest_framework.permissions import IsAdminUser, IsAuthenticated
|
|
6
6
|
from rest_framework.request import Request
|
|
@@ -10,7 +10,7 @@ from task_processor.monitoring import get_num_waiting_tasks
|
|
|
10
10
|
from task_processor.serializers import MonitoringSerializer
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
@
|
|
13
|
+
@extend_schema(methods=["GET"], responses={200: MonitoringSerializer()})
|
|
14
14
|
@api_view(http_method_names=["GET"])
|
|
15
15
|
@permission_classes([IsAuthenticated, IsAdminUser])
|
|
16
16
|
def monitoring(request: Request, /, **kwargs: Any) -> Response:
|
|
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
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/docgen.py
RENAMED
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/start.py
RENAMED
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/management/commands/waitfordb.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/core/templates/docgen-metrics.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/multivariate/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/multivariate/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/versioning/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/features/versioning/serializers.py
RENAMED
|
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
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/common/migrations/helpers/postgres_helpers.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/0001_initial.py
RENAMED
|
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
|
|
File without changes
|
{flagsmith_common-3.1.0 → flagsmith_common-3.2.1}/src/task_processor/migrations/sql/__init__.py
RENAMED
|
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
|