# tsayt

[![Actions status](https://github.com/astral-sh/tsayt/actions/workflows/ci.yml/badge.svg)](https://github.com/astral-sh/tsayt/actions)
[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.gg/astral-sh)

tsayt is another asyncio cron scheduling micro-library for Python.

## Installation

```sh
uv add tsayt
```

## Usage

```python
import asyncio
import tsayt
from tsayt import OverlapPolicy

async def frob():
    # do something

async def main():
    scheduler = tsayt.Scheduler()

    # Default: skip the next firing if the previous one is still running.
    scheduler.register("0 0 * * *", frob)

    # Or allow concurrent invocations for fully independent, stateless work.
    scheduler.register("0 0 * * *", frob, overlap=OverlapPolicy.ALLOW)

    # Runs indefinitely, executing all registered tasks on their schedules.
    await scheduler.run()

if __name__ == "__main__":
    asyncio.run(main())
```

## Development

Run tests:

```bash
uv run pytest

# with coverage
uv run coverage run -m pytest
uv run coverage report -m
```

Run lints and type checking:

```bash
uv run ruff format --check
uv run ruff check
uv run ty check
```

Build docs:

```bash
uv run sphinx-build -b html docs docs/_build/html
```

## Licence

tsayt is licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>)

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in tsayt by you, as defined in the Apache-2.0 license, shall be
dually licensed as above, without any additional terms or conditions.

<div align="center">
  <a target="_blank" href="https://astral.sh" style="background:none">
    <img src="https://raw.githubusercontent.com/astral-sh/ruff/main/assets/svg/Astral.svg">
  </a>
</div>
