Skip to content

API Reference

Auto-generated reference for every public class, method, and model in the SDK. Pages are organized by domain - pick the one you need on the left, or use search.

The reference content is extracted directly from the source code on every docs build, so it always matches the installed SDK.

Client

NiosClient

NiosClient(*, grid_url: str | None = None, username: str | None = None, password: str | None = None, wapi_version: str | None = None, use_session: bool = True, verify: bool | str | Path = True, ca_bundle: str | Path | None = None, timeout: float = 30.0, max_retries: int = 3, enforce_restrictions: bool = True, _transport: AsyncBaseTransport | None = None)

Entry point for the Infoblox NIOS SDK.

Per-domain services (dns, dhcp, ipam, ...) are exposed as @cached_property attributes and lazily instantiated on first access. The client supports use as an async context manager and reads configuration from environment variables when constructor arguments are omitted.

Environment variables:

  • NIOS_GRID_URL: Fallback for grid_url.
  • NIOS_USERNAME: Fallback for username.
  • NIOS_PASSWORD: Fallback for password.
  • NIOS_WAPI_VERSION: Fallback for wapi_version.
Example

Use as an async context manager::

async with NiosClient(
    grid_url="https://192.168.1.2",
    username="admin",
    password="secret",
) as client:
    records = await client.dns.a_record.list(name="host.example.com").all()

Initialize the NIOS client.

Parameters:

Name Type Description Default
grid_url str | None

Base URL of the NIOS Grid Manager (e.g. "https://192.168.1.2"). Falls back to the NIOS_GRID_URL environment variable.

None
username str | None

WAPI username. Falls back to NIOS_USERNAME.

None
password str | None

WAPI password. Falls back to NIOS_PASSWORD.

None
wapi_version str | None

WAPI version string (e.g. "2.14"). Falls back to NIOS_WAPI_VERSION, then the SDK default. The SDK's hand- written pydantic models, readonly/create-only sets, default return-field lists, and Literal enum types are calibrated against NIOS v2.14. Pointing at an older grid may work for reads (optional fields tolerate absence) but list/get requests can fail with AdmConProtoError: Unknown argument because the SDK requests return-fields the older schema does not know. Mitigations: pass return_fields=[...] explicitly on each call, or pin this SDK to a release aligned with your grid version.

None
use_session bool

When True (default), authenticates via a session cookie from GET /grid/session. When False, sends Basic Auth on every request.

True
verify bool | str | Path

TLS certificate verification. Pass True to verify with the system CA bundle, False to disable, or a path string to a custom CA bundle PEM file.

True
ca_bundle str | Path | None

Convenience alias for a custom CA bundle path. When set, overrides verify with str(ca_bundle).

None
timeout float

Request timeout in seconds for all WAPI calls.

30.0
max_retries int

Number of additional retry attempts on 429/5xx responses.

3
enforce_restrictions bool

When True (default), a resource method raises :class:~ibx_nios_sdk._exceptions.UnsupportedOperationError instead of calling WAPI for an operation the object type's schema restricts - create on the read-only allrecords aggregate, delete on the grid singleton, or any read of a function-only type such as dtc. The table is recorded from NIOS 9.1 / WAPI 2.14; set this False on a grid whose restrictions differ, and let the grid reject the call instead.

True
_transport AsyncBaseTransport | None

Custom httpx.AsyncBaseTransport for testing. Not intended for production use.

None

Raises:

Type Description
NiosError

If grid_url is not provided and NIOS_GRID_URL is not set, or if username/password are absent.

Source code in src/ibx_nios_sdk/client.py
def __init__(
    self,
    *,
    grid_url: str | None = None,
    username: str | None = None,
    password: str | None = None,
    wapi_version: str | None = None,
    use_session: bool = True,
    verify: bool | str | Path = True,
    ca_bundle: str | Path | None = None,
    timeout: float = 30.0,
    max_retries: int = 3,
    enforce_restrictions: bool = True,
    _transport: httpx.AsyncBaseTransport | None = None,
) -> None:
    """Initialize the NIOS client.

    Args:
        grid_url: Base URL of the NIOS Grid Manager (e.g.
            ``"https://192.168.1.2"``). Falls back to the
            ``NIOS_GRID_URL`` environment variable.
        username: WAPI username. Falls back to ``NIOS_USERNAME``.
        password: WAPI password. Falls back to ``NIOS_PASSWORD``.
        wapi_version: WAPI version string (e.g. ``"2.14"``). Falls back to
            ``NIOS_WAPI_VERSION``, then the SDK default. The SDK's hand-
            written pydantic models, readonly/create-only sets, default
            return-field lists, and Literal enum types are calibrated
            against NIOS **v2.14**. Pointing at an older grid may work for
            reads (optional fields tolerate absence) but list/get requests
            can fail with ``AdmConProtoError: Unknown argument`` because
            the SDK requests return-fields the older schema does not know.
            Mitigations: pass ``return_fields=[...]`` explicitly on each
            call, or pin this SDK to a release aligned with your grid
            version.
        use_session: When True (default), authenticates via a session cookie
            from ``GET /grid/session``. When False, sends Basic Auth on
            every request.
        verify: TLS certificate verification. Pass ``True`` to verify with
            the system CA bundle, ``False`` to disable, or a path string to
            a custom CA bundle PEM file.
        ca_bundle: Convenience alias for a custom CA bundle path. When set,
            overrides ``verify`` with ``str(ca_bundle)``.
        timeout: Request timeout in seconds for all WAPI calls.
        max_retries: Number of additional retry attempts on 429/5xx
            responses.
        enforce_restrictions: When True (default), a resource method raises
            :class:`~ibx_nios_sdk._exceptions.UnsupportedOperationError`
            instead of calling WAPI for an operation the object type's
            schema restricts - ``create`` on the read-only ``allrecords``
            aggregate, ``delete`` on the ``grid`` singleton, or any read of
            a function-only type such as ``dtc``. The table is recorded from
            NIOS 9.1 / WAPI 2.14; set this False on a grid whose
            restrictions differ, and let the grid reject the call instead.
        _transport: Custom ``httpx.AsyncBaseTransport`` for testing.
            Not intended for production use.

    Raises:
        NiosError: If ``grid_url`` is not provided and ``NIOS_GRID_URL`` is
            not set, or if ``username``/``password`` are absent.
    """
    grid_url = grid_url or os.environ.get("NIOS_GRID_URL")
    username = username or os.environ.get("NIOS_USERNAME")
    password = password or os.environ.get("NIOS_PASSWORD")
    wapi_version = wapi_version or os.environ.get("NIOS_WAPI_VERSION") or DEFAULT_WAPI_VERSION

    if not grid_url:
        raise NiosError(message="grid_url is required (set arg or NIOS_GRID_URL env var)")
    if not username or not password:
        raise NiosError(
            message="credentials are required (pass username/password or set NIOS_USERNAME/NIOS_PASSWORD)"
        )

    verify = _resolve_verify(verify, ca_bundle, os.environ.get("NIOS_VERIFY"))

    self._http = HttpClient(
        grid_url=grid_url,
        username=username,
        password=password,
        wapi_version=wapi_version,
        use_session=use_session,
        verify=verify,
        timeout=timeout,
        max_retries=max_retries,
        enforce_restrictions=enforce_restrictions,
        transport=_transport,
    )

grid_url property

grid_url: str

Base URL of the NIOS Grid Manager, without a trailing slash.

acl cached property

acl: AclService

Entry point for NIOS Access Control List resources.

cloud cached property

cloud: CloudService

Entry point for NIOS Cloud resources.

discovery cached property

discovery: DiscoveryService

Entry point for NIOS Discovery resources.

microsoftserver cached property

microsoftserver: MicrosoftserverService

Entry point for NIOS Microsoft Server resources.

federatedrealms cached property

federatedrealms: FederatedrealmsService

Entry point for NIOS Federated Realms resources.

misc cached property

misc: MiscService

Entry point for miscellaneous NIOS WAPI resources.

notification cached property

notification: NotificationService

Entry point for NIOS Notification resources.

smartfolder cached property

smartfolder: SmartfolderService

Entry point for NIOS Smart Folder resources.

dtc cached property

dtc: DtcService

Entry point for NIOS DNS Traffic Control resources.

dhcp cached property

dhcp: DhcpService

Entry point for NIOS DHCP resources.

dns cached property

dns: DnsService

Entry point for NIOS DNS resources.

grid cached property

grid: GridService

Entry point for NIOS Grid resources.

ipam cached property

ipam: IpamService

