processcube-etw-library 2026.1.22.112808b0__tar.gz → 2026.1.22.130934b0__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.
- processcube_etw_library-2026.1.22.130934b0/PKG-INFO +197 -0
- processcube_etw_library-2026.1.22.130934b0/README.md +184 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/create_external_task_client.py +0 -4
- processcube_etw_library-2026.1.22.130934b0/src/processcube_etw_library.egg-info/PKG-INFO +197 -0
- processcube_etw_library-2026.1.22.112808b0/PKG-INFO +0 -24
- processcube_etw_library-2026.1.22.112808b0/README.md +0 -11
- processcube_etw_library-2026.1.22.112808b0/src/processcube_etw_library.egg-info/PKG-INFO +0 -24
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/.github/workflows/build_and_publish.yml +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/.gitignore +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/.python-version +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/pyproject.toml +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/setup.cfg +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/__init__.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/etw_app.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/__init__.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/built_in.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/check.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/handlers.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/models.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/registry.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/health/routes.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/identity_provider.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/server_config.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/settings.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library/typed_handler.py +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library.egg-info/SOURCES.txt +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library.egg-info/dependency_links.txt +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library.egg-info/requires.txt +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/src/processcube_etw_library.egg-info/top_level.txt +0 -0
- {processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/uv.lock +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: processcube-etw-library
|
|
3
|
+
Version: 2026.1.22.130934b0
|
|
4
|
+
Summary: A library to create ETW apps with the ProcessCube platform.
|
|
5
|
+
Author-email: Jeremy Hill <jeremy.hill@profection.de>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: fastapi[standard]>=0.128.0
|
|
10
|
+
Requires-Dist: oauth2-client>=1.4.2
|
|
11
|
+
Requires-Dist: processcube-client>=5.0.0
|
|
12
|
+
Requires-Dist: tenacity>=9.1.2
|
|
13
|
+
|
|
14
|
+
# ProcessCube ETW Library
|
|
15
|
+
|
|
16
|
+
Build External Task Workers (ETW) for ProcessCube, featuring health checks, typed handlers, and environment-based configuration.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv add processcube-etw-library
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
### Environment Variables
|
|
27
|
+
|
|
28
|
+
The library uses environment variables for configuration. You can set these in your environment or in a `.env` file in your project root.
|
|
29
|
+
|
|
30
|
+
| Variable | Default | Description |
|
|
31
|
+
| ------------------------------------ | -------------------------------------- | ------------------------------------------------ |
|
|
32
|
+
| `PROCESSCUBE_ENGINE_URL` | `http://localhost:56000` | URL of the ProcessCube Engine |
|
|
33
|
+
| `PROCESSCUBE_AUTHORITY_URL` | Auto-discovered from engine | URL of the ProcessCube Authority (OAuth server) |
|
|
34
|
+
| `PROCESSCUBE_ETW_CLIENT_ID` | `test_etw` | OAuth client ID for the External Task Worker |
|
|
35
|
+
| `PROCESSCUBE_ETW_CLIENT_SECRET` | `3ef62eb3-fe49-4c2c-ba6f-73e4d234321b` | OAuth client secret for the External Task Worker |
|
|
36
|
+
| `PROCESSCUBE_ETW_CLIENT_SCOPES` | `engine_etw` | OAuth scopes for the External Task Worker |
|
|
37
|
+
| `MAX_GET_OAUTH_ACCESS_TOKEN_RETRIES` | `10` | Maximum retries for obtaining OAuth access token |
|
|
38
|
+
| `ENVIRONMENT` | `development` | Environment mode (`development` or `production`) |
|
|
39
|
+
|
|
40
|
+
#### Example `.env` File
|
|
41
|
+
|
|
42
|
+
```env
|
|
43
|
+
PROCESSCUBE_ENGINE_URL=http://localhost:56000
|
|
44
|
+
PROCESSCUBE_ETW_CLIENT_ID=my_etw_client
|
|
45
|
+
PROCESSCUBE_ETW_CLIENT_SECRET=my_secret_key
|
|
46
|
+
PROCESSCUBE_ETW_CLIENT_SCOPES=engine_etw
|
|
47
|
+
ENVIRONMENT=production
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Extending Settings
|
|
51
|
+
|
|
52
|
+
You can extend the base settings class to add your own environment variables:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from pydantic import Field
|
|
56
|
+
from processcube_etw_library.settings import ETWSettings, load_settings
|
|
57
|
+
|
|
58
|
+
class MyAppSettings(ETWSettings):
|
|
59
|
+
database_url: str = Field(default="sqlite:///app.db")
|
|
60
|
+
api_key: str = Field(default="")
|
|
61
|
+
|
|
62
|
+
# Load settings with your custom class
|
|
63
|
+
settings = load_settings(MyAppSettings)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### Start the ETW Application
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
72
|
+
|
|
73
|
+
# Create the application
|
|
74
|
+
app = new_external_task_worker_app()
|
|
75
|
+
|
|
76
|
+
# Run the application
|
|
77
|
+
app.run()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Subscribe to External Task Topics
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
84
|
+
|
|
85
|
+
app = new_external_task_worker_app()
|
|
86
|
+
|
|
87
|
+
def my_handler(task):
|
|
88
|
+
# Process the task
|
|
89
|
+
result = {"processed": True}
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
# Subscribe to a topic
|
|
93
|
+
app.subscribe_to_external_task_for_topic("my-topic", my_handler)
|
|
94
|
+
|
|
95
|
+
app.run()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Typed Handlers
|
|
99
|
+
|
|
100
|
+
Use typed handlers for automatic payload validation with Pydantic models:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from pydantic import BaseModel
|
|
104
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
105
|
+
|
|
106
|
+
class MyInput(BaseModel):
|
|
107
|
+
name: str
|
|
108
|
+
value: int
|
|
109
|
+
|
|
110
|
+
class MyOutput(BaseModel):
|
|
111
|
+
result: str
|
|
112
|
+
|
|
113
|
+
app = new_external_task_worker_app()
|
|
114
|
+
|
|
115
|
+
def my_typed_handler(payload: MyInput) -> MyOutput:
|
|
116
|
+
return MyOutput(result=f"Processed {payload.name} with value {payload.value}")
|
|
117
|
+
|
|
118
|
+
app.subscribe_to_external_task_for_topic_typed("my-typed-topic", my_typed_handler)
|
|
119
|
+
|
|
120
|
+
app.run()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Add a Custom Health Check
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
127
|
+
from processcube_etw_library.health import HealthCheck, create_url_health_check
|
|
128
|
+
|
|
129
|
+
app = new_external_task_worker_app()
|
|
130
|
+
|
|
131
|
+
# Add a URL-based health check
|
|
132
|
+
app.add_health_check(
|
|
133
|
+
HealthCheck(
|
|
134
|
+
create_url_health_check("http://my-service:8080/health"),
|
|
135
|
+
service_name="My Service",
|
|
136
|
+
tags=["backend", "api"],
|
|
137
|
+
comments=["Checks if My Service is reachable"],
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Add a custom health check function
|
|
142
|
+
def check_database():
|
|
143
|
+
# Return True if healthy, False otherwise
|
|
144
|
+
try:
|
|
145
|
+
# Your database check logic here
|
|
146
|
+
return True
|
|
147
|
+
except Exception:
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
app.add_health_check(
|
|
151
|
+
HealthCheck(
|
|
152
|
+
check_database,
|
|
153
|
+
service_name="Database",
|
|
154
|
+
tags=["backend", "database"],
|
|
155
|
+
comments=["Checks database connectivity"],
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
app.run()
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Managing Health Checks
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
# Get all registered health checks
|
|
166
|
+
checks = app.get_health_checks()
|
|
167
|
+
|
|
168
|
+
# Get a specific health check by service name
|
|
169
|
+
db_check = app.get_health_check("Database")
|
|
170
|
+
|
|
171
|
+
# Remove a health check
|
|
172
|
+
app.remove_health_check("Database")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Disabling Built-in Health Checks
|
|
176
|
+
|
|
177
|
+
By default, the library registers health checks for the ProcessCube Engine and Authority. You can disable these:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
app = new_external_task_worker_app(built_in_health_checks=False)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Health Endpoints
|
|
184
|
+
|
|
185
|
+
The application exposes health endpoints at `/healthyz` and `/readyz` that return the status of all registered health checks.
|
|
186
|
+
To check if the application is running without performing health checks, use `/livez`.
|
|
187
|
+
|
|
188
|
+
## Server Configuration
|
|
189
|
+
|
|
190
|
+
The server configuration is determined by the `ENVIRONMENT` variable:
|
|
191
|
+
|
|
192
|
+
| Setting | Development | Production |
|
|
193
|
+
| ---------- | ----------- | ---------- |
|
|
194
|
+
| Host | `0.0.0.0` | `0.0.0.0` |
|
|
195
|
+
| Port | `8000` | `8000` |
|
|
196
|
+
| Log Level | `debug` | `warning` |
|
|
197
|
+
| Access Log | `true` | `false` |
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# ProcessCube ETW Library
|
|
2
|
+
|
|
3
|
+
Build External Task Workers (ETW) for ProcessCube, featuring health checks, typed handlers, and environment-based configuration.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv add processcube-etw-library
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
### Environment Variables
|
|
14
|
+
|
|
15
|
+
The library uses environment variables for configuration. You can set these in your environment or in a `.env` file in your project root.
|
|
16
|
+
|
|
17
|
+
| Variable | Default | Description |
|
|
18
|
+
| ------------------------------------ | -------------------------------------- | ------------------------------------------------ |
|
|
19
|
+
| `PROCESSCUBE_ENGINE_URL` | `http://localhost:56000` | URL of the ProcessCube Engine |
|
|
20
|
+
| `PROCESSCUBE_AUTHORITY_URL` | Auto-discovered from engine | URL of the ProcessCube Authority (OAuth server) |
|
|
21
|
+
| `PROCESSCUBE_ETW_CLIENT_ID` | `test_etw` | OAuth client ID for the External Task Worker |
|
|
22
|
+
| `PROCESSCUBE_ETW_CLIENT_SECRET` | `3ef62eb3-fe49-4c2c-ba6f-73e4d234321b` | OAuth client secret for the External Task Worker |
|
|
23
|
+
| `PROCESSCUBE_ETW_CLIENT_SCOPES` | `engine_etw` | OAuth scopes for the External Task Worker |
|
|
24
|
+
| `MAX_GET_OAUTH_ACCESS_TOKEN_RETRIES` | `10` | Maximum retries for obtaining OAuth access token |
|
|
25
|
+
| `ENVIRONMENT` | `development` | Environment mode (`development` or `production`) |
|
|
26
|
+
|
|
27
|
+
#### Example `.env` File
|
|
28
|
+
|
|
29
|
+
```env
|
|
30
|
+
PROCESSCUBE_ENGINE_URL=http://localhost:56000
|
|
31
|
+
PROCESSCUBE_ETW_CLIENT_ID=my_etw_client
|
|
32
|
+
PROCESSCUBE_ETW_CLIENT_SECRET=my_secret_key
|
|
33
|
+
PROCESSCUBE_ETW_CLIENT_SCOPES=engine_etw
|
|
34
|
+
ENVIRONMENT=production
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Extending Settings
|
|
38
|
+
|
|
39
|
+
You can extend the base settings class to add your own environment variables:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from pydantic import Field
|
|
43
|
+
from processcube_etw_library.settings import ETWSettings, load_settings
|
|
44
|
+
|
|
45
|
+
class MyAppSettings(ETWSettings):
|
|
46
|
+
database_url: str = Field(default="sqlite:///app.db")
|
|
47
|
+
api_key: str = Field(default="")
|
|
48
|
+
|
|
49
|
+
# Load settings with your custom class
|
|
50
|
+
settings = load_settings(MyAppSettings)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
### Start the ETW Application
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
59
|
+
|
|
60
|
+
# Create the application
|
|
61
|
+
app = new_external_task_worker_app()
|
|
62
|
+
|
|
63
|
+
# Run the application
|
|
64
|
+
app.run()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Subscribe to External Task Topics
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
71
|
+
|
|
72
|
+
app = new_external_task_worker_app()
|
|
73
|
+
|
|
74
|
+
def my_handler(task):
|
|
75
|
+
# Process the task
|
|
76
|
+
result = {"processed": True}
|
|
77
|
+
return result
|
|
78
|
+
|
|
79
|
+
# Subscribe to a topic
|
|
80
|
+
app.subscribe_to_external_task_for_topic("my-topic", my_handler)
|
|
81
|
+
|
|
82
|
+
app.run()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Typed Handlers
|
|
86
|
+
|
|
87
|
+
Use typed handlers for automatic payload validation with Pydantic models:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from pydantic import BaseModel
|
|
91
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
92
|
+
|
|
93
|
+
class MyInput(BaseModel):
|
|
94
|
+
name: str
|
|
95
|
+
value: int
|
|
96
|
+
|
|
97
|
+
class MyOutput(BaseModel):
|
|
98
|
+
result: str
|
|
99
|
+
|
|
100
|
+
app = new_external_task_worker_app()
|
|
101
|
+
|
|
102
|
+
def my_typed_handler(payload: MyInput) -> MyOutput:
|
|
103
|
+
return MyOutput(result=f"Processed {payload.name} with value {payload.value}")
|
|
104
|
+
|
|
105
|
+
app.subscribe_to_external_task_for_topic_typed("my-typed-topic", my_typed_handler)
|
|
106
|
+
|
|
107
|
+
app.run()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Add a Custom Health Check
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
114
|
+
from processcube_etw_library.health import HealthCheck, create_url_health_check
|
|
115
|
+
|
|
116
|
+
app = new_external_task_worker_app()
|
|
117
|
+
|
|
118
|
+
# Add a URL-based health check
|
|
119
|
+
app.add_health_check(
|
|
120
|
+
HealthCheck(
|
|
121
|
+
create_url_health_check("http://my-service:8080/health"),
|
|
122
|
+
service_name="My Service",
|
|
123
|
+
tags=["backend", "api"],
|
|
124
|
+
comments=["Checks if My Service is reachable"],
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Add a custom health check function
|
|
129
|
+
def check_database():
|
|
130
|
+
# Return True if healthy, False otherwise
|
|
131
|
+
try:
|
|
132
|
+
# Your database check logic here
|
|
133
|
+
return True
|
|
134
|
+
except Exception:
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
app.add_health_check(
|
|
138
|
+
HealthCheck(
|
|
139
|
+
check_database,
|
|
140
|
+
service_name="Database",
|
|
141
|
+
tags=["backend", "database"],
|
|
142
|
+
comments=["Checks database connectivity"],
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
app.run()
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Managing Health Checks
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
# Get all registered health checks
|
|
153
|
+
checks = app.get_health_checks()
|
|
154
|
+
|
|
155
|
+
# Get a specific health check by service name
|
|
156
|
+
db_check = app.get_health_check("Database")
|
|
157
|
+
|
|
158
|
+
# Remove a health check
|
|
159
|
+
app.remove_health_check("Database")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Disabling Built-in Health Checks
|
|
163
|
+
|
|
164
|
+
By default, the library registers health checks for the ProcessCube Engine and Authority. You can disable these:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
app = new_external_task_worker_app(built_in_health_checks=False)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Health Endpoints
|
|
171
|
+
|
|
172
|
+
The application exposes health endpoints at `/healthyz` and `/readyz` that return the status of all registered health checks.
|
|
173
|
+
To check if the application is running without performing health checks, use `/livez`.
|
|
174
|
+
|
|
175
|
+
## Server Configuration
|
|
176
|
+
|
|
177
|
+
The server configuration is determined by the `ENVIRONMENT` variable:
|
|
178
|
+
|
|
179
|
+
| Setting | Development | Production |
|
|
180
|
+
| ---------- | ----------- | ---------- |
|
|
181
|
+
| Host | `0.0.0.0` | `0.0.0.0` |
|
|
182
|
+
| Port | `8000` | `8000` |
|
|
183
|
+
| Log Level | `debug` | `warning` |
|
|
184
|
+
| Access Log | `true` | `false` |
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
# # Prevent nest_asyncio from patching asyncio.run() in processcube_client - it breaks uvicorn's loop_factory
|
|
2
|
-
# import nest_asyncio
|
|
3
|
-
# nest_asyncio.apply = lambda *args, **kwargs: None
|
|
4
|
-
|
|
5
1
|
from processcube_client.external_task import ExternalTaskClient
|
|
6
2
|
|
|
7
3
|
from .identity_provider import IdentityProvider
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: processcube-etw-library
|
|
3
|
+
Version: 2026.1.22.130934b0
|
|
4
|
+
Summary: A library to create ETW apps with the ProcessCube platform.
|
|
5
|
+
Author-email: Jeremy Hill <jeremy.hill@profection.de>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: fastapi[standard]>=0.128.0
|
|
10
|
+
Requires-Dist: oauth2-client>=1.4.2
|
|
11
|
+
Requires-Dist: processcube-client>=5.0.0
|
|
12
|
+
Requires-Dist: tenacity>=9.1.2
|
|
13
|
+
|
|
14
|
+
# ProcessCube ETW Library
|
|
15
|
+
|
|
16
|
+
Build External Task Workers (ETW) for ProcessCube, featuring health checks, typed handlers, and environment-based configuration.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv add processcube-etw-library
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
### Environment Variables
|
|
27
|
+
|
|
28
|
+
The library uses environment variables for configuration. You can set these in your environment or in a `.env` file in your project root.
|
|
29
|
+
|
|
30
|
+
| Variable | Default | Description |
|
|
31
|
+
| ------------------------------------ | -------------------------------------- | ------------------------------------------------ |
|
|
32
|
+
| `PROCESSCUBE_ENGINE_URL` | `http://localhost:56000` | URL of the ProcessCube Engine |
|
|
33
|
+
| `PROCESSCUBE_AUTHORITY_URL` | Auto-discovered from engine | URL of the ProcessCube Authority (OAuth server) |
|
|
34
|
+
| `PROCESSCUBE_ETW_CLIENT_ID` | `test_etw` | OAuth client ID for the External Task Worker |
|
|
35
|
+
| `PROCESSCUBE_ETW_CLIENT_SECRET` | `3ef62eb3-fe49-4c2c-ba6f-73e4d234321b` | OAuth client secret for the External Task Worker |
|
|
36
|
+
| `PROCESSCUBE_ETW_CLIENT_SCOPES` | `engine_etw` | OAuth scopes for the External Task Worker |
|
|
37
|
+
| `MAX_GET_OAUTH_ACCESS_TOKEN_RETRIES` | `10` | Maximum retries for obtaining OAuth access token |
|
|
38
|
+
| `ENVIRONMENT` | `development` | Environment mode (`development` or `production`) |
|
|
39
|
+
|
|
40
|
+
#### Example `.env` File
|
|
41
|
+
|
|
42
|
+
```env
|
|
43
|
+
PROCESSCUBE_ENGINE_URL=http://localhost:56000
|
|
44
|
+
PROCESSCUBE_ETW_CLIENT_ID=my_etw_client
|
|
45
|
+
PROCESSCUBE_ETW_CLIENT_SECRET=my_secret_key
|
|
46
|
+
PROCESSCUBE_ETW_CLIENT_SCOPES=engine_etw
|
|
47
|
+
ENVIRONMENT=production
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Extending Settings
|
|
51
|
+
|
|
52
|
+
You can extend the base settings class to add your own environment variables:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from pydantic import Field
|
|
56
|
+
from processcube_etw_library.settings import ETWSettings, load_settings
|
|
57
|
+
|
|
58
|
+
class MyAppSettings(ETWSettings):
|
|
59
|
+
database_url: str = Field(default="sqlite:///app.db")
|
|
60
|
+
api_key: str = Field(default="")
|
|
61
|
+
|
|
62
|
+
# Load settings with your custom class
|
|
63
|
+
settings = load_settings(MyAppSettings)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### Start the ETW Application
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
72
|
+
|
|
73
|
+
# Create the application
|
|
74
|
+
app = new_external_task_worker_app()
|
|
75
|
+
|
|
76
|
+
# Run the application
|
|
77
|
+
app.run()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Subscribe to External Task Topics
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
84
|
+
|
|
85
|
+
app = new_external_task_worker_app()
|
|
86
|
+
|
|
87
|
+
def my_handler(task):
|
|
88
|
+
# Process the task
|
|
89
|
+
result = {"processed": True}
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
# Subscribe to a topic
|
|
93
|
+
app.subscribe_to_external_task_for_topic("my-topic", my_handler)
|
|
94
|
+
|
|
95
|
+
app.run()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Typed Handlers
|
|
99
|
+
|
|
100
|
+
Use typed handlers for automatic payload validation with Pydantic models:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from pydantic import BaseModel
|
|
104
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
105
|
+
|
|
106
|
+
class MyInput(BaseModel):
|
|
107
|
+
name: str
|
|
108
|
+
value: int
|
|
109
|
+
|
|
110
|
+
class MyOutput(BaseModel):
|
|
111
|
+
result: str
|
|
112
|
+
|
|
113
|
+
app = new_external_task_worker_app()
|
|
114
|
+
|
|
115
|
+
def my_typed_handler(payload: MyInput) -> MyOutput:
|
|
116
|
+
return MyOutput(result=f"Processed {payload.name} with value {payload.value}")
|
|
117
|
+
|
|
118
|
+
app.subscribe_to_external_task_for_topic_typed("my-typed-topic", my_typed_handler)
|
|
119
|
+
|
|
120
|
+
app.run()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Add a Custom Health Check
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from processcube_etw_library import new_external_task_worker_app
|
|
127
|
+
from processcube_etw_library.health import HealthCheck, create_url_health_check
|
|
128
|
+
|
|
129
|
+
app = new_external_task_worker_app()
|
|
130
|
+
|
|
131
|
+
# Add a URL-based health check
|
|
132
|
+
app.add_health_check(
|
|
133
|
+
HealthCheck(
|
|
134
|
+
create_url_health_check("http://my-service:8080/health"),
|
|
135
|
+
service_name="My Service",
|
|
136
|
+
tags=["backend", "api"],
|
|
137
|
+
comments=["Checks if My Service is reachable"],
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Add a custom health check function
|
|
142
|
+
def check_database():
|
|
143
|
+
# Return True if healthy, False otherwise
|
|
144
|
+
try:
|
|
145
|
+
# Your database check logic here
|
|
146
|
+
return True
|
|
147
|
+
except Exception:
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
app.add_health_check(
|
|
151
|
+
HealthCheck(
|
|
152
|
+
check_database,
|
|
153
|
+
service_name="Database",
|
|
154
|
+
tags=["backend", "database"],
|
|
155
|
+
comments=["Checks database connectivity"],
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
app.run()
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Managing Health Checks
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
# Get all registered health checks
|
|
166
|
+
checks = app.get_health_checks()
|
|
167
|
+
|
|
168
|
+
# Get a specific health check by service name
|
|
169
|
+
db_check = app.get_health_check("Database")
|
|
170
|
+
|
|
171
|
+
# Remove a health check
|
|
172
|
+
app.remove_health_check("Database")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Disabling Built-in Health Checks
|
|
176
|
+
|
|
177
|
+
By default, the library registers health checks for the ProcessCube Engine and Authority. You can disable these:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
app = new_external_task_worker_app(built_in_health_checks=False)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Health Endpoints
|
|
184
|
+
|
|
185
|
+
The application exposes health endpoints at `/healthyz` and `/readyz` that return the status of all registered health checks.
|
|
186
|
+
To check if the application is running without performing health checks, use `/livez`.
|
|
187
|
+
|
|
188
|
+
## Server Configuration
|
|
189
|
+
|
|
190
|
+
The server configuration is determined by the `ENVIRONMENT` variable:
|
|
191
|
+
|
|
192
|
+
| Setting | Development | Production |
|
|
193
|
+
| ---------- | ----------- | ---------- |
|
|
194
|
+
| Host | `0.0.0.0` | `0.0.0.0` |
|
|
195
|
+
| Port | `8000` | `8000` |
|
|
196
|
+
| Log Level | `debug` | `warning` |
|
|
197
|
+
| Access Log | `true` | `false` |
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: processcube-etw-library
|
|
3
|
-
Version: 2026.1.22.112808b0
|
|
4
|
-
Summary: A library to create ETW apps with the ProcessCube platform.
|
|
5
|
-
Author-email: Jeremy Hill <jeremy.hill@profection.de>
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.12
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: fastapi[standard]>=0.128.0
|
|
10
|
-
Requires-Dist: oauth2-client>=1.4.2
|
|
11
|
-
Requires-Dist: processcube-client>=5.0.0
|
|
12
|
-
Requires-Dist: tenacity>=9.1.2
|
|
13
|
-
|
|
14
|
-
# ProcessCube ETW Library
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
### Start the ETW application
|
|
21
|
-
|
|
22
|
-
### Subscribe to External Task Topics
|
|
23
|
-
|
|
24
|
-
### Add a custom health check
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: processcube-etw-library
|
|
3
|
-
Version: 2026.1.22.112808b0
|
|
4
|
-
Summary: A library to create ETW apps with the ProcessCube platform.
|
|
5
|
-
Author-email: Jeremy Hill <jeremy.hill@profection.de>
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.12
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: fastapi[standard]>=0.128.0
|
|
10
|
-
Requires-Dist: oauth2-client>=1.4.2
|
|
11
|
-
Requires-Dist: processcube-client>=5.0.0
|
|
12
|
-
Requires-Dist: tenacity>=9.1.2
|
|
13
|
-
|
|
14
|
-
# ProcessCube ETW Library
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
### Start the ETW application
|
|
21
|
-
|
|
22
|
-
### Subscribe to External Task Topics
|
|
23
|
-
|
|
24
|
-
### Add a custom health check
|
|
File without changes
|
{processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/setup.cfg
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
|
{processcube_etw_library-2026.1.22.112808b0 → processcube_etw_library-2026.1.22.130934b0}/uv.lock
RENAMED
|
File without changes
|