flagsmith-common 2.2.7__tar.gz → 3.1.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 (99) hide show
  1. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/PKG-INFO +53 -79
  2. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/README.md +25 -51
  3. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/pyproject.toml +44 -42
  4. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/test_tools/plugin.py +12 -10
  5. flagsmith_common-3.1.0/src/flagsmith_schemas/constants.py +4 -0
  6. flagsmith_common-3.1.0/src/flagsmith_schemas/dynamodb.py +346 -0
  7. flagsmith_common-3.1.0/src/flagsmith_schemas/pydantic_types.py +22 -0
  8. flagsmith_common-3.1.0/src/flagsmith_schemas/types.py +91 -0
  9. flagsmith_common-3.1.0/src/flagsmith_schemas/validators.py +55 -0
  10. flagsmith_common-3.1.0/src/task_processor/migrations/sql/__init__.py +0 -0
  11. flagsmith_common-3.1.0/src/task_processor/py.typed +0 -0
  12. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/views.py +1 -1
  13. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/LICENSE +0 -0
  14. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/__init__.py +0 -0
  15. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/__init__.py +0 -0
  16. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/app.py +0 -0
  17. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/cli/__init__.py +0 -0
  18. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/cli/healthcheck.py +0 -0
  19. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/constants.py +0 -0
  20. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/logging.py +0 -0
  21. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/main.py +0 -0
  22. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/management/__init__.py +0 -0
  23. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/management/commands/__init__.py +0 -0
  24. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/management/commands/docgen.py +0 -0
  25. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/management/commands/start.py +0 -0
  26. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/management/commands/waitfordb.py +0 -0
  27. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/metrics.py +0 -0
  28. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/middleware.py +0 -0
  29. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/templates/docgen-metrics.md +0 -0
  30. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/urls.py +0 -0
  31. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/utils.py +0 -0
  32. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/core/views.py +0 -0
  33. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/environments/permissions.py +0 -0
  34. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/__init__.py +0 -0
  35. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/multivariate/__init__.py +0 -0
  36. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/multivariate/serializers.py +0 -0
  37. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/serializers.py +0 -0
  38. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/versioning/__init__.py +0 -0
  39. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/features/versioning/serializers.py +0 -0
  40. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/__init__.py +0 -0
  41. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/conf.py +0 -0
  42. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/constants.py +0 -0
  43. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/logging.py +0 -0
  44. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/metrics.py +0 -0
  45. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/middleware.py +0 -0
  46. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/gunicorn/utils.py +0 -0
  47. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/migrations/__init__.py +0 -0
  48. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/migrations/helpers/__init__.py +0 -0
  49. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/migrations/helpers/postgres_helpers.py +0 -0
  50. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/organisations/permissions.py +0 -0
  51. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/projects/permissions.py +0 -0
  52. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/prometheus/__init__.py +0 -0
  53. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/prometheus/utils.py +0 -0
  54. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/py.typed +0 -0
  55. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/test_tools/__init__.py +0 -0
  56. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/test_tools/types.py +0 -0
  57. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/test_tools/utils.py +0 -0
  58. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/common/types.py +0 -0
  59. {flagsmith_common-2.2.7/src/task_processor → flagsmith_common-3.1.0/src/flagsmith_schemas}/__init__.py +0 -0
  60. {flagsmith_common-2.2.7/src/task_processor → flagsmith_common-3.1.0/src/flagsmith_schemas}/py.typed +0 -0
  61. {flagsmith_common-2.2.7/src/task_processor/migrations → flagsmith_common-3.1.0/src/task_processor}/__init__.py +0 -0
  62. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/admin.py +0 -0
  63. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/apps.py +0 -0
  64. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/decorators.py +0 -0
  65. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/exceptions.py +0 -0
  66. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/health.py +0 -0
  67. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/managers.py +0 -0
  68. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/metrics.py +0 -0
  69. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0001_initial.py +0 -0
  70. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0002_healthcheckmodel.py +0 -0
  71. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0003_add_completed_to_task.py +0 -0
  72. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0004_recreate_task_indexes.py +0 -0
  73. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0005_update_conditional_index_conditions.py +0 -0
  74. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0006_auto_20230221_0802.py +0 -0
  75. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0007_add_is_locked.py +0 -0
  76. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0008_add_get_task_to_process_function.py +0 -0
  77. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0009_add_recurring_task_run_first_run_at.py +0 -0
  78. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0010_task_priority.py +0 -0
  79. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0011_add_priority_to_get_tasks_to_process.py +0 -0
  80. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0012_add_locked_at_and_timeout.py +0 -0
  81. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/0013_add_last_picked_at.py +0 -0
  82. {flagsmith_common-2.2.7/src/task_processor/migrations/sql → flagsmith_common-3.1.0/src/task_processor/migrations}/__init__.py +0 -0
  83. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/sql/0008_get_recurring_tasks_to_process.sql +0 -0
  84. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/sql/0008_get_tasks_to_process.sql +0 -0
  85. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/sql/0011_get_tasks_to_process.sql +0 -0
  86. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql +0 -0
  87. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/migrations/sql/0013_get_recurringtasks_to_process.sql +0 -0
  88. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/models.py +0 -0
  89. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/monitoring.py +0 -0
  90. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/processor.py +0 -0
  91. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/routers.py +0 -0
  92. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/serializers.py +0 -0
  93. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/task_registry.py +0 -0
  94. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/task_run_method.py +0 -0
  95. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/tasks.py +0 -0
  96. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/threads.py +0 -0
  97. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/types.py +0 -0
  98. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/urls.py +0 -0
  99. {flagsmith_common-2.2.7 → flagsmith_common-3.1.0}/src/task_processor/utils.py +0 -0