Entry point for NIOS IPAM resources.

rpz cached property

rpz: RpzService

Entry point for NIOS Response Policy Zone resources.

security cached property

security: SecurityService

Entry point for NIOS Security resources.

threatinsight cached property

threatinsight: ThreatinsightService

Entry point for NIOS Threat Insight resources.

threatprotection cached property

threatprotection: ThreatprotectionService

Entry point for NIOS Threat Protection resources.

read_raw async

read_raw(object_type: str, *, params: Mapping[str, str] | None = None) -> Any

Read an uncoerced WAPI collection or its schema through SDK transport.

This narrow fallback accepts only a single WAPI object type. Schema and paging controls must be supplied through params; URLs, object refs, embedded query strings, and credential-bearing parameters are rejected. Prefer the typed resource APIs whenever one is available.

Source code in src/ibx_nios_sdk/client.py
async def read_raw(
    self,
    object_type: str,
    *,
    params: Mapping[str, str] | None = None,
) -> Any:
    """Read an uncoerced WAPI collection or its schema through SDK transport.

    This narrow fallback accepts only a single WAPI object type. Schema and
    paging controls must be supplied through ``params``; URLs, object refs,
    embedded query strings, and credential-bearing parameters are rejected.
    Prefer the typed resource APIs whenever one is available.
    """
    _validate_wapi_object_type(object_type)
    _validate_safe_read_params(params)
    result = await self._http.get(object_type, params=dict(params) if params else None)
    return unwrap_value(result)

read_schema async

read_schema(object_type: str | None = None) -> Any

Read the WAPI root schema or one collection object's schema.

Parameters:

Name Type Description Default
object_type str | None

A safe WAPI collection object type. When omitted, the WAPI version root schema is returned.

None

Returns:

Type Description
Any

The uncoerced JSON schema response from NIOS.

Raises:

Type Description
ValueError

If object_type is not a safe collection name.

NiosError

Or a subclass for transport or WAPI errors.

Source code in src/ibx_nios_sdk/client.py
async def read_schema(self, object_type: str | None = None) -> Any:
    """Read the WAPI root schema or one collection object's schema.

    Args:
        object_type: A safe WAPI collection object type. When omitted, the
            WAPI version root schema is returned.

    Returns:
        The uncoerced JSON schema response from NIOS.

    Raises:
        ValueError: If ``object_type`` is not a safe collection name.
        NiosError: Or a subclass for transport or WAPI errors.
    """
    if object_type is not None:
        _validate_wapi_object_type(object_type)
    result = await self._http.get(object_type or "/", params={"_schema": "1"})
    return unwrap_value(result)

aclose async

aclose() -> None

Close the underlying HTTP client and release any active WAPI session.

Calls :meth:~ibx_nios_sdk._http.HttpClient.aclose, which logs out of the WAPI session if one is active before closing the httpx.AsyncClient.

Example

Explicit lifecycle management::

client = NiosClient(grid_url=..., username=..., password=...)
try:
    ...
finally:
    await client.aclose()
Source code in src/ibx_nios_sdk/client.py
async def aclose(self) -> None:
    """Close the underlying HTTP client and release any active WAPI session.

    Calls :meth:`~ibx_nios_sdk._http.HttpClient.aclose`, which logs out of
    the WAPI session if one is active before closing the ``httpx.AsyncClient``.

    Example:
        Explicit lifecycle management::

            client = NiosClient(grid_url=..., username=..., password=...)
            try:
                ...
            finally:
                await client.aclose()
    """
    await self._http.aclose()

Core Building Blocks

HTTP Client

The low-level transport. You normally won't touch this directly - it's created by NiosClient and shared across services.

HttpClient

HttpClient(*, grid_url: str, username: str, password: str, wapi_version: str = DEFAULT_WAPI_VERSION, use_session: bool = True, verify: bool | str | Path = True, timeout: float = 30.0, max_retries: int = 3, enforce_restrictions: bool = True, transport: AsyncBaseTransport | None = None)

Async HTTP client for Infoblox NIOS WAPI.

Wraps httpx.AsyncClient with WAPI-specific behaviour: session-cookie auth (or Basic-auth fallback), automatic retry with exponential backoff on 429/5xx responses, one-shot 401 re-login, and structured error mapping via :func:~ibx_nios_sdk._exceptions.exception_for_status.

Initialize the NIOS HTTP client.

Parameters:

Name Type Description Default
grid_url str

Base URL of the NIOS Grid Manager (e.g. "https://192.168.1.2"). Trailing slashes are stripped.

required
username str

WAPI username for authentication.

required
password str

WAPI password for authentication.

required
wapi_version str

WAPI version string appended to the base URL (e.g. "2.14" → /wapi/v2.14/).

DEFAULT_WAPI_VERSION
use_session bool

When True, authenticates via a WAPI session cookie (GET /grid/session). When False, sends HTTP Basic Auth on every request instead.

True
verify bool | str | Path

TLS certificate verification. Pass True (default) to verify using the system CA bundle, False to disable verification, or a path string to a custom CA bundle PEM file.

True
timeout float

Request timeout in seconds applied to all operations.

30.0
max_retries int

Maximum number of additional attempts after the first failure for retryable status codes (429, 502, 503, 504).

3
enforce_restrictions bool

When True (default), resources refuse read/create/update/delete on object types whose WAPI schema restricts them, raising UnsupportedOperationError without a request. Set False to send the request and let the grid decide.

True
transport AsyncBaseTransport | None

Custom httpx.AsyncBaseTransport for testing or proxying. Passed directly to httpx.AsyncClient.

None
Source code in src/ibx_nios_sdk/_http.py
def __init__(
    self,
    *,
    grid_url: str,
    username: str,
    password: str,
    wapi_version: str = DEFAULT_WAPI_VERSION,
    use_session: bool = True,
    verify: bool | str | Path = True,
    timeout: float = 30.0,
    max_retries: int = 3,
    enforce_restrictions: bool = True,
    transport: httpx.AsyncBaseTransport | None = None,
) -> None:
    """Initialize the NIOS HTTP client.

    Args:
        grid_url: Base URL of the NIOS Grid Manager (e.g.
            ``"https://192.168.1.2"``). Trailing slashes are stripped.
        username: WAPI username for authentication.
        password: WAPI password for authentication.
        wapi_version: WAPI version string appended to the base URL (e.g.
            ``"2.14"`` → ``/wapi/v2.14/``).
        use_session: When True, authenticates via a WAPI session cookie
            (``GET /grid/session``). When False, sends HTTP Basic Auth on
            every request instead.
        verify: TLS certificate verification. Pass ``True`` (default) to
            verify using the system CA bundle, ``False`` to disable
            verification, or a path string to a custom CA bundle PEM file.
        timeout: Request timeout in seconds applied to all operations.
        max_retries: Maximum number of additional attempts after the first
            failure for retryable status codes (429, 502, 503, 504).
        enforce_restrictions: When True (default), resources refuse
            read/create/update/delete on object types whose WAPI schema
            restricts them, raising ``UnsupportedOperationError`` without a
            request. Set False to send the request and let the grid decide.
        transport: Custom ``httpx.AsyncBaseTransport`` for testing or
            proxying. Passed directly to ``httpx.AsyncClient``.
    """
    self._grid_url = grid_url.rstrip("/")
    self._username = username
    self._password = password
    self._wapi_version = wapi_version
    self._use_session = use_session
    self._max_retries = max_retries
    #: Whether resources gate operations on the WAPI restriction table.
    self.enforce_restrictions = enforce_restrictions
    self._logged_in = False

    client_kwargs: dict[str, Any] = {
        "base_url": f"{self._grid_url}/wapi/v{wapi_version}",
        "timeout": timeout,
        "verify": verify,
        "headers": {
            "Content-Type": "application/json",
            "x-infoblox-client": "ibx-nios-sdk",
            "x-infoblox-sdk": f"python/{__version__}",
        },
    }
    if not use_session:
        client_kwargs["auth"] = httpx.BasicAuth(username, password)
    if transport is not None:
        client_kwargs["transport"] = transport

    self._client = httpx.AsyncClient(**client_kwargs)

grid_url property

grid_url: str

Base URL of the NIOS Grid Manager, without a trailing slash.

request async

request(method: str, path: str, *, params: dict[str, str] | None = None, json: dict[str, Any] | None = None) -> dict[str, Any] | None

Send a WAPI request with lazy login, retry, and one-shot 401 re-login.

