# Hardsim SDK (v0)

Phase 1 SDK goals:

- `submit(...)` / `run(...)` to create cloud simulation jobs
- `step(...)` alias for cloud-routed environment steps
- `status(...)`, `wait(...)`, and `download(...)` for lifecycle + artifacts
- `cancel(...)` for queued/running jobs
- `upload_input(...)` helper for local URDF/USD -> S3
- Retries + typed exceptions for robust client behavior

Install from PyPI:

```bash
pip install hardsim
```

Install (editable during development):

```bash
pip install -e ./sdk
# optional upload helper dependencies:
pip install -e "./sdk[s3]"
```

Release process is documented in `docs/sdk-release.md`.

3-line usage:

```python
import hardsim as hs

job = hs.submit(robot="s3://bucket/franka.urdf", scene="table_top_v0", num_envs=64, steps=2000)
hs.wait(job.job_id)
paths = hs.download(job.job_id, "./outputs")
```

Environment variables:

- `HARDSIM_API_KEY` (required)
- `HARDSIM_API_URL` (default `http://localhost:8000`)
- `HARDSIM_HTTP_TIMEOUT_S` (default `30`)
- `HARDSIM_HTTP_RETRIES` (default `3`)
- `HARDSIM_HTTP_BACKOFF_S` (default `0.5`)
- `HARDSIM_INPUT_S3_BUCKET` (required for `upload_input(...)` when destination URI is not passed)
- `HARDSIM_INPUT_S3_PREFIX` (default `hardsim/inputs`)
- `HARDSIM_INPUT_S3_REGION` / `HARDSIM_INPUT_S3_ENDPOINT_URL` (optional)

Production base URL:

```bash
export HARDSIM_API_URL=https://api-sim.hardlightsim.com
```

Idempotent create (recommended for client retries):

```python
job = hs.step(
    robot="s3://bucket/franka.urdf",
    scene="table_top_v0",
    num_envs=64,
    steps=2000,
    idempotency_key="train-run-42-shard-0001",
)
```

Local file upload helper:

```python
import hardsim as hs

client = hs.HardsimClient.from_env()
robot_uri = client.upload_input("./assets/franka.urdf")
job = client.submit(robot=robot_uri, scene="table_top_v0", num_envs=64, steps=2000)
```