@@ -1,44 +1,45 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flagsmith-common
3
- Version: 2.2.7
3
+ Version: 3.1.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
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Programming Language :: Python :: 3.13
19
- Classifier: Programming Language :: Python :: 3.14
20
- Provides-Extra: test-tools
21
- Requires-Dist: backoff (>=2.2.1,<3.0.0)
22
- Requires-Dist: django (>4,<5)
23
- Requires-Dist: django-health-check
24
- Requires-Dist: djangorestframework
25
- Requires-Dist: djangorestframework-recursive
26
- Requires-Dist: drf-writable-nested
27
- Requires-Dist: drf-yasg (>=1.21.10,<2.0.0)
28
- Requires-Dist: environs (<15)
29
- Requires-Dist: flagsmith-flag-engine
30
- Requires-Dist: gunicorn (>=19.1)
31
- Requires-Dist: prometheus-client (>=0.0.16)
32
- Requires-Dist: psycopg2-binary (>=2.9,<3)
33
- Requires-Dist: pyfakefs (>=5,<6) ; extra == "test-tools"
34
- Requires-Dist: pytest-django (>=4,<5) ; extra == "test-tools"
35
- Requires-Dist: requests
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: typing-extensions ; extra == 'flagsmith-schemas'
25
+ Requires-Dist: backoff>=2.2.1,<3.0.0 ; extra == 'task-processor'
26
+ Requires-Dist: django>4,<6 ; extra == 'task-processor'
27
+ Requires-Dist: django-health-check ; extra == 'task-processor'
28
+ Requires-Dist: prometheus-client>=0.0.16 ; extra == 'task-processor'
29
+ Requires-Dist: pyfakefs>=5,<6 ; extra == 'test-tools'
30
+ Requires-Dist: pytest-django>=4,<5 ; extra == 'test-tools'
31
+ Maintainer: Flagsmith Team
32
+ Maintainer-email: Flagsmith Team <support@flagsmith.com>
33
+ Requires-Python: >=3.11, <4.0
37
34
  Project-URL: Changelog, https://github.com/flagsmith/flagsmith-common/blob/main/CHANGELOG.md
38
35
  Project-URL: Download, https://github.com/flagsmith/flagsmith-common/releases
