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

# Python models and configuration

> Python reference for Model, ProcessorConfig, OtelConfig, get_sdk_version and get_compatible_model_version in aic-sdk 3.2.0.

**Package:** `aic-sdk==3.2.0`. **Core SDK:** `0.24.0`. Source: [Python wrapper 3.2.0](https://github.com/ai-coustics/aic-sdk-py/tree/cca6f30d448c8e97bf7cfb13d6528a63de8f2c39).

The fragments below use these imports. Supply `license_key` from your approved secret source and use the loaded model and initialized objects described in each section. For a complete file-processing example, follow the [Python guide](/reference/sdk/language-bindings/python).

```python theme={null}
import os
import pathlib
import tempfile
from pathlib import Path
import typing
import aic_sdk as aic
from aic_sdk import Model, Processor, ProcessorConfig, OtelConfig
```

`audio` denotes a one-dimensional NumPy `float32` array. Async fragments run inside an async function.

<a id="model" />

<a id="aic_sdk-Model" />

## Model

<p><Badge>class</Badge></p>

Loaded model weights and model metadata. Create a model with `Model.from_file()`; there is no public `Model()` constructor. A loaded model can be shared by multiple processors. Native handles release their resources when Python releases the objects.

**Example**

```python theme={null}
model = Model.from_file("/path/to/model.aicmodel")
processor = Processor(model, license_key)
config = ProcessorConfig.optimal(model)
processor.initialize(config)
```

<a id="model-from_file" />

<a id="aic_sdk-Model-from_file" />

### Model.from\_file()

<p><Badge>static</Badge></p>

```python theme={null}
@staticmethod
def from_file(path: str | os.PathLike | pathlib.Path) -> Model
```

Creates a new model instance backed by memory-mapped file data. Do not modify or delete that file while the model or any dependent processor, detector or analyzer remains alive. Native references retain model data after the Python model handle is released; automatic handle management does not make changing the backing file safe.

Multiple models can be loaded for enhancement, voice activity detection or analysis.

**Parameters**

<ResponseField name="path" type="str | os.PathLike | pathlib.Path" required>
  Path to the model file (.aicmodel). You can download models manually from [artifacts.ai-coustics.io](https://artifacts.ai-coustics.io) or use [`Model.download()`](/reference/sdk/api/python/models-and-config#model-download) to fetch them programmatically. Accepts both string paths and pathlib.Path objects.
</ResponseField>

**Returns**

* [`Model`](/reference/sdk/api/python/models-and-config#model): A new Model instance.

**Raises**

* [`FileSystemError`](/reference/sdk/api/python/errors#filesystemerror): The file cannot be opened.
* [`ModelInvalidError`](/reference/sdk/api/python/errors#modelinvaliderror) or [`ModelVersionUnsupportedError`](/reference/sdk/api/python/errors#modelversionunsupportederror): Invalid or incompatible model data.

Pass a valid filesystem path without embedded NUL characters. aic-sdk 3.2.0 does not consistently map a NUL-containing path to an SDK exception.

**Example**

```python theme={null}
model = Model.from_file("/path/to/model.aicmodel")
model = Model.from_file(Path.cwd() / "model.aicmodel")
```

**See also**

* [artifacts.ai-coustics.io](https://artifacts.ai-coustics.io) for available model IDs and downloads.

<a id="model-download" />

<a id="aic_sdk-Model-download" />

### Model.download()

<p><Badge>static</Badge></p>

```python theme={null}
@staticmethod
def download(model_id: str, download_dir: str | os.PathLike | pathlib.Path) -> str
```

Downloads a model file from the ai-coustics artifact CDN.

Resolves a compatible model through its manifest and downloads it to the specified directory. An existing file is reused if its checksum matches; otherwise it is replaced.

Fresh manifests are reused from memory or the download directory according to the server's cache lifetime. Stale manifests are revalidated. Resolution is retried when the model is absent or a failed download may reflect a changed mapping.

Available models can be browsed at [artifacts.ai-coustics.io](https://artifacts.ai-coustics.io/).

**Parameters**

<ResponseField name="model_id" type="str" required>
  The model identifier (e.g., `"quail-ms-l-16khz"`).
</ResponseField>

<ResponseField name="download_dir" type="str | os.PathLike | pathlib.Path" required>
  Directory where the model file will be stored.
</ResponseField>

**Returns**

* `str`: The model file path. It remains relative when `download_dir` is relative.

**Raises**

* [`ModelDownloadError`](/reference/sdk/api/python/errors#modeldownloaderror): Manifest access, model selection, checksum, download or filesystem failure. Inspect `details` for the underlying cause.

<Note>
  This is a blocking operation that may perform network I/O.
</Note>

**Example**

```python theme={null}
# Find model IDs at <https://artifacts.ai-coustics.io>
path = Model.download("rook-ms-l-16khz", "/tmp/models")

# Or using pathlib.Path
path = Model.download("rook-ms-l-16khz", Path(tempfile.gettempdir()) / "models")

model = Model.from_file(path)
```

<a id="model-download_async" />

<a id="aic_sdk-Model-download_async" />

### Model.download\_async()

<p><Badge>static</Badge></p>

```python theme={null}
@staticmethod
def download_async(model_id: str, download_dir: str | os.PathLike | pathlib.Path) -> typing.Awaitable[str]
```

Downloads a model file asynchronously from the ai-coustics artifact CDN.

The network I/O runs on a background blocking task and does not block the caller's event loop.

Resolves a compatible model through its manifest and downloads it to the specified directory. An existing file is reused if its checksum matches; otherwise it is replaced.

Fresh manifests are reused from memory or the download directory according to the server's cache lifetime. Stale manifests are revalidated. Resolution is retried when the model is absent or a failed download may reflect a changed mapping.

Available models can be browsed at [artifacts.ai-coustics.io](https://artifacts.ai-coustics.io/).

**Parameters**

<ResponseField name="model_id" type="str" required>
  The model identifier (e.g., `"quail-ms-l-16khz"`).
</ResponseField>

<ResponseField name="download_dir" type="str | os.PathLike | pathlib.Path" required>
  Directory where the model file will be stored.
</ResponseField>

**Returns**

* `typing.Awaitable[str]`: Await it to obtain the model file path, relative when `download_dir` is relative. The released `.pyi` says `typing.Any`; the wrapper returns an awaitable resolving to `str`. Background task failure can also raise `RuntimeError`.

**Raises**

* [`ModelDownloadError`](/reference/sdk/api/python/errors#modeldownloaderror): Manifest access, model selection, checksum, download or filesystem failure. Inspect `details` for the underlying cause.

**Example**

```python theme={null}
# Find model IDs at <https://artifacts.ai-coustics.io>
path = await Model.download_async("rook-ms-l-16khz", "/tmp/models")

# Or using pathlib.Path
path = await Model.download_async("rook-ms-l-16khz", Path(tempfile.gettempdir()) / "models")

model = Model.from_file(path)
```

<a id="model-get_id" />

<a id="aic_sdk-Model-get_id" />

### Model.get\_id()

```python theme={null}
def get_id(self) -> str
```

Returns the model identifier string.

**Returns**

* `str`: The model ID string.

<a id="model-get_optimal_sample_rate" />

<a id="aic_sdk-Model-get_optimal_sample_rate" />

### Model.get\_optimal\_sample\_rate()

```python theme={null}
def get_optimal_sample_rate(self) -> int
```

Retrieves the native sample rate of the model.

This is the model's native rate in Hz. It does not validate or configure your input. Use `ProcessorConfig` to describe the actual input rate and query `get_optimal_block_size(sample_rate)` for that rate. See [audio format](/reference/concepts/audio-format) for supported rates and resampling.

**Returns**

* `int`: The model's native sample rate in Hz.

**Example**

```python theme={null}
optimal_rate = model.get_optimal_sample_rate()
print(f"Optimal sample rate: {optimal_rate} Hz")
```

See also [Latency](/reference/concepts/latency) and [Non-native sample rates](/reference/sdk/models#non-native-sample-rates).

<a id="model-get_optimal_block_size" />

<a id="aic_sdk-Model-get_optimal_block_size" />

### Model.get\_optimal\_block\_size()

```python theme={null}
def get_optimal_block_size(self, sample_rate: int) -> int
```

Retrieves the optimal block size for the model at a given sample rate.

Using the optimal block size minimizes latency by avoiding internal buffering. A non-optimal block size adds buffering latency on top of the model's base delay.

The optimal block size varies with sample rate because each model operates on a fixed time window. For example, a 10 ms window is 480 samples at 48 kHz and 160 samples at 16 kHz.

**Parameters**

<ResponseField name="sample_rate" type="int" required>
  Sample rate in Hz for which to calculate the optimal block size.
</ResponseField>

**Returns**

* `int`: The optimal block size for the given sample rate.

**Example**

```python theme={null}
sample_rate = model.get_optimal_sample_rate()
block_size = model.get_optimal_block_size(sample_rate)
print(f"Optimal block size: {block_size}")
```

<a id="processorconfig" />

<a id="aic_sdk-ProcessorConfig" />

## ProcessorConfig

<p><Badge>class</Badge></p>

Audio configuration passed to [`Processor.initialize()`](/reference/sdk/api/python/enhancement#processor-initialize), [`Vad.initialize()`](/reference/sdk/api/python/vad#vad-initialize) and [`Collector.initialize()`](/reference/sdk/api/python/analysis#collector-initialize).

Use [`ProcessorConfig.optimal()`](/reference/sdk/api/python/models-and-config#processorconfig-optimal) as a starting point, then adjust fields to match your audio stream.

<a id="processorconfig-constructor" />

<a id="aic_sdk-ProcessorConfig-constructor" />

### ProcessorConfig() constructor

```python theme={null}
ProcessorConfig(
    sample_rate: int,
    block_size: int,
    variable_block_size: bool = False,
) -> ProcessorConfig
```

Create a configuration value. Construction stores the fields; native initialization validates whether the combination is supported. Editing this object after initialization does not reconfigure a running processor, detector or collector. Reinitialize the owning object to apply changes.

**Parameters**

<ResponseField name="sample_rate" type="int" required>
  Input sample rate in Hz. Native initialization supports 8,000–192,000 Hz, subject to the model and configuration. This field is converted to an unsigned 32-bit integer.
</ResponseField>

<ResponseField name="block_size" type="int" required>
  Number of mono samples per call, greater than zero. This field is converted to a platform-sized unsigned integer.
</ResponseField>

<ResponseField name="variable_block_size" type="bool" default="False">
  Allow calls of up to `block_size` samples. With `False`, every call must contain exactly `block_size` samples.
</ResponseField>

<a id="processorconfig-optimal" />

<a id="aic_sdk-ProcessorConfig-optimal" />

### ProcessorConfig.optimal()

<p><Badge>static</Badge></p>

```python theme={null}
@staticmethod
def optimal(
    model: Model,
    sample_rate: int | None = None,
    block_size: int | None = None,
    variable_block_size: bool = False,
) -> ProcessorConfig
```

Returns a `ProcessorConfig` with the model's optimal settings and any supplied overrides.

**Parameters**

<ResponseField name="model" type="Model" required>
  The `Model` instance to get optimal config for. See [`Model`](/reference/sdk/api/python/models-and-config#model).
</ResponseField>

<ResponseField name="sample_rate" type="int | None" default="None">
  Custom sample rate in Hz. If `None`, uses the model's optimal sample rate (default: `None`).
</ResponseField>

<ResponseField name="block_size" type="int | None" default="None">
  Custom number of samples per processing call. If `None`, uses the optimal block size for the sample rate (default: `None`). A non-optimal block size increases latency.
</ResponseField>

<ResponseField name="variable_block_size" type="bool" default="False">
  Allow calls of up to `block_size` samples. With `False`, every call must contain exactly `block_size` samples.
</ResponseField>

**Returns**

* [`ProcessorConfig`](/reference/sdk/api/python/models-and-config#processorconfig): ProcessorConfig with optimal settings for the given model.

**Example**

```python theme={null}
# Use all optimal defaults
config = ProcessorConfig.optimal(model)
# Use a custom sample rate (optimal block size calculated automatically)
config = ProcessorConfig.optimal(model, sample_rate=44100)
# Use a custom sample rate and block size (increases latency)
config = ProcessorConfig.optimal(model, sample_rate=48000, block_size=512)
```

<a id="processorconfig-properties" />

### ProcessorConfig properties

<a id="processorconfig-sample_rate" />

<a id="aic_sdk-ProcessorConfig-sample_rate" />

#### ProcessorConfig.sample\_rate

<ResponseField name="sample_rate" type="int" post={["read/write"]}>
  Input sample rate in Hz. Native initialization supports 8,000–192,000 Hz, subject to the model and configuration. This field is converted to an unsigned 32-bit integer.
</ResponseField>

<a id="processorconfig-block_size" />

<a id="aic_sdk-ProcessorConfig-block_size" />

#### ProcessorConfig.block\_size

<ResponseField name="block_size" type="int" post={["read/write"]}>
  Number of mono samples per call, greater than zero. This field is converted to a platform-sized unsigned integer. A non-optimal block size increases latency.
</ResponseField>

<a id="processorconfig-variable_block_size" />

<a id="aic_sdk-ProcessorConfig-variable_block_size" />

#### ProcessorConfig.variable\_block\_size

<ResponseField name="variable_block_size" type="bool" post={["read/write"]}>
  Allows calls of up to `block_size` samples, with added buffering latency. It does not change the sample rate or allow oversized blocks.
</ResponseField>

<a id="otelconfig" />

<a id="aic_sdk-OtelConfig" />

## OtelConfig

<p><Badge>class</Badge></p>

OpenTelemetry (OTel) configuration for a [`Processor`](/reference/sdk/api/python/enhancement#processor) or [`Vad`](/reference/sdk/api/python/vad#vad).

Pass to `Processor`, [`ProcessorAsync`](/reference/sdk/api/python/enhancement#processorasync), `Vad` or [`VadAsync`](/reference/sdk/api/python/vad#vadasync) to control telemetry per instance. When no `OtelConfig` is provided, telemetry is configured according to the runtime environment (e.g. the `AIC_SDK_OTEL_ENABLE` environment variable).

**Example**

```python theme={null}
processor = Processor(model, license_key, otel_config=OtelConfig(enable=True, session_id="my-session"))
```

<a id="otelconfig-constructor" />

<a id="aic_sdk-OtelConfig-constructor" />

### OtelConfig() constructor

```python theme={null}
OtelConfig(
    enable: bool,
    session_id: str | None = None,
    export_interval_ms: int = 0,
) -> OtelConfig
```

Creates an OpenTelemetry configuration value. `enable` is required; `export_interval_ms` is an unsigned 32-bit integer. Settings are copied into the native object at construction. Later edits to this value do not change an existing session. A `session_id` containing a NUL character raises `InternalError` when passed to a processor or detector constructor.

OpenTelemetry controls optional observability, independently of SDK authorization and usage reporting. See [telemetry](/reference/concepts/sdk-telemetry).

**Parameters**

<ResponseField name="enable" type="bool" required>
  Whether to enable OpenTelemetry export.
</ResponseField>

<ResponseField name="session_id" type="str | None" default="None">
  Optional session ID. If `None`, a random ID is generated.
</ResponseField>

<ResponseField name="export_interval_ms" type="int" default="0">
  Metric export interval in ms. 0 uses the SDK default of 60,000 ms.
</ResponseField>

<a id="otelconfig-properties" />

### OtelConfig properties

<a id="otelconfig-enable" />

<a id="aic_sdk-OtelConfig-enable" />

#### OtelConfig.enable

<ResponseField name="enable" type="bool" post={["read/write"]}>
  Whether to enable OpenTelemetry export. Overrides the `AIC_SDK_OTEL_ENABLE` environment variable.
</ResponseField>

<a id="otelconfig-session_id" />

<a id="aic_sdk-OtelConfig-session_id" />

#### OtelConfig.session\_id

<ResponseField name="session_id" type="str | None" post={["read/write"]}>
  Optional session ID for telemetry. If `None`, a random session ID is generated.
</ResponseField>

<a id="otelconfig-export_interval_ms" />

<a id="aic_sdk-OtelConfig-export_interval_ms" />

#### OtelConfig.export\_interval\_ms

<ResponseField name="export_interval_ms" type="int" post={["read/write"]}>
  OpenTelemetry metric export interval in milliseconds. Set to 0 to use the SDK default of 60,000 ms.
</ResponseField>

<a id="get_sdk_version" />

<a id="aic_sdk-get_sdk_version" />

## get\_sdk\_version()

<p><Badge>function</Badge></p>

```python theme={null}
def get_sdk_version() -> str
```

Returns the version of the ai-coustics core SDK library used by this package.

**Returns**

* `str`: The library version as a string.

<Note>
  This is not necessarily the same as this package's version.
</Note>

**Example**

```python theme={null}
version = aic.get_sdk_version()
print(f"ai-coustics SDK version: {version}")
```

<a id="get_compatible_model_version" />

<a id="aic_sdk-get_compatible_model_version" />

## get\_compatible\_model\_version()

<p><Badge>function</Badge></p>

```python theme={null}
def get_compatible_model_version() -> int
```

Returns the model file format version compatible with this core SDK build. This is a format number, not a model ID or model release version.

**Returns**

* `int`: The compatible model version number.

See the [Python API index](/reference/sdk/api/python/index), [Python guide](/reference/sdk/language-bindings/python) and [troubleshooting](/production/troubleshooting).

<a id="otelconfig-__repr__" />

<a id="aic_sdk-OtelConfig-__repr__" />

### OtelConfig.**repr**()

```python theme={null}
def __repr__(self) -> str
```

Returns a diagnostic string containing the object's current fields. It is not a serialization format.

<a id="processorconfig-__repr__" />

<a id="aic_sdk-ProcessorConfig-__repr__" />

### ProcessorConfig.**repr**()

```python theme={null}
def __repr__(self) -> str
```

Returns a diagnostic string containing the object's current fields. It is not a serialization format.
