tempokat 0.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.
- tempokat-0.1.0/.gitignore +66 -0
- tempokat-0.1.0/PKG-INFO +351 -0
- tempokat-0.1.0/README.md +333 -0
- tempokat-0.1.0/pyproject.toml +60 -0
- tempokat-0.1.0/src/tempokat/__init__.py +16 -0
- tempokat-0.1.0/src/tempokat/api/__init__.py +1 -0
- tempokat-0.1.0/src/tempokat/api/deps.py +30 -0
- tempokat-0.1.0/src/tempokat/api/routers/__init__.py +1 -0
- tempokat-0.1.0/src/tempokat/api/routers/status_route.py +29 -0
- tempokat-0.1.0/src/tempokat/cli/__init__.py +4 -0
- tempokat-0.1.0/src/tempokat/cli/schedule.py +73 -0
- tempokat-0.1.0/src/tempokat/cli/worker.py +116 -0
- tempokat-0.1.0/src/tempokat/config.py +179 -0
- tempokat-0.1.0/src/tempokat/converters/__init__.py +5 -0
- tempokat-0.1.0/src/tempokat/converters/pydantic.py +47 -0
- tempokat-0.1.0/src/tempokat/discovery.py +79 -0
- tempokat-0.1.0/src/tempokat/factory.py +127 -0
- tempokat-0.1.0/src/tempokat/init.py +55 -0
- tempokat-0.1.0/src/tempokat/interceptors/__init__.py +5 -0
- tempokat-0.1.0/src/tempokat/interceptors/sentry.py +79 -0
- tempokat-0.1.0/src/tempokat/main.py +25 -0
- tempokat-0.1.0/src/tempokat/models/__init__.py +9 -0
- tempokat-0.1.0/src/tempokat/models/job.py +47 -0
- tempokat-0.1.0/src/tempokat/models/visibility.py +71 -0
- tempokat-0.1.0/src/tempokat/schedule.py +153 -0
- tempokat-0.1.0/src/tempokat/utils.py +196 -0
- tempokat-0.1.0/src/tempokat/version.py +14 -0
- tempokat-0.1.0/src/tempokat/worker.py +233 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# <velocikat:managed:kat/gitignore>
|
|
2
|
+
# Byte-compiled / optimized / DLL files
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
*$py.class
|
|
6
|
+
|
|
7
|
+
# C extensions
|
|
8
|
+
*.so
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
.Python
|
|
12
|
+
build/
|
|
13
|
+
develop-eggs/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.spec
|
|
31
|
+
|
|
32
|
+
# Installer logs
|
|
33
|
+
pip-log.txt
|
|
34
|
+
pip-delete-this-directory.txt
|
|
35
|
+
|
|
36
|
+
# Unit test / coverage reports
|
|
37
|
+
htmlcov/
|
|
38
|
+
.tox/
|
|
39
|
+
.nox/
|
|
40
|
+
.coverage
|
|
41
|
+
.coverage.*
|
|
42
|
+
.cache
|
|
43
|
+
nosetests.xml
|
|
44
|
+
coverage.xml
|
|
45
|
+
*.cover
|
|
46
|
+
*.py,cover
|
|
47
|
+
.hypothesis/
|
|
48
|
+
.pytest_cache/
|
|
49
|
+
|
|
50
|
+
# Environments
|
|
51
|
+
.env
|
|
52
|
+
.venv
|
|
53
|
+
env/
|
|
54
|
+
venv/
|
|
55
|
+
ENV/
|
|
56
|
+
env.bak/
|
|
57
|
+
venv.bak/
|
|
58
|
+
|
|
59
|
+
# IDEs
|
|
60
|
+
.idea/
|
|
61
|
+
.vscode/
|
|
62
|
+
*.sublime-project
|
|
63
|
+
*.sublime-workspace
|
|
64
|
+
# </velocikat:managed:kat/gitignore>
|
|
65
|
+
|
|
66
|
+
# Add your custom ignores below this line
|
tempokat-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tempokat
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: tempokat library
|
|
5
|
+
Author-email: velocikat <velocikat@lza.sh>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: corekat[cli]>=0.1.0
|
|
8
|
+
Requires-Dist: temporalio[opentelemetry]
|
|
9
|
+
Provides-Extra: all
|
|
10
|
+
Requires-Dist: sentry-sdk>=2.0; extra == 'all'
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
15
|
+
Provides-Extra: sentry
|
|
16
|
+
Requires-Dist: sentry-sdk>=2.0; extra == 'sentry'
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# TempоKat
|
|
20
|
+
|
|
21
|
+
> Temporal.io integration for KatCity — async-first, config-driven, production-ready.
|
|
22
|
+
|
|
23
|
+
TempоKat wraps [Temporal.io](https://temporal.io) with the KatCity patterns you already know: Pydantic configuration, factory functions, a clean CLI, and first-class Sentry support. Drop it into any KatCity service and go from zero to running durable workflows in minutes.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- **Config-driven workers** — define every worker, queue, workflow, and activity in YAML
|
|
30
|
+
- **Factory pattern** — `get_worker()`, `get_client()`, `get_looper()` mirror StashKat's API
|
|
31
|
+
- **Multi-worker Looper** — run all workers in a single process with graceful shutdown
|
|
32
|
+
- **Schedule management** — sync interval schedules declaratively from config
|
|
33
|
+
- **Pydantic data converter** — serialize workflow inputs/outputs as Pydantic models automatically
|
|
34
|
+
- **Sentry interceptor** — one-line Sentry integration for workflows and activities
|
|
35
|
+
- **Full CLI** — `tempokat worker run`, `tempokat schedule sync`, `tempokat version`
|
|
36
|
+
- **Async-first** — built on `asyncio`, `temporalio`, and KatCity's async foundations
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Core (from monorepo)
|
|
44
|
+
uv sync --package tempokat
|
|
45
|
+
|
|
46
|
+
# With Sentry support
|
|
47
|
+
uv pip install "tempokat[sentry]"
|
|
48
|
+
|
|
49
|
+
# All extras
|
|
50
|
+
uv pip install "tempokat[all]"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### 1. Generate a config file
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
tempokat config default-config > config.yaml
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Edit `config.yaml`
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
name: my-temporal-app
|
|
67
|
+
|
|
68
|
+
temporalio:
|
|
69
|
+
host: localhost:7233
|
|
70
|
+
namespace: default
|
|
71
|
+
workers:
|
|
72
|
+
- name: my-worker
|
|
73
|
+
queue: my-task-queue
|
|
74
|
+
workflows:
|
|
75
|
+
- myapp.workflows:MyWorkflow
|
|
76
|
+
activities:
|
|
77
|
+
- myapp.activities:my_activity
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. Run the worker
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
tempokat worker run --config config.yaml
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
That's it. Your worker is connected to Temporal and processing tasks.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
TempоKat uses the standard KatCity YAML + environment variable configuration system.
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
name: my-app
|
|
96
|
+
|
|
97
|
+
temporalio:
|
|
98
|
+
host: localhost:7233 # Temporal server address
|
|
99
|
+
namespace: default # Temporal namespace
|
|
100
|
+
max_concurrent_activities: 100
|
|
101
|
+
max_concurrent_workflow_tasks: 100
|
|
102
|
+
enable_metrics: false # Prometheus metrics
|
|
103
|
+
metric_bind_address: "0.0.0.0:9000"
|
|
104
|
+
|
|
105
|
+
workers:
|
|
106
|
+
- name: main-worker
|
|
107
|
+
queue: main-queue
|
|
108
|
+
workflows:
|
|
109
|
+
- myapp.workflows:OrderWorkflow
|
|
110
|
+
- myapp.workflows:PaymentWorkflow
|
|
111
|
+
activities:
|
|
112
|
+
- myapp.activities:charge_card
|
|
113
|
+
- myapp.activities:send_email
|
|
114
|
+
# Per-worker overrides (inherits from parent if omitted)
|
|
115
|
+
max_concurrent_activities: 50
|
|
116
|
+
|
|
117
|
+
schedules:
|
|
118
|
+
daily-report:
|
|
119
|
+
workflow_id: daily-report-wf
|
|
120
|
+
workflow: myapp.workflows:DailyReportWorkflow
|
|
121
|
+
task_queue: main-queue
|
|
122
|
+
interval:
|
|
123
|
+
every: 24h
|
|
124
|
+
offset: 1h
|
|
125
|
+
state: created # created | paused | deleted
|
|
126
|
+
payload:
|
|
127
|
+
report_type: full
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Environment variable overrides
|
|
131
|
+
|
|
132
|
+
All settings can be overridden with `TEMPOKAT_` prefixed env vars:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
TEMPOKAT_TEMPORALIO__HOST=prod-temporal:7233
|
|
136
|
+
TEMPOKAT_TEMPORALIO__NAMESPACE=production
|
|
137
|
+
TEMPOKAT_TEMPORALIO__ENABLE_METRICS=true
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Programmatic API
|
|
143
|
+
|
|
144
|
+
### Running workers
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
import asyncio
|
|
148
|
+
from tempokat import get_looper
|
|
149
|
+
from tempokat.config import config
|
|
150
|
+
from tempokat.init import init
|
|
151
|
+
|
|
152
|
+
async def main():
|
|
153
|
+
conf = config("config.yaml")
|
|
154
|
+
init(conf)
|
|
155
|
+
looper = await get_looper(conf)
|
|
156
|
+
await looper.run()
|
|
157
|
+
|
|
158
|
+
asyncio.run(main())
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Creating a Temporal client
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from tempokat import get_client
|
|
165
|
+
from tempokat.config import config
|
|
166
|
+
|
|
167
|
+
async def main():
|
|
168
|
+
conf = config("config.yaml")
|
|
169
|
+
client = await get_client(conf)
|
|
170
|
+
|
|
171
|
+
handle = await client.start_workflow(
|
|
172
|
+
MyWorkflow.run,
|
|
173
|
+
"some-input",
|
|
174
|
+
id="my-workflow-id",
|
|
175
|
+
task_queue="my-task-queue",
|
|
176
|
+
)
|
|
177
|
+
result = await handle.result()
|
|
178
|
+
print(result)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Syncing schedules
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from tempokat import get_client
|
|
185
|
+
from tempokat.config import config
|
|
186
|
+
from tempokat.schedule import TemporalScheduler
|
|
187
|
+
|
|
188
|
+
async def sync():
|
|
189
|
+
conf = config("config.yaml")
|
|
190
|
+
client = await get_client(conf)
|
|
191
|
+
scheduler = TemporalScheduler(client, conf.schedules)
|
|
192
|
+
await scheduler.sync_schedules()
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## CLI Reference
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
tempokat --help
|
|
201
|
+
|
|
202
|
+
Commands:
|
|
203
|
+
worker Temporal worker operations
|
|
204
|
+
schedule Temporal schedule management
|
|
205
|
+
version Show version information
|
|
206
|
+
config Configuration utilities
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Worker commands
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Run all workers from config
|
|
213
|
+
tempokat worker run --config config.yaml
|
|
214
|
+
|
|
215
|
+
# Override host and namespace at runtime
|
|
216
|
+
tempokat worker run --config config.yaml --host prod:7233 --namespace production
|
|
217
|
+
|
|
218
|
+
# Run a specific named worker
|
|
219
|
+
tempokat worker run --config config.yaml --worker payment-worker
|
|
220
|
+
|
|
221
|
+
# Ad-hoc worker (no config file needed)
|
|
222
|
+
tempokat worker run \
|
|
223
|
+
--queue my-queue \
|
|
224
|
+
--workflow myapp.workflows:MyWorkflow \
|
|
225
|
+
--activity myapp.activities:my_fn
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Schedule commands
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Sync all schedules defined in config
|
|
232
|
+
tempokat schedule sync --config config.yaml
|
|
233
|
+
|
|
234
|
+
# Override host
|
|
235
|
+
tempokat schedule sync --config config.yaml --host prod:7233
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Pydantic Data Converter
|
|
241
|
+
|
|
242
|
+
TempоKat ships a Pydantic-aware data converter that serializes workflow inputs and outputs using `model_dump_json()` automatically.
|
|
243
|
+
|
|
244
|
+
Enable it globally via config:
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
temporalio:
|
|
248
|
+
converter: tempokat.converters.pydantic:pydantic_data_converter
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Sentry Integration
|
|
254
|
+
|
|
255
|
+
Install the extra:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
uv pip install "tempokat[sentry]"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Add to config:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
sentry:
|
|
265
|
+
dsn: "https://your-dsn@sentry.io/123"
|
|
266
|
+
traces_sample_rate: 0.1
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Call `init()` at startup — TempоKat automatically registers `SentryInterceptor` on all workers:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
from tempokat.init import init
|
|
273
|
+
from tempokat.config import config
|
|
274
|
+
|
|
275
|
+
conf = config("config.yaml")
|
|
276
|
+
init(conf) # Sentry initialized + interceptor registered on all workers
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Documentation
|
|
282
|
+
|
|
283
|
+
- [Getting Started](../../docs/guides/tempokat-getting-started.md) — zero to running worker
|
|
284
|
+
- [Workers Guide](../../docs/guides/tempokat-workers.md) — multi-worker, factories, graceful shutdown
|
|
285
|
+
- [Schedules Guide](../../docs/guides/tempokat-schedules.md) — declarative schedule management
|
|
286
|
+
- [Interceptors Guide](../../docs/guides/tempokat-interceptors.md) — Sentry, custom interceptors
|
|
287
|
+
- [Converters Guide](../../docs/guides/tempokat-converters.md) — Pydantic data converter
|
|
288
|
+
- [Temporal in KatCity](../../docs/concepts/temporal-in-katcity.md) — architecture & design decisions
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Package Structure
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
tempokat/
|
|
296
|
+
├── src/tempokat/
|
|
297
|
+
│ ├── __init__.py # Public API: get_worker, get_client, get_looper, Looper, etc.
|
|
298
|
+
│ ├── main.py # CLI entry point
|
|
299
|
+
│ ├── config.py # ConfigSchema, TemporalConfigSchema, WorkerConfigSchema, etc.
|
|
300
|
+
│ ├── init.py # init() — logging + Sentry setup
|
|
301
|
+
│ ├── factory.py # get_client(), get_worker(), get_looper()
|
|
302
|
+
│ ├── worker.py # WorkerFactory, Looper, Worker lifecycle
|
|
303
|
+
│ ├── schedule.py # TemporalScheduler
|
|
304
|
+
│ ├── utils.py # heartbeat_every, gather_with_concurrency, find_workflow
|
|
305
|
+
│ ├── version.py # VERSION instance
|
|
306
|
+
│ ├── cli/
|
|
307
|
+
│ │ ├── worker.py # `tempokat worker` commands
|
|
308
|
+
│ │ └── schedule.py # `tempokat schedule` commands
|
|
309
|
+
│ ├── converters/
|
|
310
|
+
│ │ └── pydantic.py # PydanticPayloadConverter, pydantic_data_converter
|
|
311
|
+
│ └── interceptors/
|
|
312
|
+
│ └── sentry.py # SentryInterceptor
|
|
313
|
+
├── tests/
|
|
314
|
+
├── make/
|
|
315
|
+
└── pyproject.toml
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Development
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Run tests
|
|
324
|
+
make test
|
|
325
|
+
|
|
326
|
+
# Run tests with coverage
|
|
327
|
+
make test-cov
|
|
328
|
+
|
|
329
|
+
# All checks (format + lint + types + tests)
|
|
330
|
+
make check
|
|
331
|
+
|
|
332
|
+
# Auto-fix issues
|
|
333
|
+
make fix
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## VelociKat Maintenance
|
|
339
|
+
|
|
340
|
+
This project was scaffolded by VelociKat. To check for template updates:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
velocikat status
|
|
344
|
+
velocikat doctor
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
BSD 3-Clause License. See [LICENSE](../../LICENSE) for details.
|