If use_session is True and no session exists, authenticates first. Retries on 429/5xx status codes up to max_retries times. On a 401 after a successful login, re-authenticates once and retries.

Parameters:

Name Type Description Default
method str

HTTP method string (e.g. "GET", "POST").

required
path str

WAPI endpoint path relative to /wapi/v{version}/. A leading slash is added automatically if absent.

required
params dict[str, str] | None

Optional query-string parameters.

None
json dict[str, Any] | None

Optional JSON request body.

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body as a dict, or None for 204 responses.

Raises:

Type Description
NiosConnectionError

If the connection fails before a response is received.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def request(
    self,
    method: str,
    path: str,
    *,
    params: dict[str, str] | None = None,
    json: dict[str, Any] | None = None,
) -> dict[str, Any] | None:
    """Send a WAPI request with lazy login, retry, and one-shot 401 re-login.

    If ``use_session`` is True and no session exists, authenticates first.
    Retries on 429/5xx status codes up to ``max_retries`` times. On a 401
    after a successful login, re-authenticates once and retries.

    Args:
        method: HTTP method string (e.g. ``"GET"``, ``"POST"``).
        path: WAPI endpoint path relative to ``/wapi/v{version}/``. A
            leading slash is added automatically if absent.
        params: Optional query-string parameters.
        json: Optional JSON request body.

    Returns:
        The parsed JSON response body as a dict, or None for 204 responses.

    Raises:
        NiosConnectionError: If the connection fails before a response is
            received.
        NiosError: Or a subclass for non-success status codes.
    """
    if self._use_session and not self._logged_in:
        await self._login()

    url = path if path.startswith("/") else f"/{path}"
    response = await self._request_with_retry(method, url, params=params, json=json)

    if (
        self._use_session
        and response.status_code == 401
        and self._logged_in
        and not url.endswith("/grid/session")
    ):
        logger.debug("401 on %s - re-logging in", url)
        self._logged_in = False
        await self._login()
        response = await self._request_with_retry(method, url, params=params, json=json)

    return self._handle_response(response)

get async

get(path: str, *, params: dict[str, str] | None = None) -> dict[str, Any] | None

Send a GET request.

Parameters:

Name Type Description Default
path str

WAPI endpoint path relative to the base URL.

required
params dict[str, str] | None

Optional query-string parameters.

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body, or None for empty responses.

Raises:

Type Description
NiosConnectionError

If the connection fails before a response.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def get(
    self, path: str, *, params: dict[str, str] | None = None
) -> dict[str, Any] | None:
    """Send a GET request.

    Args:
        path: WAPI endpoint path relative to the base URL.
        params: Optional query-string parameters.

    Returns:
        The parsed JSON response body, or None for empty responses.

    Raises:
        NiosConnectionError: If the connection fails before a response.
        NiosError: Or a subclass for non-success status codes.
    """
    return await self.request("GET", path, params=params)

post async

post(path: str, *, params: dict[str, str] | None = None, json: dict[str, Any] | None = None) -> dict[str, Any] | None

Send a POST request.

Parameters:

Name Type Description Default
path str

WAPI endpoint path relative to the base URL.

required
params dict[str, str] | None

Optional query-string parameters (e.g. _function).

None
json dict[str, Any] | None

Optional JSON request body.

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body, or None for empty responses.

Raises:

Type Description
NiosConnectionError

If the connection fails before a response.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def post(
    self,
    path: str,
    *,
    params: dict[str, str] | None = None,
    json: dict[str, Any] | None = None,
) -> dict[str, Any] | None:
    """Send a POST request.

    Args:
        path: WAPI endpoint path relative to the base URL.
        params: Optional query-string parameters (e.g. ``_function``).
        json: Optional JSON request body.

    Returns:
        The parsed JSON response body, or None for empty responses.

    Raises:
        NiosConnectionError: If the connection fails before a response.
        NiosError: Or a subclass for non-success status codes.
    """
    return await self.request("POST", path, params=params, json=json)

put async

put(path: str, *, params: dict[str, str] | None = None, json: dict[str, Any] | None = None) -> dict[str, Any] | None

Send a PUT request.

Parameters:

Name Type Description Default
path str

WAPI endpoint path relative to the base URL.

required
params dict[str, str] | None

Optional query-string parameters (e.g. _return_fields).

None
json dict[str, Any] | None

Optional JSON request body with the full resource representation.

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body, or None for empty responses.

Raises:

Type Description
NiosConnectionError

If the connection fails before a response.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def put(
    self,
    path: str,
    *,
    params: dict[str, str] | None = None,
    json: dict[str, Any] | None = None,
) -> dict[str, Any] | None:
    """Send a PUT request.

    Args:
        path: WAPI endpoint path relative to the base URL.
        params: Optional query-string parameters (e.g. ``_return_fields``).
        json: Optional JSON request body with the full resource
            representation.

    Returns:
        The parsed JSON response body, or None for empty responses.

    Raises:
        NiosConnectionError: If the connection fails before a response.
        NiosError: Or a subclass for non-success status codes.
    """
    return await self.request("PUT", path, params=params, json=json)

delete async

delete(path: str, *, params: dict[str, str] | None = None) -> dict[str, Any] | None

Send a DELETE request.

WAPI DELETE responses return the deleted object's _ref as a plain string, which _safe_json wraps as {"_value": ref}.

Parameters:

Name Type Description Default
path str

WAPI endpoint path relative to the base URL.

required
params dict[str, str] | None

Optional query-string parameters.

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body (typically {"_value": ref}), or

dict[str, Any] | None

None for empty responses.

Raises:

Type Description
NiosConnectionError

If the connection fails before a response.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def delete(
    self, path: str, *, params: dict[str, str] | None = None
) -> dict[str, Any] | None:
    """Send a DELETE request.

    WAPI DELETE responses return the deleted object's ``_ref`` as a plain
    string, which ``_safe_json`` wraps as ``{"_value": ref}``.

    Args:
        path: WAPI endpoint path relative to the base URL.
        params: Optional query-string parameters.

    Returns:
        The parsed JSON response body (typically ``{"_value": ref}``), or
        None for empty responses.

    Raises:
        NiosConnectionError: If the connection fails before a response.
        NiosError: Or a subclass for non-success status codes.
    """
    return await self.request("DELETE", path, params=params)

get_with_return_fields async

get_with_return_fields(path: str, *, model_fields: list[str], return_fields: list[str] | None = None, return_fields_plus: list[str] | None = None, extra_params: dict[str, str] | None = None) -> dict[str, Any] | None

Send a GET request with _return_fields / _return_fields+ merged in.

Delegates field selection logic to :func:~ibx_nios_sdk._query.build_return_fields_params.

Parameters:

Name Type Description Default
path str

WAPI endpoint path relative to the base URL.

required
model_fields list[str]

Fields defined on the SDK model - used as the default set when neither return_fields nor return_fields_plus is provided.

required
return_fields list[str] | None

Exact list of fields to request; mutually exclusive with return_fields_plus.

None
return_fields_plus list[str] | None

Additional fields to append to model_fields; mutually exclusive with return_fields.

None
extra_params dict[str, str] | None

Additional query-string parameters merged after field params (e.g. {"_return_as_object": "1"}).

None

Returns:

Type Description
dict[str, Any] | None

The parsed JSON response body, or None for empty responses.

Raises:

Type Description
ValueError

If both return_fields and return_fields_plus are provided.

NiosConnectionError

If the connection fails before a response.

NiosError

Or a subclass for non-success status codes.

Source code in src/ibx_nios_sdk/_http.py
async def get_with_return_fields(
    self,
    path: str,
    *,
    model_fields: list[str],
    return_fields: list[str] | None = None,
    return_fields_plus: list[str] | None = None,
    extra_params: dict[str, str] | None = None,
) -> dict[str, Any] | None:
    """Send a GET request with ``_return_fields`` / ``_return_fields+`` merged in.

    Delegates field selection logic to
    :func:`~ibx_nios_sdk._query.build_return_fields_params`.

    Args:
        path: WAPI endpoint path relative to the base URL.
        model_fields: Fields defined on the SDK model - used as the default
            set when neither ``return_fields`` nor ``return_fields_plus`` is
            provided.
        return_fields: Exact list of fields to request; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Additional fields to append to ``model_fields``;
            mutually exclusive with ``return_fields``.
        extra_params: Additional query-string parameters merged after field
            params (e.g. ``{"_return_as_object": "1"}``).

    Returns:
        The parsed JSON response body, or None for empty responses.

    Raises:
        ValueError: If both ``return_fields`` and ``return_fields_plus``
            are provided.
        NiosConnectionError: If the connection fails before a response.
        NiosError: Or a subclass for non-success status codes.
    """
    from ibx_nios_sdk._query import build_return_fields_params

    params = build_return_fields_params(
        model_fields=model_fields,
        return_fields=return_fields,
        return_fields_plus=return_fields_plus,
    )
    if extra_params:
        params.update(extra_params)
    return await self.request("GET", path, params=params or None)

