flagsmith-common 3.0.0__tar.gz → 3.2.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.
Files changed (100) hide show
  1. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/PKG-INFO +5 -2
  2. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/pyproject.toml +8 -5
  3. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/utils.py +2 -2
  4. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/test_tools/plugin.py +12 -10
  5. flagsmith_common-3.2.0/src/flagsmith_schemas/api.py +217 -0
  6. flagsmith_common-3.2.0/src/flagsmith_schemas/constants.py +4 -0
  7. flagsmith_common-3.2.0/src/flagsmith_schemas/dynamodb.py +345 -0
  8. flagsmith_common-3.2.0/src/flagsmith_schemas/pydantic_types.py +22 -0
  9. flagsmith_common-3.2.0/src/flagsmith_schemas/types.py +78 -0
  10. flagsmith_common-3.2.0/src/flagsmith_schemas/validators.py +55 -0
  11. flagsmith_common-3.2.0/src/task_processor/migrations/sql/__init__.py +0 -0
  12. flagsmith_common-3.2.0/src/task_processor/py.typed +0 -0
  13. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/views.py +2 -2
  14. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/LICENSE +0 -0
  15. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/README.md +0 -0
  16. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/__init__.py +0 -0
  17. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/__init__.py +0 -0
  18. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/app.py +0 -0
  19. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/cli/__init__.py +0 -0
  20. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/cli/healthcheck.py +0 -0
  21. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/constants.py +0 -0
  22. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/logging.py +0 -0
  23. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/main.py +0 -0
  24. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/management/__init__.py +0 -0
  25. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/management/commands/__init__.py +0 -0
  26. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/management/commands/docgen.py +0 -0
  27. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/management/commands/start.py +0 -0
  28. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/management/commands/waitfordb.py +0 -0
  29. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/metrics.py +0 -0
  30. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/middleware.py +0 -0
  31. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/templates/docgen-metrics.md +0 -0
  32. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/urls.py +0 -0
  33. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/utils.py +0 -0
  34. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/core/views.py +0 -0
  35. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/environments/permissions.py +0 -0
  36. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/__init__.py +0 -0
  37. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/multivariate/__init__.py +0 -0
  38. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/multivariate/serializers.py +0 -0
  39. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/serializers.py +0 -0
  40. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/versioning/__init__.py +0 -0
  41. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/features/versioning/serializers.py +0 -0
  42. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/__init__.py +0 -0
  43. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/conf.py +0 -0
  44. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/constants.py +0 -0
  45. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/logging.py +0 -0
  46. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/metrics.py +0 -0
  47. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/gunicorn/middleware.py +0 -0
  48. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/migrations/__init__.py +0 -0
  49. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/migrations/helpers/__init__.py +0 -0
  50. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/migrations/helpers/postgres_helpers.py +0 -0
  51. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/organisations/permissions.py +0 -0
  52. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/projects/permissions.py +0 -0
  53. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/prometheus/__init__.py +0 -0
  54. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/prometheus/utils.py +0 -0
  55. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/py.typed +0 -0
  56. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/test_tools/__init__.py +0 -0
  57. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/test_tools/types.py +0 -0
  58. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/test_tools/utils.py +0 -0
  59. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/common/types.py +0 -0
  60. {flagsmith_common-3.0.0/src/task_processor → flagsmith_common-3.2.0/src/flagsmith_schemas}/__init__.py +0 -0
  61. {flagsmith_common-3.0.0/src/task_processor → flagsmith_common-3.2.0/src/flagsmith_schemas}/py.typed +0 -0
  62. {flagsmith_common-3.0.0/src/task_processor/migrations → flagsmith_common-3.2.0/src/task_processor}/__init__.py +0 -0
  63. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/admin.py +0 -0
  64. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/apps.py +0 -0
  65. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/decorators.py +0 -0
  66. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/exceptions.py +0 -0
  67. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/health.py +0 -0
  68. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/managers.py +0 -0
  69. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/metrics.py +0 -0
  70. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0001_initial.py +0 -0
  71. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0002_healthcheckmodel.py +0 -0
  72. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0003_add_completed_to_task.py +0 -0
  73. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0004_recreate_task_indexes.py +0 -0
  74. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0005_update_conditional_index_conditions.py +0 -0
  75. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0006_auto_20230221_0802.py +0 -0
  76. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0007_add_is_locked.py +0 -0
  77. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0008_add_get_task_to_process_function.py +0 -0
  78. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0009_add_recurring_task_run_first_run_at.py +0 -0
  79. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0010_task_priority.py +0 -0
  80. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0011_add_priority_to_get_tasks_to_process.py +0 -0
  81. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0012_add_locked_at_and_timeout.py +0 -0
  82. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/0013_add_last_picked_at.py +0 -0
  83. {flagsmith_common-3.0.0/src/task_processor/migrations/sql → flagsmith_common-3.2.0/src/task_processor/migrations}/__init__.py +0 -0
  84. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/sql/0008_get_recurring_tasks_to_process.sql +0 -0
  85. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/sql/0008_get_tasks_to_process.sql +0 -0
  86. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/sql/0011_get_tasks_to_process.sql +0 -0
  87. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql +0 -0
  88. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/migrations/sql/0013_get_recurringtasks_to_process.sql +0 -0
  89. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/models.py +0 -0
  90. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/monitoring.py +0 -0
  91. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/processor.py +0 -0
  92. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/routers.py +0 -0
  93. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/serializers.py +0 -0
  94. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/task_registry.py +0 -0
  95. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/task_run_method.py +0 -0
  96. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/tasks.py +0 -0
  97. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/threads.py +0 -0
  98. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/types.py +0 -0
  99. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/src/task_processor/urls.py +0 -0
  100. {flagsmith_common-3.0.0 → flagsmith_common-3.2.0}/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.0.0
