Metadata-Version: 2.4
Name: hawkapi-taskiq
Version: 0.1.0
Summary: TaskIQ integration for HawkAPI — modern async-native task queue, DI, scheduling, JSON-only formatter
Project-URL: Homepage, https://pypi.org/project/hawkapi-taskiq/
Project-URL: Repository, https://github.com/ashimov/hawkapi-taskiq
Project-URL: Issues, https://github.com/ashimov/hawkapi-taskiq/issues
Author-email: HawkAPI Contributors <hawkapi@users.noreply.github.com>
License: MIT License
        
        Copyright (c) 2026 HawkAPI Contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: async,hawkapi,queue,scheduling,taskiq,tasks
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Distributed Computing
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: hawkapi>=0.1.7
Requires-Dist: taskiq>=0.11
Provides-Extra: cron
Requires-Dist: croniter>=2.0; extra == 'cron'
Provides-Extra: dev
Requires-Dist: croniter>=2.0; extra == 'dev'
Requires-Dist: pyright>=1.1; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Provides-Extra: nats
Requires-Dist: taskiq-nats>=0.5; extra == 'nats'
Provides-Extra: redis
Requires-Dist: taskiq-redis>=1.0; extra == 'redis'
Description-Content-Type: text/markdown

# hawkapi-taskiq

[TaskIQ](https://taskiq-python.github.io/) integration for [HawkAPI](https://github.com/ashimov/HawkAPI). Modern async-native task queue — a lighter, async-first alternative to Celery.

## Install

```bash
pip install hawkapi-taskiq
pip install 'hawkapi-taskiq[redis]'    # + taskiq-redis
pip install 'hawkapi-taskiq[nats]'     # + taskiq-nats
pip install 'hawkapi-taskiq[cron]'     # + croniter for schedule validation
```

## Quickstart

```python
from hawkapi import Depends, HawkAPI
from hawkapi_taskiq import TaskIQConfig, get_broker, init_taskiq, task

app = HawkAPI()
broker = init_taskiq(app, config=TaskIQConfig(broker_url="redis://localhost:6379/0"))


@task(broker, name="emails.send")
async def send_email(to: str, subject: str) -> None:
    ...


@app.post("/notify")
async def notify(email: str, b = Depends(get_broker)):
    await send_email.kiq(email, "Hello")
    return {"ok": True}
```

## Broker selection

Choose by URL scheme — all others are rejected:

| URL | Broker |
|---|---|
| `memory://` | `InMemoryBroker` (tests, single-process) |
| `redis://host:6379/0` | `ListQueueBroker` (taskiq-redis) |
| `rediss://...` | same, with TLS |
| `nats://server:4222` | `NatsBroker` (taskiq-nats) |

Any other scheme raises `ValueError` at `create_broker()` — this is a security feature, not a limitation. The allowlist prevents accidentally enabling brokers that use unsafe deserialization formats.

## Scheduling

v0.1.0 ships a `Scheduled` value type with cron-syntax validation. Wire it to TaskIQ's native scheduler yourself — we deliberately avoid a "magic" registration helper that doesn't compose cleanly with the upstream `TaskiqScheduler`:

```python
from hawkapi_taskiq import Scheduled
from taskiq import TaskiqScheduler
from taskiq.schedule_sources import LabelScheduleSource


@task(broker, name="myapp.cleanup")
async def cleanup() -> None:
    ...


# 1. Validate the schedule (cron syntax) up front.
schedule = Scheduled(cron="0 * * * *")    # raises ValueError if malformed

# 2. Apply it as a label LabelScheduleSource reads.
cleanup.labels["schedule"] = [{"cron": schedule.cron, "args": [], "kwargs": {}}]


# 3. Run a scheduler process alongside the worker.
scheduler = TaskiqScheduler(broker=broker, sources=[LabelScheduleSource(broker)])
```

`Scheduled(cron="...")` validates via [`croniter`](https://github.com/kiorky/croniter) (install with `[cron]` extra). Both `cron` and `interval_seconds` set are rejected (exactly one is required).

## Health

```python
from hawkapi_taskiq import check_broker

report = await check_broker(broker)
# HealthReport(broker_ok=True, broker_type="ListQueueBroker", error="")
```

## Testing

```python
from hawkapi_taskiq import in_memory_broker, task


async def test_my_task():
    async with in_memory_broker() as broker:
        @task(broker, name="t.work")
        async def work(x: int) -> int:
            return x * 2

        await work.kiq(21)
        # Execute pending tasks via TaskIQ's normal flow.
```

## Security

- **JSON-only serialization** — TaskIQ defaults are fine; we explicitly reject any other serializer via `TaskIQConfig.serializer` to prevent arbitrary-deserialization at consume time (CWE-502).
- **Broker URL scheme allowlist** — only `memory://`, `redis://`, `rediss://`, `nats://`.
- **Task name registry** — duplicate `@task(name=...)` raises at registration. TaskIQ silently overrides; we disallow.
- **Cron expression validation** at registration time — malformed expressions fail fast.

## Development

```bash
git clone https://github.com/ashimov/hawkapi-taskiq.git
cd hawkapi-taskiq
uv sync --extra dev
uv run pytest -q
uv run ruff check . && uv run ruff format --check .
uv run pyright src/
```

## License

MIT.
