# 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.PushResult

*class* · *dataclass*

```python
class PushResult
```

Re-exported from: `ocx_sdk._results`

`ocx package push` — what landed in the registry.

**Attributes**

- `identifier` (`str`) — What was pushed.
- `status` (`str`) — What happened, e.g. `"pushed"`.
- `manifest_digest` (`str`) — Digest of the manifest that was written.
- `cascade_tags_written` (`tuple[str, ...]`) — Cascading tags updated by the push.
- `keep_tags_written` (`tuple[str, ...]`) — The `__ocx.keep.sha256-<hex>` tags written, one per platform manifest — `push`'s `--keep-tag` flag, which is on by default. Named for the wire key ocx 0.6 emits (C-005); 0.5 called it `canonical_tags_written` and wrote a `sha256.<hex>` tag, so a 0.1 call site reading the old attribute must be edited.
- `layers` (`Mapping[str, Any]`) — Layer counts (`mounted`, `uploaded`, `verified`).
- `platform_digests` (`Mapping[str, str]`) — Manifest digest per pushed platform (C-005). Absent-when-unused (D7).
- `signatures` (`tuple[SignedPlatformReport, ...]`) — One row per platform's signing outcome, when `push(..., sign=True)` was requested (C-005, C-018). Absent-when-unused (D7).
- `attestation` (`AttestationOutcome | None`) — The push's attestation outcome, when one was requested (C-005, C-019). Absent-when-unused (D7).

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

### ocx_sdk.PushResult.attestation

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

```python
attestation: AttestationOutcome | None = None
```

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

### ocx_sdk.PushResult.cascade_tags_written

*attribute* · *instance attribute*

```python
cascade_tags_written: tuple[str, ...]
```

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

### ocx_sdk.PushResult.identifier

*attribute* · *instance attribute*

```python
identifier: str
```

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

### ocx_sdk.PushResult.keep_tags_written

*attribute* · *instance attribute*

```python
keep_tags_written: tuple[str, ...]
```

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

### ocx_sdk.PushResult.layers

*attribute* · *instance attribute*

```python
layers: Mapping[str, Any]
```

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

### ocx_sdk.PushResult.manifest_digest

*attribute* · *instance attribute*

```python
manifest_digest: str
```

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

### ocx_sdk.PushResult.platform_digests

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

```python
platform_digests: Mapping[str, str] = _EMPTY
```

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

### ocx_sdk.PushResult.signatures

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

```python
signatures: tuple[SignedPlatformReport, ...] = ()
```

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

### ocx_sdk.PushResult.status

*attribute* · *instance attribute*

```python
status: str
```

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

### ocx_sdk.PushResult.ref

*property*

```python
ref: PackageRef
```

The pushed package, as a `PackageRef`.

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

### ocx_sdk.PushResult.from_json

*method* · *classmethod*

```python
def from_json(raw: str) -> PushResult
```

Parse `ocx --format json package push` output.

The payload is **bare** (D11) — the report sits at the JSON root, with
no envelope to unwrap. A push that lands and then fails to sign exits
non-zero carrying this same document, so `partial_report(err)` feeds
straight back into this parser (D10, C-009).

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