Metadata-Version: 2.3
Name: kicker
Version: 0.2.0
Summary: Lightweight job runner framework built on FastAPI and APScheduler with a simple web UI.
Author: Andrey Morozov
Author-email: Andrey Morozov <andrey@morozov.lv>
Requires-Dist: apscheduler>=3.11.2
Requires-Dist: fastapi>=0.136.1
Requires-Dist: uvicorn>=0.46.0
Requires-Python: >=3.14
Description-Content-Type: text/markdown

# kicker

Lightweight job runner built on FastAPI and APScheduler with a simple web UI.

## Features

* **FastAPI-style developer experience**
  * `app = Kicker()`
  * `@app.job(...)`
  * standard `uvicorn module:app`
* Schedule jobs with APScheduler
* Run jobs manually from UI
* Pause/resume scheduler and individual jobs
* Supports both sync and async functions
* Simple HTML interface

---

## Installation

```bash
uv add kicker
```

---

## Usage

Create a project and define your jobs:

```python
import logging
from datetime import datetime
from kicker import Kicker

logger = logging.getLogger("kicker")

app = Kicker(verbose=True)

@app.job(day_of_week='mon-fri', hour='9-20/2', minute=0)
async def job_echo():
    execution_time = datetime.now()
    execution_time_str = execution_time.strftime("%Y-%m-%d %H:%M:%S")
    function_name = job_echo.__name__

    try:
        logger.debug("`%s` starting at %s", function_name, execution_time_str)
        ...
    except BaseException as e:
        logger.exception("Error in `%s`: %s", function_name, str(e))
        return
    else:
        logger.info("`%s` executed as %s", function_name, execution_time_str)


# run the app
# uv run uvicorn package.module:app --reload
```

## Notes

* Scheduler runs in-process (not distributed)
* Running with multiple workers will duplicate job execution
* Designed for simple internal tools and automation

---

## License

MIT