3
+ Version: 3.2.0
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,14 +13,16 @@ 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'
21
21
  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
+ Requires-Dist: typing-extensions ; extra == 'flagsmith-schemas'
25
+ Requires-Dist: flagsmith-flag-engine>10 ; extra == 'flagsmith-schemas'
24
26
  Requires-Dist: backoff>=2.2.1,<3.0.0 ; extra == 'task-processor'
25
27
  Requires-Dist: django>4,<6 ; extra == 'task-processor'
26
28
  Requires-Dist: django-health-check ; extra == 'task-processor'
@@ -36,6 +38,7 @@ Project-URL: Homepage, https://flagsmith.com
36
38
  Project-URL: Issues, https://github.com/flagsmith/flagsmith-common/issues
37
39
  Project-URL: Repository, https://github.com/flagsmith/flagsmith-common
38
40
  Provides-Extra: common-core
41
+ Provides-Extra: flagsmith-schemas
39
42
  Provides-Extra: task-processor
40
43
  Provides-Extra: test-tools
41
44
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flagsmith-common"
3
- version = "3.0.0"
3
+ version = "3.2.0"
4
4
  description = "Flagsmith's common library"
5
5
  requires-python = ">=3.11,<4.0"
6
6
  dependencies = []
@@ -12,20 +12,22 @@ 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)",
20
20
  "psycopg2-binary (>=2.9,<3)",
21
21
  "requests",
22
22
  "simplejson (>=3,<4)",
23
-
24
23
  ], task-processor = [
25
24
  "backoff (>=2.2.1,<3.0.0)",
26
25
  "django (>4,<6)",
27
26
  "django-health-check",
28
27
  "prometheus-client (>=0.0.16)",
28
+ ], flagsmith-schemas = [
29
+ "typing_extensions",
30
+ "flagsmith-flag-engine>10",
29
31
  ] }