aclose async

aclose() -> None

Close the client, logging out of any active WAPI session first.

If a session cookie is active, calls _logout to invalidate it server-side before closing the underlying httpx.AsyncClient.

Example

Explicit close::

client = HttpClient(grid_url=..., username=..., password=...)
try:
    ...
finally:
    await client.aclose()
Source code in src/ibx_nios_sdk/_http.py
async def aclose(self) -> None:
    """Close the client, logging out of any active WAPI session first.

    If a session cookie is active, calls ``_logout`` to invalidate it
    server-side before closing the underlying ``httpx.AsyncClient``.

    Example:
        Explicit close::

            client = HttpClient(grid_url=..., username=..., password=...)
            try:
                ...
            finally:
                await client.aclose()
    """
    if self._use_session and self._logged_in:
        await self._logout()
    await self._client.aclose()

Resource Base Class

Every resource on every domain inherits from WapiResource. The standard list, list_page, get, create, update, delete, and call_function methods are all defined here.

WapiResource

WapiResource(client: HttpClient)

Bases: Generic[TModel]

Base class for a single WAPI object type.

Provides list/get/create/update/delete/call_function operations against a NIOS WAPI endpoint. Subclasses must set three class variables:

  • _wapi_type: WAPI object type string, e.g. "record:a".
  • _model: Pydantic model class used to parse response rows.
  • _default_return_fields: Fields requested by default via _return_fields+.

Optionally set _readonly_fields to a set of field names that must be stripped from PUT payloads on update. Set _create_only_fields for fields that are writable on POST but readonly on PUT (WAPI supports flag rw / rws - no u). These are kept on create() and stripped on update().

Read/create/update/delete are gated on the object type's WAPI restrictions (see :mod:ibx_nios_sdk._restrictions): an operation NIOS does not support raises :class:~ibx_nios_sdk._exceptions.UnsupportedOperationError without issuing a request. _restricted_ops is derived per subclass from _wapi_type; a subclass may set it explicitly to override the table. call_function is never gated - function-only types such as dtc restrict every other operation.

Initialize the resource with an HTTP client.

Parameters:

Name Type Description Default
client HttpClient

The :class:~ibx_nios_sdk._http.HttpClient instance used to make WAPI requests.

required
Source code in src/ibx_nios_sdk/_resource.py
def __init__(self, client: HttpClient) -> None:
    """Initialize the resource with an HTTP client.

    Args:
        client: The :class:`~ibx_nios_sdk._http.HttpClient` instance used
            to make WAPI requests.
    """
    self._client = client

list_page async

list_page(*, page_id: str | None = None, max_results: int = 1000, return_fields: list[str] | None = None, return_fields_plus: list[str] | None = None, **filters: Any) -> tuple[list[TModel], str | None]

Fetch a single page of WAPI results.

Parameters:

Name Type Description Default
page_id str | None

Continuation token from a previous response. Pass None to start from the first page.

None
max_results int

Maximum number of records per page (WAPI _max_results).

1000
return_fields list[str] | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus list[str] | None

Extra fields to add on top of _default_return_fields; mutually exclusive with return_fields.

None
**filters Any

Field-level filters using kwarg conventions (e.g. name="foo", comment__like="bar", extattr_Site="NYC").

{}

Returns:

Type Description
list[TModel]

A (rows, next_page_id) tuple. rows is a list of validated

str | None

model instances; next_page_id is the token for the next page, or

tuple[list[TModel], str | None]

None if this was the last page.

Raises:

Type Description
ValueError

If both return_fields and return_fields_plus are provided, or if an unknown filter operator suffix is used.

UnsupportedOperationError

If WAPI does not support reads of this object type.

NiosError

Or a subclass for WAPI errors.

Example

Fetch the first two pages manually::

rows, next_id = await resource.list_page(max_results=100)
if next_id:
    more, _ = await resource.list_page(page_id=next_id)
Source code in src/ibx_nios_sdk/_resource.py
async def list_page(
    self,
    *,
    page_id: str | None = None,
    max_results: int = 1000,
    return_fields: list[str] | None = None,
    return_fields_plus: list[str] | None = None,
    **filters: Any,
) -> tuple[list[TModel], str | None]:
    """Fetch a single page of WAPI results.

    Args:
        page_id: Continuation token from a previous response. Pass ``None``
            to start from the first page.
        max_results: Maximum number of records per page (WAPI
            ``_max_results``).
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields to add on top of
            ``_default_return_fields``; mutually exclusive with
            ``return_fields``.
        **filters: Field-level filters using kwarg conventions (e.g.
            ``name="foo"``, ``comment__like="bar"``,
            ``extattr_Site="NYC"``).

    Returns:
        A ``(rows, next_page_id)`` tuple. ``rows`` is a list of validated
        model instances; ``next_page_id`` is the token for the next page, or
        ``None`` if this was the last page.

    Raises:
        ValueError: If both ``return_fields`` and ``return_fields_plus`` are
            provided, or if an unknown filter operator suffix is used.
        UnsupportedOperationError: If WAPI does not support reads of this
            object type.
        NiosError: Or a subclass for WAPI errors.

    Example:
        Fetch the first two pages manually::

            rows, next_id = await resource.list_page(max_results=100)
            if next_id:
                more, _ = await resource.list_page(page_id=next_id)
    """
    self._require_op("read")
    params: dict[str, str] = {
        "_paging": "1",
        "_return_as_object": "1",
        "_max_results": str(max_results),
    }
    params.update(build_filter_params(filters))
    params.update(
        build_return_fields_params(
            model_fields=self._default_return_fields,
            return_fields=return_fields,
            return_fields_plus=return_fields_plus,
        )
    )
    if page_id:
        params["_page_id"] = page_id

    data = await self._client.get(self._path(), params=params)
    body = data or {}
    rows = body.get("result", []) or []
    next_id = body.get("next_page_id") or None
    parsed = [self._model.model_validate(row) for row in rows]
    return parsed, next_id  # type: ignore[return-value]

list

list(*, max_results: int = 1000, return_fields: list[str] | None = None, return_fields_plus: list[str] | None = None, **filters: Any) -> AsyncPageIterator[TModel]

Return an auto-paginated async iterator over all matching objects.

Fetches pages on demand as the caller iterates. Use await .all() on the returned iterator to collect every record into a list at once.

Parameters:

Name Type Description Default
max_results int

Maximum records per page (WAPI _max_results).

1000
return_fields list[str] | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus list[str] | None

Extra fields on top of _default_return_fields; mutually exclusive with return_fields.

None
**filters Any

Field-level filters (see :func:build_filter_params).

{}

Returns:

Name Type Description
An AsyncPageIterator[TModel]

class:~ibx_nios_sdk._paging.AsyncPageIterator that yields

AsyncPageIterator[TModel]

validated model instances across all pages.

Raises:

Type Description
UnsupportedOperationError

If WAPI does not support reads of this object type. Raised by this call, not by the first iteration.

Example

Iterate lazily::

async for record in resource.list(name="example"):
    print(record.ref)

Collect all at once::

records = await resource.list(comment__like="prod").all()
Source code in src/ibx_nios_sdk/_resource.py
def list(
    self,
    *,
    max_results: int = 1000,
    return_fields: list[str] | None = None,
    return_fields_plus: list[str] | None = None,
    **filters: Any,
) -> AsyncPageIterator[TModel]:
    """Return an auto-paginated async iterator over all matching objects.

    Fetches pages on demand as the caller iterates. Use ``await .all()``
    on the returned iterator to collect every record into a list at once.

    Args:
        max_results: Maximum records per page (WAPI ``_max_results``).
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields on top of ``_default_return_fields``;
            mutually exclusive with ``return_fields``.
        **filters: Field-level filters (see :func:`build_filter_params`).

    Returns:
        An :class:`~ibx_nios_sdk._paging.AsyncPageIterator` that yields
        validated model instances across all pages.

    Raises:
        UnsupportedOperationError: If WAPI does not support reads of this
            object type. Raised by this call, not by the first iteration.

    Example:
        Iterate lazily::

            async for record in resource.list(name="example"):
                print(record.ref)

        Collect all at once::

            records = await resource.list(comment__like="prod").all()
    """

    self._require_op("read")

    async def _fetch(page_id: str | None) -> tuple[list[dict[str, Any]], str | None]:
        params: dict[str, str] = {
            "_paging": "1",
            "_return_as_object": "1",
            "_max_results": str(max_results),
        }
        params.update(build_filter_params(filters))
        params.update(
            build_return_fields_params(
                model_fields=self._default_return_fields,
                return_fields=return_fields,
                return_fields_plus=return_fields_plus,
            )
        )
        if page_id:
            params["_page_id"] = page_id
        data = await self._client.get(self._path(), params=params)
        body = data or {}
        return body.get("result", []) or [], body.get("next_page_id") or None

    return AsyncPageIterator(fetch=_fetch, model=self._model)  # type: ignore[arg-type]

