flagsmith-common 2.2.6__tar.gz → 3.0.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-2.2.6 → flagsmith_common-3.0.0}/PKG-INFO +51 -79
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/README.md +25 -51
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/pyproject.toml +42 -42
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/main.py +3 -10
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/utils.py +0 -29
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/views.py +1 -1
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/LICENSE +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/app.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/cli/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/cli/healthcheck.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/constants.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/logging.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/docgen.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/start.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/waitfordb.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/metrics.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/middleware.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/templates/docgen-metrics.md +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/urls.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/views.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/environments/permissions.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/multivariate/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/multivariate/serializers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/serializers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/versioning/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/versioning/serializers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/conf.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/constants.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/logging.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/metrics.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/middleware.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/gunicorn/utils.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/migrations/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/migrations/helpers/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/migrations/helpers/postgres_helpers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/organisations/permissions.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/projects/permissions.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/prometheus/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/prometheus/utils.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/py.typed +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/test_tools/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/test_tools/plugin.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/test_tools/types.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/test_tools/utils.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/types.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/admin.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/apps.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/decorators.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/exceptions.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/health.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/managers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/metrics.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0001_initial.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0002_healthcheckmodel.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0003_add_completed_to_task.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0004_recreate_task_indexes.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0005_update_conditional_index_conditions.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0006_auto_20230221_0802.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0007_add_is_locked.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0008_add_get_task_to_process_function.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0009_add_recurring_task_run_first_run_at.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0010_task_priority.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0011_add_priority_to_get_tasks_to_process.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0012_add_locked_at_and_timeout.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/0013_add_last_picked_at.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/0008_get_recurring_tasks_to_process.sql +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/0008_get_tasks_to_process.sql +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/0011_get_tasks_to_process.sql +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/0013_get_recurringtasks_to_process.sql +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/migrations/sql/__init__.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/models.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/monitoring.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/processor.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/py.typed +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/routers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/serializers.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/task_registry.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/task_run_method.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/tasks.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/threads.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/types.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/urls.py +0 -0
- {flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/task_processor/utils.py +0 -0
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flagsmith-common
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Flagsmith's common library
|
|
5
|
+
Author: Matthew Elwell, Gagan Trivedi, Kim Gustyr, Zach Aysan, Francesco Lo Franco, Rodrigo López Dato, Evandro Myller, Wadii Zaim
|
|
5
6
|
License-Expression: BSD-3-Clause
|
|
6
7
|
License-File: LICENSE
|
|
7
|
-
Author: Matthew Elwell
|
|
8
|
-
Maintainer: Flagsmith Team
|
|
9
|
-
Maintainer-email: support@flagsmith.com
|
|
10
|
-
Requires-Python: >=3.11,<4.0
|
|
11
8
|
Classifier: Framework :: Django
|
|
12
9
|
Classifier: Framework :: Pytest
|
|
13
10
|
Classifier: Intended Audience :: Developers
|
|
14
11
|
Classifier: License :: OSI Approved :: BSD License
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Requires-
|
|
36
|
-
Requires-Dist: simplejson (>=3,<4)
|
|
12
|
+
Requires-Dist: django>4,<6 ; extra == 'common-core'
|
|
13
|
+
Requires-Dist: django-health-check ; extra == 'common-core'
|
|
14
|
+
Requires-Dist: djangorestframework-recursive ; extra == 'common-core'
|
|
15
|
+
Requires-Dist: djangorestframework ; extra == 'common-core'
|
|
16
|
+
Requires-Dist: drf-writable-nested ; extra == 'common-core'
|
|
17
|
+
Requires-Dist: drf-yasg>=1.21.10,<2.0.0 ; extra == 'common-core'
|
|
18
|
+
Requires-Dist: environs<15 ; extra == 'common-core'
|
|
19
|
+
Requires-Dist: gunicorn>=19.1 ; extra == 'common-core'
|
|
20
|
+
Requires-Dist: prometheus-client>=0.0.16 ; extra == 'common-core'
|
|
21
|
+
Requires-Dist: psycopg2-binary>=2.9,<3 ; extra == 'common-core'
|
|
22
|
+
Requires-Dist: requests ; extra == 'common-core'
|
|
23
|
+
Requires-Dist: simplejson>=3,<4 ; extra == 'common-core'
|
|
24
|
+
Requires-Dist: backoff>=2.2.1,<3.0.0 ; extra == 'task-processor'
|
|
25
|
+
Requires-Dist: django>4,<6 ; extra == 'task-processor'
|
|
26
|
+
Requires-Dist: django-health-check ; extra == 'task-processor'
|
|
27
|
+
Requires-Dist: prometheus-client>=0.0.16 ; extra == 'task-processor'
|
|
28
|
+
Requires-Dist: pyfakefs>=5,<6 ; extra == 'test-tools'
|
|
29
|
+
Requires-Dist: pytest-django>=4,<5 ; extra == 'test-tools'
|
|
30
|
+
Maintainer: Flagsmith Team
|
|
31
|
+
Maintainer-email: Flagsmith Team <support@flagsmith.com>
|
|
32
|
+
Requires-Python: >=3.11, <4.0
|
|
37
33
|
Project-URL: Changelog, https://github.com/flagsmith/flagsmith-common/blob/main/CHANGELOG.md
|
|
38
34
|
Project-URL: Download, https://github.com/flagsmith/flagsmith-common/releases
|
|
39
35
|
Project-URL: Homepage, https://flagsmith.com
|
|
40
36
|
Project-URL: Issues, https://github.com/flagsmith/flagsmith-common/issues
|
|
41
37
|
Project-URL: Repository, https://github.com/flagsmith/flagsmith-common
|
|
38
|
+
Provides-Extra: common-core
|
|
39
|
+
Provides-Extra: task-processor
|
|
40
|
+
Provides-Extra: test-tools
|
|
42
41
|
Description-Content-Type: text/markdown
|
|
43
42
|
|
|
44
43
|
# flagsmith-common
|
|
@@ -47,54 +46,28 @@ Description-Content-Type: text/markdown
|
|
|
47
46
|
|
|
48
47
|
Flagsmith's common library
|
|
49
48
|
|
|
50
|
-
|
|
49
|
+
## Local development
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
The project assumes the following tools installed:
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
- [uv](https://github.com/astral-sh/uv)
|
|
54
|
+
- [GNU Make](https://www.gnu.org/software/make/)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
- Make
|
|
56
|
+
To list available Makefile targets, run `make help`.
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
To set up local development environment, run `make install`.
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
To run linters, run `make lint`.
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
# Install everything (pip, poetry, and project dependencies)
|
|
65
|
-
make install
|
|
62
|
+
To run tests, run `make test`.
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
make install-pip # Upgrade pip
|
|
69
|
-
make install-poetry # Install Poetry
|
|
70
|
-
make install-packages # Install project dependencies
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
#### Development
|
|
64
|
+
## Usage
|
|
74
65
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
make lint
|
|
79
|
-
```
|
|
66
|
+
### Installation
|
|
80
67
|
|
|
81
|
-
|
|
68
|
+
1. Install all runtime packages: `uv add flagsmith-common[common-core,task-processor]`
|
|
82
69
|
|
|
83
|
-
|
|
84
|
-
# Install with development dependencies
|
|
85
|
-
make install-packages opts="--with dev"
|
|
86
|
-
|
|
87
|
-
# Install with specific extras
|
|
88
|
-
make install-packages opts="--extras 'feature1 feature2'"
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Usage
|
|
92
|
-
|
|
93
|
-
#### Installation
|
|
94
|
-
|
|
95
|
-
1. `poetry add flagsmith-common`
|
|
96
|
-
|
|
97
|
-
2. `poetry add --G dev flagsmith-common[test-tools]` — this will enable the Pytest fixtures. Skipping this step will make Pytest collection fail due to missing dependencies.
|
|
70
|
+
2. To enable the Pytest fixtures, run `uv add --G dev flagsmith-common[test-tools]`. Skipping this step will make Pytest collection fail due to missing dependencies.
|
|
98
71
|
|
|
99
72
|
3. Make sure `"common.core"` is in the `INSTALLED_APPS` of your settings module.
|
|
100
73
|
This enables the `manage.py flagsmith` commands.
|
|
@@ -104,11 +77,11 @@ This enables the `route` label for Prometheus HTTP metrics.
|
|
|
104
77
|
|
|
105
78
|
5. To enable the `/metrics` endpoint, set the `PROMETHEUS_ENABLED` setting to `True`.
|
|
106
79
|
|
|
107
|
-
|
|
80
|
+
### Test tools
|
|
108
81
|
|
|
109
|
-
|
|
82
|
+
#### Fixtures
|
|
110
83
|
|
|
111
|
-
|
|
84
|
+
##### `assert_metric`
|
|
112
85
|
|
|
113
86
|
To test your metrics using the `assert_metric` fixture:
|
|
114
87
|
|
|
@@ -127,44 +100,44 @@ def test_my_code__expected_metrics(assert_metric: AssertMetricFixture) -> None:
|
|
|
127
100
|
)
|
|
128
101
|
```
|
|
129
102
|
|
|
130
|
-
|
|
103
|
+
##### `saas_mode`
|
|
131
104
|
|
|
132
105
|
The `saas_mode` fixture makes all `common.core.utils.is_saas` calls return `True`.
|
|
133
106
|
|
|
134
|
-
|
|
107
|
+
##### `enterprise_mode`
|
|
135
108
|
|
|
136
109
|
The `enterprise_mode` fixture makes all `common.core.utils.is_enterprise` calls return `True`.
|
|
137
110
|
|
|
138
|
-
|
|
111
|
+
#### Markers
|
|
139
112
|
|
|
140
|
-
|
|
113
|
+
##### `pytest.mark.saas_mode`
|
|
141
114
|
|
|
142
115
|
Use this mark to auto-use the `saas_mode` fixture.
|
|
143
116
|
|
|
144
|
-
|
|
117
|
+
##### `pytest.mark.enterprise_mode`
|
|
145
118
|
|
|
146
119
|
Use this mark to auto-use the `enterprise_mode` fixture.
|
|
147
120
|
|
|
148
|
-
|
|
121
|
+
### Metrics
|
|
149
122
|
|
|
150
123
|
Flagsmith uses Prometheus to track performance metrics.
|
|
151
124
|
|
|
152
125
|
The following default metrics are exposed:
|
|
153
126
|
|
|
154
|
-
|
|
127
|
+
#### Common metrics
|
|
155
128
|
|
|
156
129
|
- `flagsmith_build_info`: Has the labels `version` and `ci_commit_sha`.
|
|
157
130
|
- `flagsmith_http_server_request_duration_seconds`: Histogram labeled with `method`, `route`, and `response_status`.
|
|
158
131
|
- `flagsmith_http_server_requests_total`: Counter labeled with `method`, `route`, and `response_status`.
|
|
159
|
-
- `flagsmith_http_server_response_size_bytes`:Histogram labeled with `method`, `route`, and `response_status`.
|
|
132
|
+
- `flagsmith_http_server_response_size_bytes`: Histogram labeled with `method`, `route`, and `response_status`.
|
|
160
133
|
- `flagsmith_task_processor_enqueued_tasks_total`: Counter labeled with `task_identifier`.
|
|
161
134
|
|
|
162
|
-
|
|
135
|
+
#### Task Processor metrics
|
|
163
136
|
|
|
164
137
|
- `flagsmith_task_processor_finished_tasks_total`: Counter labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
|
|
165
138
|
- `flagsmith_task_processor_task_duration_seconds`: Histogram labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
|
|
166
139
|
|
|
167
|
-
|
|
140
|
+
#### Guidelines
|
|
168
141
|
|
|
169
142
|
Try to come up with meaningful metrics to cover your feature with when developing it. Refer to [Prometheus best practices][1] when naming your metric and labels.
|
|
170
143
|
|
|
@@ -193,4 +166,3 @@ For testing your metrics, refer to [`assert_metric` documentation][5].
|
|
|
193
166
|
[3]: https://docs.gunicorn.org/en/stable/design.html#server-model
|
|
194
167
|
[4]: https://prometheus.github.io/client_python/multiprocess
|
|
195
168
|
[5]: #assert_metric
|
|
196
|
-
|
|
@@ -4,54 +4,28 @@
|
|
|
4
4
|
|
|
5
5
|
Flagsmith's common library
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Local development
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The project assumes the following tools installed:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- [uv](https://github.com/astral-sh/uv)
|
|
12
|
+
- [GNU Make](https://www.gnu.org/software/make/)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
- Make
|
|
14
|
+
To list available Makefile targets, run `make help`.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
To set up local development environment, run `make install`.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
To run linters, run `make lint`.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
# Install everything (pip, poetry, and project dependencies)
|
|
22
|
-
make install
|
|
20
|
+
To run tests, run `make test`.
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
make install-pip # Upgrade pip
|
|
26
|
-
make install-poetry # Install Poetry
|
|
27
|
-
make install-packages # Install project dependencies
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
#### Development
|
|
31
|
-
|
|
32
|
-
Run linting checks using pre-commit:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
make lint
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Additional options can be passed to the `install-packages` target:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# Install with development dependencies
|
|
42
|
-
make install-packages opts="--with dev"
|
|
43
|
-
|
|
44
|
-
# Install with specific extras
|
|
45
|
-
make install-packages opts="--extras 'feature1 feature2'"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Usage
|
|
22
|
+
## Usage
|
|
49
23
|
|
|
50
|
-
|
|
24
|
+
### Installation
|
|
51
25
|
|
|
52
|
-
1. `
|
|
26
|
+
1. Install all runtime packages: `uv add flagsmith-common[common-core,task-processor]`
|
|
53
27
|
|
|
54
|
-
2. `
|
|
28
|
+
2. To enable the Pytest fixtures, run `uv add --G dev flagsmith-common[test-tools]`. Skipping this step will make Pytest collection fail due to missing dependencies.
|
|
55
29
|
|
|
56
30
|
3. Make sure `"common.core"` is in the `INSTALLED_APPS` of your settings module.
|
|
57
31
|
This enables the `manage.py flagsmith` commands.
|
|
@@ -61,11 +35,11 @@ This enables the `route` label for Prometheus HTTP metrics.
|
|
|
61
35
|
|
|
62
36
|
5. To enable the `/metrics` endpoint, set the `PROMETHEUS_ENABLED` setting to `True`.
|
|
63
37
|
|
|
64
|
-
|
|
38
|
+
### Test tools
|
|
65
39
|
|
|
66
|
-
|
|
40
|
+
#### Fixtures
|
|
67
41
|
|
|
68
|
-
|
|
42
|
+
##### `assert_metric`
|
|
69
43
|
|
|
70
44
|
To test your metrics using the `assert_metric` fixture:
|
|
71
45
|
|
|
@@ -84,44 +58,44 @@ def test_my_code__expected_metrics(assert_metric: AssertMetricFixture) -> None:
|
|
|
84
58
|
)
|
|
85
59
|
```
|
|
86
60
|
|
|
87
|
-
|
|
61
|
+
##### `saas_mode`
|
|
88
62
|
|
|
89
63
|
The `saas_mode` fixture makes all `common.core.utils.is_saas` calls return `True`.
|
|
90
64
|
|
|
91
|
-
|
|
65
|
+
##### `enterprise_mode`
|
|
92
66
|
|
|
93
67
|
The `enterprise_mode` fixture makes all `common.core.utils.is_enterprise` calls return `True`.
|
|
94
68
|
|
|
95
|
-
|
|
69
|
+
#### Markers
|
|
96
70
|
|
|
97
|
-
|
|
71
|
+
##### `pytest.mark.saas_mode`
|
|
98
72
|
|
|
99
73
|
Use this mark to auto-use the `saas_mode` fixture.
|
|
100
74
|
|
|
101
|
-
|
|
75
|
+
##### `pytest.mark.enterprise_mode`
|
|
102
76
|
|
|
103
77
|
Use this mark to auto-use the `enterprise_mode` fixture.
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
### Metrics
|
|
106
80
|
|
|
107
81
|
Flagsmith uses Prometheus to track performance metrics.
|
|
108
82
|
|
|
109
83
|
The following default metrics are exposed:
|
|
110
84
|
|
|
111
|
-
|
|
85
|
+
#### Common metrics
|
|
112
86
|
|
|
113
87
|
- `flagsmith_build_info`: Has the labels `version` and `ci_commit_sha`.
|
|
114
88
|
- `flagsmith_http_server_request_duration_seconds`: Histogram labeled with `method`, `route`, and `response_status`.
|
|
115
89
|
- `flagsmith_http_server_requests_total`: Counter labeled with `method`, `route`, and `response_status`.
|
|
116
|
-
- `flagsmith_http_server_response_size_bytes`:Histogram labeled with `method`, `route`, and `response_status`.
|
|
90
|
+
- `flagsmith_http_server_response_size_bytes`: Histogram labeled with `method`, `route`, and `response_status`.
|
|
117
91
|
- `flagsmith_task_processor_enqueued_tasks_total`: Counter labeled with `task_identifier`.
|
|
118
92
|
|
|
119
|
-
|
|
93
|
+
#### Task Processor metrics
|
|
120
94
|
|
|
121
95
|
- `flagsmith_task_processor_finished_tasks_total`: Counter labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
|
|
122
96
|
- `flagsmith_task_processor_task_duration_seconds`: Histogram labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
|
|
123
97
|
|
|
124
|
-
|
|
98
|
+
#### Guidelines
|
|
125
99
|
|
|
126
100
|
Try to come up with meaningful metrics to cover your feature with when developing it. Refer to [Prometheus best practices][1] when naming your metric and labels.
|
|
127
101
|
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flagsmith-common"
|
|
3
|
-
version = "
|
|
3
|
+
version = "3.0.0"
|
|
4
4
|
description = "Flagsmith's common library"
|
|
5
5
|
requires-python = ">=3.11,<4.0"
|
|
6
|
-
dependencies = [
|
|
7
|
-
|
|
8
|
-
"
|
|
6
|
+
dependencies = []
|
|
7
|
+
optional-dependencies = { test-tools = [
|
|
8
|
+
"pyfakefs (>=5,<6)",
|
|
9
|
+
"pytest-django (>=4,<5)",
|
|
10
|
+
], common-core = [
|
|
11
|
+
"django (>4,<6)",
|
|
9
12
|
"django-health-check",
|
|
10
13
|
"djangorestframework-recursive",
|
|
11
14
|
"djangorestframework",
|
|
12
15
|
"drf-writable-nested",
|
|
13
16
|
"drf-yasg (>=1.21.10,<2.0.0)",
|
|
14
17
|
"environs (<15)",
|
|
15
|
-
"flagsmith-flag-engine",
|
|
16
18
|
"gunicorn (>=19.1)",
|
|
17
19
|
"prometheus-client (>=0.0.16)",
|
|
18
20
|
"psycopg2-binary (>=2.9,<3)",
|
|
19
21
|
"requests",
|
|
20
22
|
"simplejson (>=3,<4)",
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
23
|
+
|
|
24
|
+
], task-processor = [
|
|
25
|
+
"backoff (>=2.2.1,<3.0.0)",
|
|
26
|
+
"django (>4,<6)",
|
|
27
|
+
"django-health-check",
|
|
28
|
+
"prometheus-client (>=0.0.16)",
|
|
25
29
|
] }
|
|
26
30
|
authors = [
|
|
27
31
|
{ name = "Matthew Elwell" },
|
|
@@ -37,7 +41,12 @@ maintainers = [{ name = "Flagsmith Team", email = "support@flagsmith.com" }]
|
|
|
37
41
|
license = "BSD-3-Clause"
|
|
38
42
|
license-files = ["LICENSE"]
|
|
39
43
|
readme = "README.md"
|
|
40
|
-
|
|
44
|
+
classifiers = [
|
|
45
|
+
"Framework :: Django",
|
|
46
|
+
"Framework :: Pytest",
|
|
47
|
+
"Intended Audience :: Developers",
|
|
48
|
+
"License :: OSI Approved :: BSD License",
|
|
49
|
+
]
|
|
41
50
|
|
|
42
51
|
[project.urls]
|
|
43
52
|
Changelog = "https://github.com/flagsmith/flagsmith-common/blob/main/CHANGELOG.md"
|
|
@@ -52,41 +61,32 @@ flagsmith = "common.core.main:main"
|
|
|
52
61
|
[project.entry-points.pytest11]
|
|
53
62
|
flagsmith-test-tools = "common.test_tools.plugin"
|
|
54
63
|
|
|
55
|
-
[
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
64
|
+
[dependency-groups]
|
|
65
|
+
dev = [
|
|
66
|
+
"dj-database-url (>=2.3.0, <3.0.0)",
|
|
67
|
+
"django-stubs (>=5.1.3, <6.0.0)",
|
|
68
|
+
"djangorestframework-stubs (>=3.15.3, <4.0.0)",
|
|
69
|
+
"mypy (>=1.15.0, <2.0.0)",
|
|
70
|
+
"pre-commit",
|
|
71
|
+
"pyfakefs (>=5.7.4, <6.0.0)",
|
|
72
|
+
"pytest (>=8.3.4, <9.0.0)",
|
|
73
|
+
"pytest-asyncio (>=0.25.3, <1.0.0)",
|
|
74
|
+
"pytest-cov (>=6.0.0, <7.0.0)",
|
|
75
|
+
"pytest-django (>=4.10.0, <5.0.0)",
|
|
76
|
+
"pytest-freezegun (>=0.4.2, <1.0.0)",
|
|
77
|
+
"pytest-httpserver (>=1.1.3, <2.0.0)",
|
|
78
|
+
"pytest-mock (>=3.14.0, <4.0.0)",
|
|
79
|
+
"setuptools (>=78.1.1, <79.0.0)",
|
|
80
|
+
"types-simplejson (>=3.20.0.20250326, <4.0.0)",
|
|
81
|
+
"types-python-dateutil (>=2.9.0.20250516, <3.0.0)",
|
|
62
82
|
]
|
|
63
|
-
packages = [
|
|
64
|
-
{ include = "common", from = "src" },
|
|
65
|
-
{ include = "task_processor", from = "src" },
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
[tool.poetry.group.dev.dependencies]
|
|
69
|
-
dj-database-url = "^2.3.0"
|
|
70
|
-
django-stubs = "^5.1.3"
|
|
71
|
-
djangorestframework-stubs = "^3.15.3"
|
|
72
|
-
mypy = "^1.15.0"
|
|
73
|
-
pre-commit = "*"
|
|
74
|
-
pyfakefs = "^5.7.4"
|
|
75
|
-
pytest = "^8.3.4"
|
|
76
|
-
pytest-asyncio = "^0.25.3"
|
|
77
|
-
pytest-cov = "^6.0.0"
|
|
78
|
-
pytest-django = "^4.10.0"
|
|
79
|
-
pytest-freezegun = "^0.4.2"
|
|
80
|
-
pytest-httpserver = "^1.1.3"
|
|
81
|
-
pytest-mock = "^3.14.0"
|
|
82
|
-
ruff = "==0.11.9"
|
|
83
|
-
setuptools = "^78.1.1"
|
|
84
|
-
types-simplejson = "^3.20.0.20250326"
|
|
85
|
-
types-python-dateutil = "^2.9.0.20250516"
|
|
86
83
|
|
|
87
84
|
[build-system]
|
|
88
|
-
requires = ["
|
|
89
|
-
build-backend = "
|
|
85
|
+
requires = ["uv_build>=0.9.17,<0.10.0"]
|
|
86
|
+
build-backend = "uv_build"
|
|
87
|
+
|
|
88
|
+
[tool.uv.build-backend]
|
|
89
|
+
module-name = ["common", "task_processor"]
|
|
90
90
|
|
|
91
91
|
[tool.coverage.report]
|
|
92
92
|
# Regexes for lines to exclude from consideration
|
|
@@ -3,15 +3,13 @@ import logging
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
5
|
import typing
|
|
6
|
-
from tempfile import
|
|
6
|
+
from tempfile import mkdtemp
|
|
7
7
|
|
|
8
8
|
from django.core.management import (
|
|
9
9
|
execute_from_command_line as django_execute_from_command_line,
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
from common.core.cli import healthcheck
|
|
13
|
-
from common.core.constants import DEFAULT_PROMETHEUS_MULTIPROC_DIR_NAME
|
|
14
|
-
from common.core.utils import clear_directory, make_writable_directory
|
|
15
13
|
|
|
16
14
|
logger = logging.getLogger(__name__)
|
|
17
15
|
|
|
@@ -37,13 +35,8 @@ def ensure_cli_env() -> typing.Generator[None, None, None]:
|
|
|
37
35
|
# TODO @khvn26 Move logging setup to here
|
|
38
36
|
|
|
39
37
|
# Prometheus multiproc support
|
|
40
|
-
|
|
41
|
-
"PROMETHEUS_MULTIPROC_DIR"
|
|
42
|
-
os.path.join(gettempdir(), DEFAULT_PROMETHEUS_MULTIPROC_DIR_NAME),
|
|
43
|
-
)
|
|
44
|
-
if os.path.exists(prom_dir):
|
|
45
|
-
clear_directory(prom_dir)
|
|
46
|
-
make_writable_directory(prom_dir)
|
|
38
|
+
if not os.environ.get("PROMETHEUS_MULTIPROC_DIR"):
|
|
39
|
+
os.environ["PROMETHEUS_MULTIPROC_DIR"] = mkdtemp(prefix="flagsmith-prometheus-")
|
|
47
40
|
|
|
48
41
|
# Currently we don't install Flagsmith modules as a package, so we need to add
|
|
49
42
|
# $CWD to the Python path to be able to import them
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
-
import os
|
|
4
3
|
import pathlib
|
|
5
4
|
import random
|
|
6
|
-
import shutil
|
|
7
5
|
from functools import lru_cache
|
|
8
6
|
from itertools import cycle
|
|
9
7
|
from typing import (
|
|
@@ -200,30 +198,3 @@ def using_database_replica(
|
|
|
200
198
|
return manager
|
|
201
199
|
|
|
202
200
|
return manager.db_manager(chosen_replica)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def clear_directory(directory_path: str) -> None:
|
|
206
|
-
"""
|
|
207
|
-
Safely clear a directory including all subdirectories and files.
|
|
208
|
-
"""
|
|
209
|
-
for p in pathlib.Path(directory_path).rglob("*"):
|
|
210
|
-
try:
|
|
211
|
-
# Ensure that the cleanup doesn't silently fail on
|
|
212
|
-
# files and subdirs created by other users.
|
|
213
|
-
p.chmod(0o777)
|
|
214
|
-
except (PermissionError, FileNotFoundError): # pragma: no cover
|
|
215
|
-
pass
|
|
216
|
-
|
|
217
|
-
shutil.rmtree(directory_path, ignore_errors=True)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
def make_writable_directory(directory_path: str) -> None:
|
|
221
|
-
os.makedirs(directory_path, exist_ok=True)
|
|
222
|
-
|
|
223
|
-
try:
|
|
224
|
-
# While `mkdir` sets mode=0o777 by default, this can be affected by umask
|
|
225
|
-
# resulting in lesser permissions for other users. This step ensures the
|
|
226
|
-
# directory is writable for all users.
|
|
227
|
-
os.chmod(directory_path, 0o777)
|
|
228
|
-
except PermissionError: # pragma: no cover
|
|
229
|
-
pass
|
|
@@ -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
|
-
@swagger_auto_schema(method="GET", responses={200: MonitoringSerializer()}) # type: ignore[
|
|
13
|
+
@swagger_auto_schema(method="GET", responses={200: MonitoringSerializer()}) # type: ignore[untyped-decorator]
|
|
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
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/docgen.py
RENAMED
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/start.py
RENAMED
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/management/commands/waitfordb.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/core/templates/docgen-metrics.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/multivariate/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/multivariate/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.0}/src/common/features/versioning/__init__.py
RENAMED
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.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
|
|
File without changes
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.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
|
{flagsmith_common-2.2.6 → flagsmith_common-3.0.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-2.2.6 → flagsmith_common-3.0.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
|