Metadata-Version: 2.4
Name: madjik
Version: 0.2.0
Summary: Python client for the Madjik crypto market metrics API (REST), with retries, point-in-time history and webhook signature checks.
Author: Madjik
License: MIT
Project-URL: Documentation, https://docs.madjik.io
Project-URL: Homepage, https://www.madjik.io
Project-URL: Status, https://api.madjik.io/status
Keywords: crypto,market data,metrics,api,backtesting
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28
Provides-Extra: pandas
Requires-Dist: pandas>=1.5; extra == "pandas"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pandas>=1.5; extra == "dev"

# madjik

Python client for the [Madjik](https://www.madjik.io) crypto market metrics API. Docs: https://docs.madjik.io · Status: https://api.madjik.io/status

```bash
pip install madjik            # or: pip install "madjik[pandas]"
export MADJIK_API_KEY=...     # Free trial: https://api.madjik.io/pricing (e-mail verification, no card)
```

```python
from madjik import Madjik
mj = Madjik()
mj.metric("M10004")                                         # latest value
df = mj.timeseries("M10004", live_only=True, as_dataframe=True)   # point-in-time safe history
mj.metrics(as_dataframe=True)                               # every metric, ONE call
mj.definition("M10004")                                     # inputs, lookback, version (no key needed)
mj.data_inventory()                                         # how much data, last refreshed (no key needed)
```

* **History at scale:** `mj.plan_calls([...], start=..., interval="1h")` is a dry run (calls needed vs your daily quota). `mj.panel([...], start=..., live_only=True, lag=1)` pages through your plan's points-per-call limit, paces calls to the speed limit, caches finished history chunks on disk (`MADJIK_CACHE_DIR`, default `~/.cache/madjik`) and resumes the next day if the quota runs out (`df.attrs["partial"]`). `madjik.join_asof(panel, prices)` attaches prices without look-ahead.
* **Webhook receiver (Pro+):** `from madjik.webhooks import construct_event, Deduper, fastapi_handler, flask_handler`; verifies `X-Madjik-Signature-V2` with a 5-minute replay window and deduplicates on `X-Madjik-Event-Id`. `mj.test_webhook(id)` sends a sample event and re-enables a webhook that was disabled after repeated failures.
* **Limits are handled for you:** a 429 waits for the server's `Retry-After` (up to `max_wait`, default 65 s) and retries; 5xx and network errors back off. Free plan: 1 call / 60 s, 10 calls / day: use `mj.metrics()` (all metrics in one call) rather than looping.
* **History window:** `timeseries()` defaults to the last 7 days; pass `start=` for more (limited by your plan's depth and points per call).
* **Point-in-time:** `live_only=True` returns only values computed live at the time. See https://docs.madjik.io/getting-started/backtesting/
* **Webhooks (Pro+):** `verify_webhook_signature(body, request.headers["X-Madjik-Signature"], secret)`.
* **Errors:** `AuthError` (401), `PlanError` (403), `NotFoundError` (404), `RateLimitError` (429), `ServerError` (5xx), all subclasses of `MadjikError` with `.status` and `.payload`.

Examples: `examples/*.ipynb` (quickstart, point-in-time backtest, data quality). Madjik metrics are informational indicators, not investment advice.