find_one async

find_one(*, return_fields: _StrList | None = None, return_fields_plus: _StrList | None = None, **filters: Any) -> TModel | None

Return the first matching object, or None if no match is found.

Requests at most one result (max_results=1) to minimise data transfer.

Parameters:

Name Type Description Default
return_fields _StrList | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus _StrList | None

Extra fields on top of _default_return_fields; mutually exclusive with return_fields.

None
**filters Any

Field-level filters (see :func:build_filter_params).

{}

Returns:

Type Description
TModel | None

The first matching validated model instance, or None if the

TModel | None

WAPI returns an empty result set.

Raises:

Type Description
NiosError

Or a subclass for WAPI errors.

Example

Look up a record by name::

record = await resource.find_one(name="foo.example.com")
if record is None:
    print("not found")
Source code in src/ibx_nios_sdk/_resource.py
async def find_one(
    self,
    *,
    return_fields: _StrList | None = None,
    return_fields_plus: _StrList | None = None,
    **filters: Any,
) -> TModel | None:
    """Return the first matching object, or None if no match is found.

    Requests at most one result (``max_results=1``) to minimise data
    transfer.

    Args:
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields on top of ``_default_return_fields``;
            mutually exclusive with ``return_fields``.
        **filters: Field-level filters (see :func:`build_filter_params`).

    Returns:
        The first matching validated model instance, or ``None`` if the
        WAPI returns an empty result set.

    Raises:
        NiosError: Or a subclass for WAPI errors.

    Example:
        Look up a record by name::

            record = await resource.find_one(name="foo.example.com")
            if record is None:
                print("not found")
    """
    rows, _ = await self.list_page(
        max_results=1,
        return_fields=return_fields,
        return_fields_plus=return_fields_plus,
        **filters,
    )
    return rows[0] if rows else None

get async

get(ref: str, *, return_fields: _StrList | None = None, return_fields_plus: _StrList | None = None) -> TModel

Fetch a single WAPI object by its _ref.

Parameters:

Name Type Description Default
ref str

The WAPI object reference string (e.g. "record:a/ZG5z...:1.2.3.4/default").

required
return_fields _StrList | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus _StrList | None

Extra fields on top of _default_return_fields; mutually exclusive with return_fields.

None

Returns:

Type Description
TModel

A validated model instance for the requested object.

Raises:

Type Description
ValueError

If ref does not belong to this resource type.

NotFoundError

If the object no longer exists in NIOS.

UnsupportedOperationError

If WAPI does not support reads of this object type.

NiosError

Or a subclass for other WAPI errors.

Example

Fetch a record by ref::

record = await resource.get("record:a/ZG5z...:1.2.3.4/default")
print(record.ipv4addr)
Source code in src/ibx_nios_sdk/_resource.py
async def get(
    self,
    ref: str,
    *,
    return_fields: _StrList | None = None,
    return_fields_plus: _StrList | None = None,
) -> TModel:
    """Fetch a single WAPI object by its ``_ref``.

    Args:
        ref: The WAPI object reference string (e.g.
            ``"record:a/ZG5z...:1.2.3.4/default"``).
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields on top of ``_default_return_fields``;
            mutually exclusive with ``return_fields``.

    Returns:
        A validated model instance for the requested object.

    Raises:
        ValueError: If ``ref`` does not belong to this resource type.
        NotFoundError: If the object no longer exists in NIOS.
        UnsupportedOperationError: If WAPI does not support reads of this
            object type.
        NiosError: Or a subclass for other WAPI errors.

    Example:
        Fetch a record by ref::

            record = await resource.get("record:a/ZG5z...:1.2.3.4/default")
            print(record.ipv4addr)
    """
    self._require_op("read")
    self._validate_ref(ref)
    params = build_return_fields_params(
        model_fields=self._default_return_fields,
        return_fields=return_fields,
        return_fields_plus=return_fields_plus,
    )
    data = await self._client.get(f"/{ref}", params=params or None)
    return self._model.model_validate(data or {})  # type: ignore[return-value]

create async

create(obj: BaseModel | dict[str, Any], *, return_fields: _StrList | None = None, return_fields_plus: _StrList | None = None) -> TModel

Create a new WAPI object and return the populated model.

Parameters:

Name Type Description Default
obj BaseModel | dict[str, Any]

A Pydantic model instance or plain dict containing the fields for the new object. None values and the ref field are excluded from the POST body automatically.

required
return_fields _StrList | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus _StrList | None

Extra fields on top of _default_return_fields; mutually exclusive with return_fields.

None

Returns:

Type Description
TModel

A validated model instance for the newly created object, populated

TModel

with the fields requested via _return_as_object=1.

Raises:

Type Description
UnsupportedOperationError

If WAPI does not support creating this object type.

ConflictError

If the object already exists.

BadRequestError

If the request body contains invalid fields.

NiosError

Or a subclass for other WAPI errors.

Example

Create an A record::

record = await resource.create(
    {"name": "host.example.com", "ipv4addr": "1.2.3.4"}
)
print(record.ref)
Source code in src/ibx_nios_sdk/_resource.py
async def create(
    self,
    obj: BaseModel | dict[str, Any],
    *,
    return_fields: _StrList | None = None,
    return_fields_plus: _StrList | None = None,
) -> TModel:
    """Create a new WAPI object and return the populated model.

    Args:
        obj: A Pydantic model instance or plain dict containing the fields
            for the new object. ``None`` values and the ``ref`` field are
            excluded from the POST body automatically.
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields on top of ``_default_return_fields``;
            mutually exclusive with ``return_fields``.

    Returns:
        A validated model instance for the newly created object, populated
        with the fields requested via ``_return_as_object=1``.

    Raises:
        UnsupportedOperationError: If WAPI does not support creating this
            object type.
        ConflictError: If the object already exists.
        BadRequestError: If the request body contains invalid fields.
        NiosError: Or a subclass for other WAPI errors.

    Example:
        Create an A record::

            record = await resource.create(
                {"name": "host.example.com", "ipv4addr": "1.2.3.4"}
            )
            print(record.ref)
    """
    self._require_op("create")
    payload = self._dump(obj, exclude_readonly=False)
    params: dict[str, str] = {"_return_as_object": "1"}
    params.update(
        build_return_fields_params(
            model_fields=self._default_return_fields,
            return_fields=return_fields,
            return_fields_plus=return_fields_plus,
        )
    )
    data = await self._client.post(self._path(), params=params, json=payload)
    if isinstance(data, dict) and list(data) == ["result"]:
        data = data["result"]
    return self._model.model_validate(data or {})  # type: ignore[return-value]

update async

update(ref: str, obj: BaseModel | dict[str, Any], *, return_fields: _StrList | None = None, return_fields_plus: _StrList | None = None) -> TModel

Update an existing WAPI object and return the refreshed model.

Sends a PUT request with _return_as_object=1. Read-only fields listed in _readonly_fields are stripped from the payload automatically.

Parameters:

Name Type Description Default
ref str

WAPI object reference string identifying the object to update.

required
obj BaseModel | dict[str, Any]

A Pydantic model instance or plain dict of fields to update. None values, ref, and read-only fields are excluded.

required
return_fields _StrList | None

Exact list of fields to return; mutually exclusive with return_fields_plus.

None
return_fields_plus _StrList | None

Extra fields on top of _default_return_fields; mutually exclusive with return_fields.

None

Returns:

Type Description
TModel

A validated model instance reflecting the object's state after the

TModel

update.

Raises:

Type Description
ValueError

If ref does not belong to this resource type.

NotFoundError

If the object no longer exists in NIOS.

UnsupportedOperationError

If WAPI does not support updating this object type.

NiosError

