dbt-copilot-python 0.1.4__tar.gz → 0.1.5.dev2__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.
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/PKG-INFO +53 -15
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/README.md +47 -14
- dbt_copilot_python-0.1.5.dev2/dbt_copilot_python/celery_health_check/__init__.py +0 -0
- dbt_copilot_python-0.1.5.dev2/dbt_copilot_python/celery_health_check/const.py +5 -0
- dbt_copilot_python-0.1.5.dev2/dbt_copilot_python/celery_health_check/healthcheck.py +58 -0
- dbt_copilot_python-0.1.5.dev2/dbt_copilot_python/celery_health_check/heartbeat.py +29 -0
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/pyproject.toml +7 -3
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/LICENSE +0 -0
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/dbt_copilot_python/__init__.py +0 -0
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/dbt_copilot_python/database.py +0 -0
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/dbt_copilot_python/network.py +0 -0
- {dbt_copilot_python-0.1.4 → dbt_copilot_python-0.1.5.dev2}/dbt_copilot_python/utility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dbt-copilot-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5.dev2
|
|
4
4
|
Summary: Helper functions to run Django and Flask applications in AWS Copilot/ECS.
|
|
5
5
|
Author: Department for Business and Trade Platform Team
|
|
6
6
|
Author-email: sre-team@digital.trade.gov.uk
|
|
@@ -9,11 +9,16 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.9
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Requires-Dist: celery (>=5.3.6,<6.0.0)
|
|
12
14
|
Requires-Dist: opentelemetry-distro (==0.43b0)
|
|
13
15
|
Requires-Dist: opentelemetry-exporter-otlp (==1.22.0)
|
|
14
16
|
Requires-Dist: opentelemetry-instrumentation-wsgi (==0.43b0)
|
|
15
17
|
Requires-Dist: opentelemetry-propagator-aws-xray (>=1.0.1,<2.0.0)
|
|
16
18
|
Requires-Dist: opentelemetry-sdk-extension-aws (>=2.0.1,<3.0.0)
|
|
19
|
+
Requires-Dist: pytest-celery (>=0.0.0,<0.0.1)
|
|
20
|
+
Requires-Dist: pytest-mock (>=3.12.0,<4.0.0)
|
|
21
|
+
Requires-Dist: redis (>=5.0.1,<6.0.0)
|
|
17
22
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
18
23
|
Description-Content-Type: text/markdown
|
|
19
24
|
|
|
@@ -27,19 +32,17 @@ A set of utility functions for running Django & Flask apps in AWS ECS via AWS Co
|
|
|
27
32
|
|
|
28
33
|
### Installation
|
|
29
34
|
|
|
30
|
-
```
|
|
35
|
+
```shell
|
|
31
36
|
pip install dbt-copilot-python
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
### Usage
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#### ALLOWED_HOSTS
|
|
41
|
+
#### `ALLOWED_HOSTS` setting
|
|
39
42
|
|
|
40
|
-
Add the ECS container IP to `ALLOWED_HOSTS` so that the Application Load Balancer (ALB) healthcheck will succeed:
|
|
43
|
+
Add the ECS container IP to `ALLOWED_HOSTS` setting so that the Application Load Balancer (ALB) healthcheck will succeed:
|
|
41
44
|
|
|
42
|
-
```
|
|
45
|
+
```python
|
|
43
46
|
from dbt_copilot_python.network import setup_allowed_hosts
|
|
44
47
|
|
|
45
48
|
ALLOWED_HOSTS = [...]
|
|
@@ -47,7 +50,42 @@ ALLOWED_HOSTS = [...]
|
|
|
47
50
|
ALLOWED_HOSTS = setup_allowed_hosts(ALLOWED_HOSTS)
|
|
48
51
|
```
|
|
49
52
|
|
|
50
|
-
####
|
|
53
|
+
#### Celery health check
|
|
54
|
+
|
|
55
|
+
Add the health check in your application's Celery config file...
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from dbt_copilot_python.celery_health_check import healthcheck
|
|
59
|
+
|
|
60
|
+
celery_app = Celery("application_name")
|
|
61
|
+
...
|
|
62
|
+
|
|
63
|
+
celery_app = healthcheck.setup(celery_app)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Add the health check to the Celery worker service in `docker-compose.yml`...
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
healthcheck:
|
|
70
|
+
test: [ "CMD-SHELL", "python -m dbt_copilot_python.celery_health_check.healthcheck" ]
|
|
71
|
+
interval: 10s
|
|
72
|
+
timeout: 5s
|
|
73
|
+
retries: 2
|
|
74
|
+
start_period: 5s
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
In your `*-deploy` codebase, add the health check to the Celery worker service in `copilot/celery-worker/manifest.yml`...
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
healthcheck:
|
|
81
|
+
command: [ "CMD-SHELL", "launcher bash -c 'python -m dbt_copilot_python.celery_health_check.healthcheck'" ]
|
|
82
|
+
interval: 10s
|
|
83
|
+
timeout: 5s
|
|
84
|
+
retries: 2
|
|
85
|
+
start_period: 10s
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### `DATABASES` setting
|
|
51
89
|
|
|
52
90
|
To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secrets Manager, there are two options.
|
|
53
91
|
|
|
@@ -55,7 +93,7 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
55
93
|
|
|
56
94
|
Note: This is dependent on the [`dj-database-url`](https://pypi.org/project/dj-database-url/) package which can be installed via `pip install dj-database-url`.
|
|
57
95
|
|
|
58
|
-
```
|
|
96
|
+
```python
|
|
59
97
|
import dj_database_url
|
|
60
98
|
|
|
61
99
|
from dbt_copilot_python.database import database_url_from_env
|
|
@@ -69,7 +107,7 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
69
107
|
|
|
70
108
|
2. Configure the `DATABASES` setting to use a dictionary containing the settings:
|
|
71
109
|
|
|
72
|
-
```
|
|
110
|
+
```python
|
|
73
111
|
from dbt-copilot-python.database import database_from_env
|
|
74
112
|
|
|
75
113
|
DATABASES = database_from_env("DATABASE_ENV_VAR_KEY")
|
|
@@ -83,13 +121,13 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
83
121
|
|
|
84
122
|
### Install dependencies & pre-commit hooks
|
|
85
123
|
|
|
86
|
-
```
|
|
124
|
+
```shell
|
|
87
125
|
poetry install && poetry run pre-commit install
|
|
88
126
|
```
|
|
89
127
|
|
|
90
128
|
### Run the tests
|
|
91
129
|
|
|
92
|
-
```
|
|
130
|
+
```shell
|
|
93
131
|
poetry run pytest
|
|
94
132
|
```
|
|
95
133
|
|
|
@@ -104,7 +142,7 @@ To publish the Python package `dbt-copilot-python`, you will need an API token.
|
|
|
104
142
|
|
|
105
143
|
Update the version, as the same version cannot be published to PyPi.
|
|
106
144
|
|
|
107
|
-
```
|
|
145
|
+
```shell
|
|
108
146
|
poetry version patch
|
|
109
147
|
```
|
|
110
148
|
|
|
@@ -112,7 +150,7 @@ More options for the `version` command can be found in the [Poetry documentation
|
|
|
112
150
|
|
|
113
151
|
Build the Python package.
|
|
114
152
|
|
|
115
|
-
```
|
|
153
|
+
```shell
|
|
116
154
|
poetry build
|
|
117
155
|
```
|
|
118
156
|
|
|
@@ -120,7 +158,7 @@ Publish the Python package.
|
|
|
120
158
|
|
|
121
159
|
_Note: Make sure your Pull Request (PR) is approved and contains the version upgrade in `pyproject.toml` before publishing the package._
|
|
122
160
|
|
|
123
|
-
```
|
|
161
|
+
```shell
|
|
124
162
|
poetry publish
|
|
125
163
|
```
|
|
126
164
|
|
|
@@ -8,19 +8,17 @@ A set of utility functions for running Django & Flask apps in AWS ECS via AWS Co
|
|
|
8
8
|
|
|
9
9
|
### Installation
|
|
10
10
|
|
|
11
|
-
```
|
|
11
|
+
```shell
|
|
12
12
|
pip install dbt-copilot-python
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### Usage
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
#### ALLOWED_HOSTS
|
|
17
|
+
#### `ALLOWED_HOSTS` setting
|
|
20
18
|
|
|
21
|
-
Add the ECS container IP to `ALLOWED_HOSTS` so that the Application Load Balancer (ALB) healthcheck will succeed:
|
|
19
|
+
Add the ECS container IP to `ALLOWED_HOSTS` setting so that the Application Load Balancer (ALB) healthcheck will succeed:
|
|
22
20
|
|
|
23
|
-
```
|
|
21
|
+
```python
|
|
24
22
|
from dbt_copilot_python.network import setup_allowed_hosts
|
|
25
23
|
|
|
26
24
|
ALLOWED_HOSTS = [...]
|
|
@@ -28,7 +26,42 @@ ALLOWED_HOSTS = [...]
|
|
|
28
26
|
ALLOWED_HOSTS = setup_allowed_hosts(ALLOWED_HOSTS)
|
|
29
27
|
```
|
|
30
28
|
|
|
31
|
-
####
|
|
29
|
+
#### Celery health check
|
|
30
|
+
|
|
31
|
+
Add the health check in your application's Celery config file...
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from dbt_copilot_python.celery_health_check import healthcheck
|
|
35
|
+
|
|
36
|
+
celery_app = Celery("application_name")
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
celery_app = healthcheck.setup(celery_app)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Add the health check to the Celery worker service in `docker-compose.yml`...
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
healthcheck:
|
|
46
|
+
test: [ "CMD-SHELL", "python -m dbt_copilot_python.celery_health_check.healthcheck" ]
|
|
47
|
+
interval: 10s
|
|
48
|
+
timeout: 5s
|
|
49
|
+
retries: 2
|
|
50
|
+
start_period: 5s
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
In your `*-deploy` codebase, add the health check to the Celery worker service in `copilot/celery-worker/manifest.yml`...
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
healthcheck:
|
|
57
|
+
command: [ "CMD-SHELL", "launcher bash -c 'python -m dbt_copilot_python.celery_health_check.healthcheck'" ]
|
|
58
|
+
interval: 10s
|
|
59
|
+
timeout: 5s
|
|
60
|
+
retries: 2
|
|
61
|
+
start_period: 10s
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### `DATABASES` setting
|
|
32
65
|
|
|
33
66
|
To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secrets Manager, there are two options.
|
|
34
67
|
|
|
@@ -36,7 +69,7 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
36
69
|
|
|
37
70
|
Note: This is dependent on the [`dj-database-url`](https://pypi.org/project/dj-database-url/) package which can be installed via `pip install dj-database-url`.
|
|
38
71
|
|
|
39
|
-
```
|
|
72
|
+
```python
|
|
40
73
|
import dj_database_url
|
|
41
74
|
|
|
42
75
|
from dbt_copilot_python.database import database_url_from_env
|
|
@@ -50,7 +83,7 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
50
83
|
|
|
51
84
|
2. Configure the `DATABASES` setting to use a dictionary containing the settings:
|
|
52
85
|
|
|
53
|
-
```
|
|
86
|
+
```python
|
|
54
87
|
from dbt-copilot-python.database import database_from_env
|
|
55
88
|
|
|
56
89
|
DATABASES = database_from_env("DATABASE_ENV_VAR_KEY")
|
|
@@ -64,13 +97,13 @@ To configure the `DATABASES` setting from an RDS JSON object stored in AWS Secre
|
|
|
64
97
|
|
|
65
98
|
### Install dependencies & pre-commit hooks
|
|
66
99
|
|
|
67
|
-
```
|
|
100
|
+
```shell
|
|
68
101
|
poetry install && poetry run pre-commit install
|
|
69
102
|
```
|
|
70
103
|
|
|
71
104
|
### Run the tests
|
|
72
105
|
|
|
73
|
-
```
|
|
106
|
+
```shell
|
|
74
107
|
poetry run pytest
|
|
75
108
|
```
|
|
76
109
|
|
|
@@ -85,7 +118,7 @@ To publish the Python package `dbt-copilot-python`, you will need an API token.
|
|
|
85
118
|
|
|
86
119
|
Update the version, as the same version cannot be published to PyPi.
|
|
87
120
|
|
|
88
|
-
```
|
|
121
|
+
```shell
|
|
89
122
|
poetry version patch
|
|
90
123
|
```
|
|
91
124
|
|
|
@@ -93,7 +126,7 @@ More options for the `version` command can be found in the [Poetry documentation
|
|
|
93
126
|
|
|
94
127
|
Build the Python package.
|
|
95
128
|
|
|
96
|
-
```
|
|
129
|
+
```shell
|
|
97
130
|
poetry build
|
|
98
131
|
```
|
|
99
132
|
|
|
@@ -101,7 +134,7 @@ Publish the Python package.
|
|
|
101
134
|
|
|
102
135
|
_Note: Make sure your Pull Request (PR) is approved and contains the version upgrade in `pyproject.toml` before publishing the package._
|
|
103
136
|
|
|
104
|
-
```
|
|
137
|
+
```shell
|
|
105
138
|
poetry publish
|
|
106
139
|
```
|
|
107
140
|
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# See https://medium.com/ambient-innovation/health-checks-for-celery-in-kubernetes-cf3274a3e106
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from datetime import UTC
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from celery import signals
|
|
8
|
+
|
|
9
|
+
from .const import HEARTBEAT_FILE
|
|
10
|
+
from .const import READINESS_FILE
|
|
11
|
+
from .heartbeat import HeartBeat
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def on_worker_ready(**_):
|
|
15
|
+
READINESS_FILE.touch()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def on_worker_shutdown(**_):
|
|
19
|
+
READINESS_FILE.unlink(missing_ok=True)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def setup(celery_app=None):
|
|
23
|
+
signals.worker_ready.connect(on_worker_ready)
|
|
24
|
+
|
|
25
|
+
signals.worker_shutdown.connect(on_worker_shutdown)
|
|
26
|
+
|
|
27
|
+
celery_app.steps["worker"].add(HeartBeat)
|
|
28
|
+
return celery_app
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def check_health():
|
|
32
|
+
if not READINESS_FILE.is_file():
|
|
33
|
+
print("Healthcheck: Celery readiness file NOT found.")
|
|
34
|
+
sys.exit(1)
|
|
35
|
+
|
|
36
|
+
if not HEARTBEAT_FILE.is_file():
|
|
37
|
+
print("Healthcheck: Celery heartbeat file NOT found.")
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
|
|
40
|
+
heartbeat_timestamp = float(HEARTBEAT_FILE.read_text())
|
|
41
|
+
current_timestamp = datetime.now(UTC).timestamp()
|
|
42
|
+
time_diff = current_timestamp - heartbeat_timestamp
|
|
43
|
+
if time_diff > 60:
|
|
44
|
+
print(
|
|
45
|
+
"Healthcheck: Celery Worker heartbeat file timestamp "
|
|
46
|
+
+ "DOES NOT match the given constraint."
|
|
47
|
+
)
|
|
48
|
+
sys.exit(1)
|
|
49
|
+
|
|
50
|
+
print(
|
|
51
|
+
"Healthcheck: Celery Worker heartbeat file found and timestamp "
|
|
52
|
+
+ "matches the given constraint."
|
|
53
|
+
)
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
check_health()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from datetime import UTC
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
from celery import bootsteps
|
|
5
|
+
|
|
6
|
+
from .const import HEARTBEAT_FILE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HeartBeat(bootsteps.StartStopStep):
|
|
10
|
+
requires = {"celery.worker.components:Timer"}
|
|
11
|
+
|
|
12
|
+
def __init__(self, parent, **kwargs):
|
|
13
|
+
super().__init__(parent, **kwargs)
|
|
14
|
+
self.requests = []
|
|
15
|
+
self.tref = None
|
|
16
|
+
|
|
17
|
+
def start(self, worker):
|
|
18
|
+
self.tref = worker.timer.call_repeatedly(
|
|
19
|
+
1.0,
|
|
20
|
+
self.update_heartbeat_file,
|
|
21
|
+
(worker,),
|
|
22
|
+
priority=10,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def stop(self, worker):
|
|
26
|
+
HEARTBEAT_FILE.unlink(missing_ok=True)
|
|
27
|
+
|
|
28
|
+
def update_heartbeat_file(self, worker):
|
|
29
|
+
HEARTBEAT_FILE.write_text(str(datetime.timestamp(datetime.now(UTC))))
|
|
@@ -3,7 +3,7 @@ line-length = 100
|
|
|
3
3
|
|
|
4
4
|
[tool.poetry]
|
|
5
5
|
name = "dbt-copilot-python"
|
|
6
|
-
version = "0.1.
|
|
6
|
+
version = "0.1.5-dev2"
|
|
7
7
|
description = "Helper functions to run Django and Flask applications in AWS Copilot/ECS."
|
|
8
8
|
authors = ["Department for Business and Trade Platform Team <sre-team@digital.trade.gov.uk>"]
|
|
9
9
|
readme = "README.md"
|
|
@@ -11,17 +11,21 @@ packages = [{ include = "dbt_copilot_python" }]
|
|
|
11
11
|
|
|
12
12
|
[tool.poetry.dependencies]
|
|
13
13
|
python = "^3.9"
|
|
14
|
-
|
|
14
|
+
celery = "^5.3.6"
|
|
15
15
|
opentelemetry-distro = "0.43b0"
|
|
16
16
|
opentelemetry-exporter-otlp = "1.22.0"
|
|
17
17
|
opentelemetry-instrumentation-wsgi = "0.43b0"
|
|
18
18
|
opentelemetry-propagator-aws-xray = "^1.0.1"
|
|
19
19
|
opentelemetry-sdk-extension-aws = "^2.0.1"
|
|
20
|
+
requests = "^2.31.0"
|
|
21
|
+
pytest-celery = "^0.0.0"
|
|
22
|
+
redis = "^5.0.1"
|
|
23
|
+
pytest-mock = "^3.12.0"
|
|
20
24
|
|
|
21
25
|
[tool.poetry.group.dev.dependencies]
|
|
26
|
+
pre-commit = "^3.3.3"
|
|
22
27
|
pytest = "^7.3.2"
|
|
23
28
|
requests-mock = "^1.11.0"
|
|
24
|
-
pre-commit = "^3.3.3"
|
|
25
29
|
tox = "^4.6.3"
|
|
26
30
|
|
|
27
31
|
[build-system]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|