> ## Documentation Index
> Fetch the complete documentation index at: https://repost.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Observe the Python Client

> Runtime diagnostics, bounded lifecycle observers, OpenTelemetry metrics, and traces for the Python client.

The runtime exposes diagnostics, a bounded observer stream, and an optional OpenTelemetry package. These surfaces contain no credentials or payloads.

## Diagnostics

```python theme={"languages":{"custom":["/languages/repost.json"]}}
diagnostics = client.diagnostics()
print(diagnostics.in_flight_operations)
print(diagnostics.dropped_observer_events)
print(diagnostics.observer_failures)
```

`RuntimeDiagnostics` also counts concurrency and byte-budget rejections, response limit and close failures, scheduler and executor overload, telemetry failures, and lifecycle state. Each call returns an immutable snapshot.

## Observers

```python theme={"languages":{"custom":["/languages/repost.json"]}}
from repost_client import ClientOptions, ObserverEvent, ObserverEventKind
from repost_sdk import RepostClient

def observe(event: ObserverEvent) -> None:
    if event.kind is ObserverEventKind.OPERATION_END:
        record_end(event.operation_id, event.delivery_state)

client = RepostClient(ClientOptions(observer=observe))
```

Observers receive operation start/end, attempt start/end, retry-delay, and cancellation events. They run on a dedicated dispatch thread, never the caller or transport thread. The queue holds 1,024 events. When it fills, the runtime drops and counts events instead of slowing a send. A slow or throwing observer cannot change the send result.

## OpenTelemetry

Install the isolated bridge package and wire its two explicit adapters:

```bash theme={"languages":{"custom":["/languages/repost.json"]}}
python -m pip install repost-client-otel
```

```python theme={"languages":{"custom":["/languages/repost.json"]}}
from repost_client import ClientOptions
from repost_client_otel import metrics_observer, telemetry
from repost_sdk import RepostClient

client = RepostClient(ClientOptions(
    observer=metrics_observer(),
    telemetry=telemetry(),
))
```

The metrics observer records exactly these instruments:

| Instrument                         | Unit         |
| ---------------------------------- | ------------ |
| `repost.client.operations`         | `operations` |
| `repost.client.operation.duration` | `ms`         |
| `repost.client.attempts`           | `attempts`   |
| `repost.client.attempt.duration`   | `ms`         |
| `repost.client.retry.delay`        | `ms`         |

Metrics use the low-cardinality attributes `outcome`, `error.code`, `delivery.state`, and `http.status.class`. Tracing emits one `repost.send` span and one `repost.send.attempt` child per attempt. The attempt carries `http.request.method`, `repost.retry.attempt`, `network.protocol.name`, and a success status when known. Trace context is propagated with `traceparent`.

## Continue

<Columns cols={3} className="gap-y-4">
  <Card title="Testing" icon="flask-conical" href="/docs/send/python/testing" cta="Test" arrow="true">
    Record observer events and deterministic attempt timing.
  </Card>

  <Card title="Frameworks" icon="boxes" href="/docs/send/python/frameworks" cta="Integrate" arrow="true">
    Parent send spans under inbound request spans.
  </Card>

  <Card title="Reliability" icon="shield-check" href="/docs/send/python/reliability" cta="Outcomes" arrow="true">
    Interpret delivery states and error codes.
  </Card>
</Columns>
