Metadata-Version: 2.4
Name: wildtrax-client
Version: 0.1.0
Summary: Python client for the WildTrax 2027 HTTP /api control surface
Author: Halter Technical
License-Expression: MIT
Project-URL: Homepage, https://wildtrax.io
Project-URL: Documentation, https://wildtrax.io/resources/python-client
Keywords: wildtrax,audio,recording,remote,osc,control
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Multimedia :: Sound/Audio
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# PyWildTrax

A small, dependency-free Python client for the **WildTrax 2027** HTTP `/api`
control surface. Drive recording, tracks, metadata, the soundboard, the playlist,
and more from scripts — the same actions the OSC protocol exposes, over plain HTTP.

Built on the Python standard library only (`urllib`) — no `requests`, no extra
installs, works anywhere Python 3.8+ runs.

## Install

```bash
pip install wildtrax-client
# or, from a checkout:
pip install -e .
```

> Install as **`wildtrax-client`**, import as **`wildtrax_client`**:
> ```python
> from wildtrax_client import WildTrax
> ```

## Quick start

```python
from wildtrax_client import WildTrax

wt = WildTrax("192.168.1.155")      # default HTTP port 5659
wt.wait_for_approval()              # blocks until the host approves this device

wt.metadata.scene("SC07")
wt.transport.record()
# ...
wt.transport.stop()

print(wt.session_state())
```

## Approval model

WildTrax has no passwords — security is the host approving devices on the LAN.
The **first** request from a new device shows up as *pending* in the desktop
**Session Manager** and the client gets `202`. A human approves it once (and grants
**Write** for write actions like recording). After that, the device is remembered.

- `wt.wait_for_approval(timeout=120)` — poll until approved, or raise.
- Or catch `PendingApprovalError` yourself and retry.
- `wt.is_approved()` / `wt.can_write()` — check status without blocking.

The server must have a **fixed HTTP port** enabled (Session Manager → Advanced →
*Fixed network ports*) so the port is stable; otherwise it binds an ephemeral one.

## API

Methods are grouped to mirror the `/api` route families:

| Namespace | Examples |
|---|---|
| `wt.transport` | `record()`, `stop()`, `false_start()` |
| `wt.tracks` | `arm(i)`, `mute(i, True)`, `pan(i, 2)`, `name(i, "Boom")`, `add()`, `remove(i)`, `set_count(n)` |
| `wt.metadata` | `scene("SC07")`, `take("T001")`, `note(...)`, `add_marker()`, `next_scene(...)`, `reset_next()`, `auto_increment("take", True)` |
| `wt.config` | `preroll(True)`, `meter_smoothness(0.5)`, `global_monitor(True)`, `playback_volume(80)`, `matrix_cell("input", 1, 1)` |
| `wt.soundboard` | `play(1)`, `stop(1)`, `add_pad()`, `title(1, "FX")`, `repeat(1, True)`, `trigger_mode(1, 1)`, `routing_mode(1, 5)`, `routing_cell(1, 1, 2, 1.0)` |
| `wt.playlist` | `play()`, `stop()`, `loop(True)`, `index(2)`, `add_row()`, `row_title(1, "Cue")`, `row_routing_mode(1, 0)` |
| `wt.export` | `add()`, `remove(i)`, `update(i, "name", "Mix")`, `toggle_track(f, t)` |
| `wt.report` | `csv()`, `auto_save(True)`, `edit_entry(3, "circled", True)` |

> **Indices are 1-based.** Every index argument (`i`, pad index, row index, file
> index) is 1-based, matching the WildTrax UI (Track 1, Input 1) and the OSC
> surface — `wt.tracks.mute(1)` mutes the track shown as "Track 1". The server
> converts to its 0-based models at the HTTP seam.

Readback: `wt.session_state()`, `wt.recording()`, `wt.get_tracks()`,
`wt.get_metadata()`, `wt.report.csv()`. Per-element reads (1-based, mirror the OSC
flat read-side): `wt.get_pad(i)`, `wt.get_playlist_row(i)`, `wt.get_export_file(i)`,
`wt.get_matrix(which)`, `wt.get_soundreport_entry(i)`, `wt.get_session_client(i)`.

> **Session administration** (approving/kicking clients, permissions, renaming the
> session) is **not** available remotely — it's reserved for the desktop host.

## Errors

All raise subclasses of `WildTraxError`:

| Exception | Meaning (HTTP) |
|---|---|
| `ConnectionFailed` | host unreachable |
| `PendingApprovalError` | `202` — awaiting approval |
| `PermissionDenied` | `403` — approved but no Write |
| `NotFound` | `404` — bad route or index |
| `RecordingInProgress` | `409` — blocked while recording |
| `RateLimited` | `429` — transport command debounced |
| `BadRequest` | `400` — malformed body |

## License

MIT
