Metadata-Version: 2.4
Name: zimer
Version: 0.4.0
Summary: A simple decorator for timing functions.
Author-email: Zubin Aysola <zubin-email@email.com>
Project-URL: Homepage, https://github.com/zaysola/ztime
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown

# zimer

A lightweight utility package that ships two decorators that make everyday Python development a bit easier:

* **`zimer`** – measure the execution time of synchronous and asynchronous functions, optionally repeating them and printing the average runtime.
* **`with_retry`** – automatically retry a function when it raises an exception, with optional exponential back-off. Works with both sync and async callables.

---

## Installation

```bash
pip install zimer
```

---

## `zimer` – timing decorator

```python
from zimer import zimer
import time, asyncio

@zimer                      # one run, prints elapsed time
def slow_sync():
    time.sleep(1)

@zimer(repeats=3)           # three runs, prints average
async def slow_async():
    await asyncio.sleep(0.5)

slow_sync()
asyncio.run(slow_async())
```

---

## `with_retry` – retry decorator

```python
from zimer import with_retry
import random, asyncio

# --- synchronous example -----------------------------------------
@with_retry(num_retries=3, backoff=1, backoff_exponent=2)  # 1s, 4s between tries
def flaky_sync():
    if random.random() < 0.7:
        raise ValueError("Still broken …")
    return "✓ finally worked"

# --- asynchronous example ----------------------------------------
@with_retry                # default: 5 retries, no back-off
async def flaky_async():
    if random.random() < 0.5:
        raise RuntimeError("Try again …")
    return "✓ async worked"

print(flaky_sync())
print(asyncio.run(flaky_async()))
```

Arguments:
* `num_retries` – total attempts (initial call + retries). Must be ≥ 1.
* `backoff` – initial pause between retries (seconds). Must be ≥ 0.
* `backoff_exponent` – growth factor applied to the retry count to compute the
  wait time: `sleep = backoff * ((attempt + 1) ** backoff_exponent)`.

---

## Testing

Clone the repo and run:

```bash
pip install -r requirements-dev.txt  # pytest, etc.
pytest -q
```

All unit tests live under `tests/` and cover both decorators.

---

## License

MIT © 2024 Zubin Aysola
