Metadata-Version: 2.4
Name: loaderup
Version: 0.1.4
Summary: Lightweight load-testing API and CLI built around FastAPI, k6, and decorator-based target registration.
Author: Mahdi Haroun
License: MIT
Project-URL: Homepage, https://github.com/MahdiHaroun/LoaderUp
Project-URL: Repository, https://github.com/MahdiHaroun/LoaderUp
Project-URL: Issues, https://github.com/MahdiHaroun/LoaderUp/issues
Keywords: load-testing,fastapi,k6,performance,api-testing,benchmark
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Framework :: FastAPI
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: fastapi<=0.115.8,>=0.100
Requires-Dist: httpx>=0.28.1
Requires-Dist: pydantic>=2.12.5
Requires-Dist: python-multipart>=0.0.24
Requires-Dist: uvicorn>=0.44.0
Requires-Dist: rich>=13.10.0

# LoaderUp

Lightweight load-testing API and CLI built around FastAPI, k6, and decorator-based target registration.

## Requirements

- Python `>=3.12`
- `uv` (recommended package manager)
- `k6` 

## Install

```bash
uv pip install -e .
```

## Run API directly

```bash
python -m loader.main
```

Server starts on `http://127.0.0.1:5050` by default.

## Run via CLI

```bash
python -m loaderup.cli up --app loader.main:app --targets loader.demo_registry_target --reload
```

This command opens the dashboard automatically at `http://127.0.0.1:5050/`.
Use `--no-open-browser` if you want to disable auto-open.

You can also use fallback-friendly forms like:

```bash
python -m loaderup.cli up --app main:app --targets demo_registry_targets --reload
```

## Using the decorator with FastAPI

Create your FastAPI app as usual:

```python
# main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def home():
    return {"message": "ok"}


@app.post("/users")
def create_user(payload: dict):
    return {"id": 1, **payload}
```

Then create a module with the load targets you want LoaderUp to test. The decorated functions do not need to call your route handlers; importing this module registers the target metadata.

```python
# targets.py
from loaderup import load_target


@load_target(
    name="home page",
    method="GET",
    path="/",
    expected_status=200,
    tags=["public"],
)
def home_page():
    pass


@load_target(
    name="create user",
    method="POST",
    path="/users",
    payload_example={"name": "Ada"},
    expected_status=200,
    tags=["users"],
)
def create_user():
    pass
```

Start LoaderUp and tell it to import the target module:

```bash
python -m loaderup.cli up --app main:app --targets targets --reload
```

Run all decorator-registered targets against your FastAPI app:

```bash
curl -X POST http://127.0.0.1:5050/run/registry \
  -H 'Content-Type: application/json' \
  -d '{"base_url":"http://127.0.0.1:5050","vus":10,"duration_seconds":30}'
```

## Health check

```bash
curl http://127.0.0.1:5050/health
```

## Dashboard

Open:

```bash
http://127.0.0.1:5050/
```

Dashboard includes:

- live status + progress stream
- metrics cards + quick chart bars
- saved run history (persisted in `artifacts/history/runs.jsonl`)
- React-based multi-tab control center (`Run Now`, `Live`, `Registered Targets`, `History`)

## Notes

- Registry targets are loaded when the module is imported.
- Use `/run/targets` to submit explicit targets.
- Use `/run/registry` to run all decorator-registered targets.