30
32
  authors = [
31
33
  { name = "Matthew Elwell" },
@@ -68,6 +70,7 @@ dev = [
68
70
  "djangorestframework-stubs (>=3.15.3, <4.0.0)",
69
71
  "mypy (>=1.15.0, <2.0.0)",
70
72
  "pre-commit",
73
+ "pydantic>=2.12.5",
71
74
  "pyfakefs (>=5.7.4, <6.0.0)",
72
75
  "pytest (>=8.3.4, <9.0.0)",
73
76
  "pytest-asyncio (>=0.25.3, <1.0.0)",
@@ -77,8 +80,8 @@ dev = [
77
80
  "pytest-httpserver (>=1.1.3, <2.0.0)",
78
81
  "pytest-mock (>=3.14.0, <4.0.0)",
79
82
  "setuptools (>=78.1.1, <79.0.0)",
80
- "types-simplejson (>=3.20.0.20250326, <4.0.0)",
81
83
  "types-python-dateutil (>=2.9.0.20250516, <3.0.0)",
84
+ "types-simplejson (>=3.20.0.20250326, <4.0.0)",
82
85
  ]
83
86
 
84
87
  [build-system]
@@ -86,7 +89,7 @@ requires = ["uv_build>=0.9.17,<0.10.0"]
86
89
  build-backend = "uv_build"
87
90
 
88
91
  [tool.uv.build-backend]
89
- module-name = ["common", "task_processor"]
92
+ module-name = ["common", "task_processor", "flagsmith_schemas"]
90
93
 
91
94
  [tool.coverage.report]
92
95
  # Regexes for lines to exclude from consideration
@@ -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 drf_yasg.generators import EndpointEnumerator # type: ignore[import-untyped]
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
 
@@ -1,11 +1,7 @@
1
1
  from functools import partial
2
- from typing import Generator
2
+ from typing import TYPE_CHECKING, Generator
3
3
 
4
- import prometheus_client
5
4
  import pytest
6
- from prometheus_client.metrics import MetricWrapperBase
7
- from pyfakefs.fake_filesystem import FakeFilesystem
8
- from pytest_django.fixtures import SettingsWrapper
9
5
 
10
6
  from common.test_tools.types import (
11
7
  AssertMetricFixture,
@@ -15,6 +11,10 @@ from common.test_tools.types import (
15
11
  )
16
12
  from task_processor.task_run_method import TaskRunMethod
17
13
 
14
+ if TYPE_CHECKING:
15
+ from pyfakefs.fake_filesystem import FakeFilesystem
16
+ from pytest_django.fixtures import SettingsWrapper
17
+
18
18
 
19
19
  def pytest_addoption(parser: pytest.Parser) -> None:
20
20
  group = parser.getgroup("snapshot")
@@ -26,12 +26,14 @@ def pytest_addoption(parser: pytest.Parser) -> None:
26
26
 
27
27
 
28
28
  def assert_metric_impl() -> Generator[AssertMetricFixture, None, None]:
29
+ import prometheus_client
30
+
29
31
  registry = prometheus_client.REGISTRY
30
32
  collectors = [*registry._collector_to_names]
31
33
 
32
34
  # Reset registry state
33
35
  for collector in collectors:
34
- if isinstance(collector, MetricWrapperBase):
36
+ if isinstance(collector, prometheus_client.metrics.MetricWrapperBase):
35
37
  collector.clear()
36
38
 
37
39
  def _assert_metric(
@@ -53,7 +55,7 @@ assert_metric = pytest.fixture(assert_metric_impl)
53
55
 
54
56
 
55
57
  @pytest.fixture()
56
- def saas_mode(fs: FakeFilesystem) -> Generator[None, None, None]:
58
+ def saas_mode(fs: "FakeFilesystem") -> Generator[None, None, None]:
57
59
  from common.core.utils import is_saas
58
60
 
59
61
  is_saas.cache_clear()
@@ -65,7 +67,7 @@ def saas_mode(fs: FakeFilesystem) -> Generator[None, None, None]:
65
67
 
66
68
 
67
69
  @pytest.fixture()
68
- def enterprise_mode(fs: FakeFilesystem) -> Generator[None, None, None]:
70
+ def enterprise_mode(fs: "FakeFilesystem") -> Generator[None, None, None]:
69
71
  from common.core.utils import is_enterprise
70
72
 
71
73
  is_enterprise.cache_clear()
@@ -77,7 +79,7 @@ def enterprise_mode(fs: FakeFilesystem) -> Generator[None, None, None]:
77
79
 
78
80
 
79
81
  @pytest.fixture()
80
- def task_processor_mode(settings: SettingsWrapper) -> None:
82
+ def task_processor_mode(settings: "SettingsWrapper") -> None:
81
83
  settings.TASK_PROCESSOR_MODE = True
82
84
  # The setting is supposed to be set before the metrics module is imported,
83
85
  # so reload it
@@ -101,7 +103,7 @@ def flagsmith_markers_marked(
101
103
 
102
104
  @pytest.fixture(name="run_tasks")
103
105
  def run_tasks_impl(
104
- settings: SettingsWrapper,
106
+ settings: "SettingsWrapper",
105
107
  transactional_db: None,
106
108
  task_processor_mode: None,
107
109
  ) -> RunTasksFixture:
@@ -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."""
@@ -0,0 +1,4 @@
1
+ from importlib.util import find_spec
2
+
3
+ PYDANTIC_INSTALLED = find_spec("pydantic") is not None
4
+ MAX_STRING_FEATURE_STATE_VALUE_LENGTH = 20_000