# ocx_sdk

*module*

Python SDK for [OCX](https://github.com/ocx-sh/ocx).

`ocx-sdk` drives the ocx binary rather than reimplementing it: ocx owns
resolution, verification, and the identifier grammar, and this package gives
you typed, CWD-independent handles over the commands it exposes.

```python
from ocx_sdk import Ocx, bootstrap

ocx = Ocx(exe=bootstrap.ensure())
project = ocx.project("/srv/build")
project.pull()
project.exec(["task", "verify"])
```

**This module is the API.** Everything listed in `__all__` is the stable
surface; every other module is underscored and package-private, and the one
public submodule is `ocx_sdk.bootstrap`. Reaching into an underscored path
means the next release may move it without notice — pre-1.0, breaking
changes ship without shims.

Start at `Ocx` for the runtime API and `bootstrap.ensure` for provisioning.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/__init__.py#L1-L1)

## ocx_sdk.RetryPolicy

*class* · *dataclass*

```python
class RetryPolicy
```

Re-exported from: `ocx_sdk._types`

How to retry a failure ocx classified as transient.

Attempt one is not a retry: `attempts=3` means at most two backoff waits.
`timeout` is per attempt, so the worst case is
`attempts * timeout + sum(backoff)`.

**Attributes**

- `attempts` (`int`) — Total attempts, including the first.
- `backoff` (`float`) — Delay before the first retry, in seconds.
- `multiplier` (`float`) — Growth factor applied to `backoff` per retry.
- `max_backoff` (`float`) — Ceiling for the computed delay.
- `max_retry_after` (`float`) — Ceiling for a server-supplied `Retry-After`. It is honored verbatim up to this value rather than truncated to `max_backoff` — truncating it would hammer a registry that just asked for room. Beyond it the answer is to fail, not to wait.
- `jitter` (`bool`) — Draw the delay uniformly from `[0, delay]` (AWS full jitter).
- `retry_on` (`frozenset[ExitCode]`) — Exit codes worth retrying. Applies to the process path only; `_dist` classifies by transport condition instead, so this set does not affect `bootstrap.ensure()`.
- `sleep` (`Callable[[float], None] | None`) — Sleep seam, defaulting to `time.sleep`. Async drivers use `asyncio.sleep` and ignore this field.

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L258-L299)

### ocx_sdk.RetryPolicy.attempts

*attribute* · *class attribute* · *instance attribute*

```python
attempts: int = 3
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L283-L283)

### ocx_sdk.RetryPolicy.backoff

*attribute* · *class attribute* · *instance attribute*

```python
backoff: float = 1.0
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L284-L284)

### ocx_sdk.RetryPolicy.jitter

*attribute* · *class attribute* · *instance attribute*

```python
jitter: bool = True
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L288-L288)

### ocx_sdk.RetryPolicy.max_backoff

*attribute* · *class attribute* · *instance attribute*

```python
max_backoff: float = 30.0
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L286-L286)

### ocx_sdk.RetryPolicy.max_retry_after

*attribute* · *class attribute* · *instance attribute*

```python
max_retry_after: float = 300.0
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L287-L287)

### ocx_sdk.RetryPolicy.multiplier

*attribute* · *class attribute* · *instance attribute*

```python
multiplier: float = 2.0
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L285-L285)

### ocx_sdk.RetryPolicy.retry_on

*attribute* · *class attribute* · *instance attribute*

```python
retry_on: frozenset[ExitCode] = frozenset({ExitCode.TEMP_FAIL})
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L289-L289)

### ocx_sdk.RetryPolicy.sleep

*attribute* · *class attribute* · *instance attribute*

```python
sleep: Callable[[float], None] | None = None
```

[View source](https://github.com/ocx-sh/ocx-sdk-python/blob/main/src/ocx_sdk/_types.py#L290-L290)
