Metadata-Version: 2.4
Name: tempokat
Version: 0.1.0
Summary: tempokat library
Author-email: velocikat <velocikat@lza.sh>
Requires-Python: >=3.12
Requires-Dist: corekat[cli]>=0.1.0
Requires-Dist: temporalio[opentelemetry]
Provides-Extra: all
Requires-Dist: sentry-sdk>=2.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: sentry
Requires-Dist: sentry-sdk>=2.0; extra == 'sentry'
Description-Content-Type: text/markdown

# TempоKat

> Temporal.io integration for KatCity — async-first, config-driven, production-ready.

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.

---

## 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
- **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

```bash
# 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

```bash
tempokat config default-config > config.yaml
```

### 2. Edit `config.yaml`

```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

```bash
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.

```yaml
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:

```bash
TEMPOKAT_TEMPORALIO__HOST=prod-temporal:7233
TEMPOKAT_TEMPORALIO__NAMESPACE=production
TEMPOKAT_TEMPORALIO__ENABLE_METRICS=true
```

---

## Programmatic API

### Running workers

```python
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

```python
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

```python
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

```bash
# 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

```bash
# 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:

```yaml
temporalio:
  converter: tempokat.converters.pydantic:pydantic_data_converter
```

---

## Sentry Integration

Install the extra:

```bash
uv pip install "tempokat[sentry]"
```

Add to config:

```yaml
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:

```python
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](../../docs/guides/tempokat-getting-started.md) — zero to running worker
- [Workers Guide](../../docs/guides/tempokat-workers.md) — multi-worker, factories, graceful shutdown
- [Schedules Guide](../../docs/guides/tempokat-schedules.md) — declarative schedule management
- [Interceptors Guide](../../docs/guides/tempokat-interceptors.md) — Sentry, custom interceptors
- [Converters Guide](../../docs/guides/tempokat-converters.md) — Pydantic data converter
- [Temporal in KatCity](../../docs/concepts/temporal-in-katcity.md) — 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

```bash
# 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:

```bash
velocikat status
velocikat doctor
```

---

## License

BSD 3-Clause License. See [LICENSE](../../LICENSE) for details.
