flagsmith-common 3.2.1__tar.gz → 3.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_common-3.2.1 → flagsmith_common-3.3.0}/PKG-INFO +2 -1
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/pyproject.toml +2 -1
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/templates/docgen-metrics.md +3 -1
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/conf.py +11 -1
- flagsmith_common-3.3.0/src/common/gunicorn/metrics_server.py +65 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/dynamodb.py +79 -21
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/types.py +51 -2
- flagsmith_common-3.3.0/src/flagsmith_schemas/utils.py +15 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/LICENSE +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/README.md +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/app.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/cli/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/cli/healthcheck.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/constants.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/logging.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/main.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/docgen.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/start.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/waitfordb.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/metrics.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/middleware.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/urls.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/utils.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/views.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/environments/permissions.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/multivariate/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/multivariate/serializers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/serializers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/versioning/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/versioning/serializers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/constants.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/logging.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/metrics.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/middleware.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/gunicorn/utils.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/migrations/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/migrations/helpers/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/migrations/helpers/postgres_helpers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/organisations/permissions.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/projects/permissions.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/prometheus/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/prometheus/utils.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/py.typed +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/test_tools/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/test_tools/plugin.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/test_tools/types.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/test_tools/utils.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/types.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/api.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/constants.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/py.typed +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/pydantic_types.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/flagsmith_schemas/validators.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/admin.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/apps.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/decorators.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/exceptions.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/health.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/managers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/metrics.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0001_initial.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0002_healthcheckmodel.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0003_add_completed_to_task.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0004_recreate_task_indexes.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0005_update_conditional_index_conditions.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0006_auto_20230221_0802.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0007_add_is_locked.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0008_add_get_task_to_process_function.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0009_add_recurring_task_run_first_run_at.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0010_task_priority.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0011_add_priority_to_get_tasks_to_process.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0012_add_locked_at_and_timeout.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/0013_add_last_picked_at.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/0008_get_recurring_tasks_to_process.sql +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/0008_get_tasks_to_process.sql +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/0011_get_tasks_to_process.sql +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/0013_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/migrations/sql/__init__.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/models.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/monitoring.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/processor.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/py.typed +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/routers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/serializers.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/task_registry.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/task_run_method.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/tasks.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/threads.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/types.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/urls.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/utils.py +0 -0
- {flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/task_processor/views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flagsmith-common
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.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
|
|
@@ -21,6 +21,7 @@ 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: simplejson ; extra == 'flagsmith-schemas'
|
|
24
25
|
Requires-Dist: typing-extensions ; extra == 'flagsmith-schemas'
|
|
25
26
|
Requires-Dist: flagsmith-flag-engine>6 ; extra == 'flagsmith-schemas'
|
|
26
27
|
Requires-Dist: backoff>=2.2.1,<3.0.0 ; extra == 'task-processor'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flagsmith-common"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.3.0"
|
|
4
4
|
description = "Flagsmith's common library"
|
|
5
5
|
requires-python = ">=3.11,<4.0"
|
|
6
6
|
dependencies = []
|
|
@@ -26,6 +26,7 @@ optional-dependencies = { test-tools = [
|
|
|
26
26
|
"django-health-check",
|
|
27
27
|
"prometheus-client (>=0.0.16)",
|
|
28
28
|
], flagsmith-schemas = [
|
|
29
|
+
"simplejson",
|
|
29
30
|
"typing_extensions",
|
|
30
31
|
"flagsmith-flag-engine>6",
|
|
31
32
|
] }
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/templates/docgen-metrics.md
RENAMED
|
@@ -6,7 +6,9 @@ sidebar_position: 20
|
|
|
6
6
|
|
|
7
7
|
## Prometheus
|
|
8
8
|
|
|
9
|
-
To enable the Prometheus `/metrics` endpoint, set the `PROMETHEUS_ENABLED` environment variable to `true`.
|
|
9
|
+
To enable the Prometheus `/metrics` endpoint, set the `PROMETHEUS_ENABLED` environment variable to `true`.
|
|
10
|
+
|
|
11
|
+
When enabled, Flagsmith serves the `/metrics` endpoint on port 9100.
|
|
10
12
|
|
|
11
13
|
The metrics provided by Flagsmith are described below.
|
|
12
14
|
|
|
@@ -4,6 +4,7 @@ This module is used as a default configuration file for Gunicorn.
|
|
|
4
4
|
It is used to correctly support Prometheus metrics in a multi-process environment.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import os
|
|
7
8
|
import typing
|
|
8
9
|
|
|
9
10
|
from prometheus_client.multiprocess import mark_process_dead
|
|
@@ -13,6 +14,15 @@ if typing.TYPE_CHECKING: # pragma: no cover
|
|
|
13
14
|
from gunicorn.workers.base import Worker # type: ignore[import-untyped]
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
def
|
|
17
|
+
def when_ready(server: "Arbiter") -> None:
|
|
18
|
+
"""Start the standalone Prometheus metrics server after Gunicorn is ready."""
|
|
19
|
+
prometheus_enabled = os.getenv("PROMETHEUS_ENABLED", "")
|
|
20
|
+
if prometheus_enabled.lower() == "true": # Django settings are not available
|
|
21
|
+
from common.gunicorn.metrics_server import start_metrics_server
|
|
22
|
+
|
|
23
|
+
start_metrics_server()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def child_exit(server: "Arbiter", worker: "Worker") -> None:
|
|
17
27
|
"""Detach the process Prometheus metrics collector when a worker exits."""
|
|
18
28
|
mark_process_dead(worker.pid) # type: ignore[no-untyped-call]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Standalone Prometheus metrics HTTP server.
|
|
3
|
+
|
|
4
|
+
This module provides a separate HTTP server for Prometheus metrics,
|
|
5
|
+
independent of the main Gunicorn application server. This improves
|
|
6
|
+
metrics reliability under high API load.
|
|
7
|
+
|
|
8
|
+
The server runs in a daemon thread and serves metrics from the shared
|
|
9
|
+
PROMETHEUS_MULTIPROC_DIR directory.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
import os
|
|
14
|
+
import threading
|
|
15
|
+
|
|
16
|
+
from prometheus_client import CollectorRegistry, start_http_server
|
|
17
|
+
from prometheus_client.multiprocess import MultiProcessCollector
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
METRICS_SERVER_PORT = 9100
|
|
22
|
+
|
|
23
|
+
_server_started = False
|
|
24
|
+
_server_lock = threading.Lock()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_multiprocess_registry() -> CollectorRegistry:
|
|
28
|
+
"""Create a registry configured for multiprocess metric collection."""
|
|
29
|
+
registry = CollectorRegistry()
|
|
30
|
+
MultiProcessCollector(registry) # type: ignore[no-untyped-call]
|
|
31
|
+
return registry
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def start_metrics_server(
|
|
35
|
+
port: int = METRICS_SERVER_PORT,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Start the standalone Prometheus metrics HTTP server.
|
|
39
|
+
|
|
40
|
+
This function is idempotent - calling it multiple times will only
|
|
41
|
+
start one server. The server runs in a daemon thread.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
port: The port to serve metrics on. Defaults to 9100.
|
|
45
|
+
"""
|
|
46
|
+
global _server_started
|
|
47
|
+
|
|
48
|
+
with _server_lock:
|
|
49
|
+
if _server_started:
|
|
50
|
+
logger.debug("Metrics server already started")
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
prometheus_multiproc_dir = os.environ.get("PROMETHEUS_MULTIPROC_DIR")
|
|
54
|
+
if not prometheus_multiproc_dir:
|
|
55
|
+
logger.warning("PROMETHEUS_MULTIPROC_DIR not set, skipping metrics server")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
registry = get_multiprocess_registry()
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
start_http_server(port=port, registry=registry)
|
|
62
|
+
_server_started = True
|
|
63
|
+
logger.info("Prometheus metrics server started on port %d", port)
|
|
64
|
+
except OSError as e:
|
|
65
|
+
logger.error("Failed to start metrics server on port %d: %s", port, e)
|
|
@@ -20,6 +20,7 @@ from flagsmith_schemas.types import (
|
|
|
20
20
|
DynamoFloat,
|
|
21
21
|
DynamoInt,
|
|
22
22
|
FeatureType,
|
|
23
|
+
JsonGzipped,
|
|
23
24
|
UUIDStr,
|
|
24
25
|
)
|
|
25
26
|
|
|
@@ -200,7 +201,7 @@ class Webhook(TypedDict):
|
|
|
200
201
|
"""Secret used to sign webhook payloads."""
|
|
201
202
|
|
|
202
203
|
|
|
203
|
-
class
|
|
204
|
+
class _EnvironmentBaseFields(TypedDict):
|
|
204
205
|
"""Common fields for Environment documents."""
|
|
205
206
|
|
|
206
207
|
name: NotRequired[str]
|
|
@@ -208,11 +209,6 @@ class _EnvironmentFields(TypedDict):
|
|
|
208
209
|
updated_at: NotRequired[DateTimeStr | None]
|
|
209
210
|
"""Last updated timestamp. If not set, current timestamp should be assumed."""
|
|
210
211
|
|
|
211
|
-
project: Project
|
|
212
|
-
"""Project-specific data for this environment."""
|
|
213
|
-
feature_states: list[FeatureState]
|
|
214
|
-
"""List of feature states representing the environment defaults."""
|
|
215
|
-
|
|
216
212
|
allow_client_traits: NotRequired[bool]
|
|
217
213
|
"""Whether the SDK API should allow clients to set traits for this environment. Identical to project-level's `persist_trait_data` setting. Defaults to `True`."""
|
|
218
214
|
hide_sensitive_data: NotRequired[bool]
|
|
@@ -240,7 +236,52 @@ class _EnvironmentFields(TypedDict):
|
|
|
240
236
|
"""Webhook configuration."""
|
|
241
237
|
|
|
242
238
|
|
|
243
|
-
|
|
239
|
+
class _EnvironmentV1Fields(TypedDict):
|
|
240
|
+
"""Common fields for environment documents in `flagsmith_environments`."""
|
|
241
|
+
|
|
242
|
+
api_key: str
|
|
243
|
+
"""Public client-side API key for the environment. **INDEXED**."""
|
|
244
|
+
id: DynamoInt
|
|
245
|
+
"""Unique identifier for the environment in Core."""
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class _EnvironmentV2MetaFields(TypedDict):
|
|
249
|
+
"""Common fields for environment documents in `flagsmith_environments_v2`."""
|
|
250
|
+
|
|
251
|
+
environment_id: str
|
|
252
|
+
"""Unique identifier for the environment in Core. Same as `Environment.id`, but string-typed to reduce coupling with Core's type definitions **INDEXED**."""
|
|
253
|
+
environment_api_key: str
|
|
254
|
+
"""Public client-side API key for the environment. **INDEXED**."""
|
|
255
|
+
document_key: Literal["_META"]
|
|
256
|
+
"""The fixed document key for the environment v2 document. Always `"_META"`. **INDEXED**."""
|
|
257
|
+
|
|
258
|
+
id: DynamoInt
|
|
259
|
+
"""Unique identifier for the environment in Core. Exists for compatibility with the API environment document schema."""
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class _EnvironmentBaseFieldsUncompressed(TypedDict):
|
|
263
|
+
"""Common fields for uncompressed environment documents."""
|
|
264
|
+
|
|
265
|
+
project: Project
|
|
266
|
+
"""Project-specific data for this environment."""
|
|
267
|
+
feature_states: list[FeatureState]
|
|
268
|
+
"""List of feature states representing the environment defaults."""
|
|
269
|
+
compressed: NotRequired[Literal[False]]
|
|
270
|
+
"""Either `False` or absent to indicate the data is uncompressed."""
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class _EnvironmentBaseFieldsCompressed(TypedDict):
|
|
274
|
+
"""Common fields for compressed environment documents."""
|
|
275
|
+
|
|
276
|
+
project: JsonGzipped[Project]
|
|
277
|
+
"""Project-specific data for this environment. **COMPRESSED**."""
|
|
278
|
+
feature_states: JsonGzipped[list[FeatureState]]
|
|
279
|
+
"""List of feature states representing the environment defaults. **COMPRESSED**."""
|
|
280
|
+
compressed: Literal[True]
|
|
281
|
+
"""Always `True` to indicate the data is compressed."""
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
### Root document schemas below. Indexed fields are marked as **INDEXED** in the docstrings. Compressed fields are marked as **COMPRESSED**. ###
|
|
244
285
|
|
|
245
286
|
|
|
246
287
|
class EnvironmentAPIKey(TypedDict):
|
|
@@ -295,33 +336,50 @@ class Identity(TypedDict):
|
|
|
295
336
|
"""Unique identifier for the identity in Core. If identity created via Core's `edge-identities` API, this can be missing or `None`."""
|
|
296
337
|
|
|
297
338
|
|
|
298
|
-
class Environment(
|
|
339
|
+
class Environment(
|
|
340
|
+
_EnvironmentBaseFieldsUncompressed,
|
|
341
|
+
_EnvironmentV1Fields,
|
|
342
|
+
_EnvironmentBaseFields,
|
|
343
|
+
):
|
|
299
344
|
"""Represents a Flagsmith environment. Carries all necessary data for flag evaluation within the environment.
|
|
300
345
|
|
|
301
346
|
**DynamoDB table**: `flagsmith_environments`
|
|
302
347
|
"""
|
|
303
348
|
|
|
304
|
-
api_key: str
|
|
305
|
-
"""Public client-side API key for the environment. **INDEXED**."""
|
|
306
|
-
id: DynamoInt
|
|
307
|
-
"""Unique identifier for the environment in Core."""
|
|
308
349
|
|
|
350
|
+
class EnvironmentCompressed(
|
|
351
|
+
_EnvironmentBaseFieldsCompressed,
|
|
352
|
+
_EnvironmentV1Fields,
|
|
353
|
+
_EnvironmentBaseFields,
|
|
354
|
+
):
|
|
355
|
+
"""Represents a Flagsmith environment. Carries all necessary data for flag evaluation within the environment.
|
|
356
|
+
Has compressed fields.
|
|
357
|
+
|
|
358
|
+
**DynamoDB table**: `flagsmith_environments`
|
|
359
|
+
"""
|
|
309
360
|
|
|
310
|
-
|
|
361
|
+
|
|
362
|
+
class EnvironmentV2Meta(
|
|
363
|
+
_EnvironmentBaseFieldsUncompressed,
|
|
364
|
+
_EnvironmentV2MetaFields,
|
|
365
|
+
_EnvironmentBaseFields,
|
|
366
|
+
):
|
|
311
367
|
"""Represents a Flagsmith environment. Carries all necessary data for flag evaluation within the environment.
|
|
312
368
|
|
|
313
369
|
**DynamoDB table**: `flagsmith_environments_v2`
|
|
314
370
|
"""
|
|
315
371
|
|
|
316
|
-
environment_id: str
|
|
317
|
-
"""Unique identifier for the environment in Core. Same as `Environment.id`, but string-typed to reduce coupling with Core's type definitions **INDEXED**."""
|
|
318
|
-
environment_api_key: str
|
|
319
|
-
"""Public client-side API key for the environment. **INDEXED**."""
|
|
320
|
-
document_key: Literal["_META"]
|
|
321
|
-
"""The fixed document key for the environment v2 document. Always `"_META"`. **INDEXED**."""
|
|
322
372
|
|
|
323
|
-
|
|
324
|
-
|
|
373
|
+
class EnvironmentV2MetaCompressed(
|
|
374
|
+
_EnvironmentBaseFieldsCompressed,
|
|
375
|
+
_EnvironmentV2MetaFields,
|
|
376
|
+
_EnvironmentBaseFields,
|
|
377
|
+
):
|
|
378
|
+
"""Represents a Flagsmith environment. Carries all necessary data for flag evaluation within the environment.
|
|
379
|
+
Has compressed fields.
|
|
380
|
+
|
|
381
|
+
**DynamoDB table**: `flagsmith_environments_v2`
|
|
382
|
+
"""
|
|
325
383
|
|
|
326
384
|
|
|
327
385
|
class EnvironmentV2IdentityOverride(TypedDict):
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import (
|
|
3
|
+
TYPE_CHECKING,
|
|
4
|
+
Annotated,
|
|
5
|
+
Any,
|
|
6
|
+
Generic,
|
|
7
|
+
Literal,
|
|
8
|
+
SupportsBytes,
|
|
9
|
+
TypeAlias,
|
|
10
|
+
TypeVar,
|
|
11
|
+
get_args,
|
|
12
|
+
)
|
|
3
13
|
|
|
4
14
|
from flagsmith_schemas.constants import PYDANTIC_INSTALLED
|
|
5
15
|
|
|
6
16
|
if PYDANTIC_INSTALLED:
|
|
7
|
-
from pydantic import
|
|
17
|
+
from pydantic import (
|
|
18
|
+
GetCoreSchemaHandler,
|
|
19
|
+
TypeAdapter,
|
|
20
|
+
WithJsonSchema,
|
|
21
|
+
)
|
|
22
|
+
from pydantic_core import core_schema
|
|
8
23
|
|
|
9
24
|
from flagsmith_schemas.pydantic_types import (
|
|
10
25
|
ValidateDecimalAsFloat,
|
|
@@ -13,6 +28,7 @@ if PYDANTIC_INSTALLED:
|
|
|
13
28
|
ValidateStrAsISODateTime,
|
|
14
29
|
ValidateStrAsUUID,
|
|
15
30
|
)
|
|
31
|
+
from flagsmith_schemas.utils import json_gzip
|
|
16
32
|
elif not TYPE_CHECKING:
|
|
17
33
|
# This code runs at runtime when Pydantic is not installed.
|
|
18
34
|
# We could use PEP 649 strings with `Annotated`, but Pydantic is inconsistent in how it parses them.
|
|
@@ -26,6 +42,39 @@ elif not TYPE_CHECKING:
|
|
|
26
42
|
ValidateStrAsISODateTime = ...
|
|
27
43
|
ValidateStrAsUUID = ...
|
|
28
44
|
|
|
45
|
+
T = TypeVar("T")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class DynamoBinary(SupportsBytes):
|
|
49
|
+
"""boto3's wrapper type for bytes stored in DynamoDB."""
|
|
50
|
+
|
|
51
|
+
value: bytes | bytearray
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class JsonGzipped(DynamoBinary, Generic[T]):
|
|
55
|
+
"""A gzipped JSON blob representing a value of type `T`."""
|
|
56
|
+
|
|
57
|
+
if PYDANTIC_INSTALLED:
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def __get_pydantic_core_schema__(
|
|
61
|
+
cls,
|
|
62
|
+
source_type: "type[JsonGzipped[T]]",
|
|
63
|
+
handler: GetCoreSchemaHandler,
|
|
64
|
+
) -> core_schema.CoreSchema:
|
|
65
|
+
_adapter: TypeAdapter[T] = TypeAdapter(get_args(source_type)[0])
|
|
66
|
+
|
|
67
|
+
def _validate_json_gzipped(data: Any) -> bytes:
|
|
68
|
+
return json_gzip(_adapter.validate_python(data))
|
|
69
|
+
|
|
70
|
+
# We're returning bytes here for two reasons:
|
|
71
|
+
# 1. boto3.dynamodb seems to expect bytes as input for Binary columns.
|
|
72
|
+
# 2. We want to avoid having boto3 as a dependency.
|
|
73
|
+
return core_schema.no_info_before_validator_function(
|
|
74
|
+
_validate_json_gzipped,
|
|
75
|
+
core_schema.bytes_schema(strict=False),
|
|
76
|
+
)
|
|
77
|
+
|
|
29
78
|
|
|
30
79
|
DynamoInt: TypeAlias = Annotated[Decimal, ValidateDecimalAsInt]
|
|
31
80
|
"""An integer value stored in DynamoDB.
|
|
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.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/docgen.py
RENAMED
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/start.py
RENAMED
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/core/management/commands/waitfordb.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
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/multivariate/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/multivariate/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/src/common/features/versioning/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/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.2.1 → flagsmith_common-3.3.0}/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
|
|
File without changes
|
{flagsmith_common-3.2.1 → flagsmith_common-3.3.0}/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.2.1 → flagsmith_common-3.3.0}/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
|
|
File without changes
|
|
File without changes
|