39
36
  Project-URL: Homepage, https://flagsmith.com
40
37
  Project-URL: Issues, https://github.com/flagsmith/flagsmith-common/issues
41
38
  Project-URL: Repository, https://github.com/flagsmith/flagsmith-common
39
+ Provides-Extra: common-core
40
+ Provides-Extra: flagsmith-schemas
41
+ Provides-Extra: task-processor
42
+ Provides-Extra: test-tools
42
43
  Description-Content-Type: text/markdown
43
44
 
44
45
  # flagsmith-common
@@ -47,54 +48,28 @@ Description-Content-Type: text/markdown
47
48
 
48
49
  Flagsmith's common library
49
50
 
50
- ### Development Setup
51
+ ## Local development
51
52
 
52
- This project uses [Poetry](https://python-poetry.org/) for dependency management and includes a Makefile to simplify common development tasks.
53
+ The project assumes the following tools installed:
53
54
 
54
- #### Prerequisites
55
+ - [uv](https://github.com/astral-sh/uv)
56
+ - [GNU Make](https://www.gnu.org/software/make/)
55
57
 
56
- - Python >= 3.11
57
- - Make
58
+ To list available Makefile targets, run `make help`.
58
59
 
59
- #### Installation
60
+ To set up local development environment, run `make install`.
60
61
 
61
- You can set up your development environment using the provided Makefile:
62
+ To run linters, run `make lint`.
62
63
 
63
- ```bash
64
- # Install everything (pip, poetry, and project dependencies)
65
- make install
64
+ To run tests, run `make test`.
66
65
 
67
- # Individual installation steps are also available
68
- make install-pip # Upgrade pip
69
- make install-poetry # Install Poetry
70
- make install-packages # Install project dependencies
71
- ```
72
-
73
- #### Development
66
+ ## Usage
74
67
 
75
- Run linting checks using pre-commit:
76
-
77
- ```bash
78
- make lint
79
- ```
68
+ ### Installation
80
69
 
81
- Additional options can be passed to the `install-packages` target:
70
+ 1. Install all runtime packages: `uv add flagsmith-common[common-core,task-processor]`
82
71
 
83
- ```bash
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.
72
+ 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
73
 
99
74
  3. Make sure `"common.core"` is in the `INSTALLED_APPS` of your settings module.
100
75
  This enables the `manage.py flagsmith` commands.
@@ -104,11 +79,11 @@ This enables the `route` label for Prometheus HTTP metrics.
104
79
 
105
80
  5. To enable the `/metrics` endpoint, set the `PROMETHEUS_ENABLED` setting to `True`.
106
81
 
107
- #### Test tools
82
+ ### Test tools
108
83
 
109
- ##### Fixtures
84
+ #### Fixtures
110
85
 
111
- ###### `assert_metric`
86
+ ##### `assert_metric`
112
87
 
113
88
  To test your metrics using the `assert_metric` fixture:
114
89
 
@@ -127,44 +102,44 @@ def test_my_code__expected_metrics(assert_metric: AssertMetricFixture) -> None:
127
102
  )
128
103
  ```
129
104
 
130
- ###### `saas_mode`
105
+ ##### `saas_mode`
131
106
 
132
107
  The `saas_mode` fixture makes all `common.core.utils.is_saas` calls return `True`.
133
108
 
134
- ###### `enterprise_mode`
109
+ ##### `enterprise_mode`
135
110
 
136
111
  The `enterprise_mode` fixture makes all `common.core.utils.is_enterprise` calls return `True`.
137
112
 
138
- ##### Markers
113
+ #### Markers
139
114
 
140
- ###### `pytest.mark.saas_mode`
115
+ ##### `pytest.mark.saas_mode`
141
116
 
142
117
  Use this mark to auto-use the `saas_mode` fixture.
143
118
 
144
- ###### `pytest.mark.enterprise_mode`
119
+ ##### `pytest.mark.enterprise_mode`
145
120
 
146
121
  Use this mark to auto-use the `enterprise_mode` fixture.
147
122
 
148
- #### Metrics
123
+ ### Metrics
149
124
 
150
125
  Flagsmith uses Prometheus to track performance metrics.
151
126
 
152
127
  The following default metrics are exposed:
153
128
 
154
- ##### Common metrics
129
+ #### Common metrics
155
130
 
156
131
  - `flagsmith_build_info`: Has the labels `version` and `ci_commit_sha`.
157
132
  - `flagsmith_http_server_request_duration_seconds`: Histogram labeled with `method`, `route`, and `response_status`.
158
133
  - `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`.
134
+ - `flagsmith_http_server_response_size_bytes`: Histogram labeled with `method`, `route`, and `response_status`.
160
135
  - `flagsmith_task_processor_enqueued_tasks_total`: Counter labeled with `task_identifier`.
161
136
 
162
- ##### Task Processor metrics
137
+ #### Task Processor metrics
163
138
 
164
139
  - `flagsmith_task_processor_finished_tasks_total`: Counter labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
165
140
  - `flagsmith_task_processor_task_duration_seconds`: Histogram labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
166
141
 
167
- ##### Guidelines
142
+ #### Guidelines
168
143
 
169
144
  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
145
 
@@ -193,4 +168,3 @@ For testing your metrics, refer to [`assert_metric` documentation][5].
193
168
  [3]: https://docs.gunicorn.org/en/stable/design.html#server-model
194
169
  [4]: https://prometheus.github.io/client_python/multiprocess
195
170
  [5]: #assert_metric
196
-
@@ -4,54 +4,28 @@
4
4
 
5
5
  Flagsmith's common library
6
6
 
7
- ### Development Setup
7
+ ## Local development
8
8
 
9
- This project uses [Poetry](https://python-poetry.org/) for dependency management and includes a Makefile to simplify common development tasks.
9
+ The project assumes the following tools installed:
10
10
 
11
- #### Prerequisites
11
+ - [uv](https://github.com/astral-sh/uv)
12
+ - [GNU Make](https://www.gnu.org/software/make/)
12
13
 
13
- - Python >= 3.11
14
- - Make
14
+ To list available Makefile targets, run `make help`.
15
15
 
16
- #### Installation
16
+ To set up local development environment, run `make install`.
17
17
 
18
- You can set up your development environment using the provided Makefile:
18
+ To run linters, run `make lint`.
19
19
 
20
- ```bash
21
- # Install everything (pip, poetry, and project dependencies)
22
- make install
20
+ To run tests, run `make test`.
23
21
 
24
- # Individual installation steps are also available
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
- #### Installation
24
+ ### Installation
51
25
 
52
- 1. `poetry add flagsmith-common`
26
+ 1. Install all runtime packages: `uv add flagsmith-common[common-core,task-processor]`
53
27
 
54
- 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.
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
- #### Test tools
38
+ ### Test tools
65
39
 
66
- ##### Fixtures
40
+ #### Fixtures
67
41
 
68
- ###### `assert_metric`
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
- ###### `saas_mode`
61
+ ##### `saas_mode`
88
62
 
89
63
  The `saas_mode` fixture makes all `common.core.utils.is_saas` calls return `True`.
90
64
 
91
- ###### `enterprise_mode`
65
+ ##### `enterprise_mode`
92
66
 
93
67
  The `enterprise_mode` fixture makes all `common.core.utils.is_enterprise` calls return `True`.
94
68
 
95
- ##### Markers
69
+ #### Markers
96
70
 
97
- ###### `pytest.mark.saas_mode`
71
+ ##### `pytest.mark.saas_mode`
98
72
 
99
73
  Use this mark to auto-use the `saas_mode` fixture.
100
74
 
101
- ###### `pytest.mark.enterprise_mode`
75
+ ##### `pytest.mark.enterprise_mode`
102
76
 
103
77
  Use this mark to auto-use the `enterprise_mode` fixture.
104
78
 
105
- #### Metrics
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
- ##### Common metrics
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
- ##### Task Processor metrics
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
- ##### Guidelines
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,32 @@
1
1
  [project]
2
2
  name = "flagsmith-common"
3
- version = "2.2.7"
3
+ version = "3.1.0"
4
4
  description = "Flagsmith's common library"
5
5
  requires-python = ">=3.11,<4.0"
6
- dependencies = [
7
- "backoff (>=2.2.1,<3.0.0)",
8
- "django (>4,<5)",
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
- optional-dependencies = { test-tools = [
23
- "pyfakefs (>=5,<6)",
24
- "pytest-django (>=4,<5)",
23
+ ], task-processor = [
24
+ "backoff (>=2.2.1,<3.0.0)",
25
+ "django (>4,<6)",
26
+ "django-health-check",
27
+ "prometheus-client (>=0.0.16)",
28
+ ], flagsmith-schemas = [
29
+ "typing_extensions",
25
30
  ] }
26
31
  authors = [
27
32
  { name = "Matthew Elwell" },
@@ -37,7 +42,12 @@ maintainers = [{ name = "Flagsmith Team", email = "support@flagsmith.com" }]
37
42
  license = "BSD-3-Clause"
38
43
  license-files = ["LICENSE"]
39
44
  readme = "README.md"
40
- dynamic = ["classifiers"]
45
+ classifiers = [
46
+ "Framework :: Django",
47
+ "Framework :: Pytest",
48
+ "Intended Audience :: Developers",
49
+ "License :: OSI Approved :: BSD License",
50
+ ]
41
51
 
42
52
  [project.urls]
43
53
  Changelog = "https://github.com/flagsmith/flagsmith-common/blob/main/CHANGELOG.md"
@@ -52,41 +62,33 @@ flagsmith = "common.core.main:main"
52
62
  [project.entry-points.pytest11]
53
63
  flagsmith-test-tools = "common.test_tools.plugin"
54
64
 
55
- [tool.poetry]
56
- requires-poetry = ">=2.0"
57
- classifiers = [
58
- "Framework :: Django",
59
- "Framework :: Pytest",
60
- "Intended Audience :: Developers",
61
- "License :: OSI Approved :: BSD License",
65
+ [dependency-groups]
66
+ dev = [
67
+ "dj-database-url (>=2.3.0, <3.0.0)",
68
+ "django-stubs (>=5.1.3, <6.0.0)",
69
+ "djangorestframework-stubs (>=3.15.3, <4.0.0)",
70
+ "mypy (>=1.15.0, <2.0.0)",
71
+ "pre-commit",
72
+ "pydantic>=2.12.5",
73
+ "pyfakefs (>=5.7.4, <6.0.0)",
74
+ "pytest (>=8.3.4, <9.0.0)",
75
+ "pytest-asyncio (>=0.25.3, <1.0.0)",
76
+ "pytest-cov (>=6.0.0, <7.0.0)",
77
+ "pytest-django (>=4.10.0, <5.0.0)",
78
+ "pytest-freezegun (>=0.4.2, <1.0.0)",
79
+ "pytest-httpserver (>=1.1.3, <2.0.0)",
80
+ "pytest-mock (>=3.14.0, <4.0.0)",
81
+ "setuptools (>=78.1.1, <79.0.0)",
82
+ "types-python-dateutil (>=2.9.0.20250516, <3.0.0)",
83
+ "types-simplejson (>=3.20.0.20250326, <4.0.0)",
62
84
  ]
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
85
 
87
86
  [build-system]
88
- requires = ["poetry-core"]
89
- build-backend = "poetry.core.masonry.api"
87
+ requires = ["uv_build>=0.9.17,<0.10.0"]
88
+ build-backend = "uv_build"
89
+
90
+ [tool.uv.build-backend]
91
+ module-name = ["common", "task_processor", "flagsmith_schemas"]
90
92
 
91
93
  [tool.coverage.report]
92
94
  # Regexes for lines to exclude from consideration
@@ -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,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