Or a subclass for other WAPI errors.

Example

Change the comment on a host record::

updated = await resource.update(
    "record:host/ZG5z...",
    {"comment": "updated by SDK"},
)
Source code in src/ibx_nios_sdk/_resource.py
async def update(
    self,
    ref: str,
    obj: BaseModel | dict[str, Any],
    *,
    return_fields: _StrList | None = None,
    return_fields_plus: _StrList | None = None,
) -> TModel:
    """Update an existing WAPI object and return the refreshed model.

    Sends a PUT request with ``_return_as_object=1``. Read-only fields
    listed in ``_readonly_fields`` are stripped from the payload
    automatically.

    Args:
        ref: WAPI object reference string identifying the object to update.
        obj: A Pydantic model instance or plain dict of fields to update.
            ``None`` values, ``ref``, and read-only fields are excluded.
        return_fields: Exact list of fields to return; mutually exclusive
            with ``return_fields_plus``.
        return_fields_plus: Extra fields on top of ``_default_return_fields``;
            mutually exclusive with ``return_fields``.

    Returns:
        A validated model instance reflecting the object's state after the
        update.

    Raises:
        ValueError: If ``ref`` does not belong to this resource type.
        NotFoundError: If the object no longer exists in NIOS.
        UnsupportedOperationError: If WAPI does not support updating this
            object type.
        NiosError: Or a subclass for other WAPI errors.

    Example:
        Change the comment on a host record::

            updated = await resource.update(
                "record:host/ZG5z...",
                {"comment": "updated by SDK"},
            )
    """
    self._require_op("update")
    self._validate_ref(ref)
    payload = self._dump(obj, exclude_readonly=True)
    params: dict[str, str] = {"_return_as_object": "1"}
    params.update(
        build_return_fields_params(
            model_fields=self._default_return_fields,
            return_fields=return_fields,
            return_fields_plus=return_fields_plus,
        )
    )
    data = await self._client.put(f"/{ref}", params=params, json=payload)
    if isinstance(data, dict) and list(data) == ["result"]:
        data = data["result"]
    return self._model.model_validate(data or {})  # type: ignore[return-value]

delete async

delete(ref: str) -> str

Delete a WAPI object by its _ref.

Parameters:

Name Type Description Default
ref str

WAPI object reference string identifying the object to delete.

required

Returns:

Type Description
str

The _ref of the deleted object as returned by NIOS, which may

str

differ from the input ref in some WAPI versions. Falls back to

str

the input ref if NIOS does not return a value.

Raises:

Type Description
ValueError

If ref does not belong to this resource type.

NotFoundError

If the object does not exist in NIOS.

UnsupportedOperationError

If WAPI does not support deleting this object type.

NiosError

Or a subclass for other WAPI errors.

Example

Delete an A record::

deleted_ref = await resource.delete("record:a/ZG5z...:1.2.3.4/default")
Source code in src/ibx_nios_sdk/_resource.py
async def delete(self, ref: str) -> str:
    """Delete a WAPI object by its ``_ref``.

    Args:
        ref: WAPI object reference string identifying the object to delete.

    Returns:
        The ``_ref`` of the deleted object as returned by NIOS, which may
        differ from the input ``ref`` in some WAPI versions. Falls back to
        the input ``ref`` if NIOS does not return a value.

    Raises:
        ValueError: If ``ref`` does not belong to this resource type.
        NotFoundError: If the object does not exist in NIOS.
        UnsupportedOperationError: If WAPI does not support deleting this
            object type.
        NiosError: Or a subclass for other WAPI errors.

    Example:
        Delete an A record::

            deleted_ref = await resource.delete("record:a/ZG5z...:1.2.3.4/default")
    """
    self._require_op("delete")
    self._validate_ref(ref)
    data = await self._client.delete(f"/{ref}")
    if isinstance(data, dict) and "_value" in data:
        return str(data["_value"])
    return ref

call_function async

call_function(ref: str | None, function: str, **kwargs: Any) -> dict[str, Any]

Call a WAPI function on a specific object or on the object type.

Uses POST /<ref>?_function=<name> when ref is provided, or POST /<wapi_type>?_function=<name> for type-level functions. None kwarg values are excluded from the request body.

Parameters:

Name Type Description Default
ref str | None

WAPI object reference, or None to call a type-level function.

required
function str

WAPI function name (e.g. "nextavailableip").

required
**kwargs Any

Function arguments passed as the POST body.

{}

Returns:

Type Description
dict[str, Any]

The parsed JSON response body from the function call as a dict

dict[str, Any]

(empty dict if the WAPI returns no body).

Raises:

Type Description
ValueError

If ref is provided but does not belong to this resource type.

NiosError

Or a subclass for WAPI errors.

Example

Find the next available IP in a network::

result = await resource.call_function(
    "network/ZG5z...",
    "nextavailableip",
    num=1,
)
print(result["ips"])
Source code in src/ibx_nios_sdk/_resource.py
async def call_function(
    self,
    ref: str | None,
    function: str,
    **kwargs: Any,
) -> dict[str, Any]:
    """Call a WAPI function on a specific object or on the object type.

    Uses ``POST /<ref>?_function=<name>`` when ``ref`` is provided, or
    ``POST /<wapi_type>?_function=<name>`` for type-level functions.
    ``None`` kwarg values are excluded from the request body.

    Args:
        ref: WAPI object reference, or ``None`` to call a type-level
            function.
        function: WAPI function name (e.g. ``"nextavailableip"``).
        **kwargs: Function arguments passed as the POST body.

    Returns:
        The parsed JSON response body from the function call as a dict
        (empty dict if the WAPI returns no body).

    Raises:
        ValueError: If ``ref`` is provided but does not belong to this
            resource type.
        NiosError: Or a subclass for WAPI errors.

    Example:
        Find the next available IP in a network::

            result = await resource.call_function(
                "network/ZG5z...",
                "nextavailableip",
                num=1,
            )
            print(result["ips"])
    """
    if ref is not None:
        self._validate_ref(ref)
        path = f"/{ref}"
    else:
        path = self._path()
    params = {"_function": function}
    body = {k: v for k, v in kwargs.items() if v is not None}
    data = await self._client.post(path, params=params, json=body or None)
    return data or {}

set_extattrs async

set_extattrs(ref: str, **kwargs: Any) -> TModel

Set extensible attributes on a WAPI object.

Wraps kwarg key/value pairs into the WAPI extattrs nested shape ({"<name>": {"value": <val>}}) and delegates to :meth:update.

Parameters:

Name Type Description Default
ref str

WAPI object reference string identifying the target object.

required
**kwargs Any

Extensible-attribute name/value pairs to set (e.g. Site="NYC", Owner="ops-team").

{}

Returns:

Type Description
TModel

A validated model instance reflecting the object's state after the

TModel

update.

Raises:

Type Description
ValueError

If ref does not belong to this resource type.

NiosError

Or a subclass for WAPI errors.

Example

Tag a host record with a site attribute::

updated = await resource.set_extattrs(
    "record:host/ZG5z...",
    Site="NYC",
    Owner="ops-team",
)
Source code in src/ibx_nios_sdk/_resource.py
async def set_extattrs(self, ref: str, **kwargs: Any) -> TModel:
    """Set extensible attributes on a WAPI object.

    Wraps kwarg key/value pairs into the WAPI ``extattrs`` nested shape
    (``{"<name>": {"value": <val>}}``) and delegates to
    :meth:`update`.

    Args:
        ref: WAPI object reference string identifying the target object.
        **kwargs: Extensible-attribute name/value pairs to set (e.g.
            ``Site="NYC"``, ``Owner="ops-team"``).

    Returns:
        A validated model instance reflecting the object's state after the
        update.

    Raises:
        ValueError: If ``ref`` does not belong to this resource type.
        NiosError: Or a subclass for WAPI errors.

    Example:
        Tag a host record with a site attribute::

            updated = await resource.set_extattrs(
                "record:host/ZG5z...",
                Site="NYC",
                Owner="ops-team",
            )
    """
    extattrs = {name: {"value": value} for name, value in kwargs.items()}
    return await self.update(ref, {"extattrs": extattrs})

Query Builder & Pagination

Translate Python kwargs into WAPI query parameters.

WAPI operator conventions

field=value -> exact match field~=value -> regex/substring match (kwarg: field__like) field<=value -> less than or equal (kwarg: field__lte) field>=value -> greater than or equal (kwarg: field__gte) field!=value -> not equal (kwarg: field__not) *EA_name=value -> extensible-attr filter (kwarg: extattr_EA_name)

