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

# CortexHubClient

> Asynchronous WebSocket client for CortexHub

```python theme={null}
from grid_cortex_client import CortexHubClient
```

Asynchronous WebSocket client for CortexHub.

Provides a persistent WebSocket connection for efficient model inference.
Supports both request-response and pub/sub patterns.

For synchronous usage, use CortexClient instead.

## Constructor

```python theme={null}
CortexHubClient(api_key: Optional[str] = None, base_url: Optional[str] = None, timeout: float = 60.0)
```

## Methods

### `available_models()`

```python theme={null}
available_models() -> list[str]
```

Return registered model identifiers.

### `close()`

```python theme={null}
close() -> None
```

Close WebSocket connection and cleanup pub/sub resources.

### `collect()`

```python theme={null}
collect(count: Optional[int] = None) -> list[HubResult]
```

Collect all results into a list.

Convenience method that collects subscribe() results.

<ParamField body="count">
  If provided, collect exactly this many results. If None, collect until no pending requests remain.
</ParamField>

**Returns:**

List of HubResult objects.

### `connect()`

```python theme={null}
connect() -> None
```

Establish WebSocket connection.

### `help()`

```python theme={null}
help(model_id: str) -> str
```

Return documentation for a model.

### `publish()`

```python theme={null}
publish(model_id: Union[str, ModelType], request_id: Optional[str] = None, **kwargs: Any) -> str
```

Publish a model inference request (non-blocking).

Sends the request and returns immediately. Results arrive via subscribe().

<ParamField body="model_id" required>
  Model to run (ModelType enum or string)
</ParamField>

<ParamField body="request_id">
  Optional ID to track this request. Auto-generated if not provided.
</ParamField>

<ParamField body="**kwargs">
  Model-specific parameters (e.g., image\_input, prompt)
</ParamField>

**Returns:**

The request\_id (useful when auto-generated)

**Raises:**

RuntimeError: If not connected

### `run()`

```python theme={null}
run(model_id: Union[str, ModelType], **kwargs: Any) -> Any
```

Run model inference via CortexHub (blocking request-response).

<ParamField body="model_id" required>
  Model to run (ModelType enum or string)
</ParamField>

<ParamField body="**kwargs">
  Model-specific parameters (e.g., image\_input, prompt)
</ParamField>

**Returns:**

Model output (same format as CortexClient.run)

**Raises:**

RuntimeError: If not connected or if pub/sub mode is active
CortexHubError: If server returns an error

### `submit()`

```python theme={null}
submit(model_id: Union[str, ModelType], request_id: Optional[str] = None, timeout_s: float | None = None, **kwargs: Any) -> 'asyncio.Task[HubResult]'
```

Submit a request and return a Task for its eventual result.

This is a convenience wrapper over the pub/sub API that lets you write:

> > > async with CortexHubClient() as hub:
> > > ...     depth\_t = hub.submit(ModelType.ZOEDEPTH, image\_input=img)
> > > ...     mask\_t = hub.submit(ModelType.GSAM2, image\_input=img, prompt="cat")
> > > ...     depth\_res, mask\_res = await asyncio.gather(depth\_t, mask\_t)

### `subscribe()`

```python theme={null}
subscribe(count: Optional[int] = None) -> AsyncIterator[HubResult]
```

Subscribe to inference results.

Yields results as they arrive from published requests.

<ParamField body="count">
  If provided, stop after receiving this many results. If None, yields indefinitely until no pending requests remain.
</ParamField>

**Yields:**

HubResult objects containing request\_id, model, data, ok, and error.

```python theme={null}
await hub.publish(ModelType.ZOEDEPTH, request_id="d1", image_input=img)
await hub.publish(ModelType.GSAM2, request_id="m1", image_input=img, prompt="cat")
async for result in hub.subscribe(count=2):
    if result.ok:
        print(f"{result.request_id}: shape={result.data.shape}")
    else:
        print(f"{result.request_id}: error={result.error}")
```


## Related topics

- [GRID Cortex Client](/models/cortex.md)
- [grid-cortex-client](/python-api/grid-cortex-client/overview.md)
- [HubResult](/python-api/grid-cortex-client/hubresult.md)
- [CortexHubError](/python-api/grid-cortex-client/cortexhuberror.md)
- [CortexClient](/python-api/grid-cortex-client/cortexclient.md)
