# This file was auto-generated by Fern from our API Definition.

import typing
from ..core.client_wrapper import SyncClientWrapper
from .types.list_integration_options import ListIntegrationOptions
from ..core.request_options import RequestOptions
from .types.list_integrations_response import ListIntegrationsResponse
from ..core.unchecked_base_model import construct_type
from ..common.errors.bad_request_error import BadRequestError
from ..common.types.problem import Problem
from ..common.errors.unauthorized_error import UnauthorizedError
from ..common.errors.forbidden_error import ForbiddenError
from ..common.errors.not_found_error import NotFoundError
from ..common.errors.method_not_allowed_error import MethodNotAllowedError
from ..common.errors.conflict_error import ConflictError
from ..common.errors.unsupported_media_type_error import UnsupportedMediaTypeError
from ..common.errors.too_many_requests_error import TooManyRequestsError
from ..common.errors.internal_server_error import InternalServerError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..account_base.types.account_id import AccountId
from .types.list_account_integrations_response import ListAccountIntegrationsResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..integration_base.types.integration_id import IntegrationId
from .types.get_integration_response import GetIntegrationResponse
from ..providers_generated.types.provider_config import ProviderConfig
from ..integration_points.types.integration_point_id import IntegrationPointId
from .types.bridge_selector import BridgeSelector
from .types.webhook_config import WebhookConfig
from ..management.types.mapping_chain import MappingChain
from ..management.types.additional_mapping import AdditionalMapping
from .types.create_integration_response import CreateIntegrationResponse
from ..common.errors.not_implemented_error import NotImplementedError
from ..common.errors.bad_gateway_error import BadGatewayError
from ..common.errors.service_unavailable_error import ServiceUnavailableError
from ..common.errors.gateway_timeout_error import GatewayTimeoutError
from .types.create_integration_request import CreateIntegrationRequest
from ..token_base.types.token_id import TokenId
from ..capabilities_base.types.category_id import CategoryId
import datetime as dt
from ..accounts.types.account import Account
from ..integration_points.types.integration_point import IntegrationPoint
from .types.update_integration_response import UpdateIntegrationResponse
from ..common.types.patch_operation import PatchOperation
from .types.patch_integration_response import PatchIntegrationResponse
from ..core.client_wrapper import AsyncClientWrapper

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class IntegrationsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        expand: typing.Optional[
            typing.Union[
                ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]
            ]
        ] = None,
        total: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListIntegrationsResponse:
        """
        Returns a list of all `Integration` objects that match the query params.

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of `Integration` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Integration` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

        expand : typing.Optional[typing.Union[ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]]]
            Expand the integration result with the related integration point and/or account information.

        total : typing.Optional[bool]
            Return total number of all integrations in the system, respecting all applied filters. This is expensive, use sparingly.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ListIntegrationsResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.integrations import ListIntegrationOptions

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.list(
            limit=1,
            start_after="string",
            order="string",
            filter="string",
            expand=ListIntegrationOptions.ACCOUNT,
            total=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/integrations",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
                "expand": expand,
                "total": total,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListIntegrationsResponse,
                    construct_type(
                        type_=ListIntegrationsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_account(
        self,
        account_id: AccountId,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        expand: typing.Optional[
            typing.Union[
                ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]
            ]
        ] = None,
        total: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListAccountIntegrationsResponse:
        """
        Returns a list of all `Integration` objects belonging to the
        `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        limit : typing.Optional[int]
            Number of `Integration` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Integration` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

        expand : typing.Optional[typing.Union[ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]]]
            Expand the integration result with the related integration point and/or account information.

        total : typing.Optional[bool]
            Return total number of integrations for a particular account. This is expensive, use sparingly.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ListAccountIntegrationsResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.integrations import ListIntegrationOptions

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.list_account(
            account_id="string",
            limit=1,
            start_after="string",
            order="string",
            filter="string",
            expand=ListIntegrationOptions.ACCOUNT,
            total=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
                "expand": expand,
                "total": total,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListAccountIntegrationsResponse,
                    construct_type(
                        type_=ListAccountIntegrationsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetIntegrationResponse:
        """
        Returns the `Integration` object matching `{integrationId}` where
        the `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetIntegrationResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.get(
            account_id="string",
            integration_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetIntegrationResponse,
                    construct_type(
                        type_=GetIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        account_id: AccountId,
        *,
        provider_config: ProviderConfig,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        bridge_selector: typing.Optional[BridgeSelector] = OMIT,
        webhook_config: typing.Optional[WebhookConfig] = OMIT,
        mappings: typing.Optional[typing.Sequence[MappingChain]] = OMIT,
        additional_mappings: typing.Optional[typing.Sequence[AdditionalMapping]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateIntegrationResponse:
        """
        Creates an `Integration` object belonging to the `Account` matching
        `{accountId}`. Configures the `Integration` with the Provider specified
        in the request. Returns an `Integration` token for use with `Integration` APIs.

        Parameters
        ----------
        account_id : AccountId

        provider_config : ProviderConfig
            Provider configuration for this Integration.

        name : typing.Optional[str]
            Unique short name for this Integrations (lowercase [a-z0-9_-], can be used in URLs). Also used for case insensitive duplicate name detection and default sort order. Defaults to IntegrationId if both name and fullname are not specified.

        fullname : typing.Optional[str]
            Human friendly display name for this Integrations, will auto-generate 'name' field (if 'name' is not specified). Defaults to the same value as the 'name' field if not specified.

        integration_point_id : typing.Optional[IntegrationPointId]
            Integration Point associated with this integration.

        bridge_selector : typing.Optional[BridgeSelector]
            Use a Bridge to connect to the provider.

        webhook_config : typing.Optional[WebhookConfig]
            Web hook config for this integration

        mappings : typing.Optional[typing.Sequence[MappingChain]]
            A list of mapping chains to apply to the integration. Each mapping chain is a list of mappings to apply to the integration in the order they should be applied. Mappings are applied by operation ID. Leave this empty to use the default default mappings.

        additional_mappings : typing.Optional[typing.Sequence[AdditionalMapping]]
            Additional data mappings for this integration. This allows for custom data to be mapped to the custom_fields portion of the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CreateIntegrationResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.common import ActionId, ResourceId
        from synqly.integrations import BridgeSelector_Id, WebhookConfig
        from synqly.management import AdditionalMapping, MappingChain, MappingDataType
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.create(
            account_id="string",
            name="string",
            fullname="string",
            provider_config=ProviderConfig_AppsecAmazonInspector(),
            integration_point_id="string",
            bridge_selector=BridgeSelector_Id(value="string"),
            webhook_config=WebhookConfig(
                items=[],
            ),
            mappings=[
                MappingChain(
                    mappings=["string"],
                    operation_ids=["string"],
                )
            ],
            additional_mappings=[
                AdditionalMapping(
                    resource=ResourceId.ALERTS,
                    actions=[ActionId.QUERY],
                    source="string",
                    destination="string",
                    literal=True,
                    data_type=MappingDataType.STRING,
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "provider_config": provider_config,
                "integration_point_id": integration_point_id,
                "bridge_selector": bridge_selector,
                "webhook_config": webhook_config,
                "mappings": mappings,
                "additional_mappings": additional_mappings,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateIntegrationResponse,
                    construct_type(
                        type_=CreateIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGatewayError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def verify(
        self,
        account_id: AccountId,
        *,
        integration: CreateIntegrationRequest,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Verifies an ephemeral `Integration` and provider configuration and tests the authentication and provider connectivity.
        The provider config credential IDs can utilize persistent IDs or use "#/n" reference IDs;
        where (n) is the zero based offset in the optional credentials list.

        Parameters
        ----------
        account_id : AccountId

        integration : CreateIntegrationRequest

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.common import ActionId, ResourceId
        from synqly.integrations import (
            BridgeSelector_Id,
            CreateIntegrationRequest,
            WebhookConfig,
        )
        from synqly.management import AdditionalMapping, MappingChain, MappingDataType
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.verify(
            account_id="string",
            integration=CreateIntegrationRequest(
                name="string",
                fullname="string",
                provider_config=ProviderConfig_AppsecAmazonInspector(),
                integration_point_id="string",
                bridge_selector=BridgeSelector_Id(value="string"),
                webhook_config=WebhookConfig(
                    items=[],
                ),
                mappings=[
                    MappingChain(
                        mappings=["string"],
                        operation_ids=["string"],
                    )
                ],
                additional_mappings=[
                    AdditionalMapping(
                        resource=ResourceId.ALERTS,
                        actions=[ActionId.QUERY],
                        source="string",
                        destination="string",
                        literal=True,
                        data_type=MappingDataType.STRING,
                    )
                ],
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/verify",
            method="POST",
            json={
                "integration": integration,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGatewayError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self,
        account_id_: AccountId,
        integration_id: IntegrationId,
        *,
        id: IntegrationId,
        fullname: str,
        refresh_token_id: TokenId,
        account_id: AccountId,
        category: CategoryId,
        provider_config: ProviderConfig,
        provider_fullname: str,
        provider_type: str,
        name: str,
        created_at: dt.datetime,
        updated_at: dt.datetime,
        account: typing.Optional[Account] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        integration_point: typing.Optional[IntegrationPoint] = OMIT,
        bridge_selector: typing.Optional[BridgeSelector] = OMIT,
        webhook_config: typing.Optional[WebhookConfig] = OMIT,
        mappings: typing.Optional[typing.Sequence[MappingChain]] = OMIT,
        additional_mappings: typing.Optional[typing.Sequence[AdditionalMapping]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateIntegrationResponse:
        """
        Updates the `Integration` object matching `{integrationId}`, where the
        `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id_ : AccountId

        integration_id : IntegrationId

        id : IntegrationId

        fullname : str
            Human friendly display name for this integration.

        refresh_token_id : TokenId
            Integration refresh token id

        account_id : AccountId
            Account associated with this integration. Use the expand=accounts parameter with the List and ListAccount APIs to expand the Account to the full object

        category : CategoryId
            Id of the Connector Category for this Integration.

        provider_config : ProviderConfig
            Provider configuration for this Integration.

        provider_fullname : str
            Human friendly display name for the provider.

        provider_type : str
            Type of the provider for this Integration.

        name : str
            Human-readable name for this resource

        created_at : dt.datetime
            Time object was originally created

        updated_at : dt.datetime
            Last time object was updated

        account : typing.Optional[Account]
            When using the expand option on the List or ListAccount APIs, the full account object is included in the response

        integration_point_id : typing.Optional[IntegrationPointId]
            Integration Point associated with this integration. Use the expand=integration_points parameter with the List and ListAccount APIs to expand the Integration Point to the full object

        integration_point : typing.Optional[IntegrationPoint]
            When using the expand option on the List or ListAccount APIs, the full integration_point object is included in the response

        bridge_selector : typing.Optional[BridgeSelector]
            Use a Bridge to connect to the provider.

        webhook_config : typing.Optional[WebhookConfig]
            Webhook configuration for this integration. Some providers support webhooks, and will allow end users providers to send events to a server for new or updated data.

        mappings : typing.Optional[typing.Sequence[MappingChain]]
            A list of mapping chains to apply to the integration. Each mapping chain is a list of mappings to apply to the integration in the order they should be applied. Mappings are applied by operation ID. Leave this empty to use the default default mappings.

        additional_mappings : typing.Optional[typing.Sequence[AdditionalMapping]]
            Additional data mappings for this integration. This allows for custom data to be mapped to the custom_fields portion of the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        UpdateIntegrationResponse

        Examples
        --------
        import datetime

        from synqly import SynqlyManagement
        from synqly.accounts import Account
        from synqly.capabilities_base import CategoryId
        from synqly.integration_points import IntegrationEnvironments, IntegrationPoint
        from synqly.integrations import BridgeSelector_Id, WebhookConfig
        from synqly.organization_base import Environment
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.update(
            account_id_="string",
            integration_id="string",
            id="string",
            fullname="string",
            refresh_token_id="string",
            account_id="string",
            account=Account(
                id="string",
                fullname="string",
                organization_id="string",
                environment=Environment.TEST,
                labels=["string"],
                name="string",
                created_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                updated_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            ),
            category=CategoryId.APPSEC,
            provider_config=ProviderConfig_AppsecAmazonInspector(),
            provider_fullname="string",
            provider_type="string",
            integration_point_id="string",
            integration_point=IntegrationPoint(
                id="string",
                connector=CategoryId.APPSEC,
                environments=IntegrationEnvironments(),
                name="string",
                created_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                updated_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            ),
            bridge_selector=BridgeSelector_Id(value={"key": "value"}),
            webhook_config=WebhookConfig(
                items=[],
            ),
            mappings=[],
            additional_mappings=[],
            name="string",
            created_at=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            updated_at=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id_)}/{jsonable_encoder(integration_id)}",
            method="PUT",
            json={
                "id": id,
                "fullname": fullname,
                "refresh_token_id": refresh_token_id,
                "account_id": account_id,
                "account": account,
                "category": category,
                "provider_config": provider_config,
                "provider_fullname": provider_fullname,
                "provider_type": provider_type,
                "integration_point_id": integration_point_id,
                "integration_point": integration_point,
                "bridge_selector": bridge_selector,
                "webhook_config": webhook_config,
                "mappings": mappings,
                "additional_mappings": additional_mappings,
                "name": name,
                "created_at": created_at,
                "updated_at": updated_at,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    UpdateIntegrationResponse,
                    construct_type(
                        type_=UpdateIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def patch(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request: typing.Sequence[PatchOperation],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatchIntegrationResponse:
        """
        Patches the `Integration` object matching `{integrationId}`, where the
        `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request : typing.Sequence[PatchOperation]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PatchIntegrationResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.common import PatchOp, PatchOperation

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.patch(
            account_id="string",
            integration_id="string",
            request=[
                PatchOperation(
                    op=PatchOp.ADD,
                    path="string",
                    from_="string",
                    value={"key": "value"},
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PatchIntegrationResponse,
                    construct_type(
                        type_=PatchIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the `Integration` object matching `{integrationId}, where the `Integration`belongs to the`Account`matching`{accountId}`. Deleting an `Integration` also deletes any tokens that belong to it.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.integrations.delete(
            account_id="string",
            integration_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncIntegrationsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        expand: typing.Optional[
            typing.Union[
                ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]
            ]
        ] = None,
        total: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListIntegrationsResponse:
        """
        Returns a list of all `Integration` objects that match the query params.

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of `Integration` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Integration` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

        expand : typing.Optional[typing.Union[ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]]]
            Expand the integration result with the related integration point and/or account information.

        total : typing.Optional[bool]
            Return total number of all integrations in the system, respecting all applied filters. This is expensive, use sparingly.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ListIntegrationsResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.integrations import ListIntegrationOptions

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.list(
                limit=1,
                start_after="string",
                order="string",
                filter="string",
                expand=ListIntegrationOptions.ACCOUNT,
                total=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/integrations",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
                "expand": expand,
                "total": total,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListIntegrationsResponse,
                    construct_type(
                        type_=ListIntegrationsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_account(
        self,
        account_id: AccountId,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        expand: typing.Optional[
            typing.Union[
                ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]
            ]
        ] = None,
        total: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListAccountIntegrationsResponse:
        """
        Returns a list of all `Integration` objects belonging to the
        `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        limit : typing.Optional[int]
            Number of `Integration` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Integration` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

        expand : typing.Optional[typing.Union[ListIntegrationOptions, typing.Sequence[ListIntegrationOptions]]]
            Expand the integration result with the related integration point and/or account information.

        total : typing.Optional[bool]
            Return total number of integrations for a particular account. This is expensive, use sparingly.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ListAccountIntegrationsResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.integrations import ListIntegrationOptions

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.list_account(
                account_id="string",
                limit=1,
                start_after="string",
                order="string",
                filter="string",
                expand=ListIntegrationOptions.ACCOUNT,
                total=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
                "expand": expand,
                "total": total,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListAccountIntegrationsResponse,
                    construct_type(
                        type_=ListAccountIntegrationsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetIntegrationResponse:
        """
        Returns the `Integration` object matching `{integrationId}` where
        the `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetIntegrationResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.get(
                account_id="string",
                integration_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetIntegrationResponse,
                    construct_type(
                        type_=GetIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        account_id: AccountId,
        *,
        provider_config: ProviderConfig,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        bridge_selector: typing.Optional[BridgeSelector] = OMIT,
        webhook_config: typing.Optional[WebhookConfig] = OMIT,
        mappings: typing.Optional[typing.Sequence[MappingChain]] = OMIT,
        additional_mappings: typing.Optional[typing.Sequence[AdditionalMapping]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateIntegrationResponse:
        """
        Creates an `Integration` object belonging to the `Account` matching
        `{accountId}`. Configures the `Integration` with the Provider specified
        in the request. Returns an `Integration` token for use with `Integration` APIs.

        Parameters
        ----------
        account_id : AccountId

        provider_config : ProviderConfig
            Provider configuration for this Integration.

        name : typing.Optional[str]
            Unique short name for this Integrations (lowercase [a-z0-9_-], can be used in URLs). Also used for case insensitive duplicate name detection and default sort order. Defaults to IntegrationId if both name and fullname are not specified.

        fullname : typing.Optional[str]
            Human friendly display name for this Integrations, will auto-generate 'name' field (if 'name' is not specified). Defaults to the same value as the 'name' field if not specified.

        integration_point_id : typing.Optional[IntegrationPointId]
            Integration Point associated with this integration.

        bridge_selector : typing.Optional[BridgeSelector]
            Use a Bridge to connect to the provider.

        webhook_config : typing.Optional[WebhookConfig]
            Web hook config for this integration

        mappings : typing.Optional[typing.Sequence[MappingChain]]
            A list of mapping chains to apply to the integration. Each mapping chain is a list of mappings to apply to the integration in the order they should be applied. Mappings are applied by operation ID. Leave this empty to use the default default mappings.

        additional_mappings : typing.Optional[typing.Sequence[AdditionalMapping]]
            Additional data mappings for this integration. This allows for custom data to be mapped to the custom_fields portion of the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CreateIntegrationResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.common import ActionId, ResourceId
        from synqly.integrations import BridgeSelector_Id, WebhookConfig
        from synqly.management import AdditionalMapping, MappingChain, MappingDataType
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.create(
                account_id="string",
                name="string",
                fullname="string",
                provider_config=ProviderConfig_AppsecAmazonInspector(),
                integration_point_id="string",
                bridge_selector=BridgeSelector_Id(value="string"),
                webhook_config=WebhookConfig(
                    items=[],
                ),
                mappings=[
                    MappingChain(
                        mappings=["string"],
                        operation_ids=["string"],
                    )
                ],
                additional_mappings=[
                    AdditionalMapping(
                        resource=ResourceId.ALERTS,
                        actions=[ActionId.QUERY],
                        source="string",
                        destination="string",
                        literal=True,
                        data_type=MappingDataType.STRING,
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "provider_config": provider_config,
                "integration_point_id": integration_point_id,
                "bridge_selector": bridge_selector,
                "webhook_config": webhook_config,
                "mappings": mappings,
                "additional_mappings": additional_mappings,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateIntegrationResponse,
                    construct_type(
                        type_=CreateIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGatewayError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def verify(
        self,
        account_id: AccountId,
        *,
        integration: CreateIntegrationRequest,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Verifies an ephemeral `Integration` and provider configuration and tests the authentication and provider connectivity.
        The provider config credential IDs can utilize persistent IDs or use "#/n" reference IDs;
        where (n) is the zero based offset in the optional credentials list.

        Parameters
        ----------
        account_id : AccountId

        integration : CreateIntegrationRequest

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.common import ActionId, ResourceId
        from synqly.integrations import (
            BridgeSelector_Id,
            CreateIntegrationRequest,
            WebhookConfig,
        )
        from synqly.management import AdditionalMapping, MappingChain, MappingDataType
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.verify(
                account_id="string",
                integration=CreateIntegrationRequest(
                    name="string",
                    fullname="string",
                    provider_config=ProviderConfig_AppsecAmazonInspector(),
                    integration_point_id="string",
                    bridge_selector=BridgeSelector_Id(value="string"),
                    webhook_config=WebhookConfig(
                        items=[],
                    ),
                    mappings=[
                        MappingChain(
                            mappings=["string"],
                            operation_ids=["string"],
                        )
                    ],
                    additional_mappings=[
                        AdditionalMapping(
                            resource=ResourceId.ALERTS,
                            actions=[ActionId.QUERY],
                            source="string",
                            destination="string",
                            literal=True,
                            data_type=MappingDataType.STRING,
                        )
                    ],
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/verify",
            method="POST",
            json={
                "integration": integration,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGatewayError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self,
        account_id_: AccountId,
        integration_id: IntegrationId,
        *,
        id: IntegrationId,
        fullname: str,
        refresh_token_id: TokenId,
        account_id: AccountId,
        category: CategoryId,
        provider_config: ProviderConfig,
        provider_fullname: str,
        provider_type: str,
        name: str,
        created_at: dt.datetime,
        updated_at: dt.datetime,
        account: typing.Optional[Account] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        integration_point: typing.Optional[IntegrationPoint] = OMIT,
        bridge_selector: typing.Optional[BridgeSelector] = OMIT,
        webhook_config: typing.Optional[WebhookConfig] = OMIT,
        mappings: typing.Optional[typing.Sequence[MappingChain]] = OMIT,
        additional_mappings: typing.Optional[typing.Sequence[AdditionalMapping]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateIntegrationResponse:
        """
        Updates the `Integration` object matching `{integrationId}`, where the
        `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id_ : AccountId

        integration_id : IntegrationId

        id : IntegrationId

        fullname : str
            Human friendly display name for this integration.

        refresh_token_id : TokenId
            Integration refresh token id

        account_id : AccountId
            Account associated with this integration. Use the expand=accounts parameter with the List and ListAccount APIs to expand the Account to the full object

        category : CategoryId
            Id of the Connector Category for this Integration.

        provider_config : ProviderConfig
            Provider configuration for this Integration.

        provider_fullname : str
            Human friendly display name for the provider.

        provider_type : str
            Type of the provider for this Integration.

        name : str
            Human-readable name for this resource

        created_at : dt.datetime
            Time object was originally created

        updated_at : dt.datetime
            Last time object was updated

        account : typing.Optional[Account]
            When using the expand option on the List or ListAccount APIs, the full account object is included in the response

        integration_point_id : typing.Optional[IntegrationPointId]
            Integration Point associated with this integration. Use the expand=integration_points parameter with the List and ListAccount APIs to expand the Integration Point to the full object

        integration_point : typing.Optional[IntegrationPoint]
            When using the expand option on the List or ListAccount APIs, the full integration_point object is included in the response

        bridge_selector : typing.Optional[BridgeSelector]
            Use a Bridge to connect to the provider.

        webhook_config : typing.Optional[WebhookConfig]
            Webhook configuration for this integration. Some providers support webhooks, and will allow end users providers to send events to a server for new or updated data.

        mappings : typing.Optional[typing.Sequence[MappingChain]]
            A list of mapping chains to apply to the integration. Each mapping chain is a list of mappings to apply to the integration in the order they should be applied. Mappings are applied by operation ID. Leave this empty to use the default default mappings.

        additional_mappings : typing.Optional[typing.Sequence[AdditionalMapping]]
            Additional data mappings for this integration. This allows for custom data to be mapped to the custom_fields portion of the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        UpdateIntegrationResponse

        Examples
        --------
        import asyncio
        import datetime

        from synqly import AsyncSynqlyManagement
        from synqly.accounts import Account
        from synqly.capabilities_base import CategoryId
        from synqly.integration_points import IntegrationEnvironments, IntegrationPoint
        from synqly.integrations import BridgeSelector_Id, WebhookConfig
        from synqly.organization_base import Environment
        from synqly.providers_generated import ProviderConfig_AppsecAmazonInspector

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.update(
                account_id_="string",
                integration_id="string",
                id="string",
                fullname="string",
                refresh_token_id="string",
                account_id="string",
                account=Account(
                    id="string",
                    fullname="string",
                    organization_id="string",
                    environment=Environment.TEST,
                    labels=["string"],
                    name="string",
                    created_at=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    updated_at=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                ),
                category=CategoryId.APPSEC,
                provider_config=ProviderConfig_AppsecAmazonInspector(),
                provider_fullname="string",
                provider_type="string",
                integration_point_id="string",
                integration_point=IntegrationPoint(
                    id="string",
                    connector=CategoryId.APPSEC,
                    environments=IntegrationEnvironments(),
                    name="string",
                    created_at=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    updated_at=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                ),
                bridge_selector=BridgeSelector_Id(value={"key": "value"}),
                webhook_config=WebhookConfig(
                    items=[],
                ),
                mappings=[],
                additional_mappings=[],
                name="string",
                created_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                updated_at=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id_)}/{jsonable_encoder(integration_id)}",
            method="PUT",
            json={
                "id": id,
                "fullname": fullname,
                "refresh_token_id": refresh_token_id,
                "account_id": account_id,
                "account": account,
                "category": category,
                "provider_config": provider_config,
                "provider_fullname": provider_fullname,
                "provider_type": provider_type,
                "integration_point_id": integration_point_id,
                "integration_point": integration_point,
                "bridge_selector": bridge_selector,
                "webhook_config": webhook_config,
                "mappings": mappings,
                "additional_mappings": additional_mappings,
                "name": name,
                "created_at": created_at,
                "updated_at": updated_at,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    UpdateIntegrationResponse,
                    construct_type(
                        type_=UpdateIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def patch(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request: typing.Sequence[PatchOperation],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatchIntegrationResponse:
        """
        Patches the `Integration` object matching `{integrationId}`, where the
        `Integration` belongs to the `Account` matching `{accountId}`.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request : typing.Sequence[PatchOperation]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PatchIntegrationResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.common import PatchOp, PatchOperation

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.patch(
                account_id="string",
                integration_id="string",
                request=[
                    PatchOperation(
                        op=PatchOp.ADD,
                        path="string",
                        from_="string",
                        value={"key": "value"},
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PatchIntegrationResponse,
                    construct_type(
                        type_=PatchIntegrationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the `Integration` object matching `{integrationId}, where the `Integration`belongs to the`Account`matching`{accountId}`. Deleting an `Integration` also deletes any tokens that belong to it.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.integrations.delete(
                account_id="string",
                integration_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/integrations/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