build_filter_params

build_filter_params(filters: dict[str, Any]) -> dict[str, str]

Translate kwarg-style filters into WAPI query-param key/value pairs.

Keys with a __<op> suffix map to the corresponding WAPI operator (like → ~, gte → >, lte → <, not → !). Keys prefixed with extattr_ are mapped to *<EA_name> for extensible-attribute filtering. None values are silently dropped.

Parameters:

Name Type Description Default
filters dict[str, Any]

Dict of filter kwargs, typically the **filters captured by a resource method (e.g. {"name": "foo", "age__gte": 5}).

required

Returns:

Type Description
dict[str, str]

A dict of WAPI query-parameter name/value pairs ready to pass as

dict[str, str]

params to an HTTP request.

Raises:

Type Description
ValueError

If an unknown __<op> suffix is encountered.

Example

Build filters for a WAPI list request::

params = build_filter_params({"name": "foo", "comment__like": "bar"})
# {"name": "foo", "comment~": "bar"}
Source code in src/ibx_nios_sdk/_query.py
def build_filter_params(filters: dict[str, Any]) -> dict[str, str]:
    """Translate kwarg-style filters into WAPI query-param key/value pairs.

    Keys with a ``__<op>`` suffix map to the corresponding WAPI operator
    (``like`` → ``~``, ``gte`` → ``>``, ``lte`` → ``<``, ``not`` → ``!``).
    Keys prefixed with ``extattr_`` are mapped to ``*<EA_name>`` for
    extensible-attribute filtering. ``None`` values are silently dropped.

    Args:
        filters: Dict of filter kwargs, typically the ``**filters`` captured
            by a resource method (e.g. ``{"name": "foo", "age__gte": 5}``).

    Returns:
        A dict of WAPI query-parameter name/value pairs ready to pass as
        ``params`` to an HTTP request.

    Raises:
        ValueError: If an unknown ``__<op>`` suffix is encountered.

    Example:
        Build filters for a WAPI list request::

            params = build_filter_params({"name": "foo", "comment__like": "bar"})
            # {"name": "foo", "comment~": "bar"}
    """
    out: dict[str, str] = {}
    for key, value in filters.items():
        if value is None:
            continue

        if key.startswith("extattr_"):
            ea_name = key[len("extattr_") :]
            out[f"*{ea_name}"] = _stringify(value)
            continue

        if "__" in key:
            field, _, suffix = key.rpartition("__")
            op = _OPERATOR_SUFFIX_MAP.get(suffix)
            if op is None:
                raise ValueError(f"unknown filter operator: {suffix!r} in kwarg {key!r}")
            out[f"{field}{op}"] = _stringify(value)
            continue

        out[key] = _stringify(value)

    return out

build_return_fields_params

build_return_fields_params(*, model_fields: list[str], return_fields: list[str] | None, return_fields_plus: list[str] | None) -> dict[str, str]

Build the _return_fields / _return_fields+ query params.

Selection rules:

  • Both None → _return_fields+=<model_fields> so the full model can be populated from the response.
  • return_fields=[..] → _return_fields=<exact list> (caller controls exactly which fields are returned).
  • return_fields_plus=[..] → _return_fields+=<model_fields + extras> (model fields plus caller-specified extras).
  • Passing both → ValueError.

Parameters:

Name Type Description Default
model_fields list[str]

Fields declared on the SDK model used as the default set.

required
return_fields list[str] | None

Explicit list of fields; mutually exclusive with return_fields_plus.

required
return_fields_plus list[str] | None

Extra fields to append to model_fields; mutually exclusive with return_fields.

required

Returns:

Type Description
dict[str, str]

A dict containing either _return_fields or _return_fields+, or

dict[str, str]

an empty dict when model_fields is empty and both optional args are

dict[str, str]

None.

Raises:

Type Description
ValueError

If both return_fields and return_fields_plus are non-None.

Example

Request only specific fields::

params = build_return_fields_params(
    model_fields=["name", "comment"],
    return_fields=["name"],
    return_fields_plus=None,
)
# {"_return_fields": "name"}
Source code in src/ibx_nios_sdk/_query.py
def build_return_fields_params(
    *,
    model_fields: list[str],
    return_fields: list[str] | None,
    return_fields_plus: list[str] | None,
) -> dict[str, str]:
    """Build the ``_return_fields`` / ``_return_fields+`` query params.

    Selection rules:

    - Both ``None`` → ``_return_fields+=<model_fields>`` so the full model
      can be populated from the response.
    - ``return_fields=[..]`` → ``_return_fields=<exact list>`` (caller
      controls exactly which fields are returned).
    - ``return_fields_plus=[..]`` → ``_return_fields+=<model_fields + extras>``
      (model fields plus caller-specified extras).
    - Passing both → ``ValueError``.

    Args:
        model_fields: Fields declared on the SDK model used as the default set.
        return_fields: Explicit list of fields; mutually exclusive with
            ``return_fields_plus``.
        return_fields_plus: Extra fields to append to ``model_fields``; mutually
            exclusive with ``return_fields``.

    Returns:
        A dict containing either ``_return_fields`` or ``_return_fields+``, or
        an empty dict when ``model_fields`` is empty and both optional args are
        ``None``.

    Raises:
        ValueError: If both ``return_fields`` and ``return_fields_plus`` are
            non-None.

    Example:
        Request only specific fields::

            params = build_return_fields_params(
                model_fields=["name", "comment"],
                return_fields=["name"],
                return_fields_plus=None,
            )
            # {"_return_fields": "name"}
    """
    if return_fields is not None and return_fields_plus is not None:
        raise ValueError("cannot pass both return_fields and return_fields_plus")

    if return_fields is not None:
        return {"_return_fields": ",".join(return_fields)}

    combined = list(model_fields)
    if return_fields_plus:
        combined.extend(return_fields_plus)
    if not combined:
        return {}
    return {"_return_fields+": ",".join(combined)}

AsyncPageIterator - transparent multi-page async iteration over WAPI list responses.

AsyncPageIterator

AsyncPageIterator(*, fetch: Fetcher, model: type[TModel])

Bases: Generic[TModel]

Async iterator yielding parsed model instances from a paged WAPI response.

Callers pass a fetch coroutine that takes a page_id (or None for the first page) and returns (rows, next_page_id). Iteration terminates when next_page_id is None or "".

Initialize the page iterator.

Parameters:

Name Type Description Default
fetch Fetcher

Async callable that accepts a page_id (or None for the first page) and returns a (rows, next_page_id) tuple. next_page_id should be None or "" to signal the last page.

required
model type[TModel]

Pydantic model class used to validate each row dict via model.model_validate(row).

required
Source code in src/ibx_nios_sdk/_paging.py
def __init__(self, *, fetch: Fetcher, model: type[TModel]) -> None:
    """Initialize the page iterator.

    Args:
        fetch: Async callable that accepts a ``page_id`` (or ``None`` for
            the first page) and returns a ``(rows, next_page_id)`` tuple.
            ``next_page_id`` should be ``None`` or ``""`` to signal the
            last page.
        model: Pydantic model class used to validate each row dict via
            ``model.model_validate(row)``.
    """
    self._fetch = fetch
    self._model = model

all async

all() -> list[TModel]

Collect all pages into a single list.

Exhausts the iterator, fetching every page, and returns the combined results. Prefer async iteration (async for) for large result sets to avoid loading everything into memory at once.

Returns:

Type Description
list[TModel]

A list of validated model instances from all pages.

Example

Fetch all records at once::

iterator = resource.list(name="example")
records = await iterator.all()
Source code in src/ibx_nios_sdk/_paging.py
async def all(self) -> list[TModel]:
    """Collect all pages into a single list.

    Exhausts the iterator, fetching every page, and returns the combined
    results. Prefer async iteration (``async for``) for large result sets
    to avoid loading everything into memory at once.

    Returns:
        A list of validated model instances from all pages.

    Example:
        Fetch all records at once::

            iterator = resource.list(name="example")
            records = await iterator.all()
    """
    return [item async for item in self]

Object-Type Restrictions

The generated table of operations each WAPI object type refuses, consulted by WapiResource before every read, create, update, and delete. Regenerate it with tools/refresh_object_restrictions.py after refreshing the schema snapshot.

Per-object-type restrictions on read/create/update/delete.

Generated by tools/refresh_object_restrictions.py - do not edit by hand.

