TempоKat
Temporal.io integration for KatCity — async-first, config-driven, production-ready.
TempоKat wraps 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.
Features
- Config-driven workers — define every worker, queue, workflow, and activity in YAML
- Factory pattern —
get_worker(),get_client(),get_looper()mirror StashKat's API - Multi-worker Looper — run all workers in a single process with graceful shutdown
- Schedule management — sync interval schedules declaratively from config
- Pydantic data converter — serialize workflow inputs/outputs as Pydantic models automatically
- Agnostic progress tracking —
ProgressTrackermixin + canonicalWorkflowProgressenvelope + unified/status,/progress,/progress/streamendpoints - JWT token signing — multi-key keyring with
kid-based rotation and Prometheus metrics - Sentry interceptor — one-line Sentry integration for workflows and activities
- Full CLI —
tempokat worker run,tempokat schedule sync,tempokat version - Async-first — built on
asyncio,temporalio, and KatCity's async foundations
Installation
# Core (from monorepo)
uv sync --package tempokat
# With Sentry support
uv pip install "tempokat[sentry]"
# All extras
uv pip install "tempokat[all]"
Quick Start
1. Generate a config file
tempokat config default-config > config.yaml
2. Edit config.yaml
name: my-temporal-app
temporalio:
host: localhost:7233
namespace: default
workers:
- name: my-worker
queue: my-task-queue
workflows:
- myapp.workflows:MyWorkflow
activities:
- myapp.activities:my_activity
3. Run the worker
tempokat worker run --config config.yaml
That's it. Your worker is connected to Temporal and processing tasks.
Configuration
TempоKat uses the standard KatCity YAML + environment variable configuration system.
name: my-app
temporalio:
host: localhost:7233 # Temporal server address
namespace: default # Temporal namespace
max_concurrent_activities: 100
max_concurrent_workflow_tasks: 100
enable_metrics: false # Prometheus metrics
metric_bind_address: "0.0.0.0:9000"
workers:
- name: main-worker
queue: main-queue
workflows:
- myapp.workflows:OrderWorkflow
- myapp.workflows:PaymentWorkflow
activities:
- myapp.activities:charge_card
- myapp.activities:send_email
# Per-worker overrides (inherits from parent if omitted)
max_concurrent_activities: 50
schedules:
daily-report:
workflow_id: daily-report-wf
workflow: myapp.workflows:DailyReportWorkflow
task_queue: main-queue
interval:
every: 24h
offset: 1h
state: created # created | paused | deleted
payload:
report_type: full
Environment variable overrides
All settings can be overridden with TEMPOKAT_ prefixed env vars:
TEMPOKAT_TEMPORALIO__HOST=prod-temporal:7233
TEMPOKAT_TEMPORALIO__NAMESPACE=production
TEMPOKAT_TEMPORALIO__ENABLE_METRICS=true
Programmatic API
Running workers
import asyncio
from tempokat import get_looper
from tempokat.config import config
from tempokat.init import init
async def main():
conf = config("config.yaml")
init(conf)
looper = await get_looper(conf)
await looper.run()
asyncio.run(main())
Creating a Temporal client
from tempokat import get_client
from tempokat.config import config
async def main():
conf = config("config.yaml")
client = await get_client(conf)
handle = await client.start_workflow(
MyWorkflow.run,
"some-input",
id="my-workflow-id",
task_queue="my-task-queue",
)
result = await handle.result()
print(result)
Syncing schedules
from tempokat import get_client
from tempokat.config import config
from tempokat.schedule import TemporalScheduler
async def sync():
conf = config("config.yaml")
client = await get_client(conf)
scheduler = TemporalScheduler(client, conf.schedules)
await scheduler.sync_schedules()
CLI Reference
tempokat --help
Commands:
worker Temporal worker operations
schedule Temporal schedule management
version Show version information
config Configuration utilities
Worker commands
# Run all workers from config
tempokat worker run --config config.yaml
# Override host and namespace at runtime
tempokat worker run --config config.yaml --host prod:7233 --namespace production
# Run a specific named worker
tempokat worker run --config config.yaml --worker payment-worker
# Ad-hoc worker (no config file needed)
tempokat worker run \
--queue my-queue \
--workflow myapp.workflows:MyWorkflow \
--activity myapp.activities:my_fn
Schedule commands
# Sync all schedules defined in config
tempokat schedule sync --config config.yaml
# Override host
tempokat schedule sync --config config.yaml --host prod:7233
Pydantic Data Converter
TempоKat ships a Pydantic-aware data converter that serializes workflow inputs and outputs using model_dump_json() automatically.
Enable it globally via config:
temporalio:
converter: tempokat.converters.pydantic:pydantic_data_converter
Sentry Integration
Install the extra:
uv pip install "tempokat[sentry]"
Add to config:
sentry:
dsn: "https://your-dsn@sentry.io/123"
traces_sample_rate: 0.1
Call init() at startup — TempоKat automatically registers SentryInterceptor on all workers:
from tempokat.init import init
from tempokat.config import config
conf = config("config.yaml")
init(conf) # Sentry initialized + interceptor registered on all workers
Documentation
- Getting Started — zero to running worker
- Workers Guide — multi-worker, factories, graceful shutdown
- Schedules Guide — declarative schedule management
- Progress Tracking Guide — agnostic job status & cyclic-graph progress
- Token Signing Guide — JWT signing, key rotation, metrics
- Interceptors Guide — Sentry, custom interceptors
- Converters Guide — Pydantic data converter
- Temporal in KatCity — architecture & design decisions
Package Structure
tempokat/
├── src/tempokat/
│ ├── __init__.py # Public API: get_worker, get_client, get_looper, Looper, etc.
│ ├── main.py # CLI entry point
│ ├── config.py # ConfigSchema, TemporalConfigSchema, WorkerConfigSchema, etc.
│ ├── init.py # init() — logging + Sentry setup
│ ├── factory.py # get_client(), get_worker(), get_looper()
│ ├── worker.py # WorkerFactory, Looper, Worker lifecycle
│ ├── schedule.py # TemporalScheduler
│ ├── utils.py # heartbeat_every, gather_with_concurrency, find_workflow
│ ├── version.py # VERSION instance
│ ├── cli/
│ │ ├── worker.py # `tempokat worker` commands
│ │ └── schedule.py # `tempokat schedule` commands
│ ├── converters/
│ │ └── pydantic.py # PydanticPayloadConverter, pydantic_data_converter
│ └── interceptors/
│ └── sentry.py # SentryInterceptor
├── tests/
├── make/
└── pyproject.toml
Development
# Run tests
make test
# Run tests with coverage
make test-cov
# All checks (format + lint + types + tests)
make check
# Auto-fix issues
make fix
VelociKat Maintenance
This project was scaffolded by VelociKat. To check for template updates:
velocikat status
velocikat doctor
License
BSD 3-Clause License. See LICENSE for details.
Release files for tempokat 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tempokat-0.1.4.tar.gz | 31.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tempokat-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.4 kB
Release files / tempokat-0.1.4.tar.gz
| Download URL | tempokat-0.1.4.tar.gz |
|---|---|
| Size | 31.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1ae81fada6c11b136d2c4e768e592e6e33b094587a73aa250f85092a4d725686
|
|
BLAKE2b-256 checksum How to use checksums |
e7dba9ff728dd8169d2bc1489955f25dc742ab4c7d5298fef0baa59488af9420
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / tempokat-0.1.4-py3-none-any.whl
| Download URL | tempokat-0.1.4-py3-none-any.whl |
|---|---|
| Size | 44.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3d259451af3fc1abbb9f5ee7fac71a2785f3b195ca6301e305dc8af84993f3e1
|
|
BLAKE2b-256 checksum How to use checksums |
9507459394ea57c81cc4c926b85d3322ecc738f00f438ceb17edee78fc48095a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|