Source code for arize.ai_integrations.client

"""Client implementation for managing AI integrations in the Arize platform."""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any

from arize.pre_releases import ReleaseStage, prerelease_endpoint
from arize.utils.resolve import (
    _find_ai_integration_id,
    _resolve_resource,
)

if TYPE_CHECKING:
    # builtins is needed to use builtins.list in type annotations because
    # the class has a list() method that shadows the built-in list type
    import builtins

    from arize._generated.api_client.api_client import ApiClient
    from arize.ai_integrations.types import (
        AiIntegration,
        AiIntegrationAuthType,
        AiIntegrationListResponse,
        AiIntegrationProvider,
        AiIntegrationScoping,
        AwsProviderMetadata,
        GcpProviderMetadata,
    )
    from arize.config import SDKConfiguration

logger = logging.getLogger(__name__)

# Sentinel object used to distinguish "caller did not pass this argument" from
# "caller explicitly passed None" in update().  This matters because the
# generated pydantic model uses ``model_fields_set`` to decide whether to
# serialize a nullable field as JSON ``null`` (clearing it on the server) vs.
# omitting it entirely (leaving it unchanged).
_UNSET: Any = object()


[docs] class AiIntegrationsClient: """Client for managing Arize AI integrations. This class is primarily intended for internal use within the SDK. Users are highly encouraged to access resource-specific functionality via :class:`arize.ArizeClient`. The AI integrations client is a thin wrapper around the generated REST API client, using the shared generated API client owned by :class:`arize.config.SDKConfiguration`. AI integrations configure access to external LLM providers (OpenAI, Azure OpenAI, AWS Bedrock, Vertex AI, Anthropic, and others) for use within the Arize platform. """ def __init__( self, *, sdk_config: SDKConfiguration, generated_client: ApiClient ) -> None: """ Args: sdk_config: Resolved SDK configuration. generated_client: Shared generated API client instance. """ # noqa: D205, D212 self._sdk_config = sdk_config # Import at runtime to keep the module lazy-loaded from arize._generated import api_client as gen self._api = gen.AIIntegrationsApi(generated_client)
[docs] @prerelease_endpoint(key="ai_integrations.list", stage=ReleaseStage.ALPHA) def list( self, *, name: str | None = None, space: str | None = None, limit: int = 100, cursor: str | None = None, ) -> AiIntegrationListResponse: """List AI integrations the user has access to. This endpoint supports cursor-based pagination. When provided, ``space`` filters results to a particular space. Args: name: Optional case-insensitive substring filter on the integration name. space: Optional space filter. If the value is a base64-encoded resource ID it is treated as a space ID; otherwise it is used as a case-insensitive substring filter on the space name. limit: Maximum number of integrations to return. The server may enforce an upper bound (max 100). cursor: Opaque pagination cursor from a previous response. Returns: A paginated AI integrations list response from the Arize REST API. Raises: ApiException: If the API request fails. """ resolved_space = _resolve_resource(space) return self._api.ai_integrations_list( space_id=resolved_space.id, space_name=resolved_space.name, name=name, limit=limit, cursor=cursor, )
[docs] @prerelease_endpoint(key="ai_integrations.get", stage=ReleaseStage.ALPHA) def get( self, *, integration: str, space: str | None = None ) -> AiIntegration: """Get an AI integration by name or ID. Args: integration: Integration name or ID to retrieve. space: Optional space name or ID used to disambiguate when resolving by name. Returns: The AI integration object. Raises: ApiException: If the API request fails (for example, integration not found). """ integration_id = _find_ai_integration_id( api=self._api, integration=integration, space=space, ) return self._api.ai_integrations_get(integration_id=integration_id)
[docs] @prerelease_endpoint(key="ai_integrations.create", stage=ReleaseStage.ALPHA) def create( self, *, name: str, provider: AiIntegrationProvider, api_key: str | None = None, base_url: str | None = None, model_names: builtins.list[str] | None = None, headers: dict[str, str] | None = None, enable_default_models: bool | None = None, function_calling_enabled: bool | None = None, auth_type: AiIntegrationAuthType | None = None, provider_metadata: AwsProviderMetadata | GcpProviderMetadata | None = None, scopings: builtins.list[AiIntegrationScoping] | None = None, ) -> AiIntegration: """Create a new AI integration. Integration names must be unique within the account. For ``awsBedrock`` provider, ``provider_metadata`` must include ``role_arn``. For ``vertexAI`` provider, ``provider_metadata`` must include ``project_id``, ``location``, and ``project_access_label``. Args: name: Integration name (must be unique within the account). provider: LLM provider (e.g. ``openAI``, ``azureOpenAI``, ``awsBedrock``, ``vertexAI``, ``anthropic``, ``custom``). api_key: API key for the provider (write-only, never returned). base_url: Custom base URL for the provider. model_names: Supported model names. headers: Custom headers to include in requests. enable_default_models: Enable the provider's default model list. Defaults to ``False`` if not provided. function_calling_enabled: Enable function/tool calling. Defaults to ``True`` if not provided. auth_type: Authentication type. Defaults to ``default`` if not provided. provider_metadata: Typed provider metadata (``AwsProviderMetadata`` or ``GcpProviderMetadata``), including the required ``kind`` discriminator. scopings: Visibility scoping rules. Defaults to account-wide if omitted. Returns: The created AI integration object. Raises: ApiException: If the API request fails. """ from arize._generated import api_client as gen wrapped_metadata = ( gen.AiIntegrationsCreateRequestProviderMetadata( actual_instance=provider_metadata ) if provider_metadata is not None else None ) body = gen.AiIntegrationsCreateRequest( name=name, provider=provider, api_key=api_key, base_url=base_url, model_names=model_names, headers=headers, enable_default_models=enable_default_models, function_calling_enabled=function_calling_enabled, auth_type=auth_type, provider_metadata=wrapped_metadata, scopings=scopings, ) return self._api.ai_integrations_create( ai_integrations_create_request=body )
[docs] @prerelease_endpoint(key="ai_integrations.update", stage=ReleaseStage.ALPHA) def update( self, *, integration: str, space: str | None = None, name: str | None = _UNSET, provider: AiIntegrationProvider | None = _UNSET, api_key: str | None = _UNSET, base_url: str | None = _UNSET, model_names: builtins.list[str] | None = _UNSET, headers: dict[str, str] | None = _UNSET, enable_default_models: bool | None = _UNSET, function_calling_enabled: bool | None = _UNSET, auth_type: AiIntegrationAuthType | None = _UNSET, provider_metadata: AwsProviderMetadata | GcpProviderMetadata | None = _UNSET, scopings: builtins.list[AiIntegrationScoping] | None = _UNSET, ) -> AiIntegration: """Update an AI integration by name or ID. Only the fields you pass are sent to the server. Omitted fields are left unchanged. To explicitly clear a nullable field (e.g. ``api_key``), pass ``None``. Args: integration: Integration name or ID to update. space: Optional space name or ID used to disambiguate when resolving by name. name: Updated integration name. provider: Updated LLM provider. api_key: New API key. Pass ``None`` to clear the existing key. base_url: Updated custom base URL. Pass ``None`` to clear. model_names: Updated model names (replaces all existing). headers: Updated custom headers. Pass ``None`` to clear. enable_default_models: Updated default models flag. function_calling_enabled: Updated function calling flag. auth_type: Updated authentication type. provider_metadata: Updated typed provider metadata (``AwsProviderMetadata`` or ``GcpProviderMetadata``). Pass ``None`` to clear. scopings: Updated visibility scoping rules (replaces all existing). Returns: The updated AI integration object. Raises: ApiException: If the API request fails (for example, integration not found or insufficient permissions). """ from arize._generated import api_client as gen wrapped_metadata: Any = _UNSET if provider_metadata is not _UNSET: wrapped_metadata = ( gen.AiIntegrationsUpdateRequestProviderMetadata( actual_instance=provider_metadata ) if provider_metadata is not None else None ) # Build kwargs with only the fields the caller actually provided so # that pydantic's model_fields_set accurately reflects intent. This # prevents nullable fields (api_key, base_url, headers, # provider_metadata) from being serialized as JSON null when the # caller didn't mention them. kwargs: dict[str, Any] = { k: v for k, v in ( ("name", name), ("provider", provider), ("api_key", api_key), ("base_url", base_url), ("model_names", model_names), ("headers", headers), ("enable_default_models", enable_default_models), ("function_calling_enabled", function_calling_enabled), ("auth_type", auth_type), ("provider_metadata", wrapped_metadata), ("scopings", scopings), ) if v is not _UNSET } integration_id = _find_ai_integration_id( api=self._api, integration=integration, space=space, ) body = gen.AiIntegrationsUpdateRequest(**kwargs) return self._api.ai_integrations_update( integration_id=integration_id, ai_integrations_update_request=body, )
[docs] @prerelease_endpoint(key="ai_integrations.delete", stage=ReleaseStage.ALPHA) def delete(self, *, integration: str, space: str | None = None) -> None: """Delete an AI integration by name or ID. This operation is irreversible. Args: integration: Integration name or ID to delete. space: Optional space name or ID used to disambiguate when resolving by name. Raises: ApiException: If the API request fails (for example, integration not found or insufficient permissions). """ integration_id = _find_ai_integration_id( api=self._api, integration=integration, space=space, ) self._api.ai_integrations_delete(integration_id=integration_id)