NIOS refuses operations an object type does not support, answering AdmConProtoError: Operation <op> not allowed for <type>: a read-only aggregate such as allrecords rejects every mutation, a singleton such as grid rejects delete, and a function-only type such as dtc rejects even read while still accepting call_function. :class:~ibx_nios_sdk._resource.WapiResource consults this table so those calls raise :class:~ibx_nios_sdk._exceptions.UnsupportedOperationError locally instead of making a request the grid will refuse.

Source: grid ?_schema restrictions via tests/fixtures/wapi_schema_v2.14.json

restricted_ops

restricted_ops(wapi_type: str) -> frozenset[str]

Return the operations wapi_type does not support.

Parameters:

Name Type Description Default
wapi_type str

WAPI object type string, e.g. "allrecords".

required

Returns:

Type Description
frozenset[str]

A frozenset of operation names drawn from :data:OPERATIONS; empty when

frozenset[str]

the type supports every operation, or is unknown to the table.

Source code in src/ibx_nios_sdk/_restrictions.py
def restricted_ops(wapi_type: str) -> frozenset[str]:
    """Return the operations ``wapi_type`` does not support.

    Args:
        wapi_type: WAPI object type string, e.g. ``"allrecords"``.

    Returns:
        A frozenset of operation names drawn from :data:`OPERATIONS`; empty when
        the type supports every operation, or is unknown to the table.
    """
    return RESTRICTED_OPS.get(wapi_type, frozenset())

Exceptions

Domain-aware exception hierarchy for the NIOS SDK.

NiosError

NiosError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: Exception

Base exception for all NIOS SDK errors.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

NiosConnectionError

NiosConnectionError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

TLS failure, DNS failure, connect timeout - pre-HTTP-response errors.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

AuthenticationError

AuthenticationError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

401 - credentials rejected or session expired.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

NotFoundError

NotFoundError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

404 - object does not exist.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

BadRequestError

BadRequestError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

400 - malformed request or invalid field values.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

ConflictError

ConflictError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

409 - object already exists or state conflict.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

RateLimitError

RateLimitError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None, retry_after: float | None = None)

Bases: NiosError

429 - too many requests.

Initialize a rate-limit error with optional retry delay.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code (typically 429).

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field.

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
retry_after float | None

Seconds to wait before retrying, parsed from the Retry-After response header. None if the header was absent.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
    retry_after: float | None = None,
) -> None:
    """Initialize a rate-limit error with optional retry delay.

    Args:
        status_code: HTTP status code (typically 429).
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field.
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
        retry_after: Seconds to wait before retrying, parsed from the
            ``Retry-After`` response header. None if the header was absent.
    """
    super().__init__(
        status_code=status_code,
        message=message,
        response_body=response_body,
        wapi_code=wapi_code,
        wapi_text=wapi_text,
        request_url=request_url,
    )
    self.retry_after = retry_after

ServerError

ServerError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

5xx - server-side failure.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

ValidationError

ValidationError(*, status_code: int | None = None, message: str, response_body: dict[str, Any] | None = None, wapi_code: str | None = None, wapi_text: str | None = None, request_url: str | None = None)

Bases: NiosError

Pydantic parse failure - response did not match the expected model.

Initialize the base NIOS error.

Parameters:

Name Type Description Default
status_code int | None

HTTP status code that triggered the error, or None for non-HTTP errors.

None
message str

Human-readable error description.

required
response_body dict[str, Any] | None

Parsed JSON response body from the WAPI, if available.

None
wapi_code str | None

WAPI-specific error code from the code field (e.g. "AdmConProhibited").

None
wapi_text str | None

WAPI-specific error text from the text field.

None
request_url str | None

Full URL of the request that caused the error.

None
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(
    self,
    *,
    status_code: int | None = None,
    message: str,
    response_body: dict[str, Any] | None = None,
    wapi_code: str | None = None,
    wapi_text: str | None = None,
    request_url: str | None = None,
) -> None:
    """Initialize the base NIOS error.

    Args:
        status_code: HTTP status code that triggered the error, or None for
            non-HTTP errors.
        message: Human-readable error description.
        response_body: Parsed JSON response body from the WAPI, if available.
        wapi_code: WAPI-specific error code from the ``code`` field (e.g.
            ``"AdmConProhibited"``).
        wapi_text: WAPI-specific error text from the ``text`` field.
        request_url: Full URL of the request that caused the error.
    """
    self.status_code = status_code
    self.message = message
    self.response_body = response_body
    self.wapi_code = wapi_code
    self.wapi_text = wapi_text
    self.request_url = request_url
    super().__init__(message)

UnsupportedOperationError

UnsupportedOperationError(*, wapi_type: str, operation: str)

Bases: NiosError

Object type does not support the requested operation - raised before the request.

NIOS restricts some operations per object type: allrecords is a read-only aggregate, grid cannot be deleted, dtc accepts only function calls. The grid answers those with AdmConProtoError: Operation <op> not allowed for <type>; the SDK raises this instead, from the restriction table in :mod:ibx_nios_sdk._restrictions.

Pass enforce_restrictions=False to :class:~ibx_nios_sdk.client.NiosClient to skip the local check and let the grid decide - useful on a NIOS version whose restrictions differ from the table's.

Initialize the error for one object type and operation.

Parameters:

Name Type Description Default
wapi_type str

WAPI object type that refused the operation.

required
operation str

Operation name - read, create, update, or delete.

required
Source code in src/ibx_nios_sdk/_exceptions.py
def __init__(self, *, wapi_type: str, operation: str) -> None:
    """Initialize the error for one object type and operation.

    Args:
        wapi_type: WAPI object type that refused the operation.
        operation: Operation name - ``read``, ``create``, ``update``, or
            ``delete``.
    """
    self.wapi_type = wapi_type
    self.operation = operation
    super().__init__(
        message=(
            f"WAPI object type {wapi_type!r} does not support {operation}; "
            "pass enforce_restrictions=False to NiosClient to try anyway"
        )
    )

exception_for_status

exception_for_status(status_code: int, message: str, response_body: dict[str, Any] | None, *, retry_after: float | None = None, request_url: str | None = None) -> NiosError

Create the appropriate exception for an HTTP status code.

Maps well-known WAPI status codes to specific exception subclasses (e.g. 401 to AuthenticationError, 429 to RateLimitError). Codes in the 500–599 range produce ServerError; all other unrecognised codes produce the base NiosError.

Parameters:

Name Type Description Default
status_code int

HTTP response status code.

required
message str

Human-readable error message extracted from the response.

required
response_body dict[str, Any] | None

Parsed JSON response body, or None.

required
retry_after float | None

Seconds to wait before retrying; used only for 429 responses where a Retry-After header was present.

None
request_url str | None

Full URL of the request that triggered the error.

None

Returns:

Type Description
NiosError

A NiosError subclass instance matching the status code.

Source code in src/ibx_nios_sdk/_exceptions.py
def exception_for_status(
    status_code: int,
    message: str,
    response_body: dict[str, Any] | None,
    *,
    retry_after: float | None = None,
    request_url: str | None = None,
) -> NiosError:
    """Create the appropriate exception for an HTTP status code.

    Maps well-known WAPI status codes to specific exception subclasses (e.g.
    401 to ``AuthenticationError``, 429 to ``RateLimitError``). Codes in the
    500–599 range produce ``ServerError``; all other unrecognised codes produce
    the base ``NiosError``.

    Args:
        status_code: HTTP response status code.
        message: Human-readable error message extracted from the response.
        response_body: Parsed JSON response body, or None.
        retry_after: Seconds to wait before retrying; used only for 429
            responses where a ``Retry-After`` header was present.
        request_url: Full URL of the request that triggered the error.

    Returns:
        A ``NiosError`` subclass instance matching the status code.
    """
    wapi_code, wapi_text = _extract_wapi_fields(response_body)

    exc_class = _STATUS_MAP.get(status_code)
    if exc_class is None:
        if 500 <= status_code < 600:
            exc_class = ServerError
        else:
            return NiosError(
                status_code=status_code,
                message=message,
                response_body=response_body,
                wapi_code=wapi_code,
                wapi_text=wapi_text,
                request_url=request_url,
            )

    if exc_class is RateLimitError:
        return RateLimitError(
            status_code=status_code,
            message=message,
            response_body=response_body,
            wapi_code=wapi_code,
            wapi_text=wapi_text,
            request_url=request_url,
            retry_after=retry_after,
        )

    return exc_class(
        status_code=status_code,
        message=message,
        response_body=response_body,
        wapi_code=wapi_code,
        wapi_text=wapi_text,
        request_url=request_url,
    )