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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..common.types.id import Id
from ..core.request_options import RequestOptions
from .types.list_credentials_response import ListCredentialsResponse
from ..core.jsonable_encoder import jsonable_encoder
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 .types.credential_id import CredentialId
from .types.get_credential_response import GetCredentialResponse
from .types.lookup_credential_response import LookupCredentialResponse
from .types.credential_config import CredentialConfig
from .types.owner_type import OwnerType
import datetime as dt
from .types.create_credential_response import CreateCredentialResponse
from .types.managed_type import ManagedType
from ..account_base.types.account_id import AccountId
from ..integration_base.types.integration_id import IntegrationId
from ..integration_points.types.integration_point_id import IntegrationPointId
from ..organization_webhook_base.types.webhook_id import WebhookId
from .types.update_credential_response import UpdateCredentialResponse
from ..common.types.patch_operation import PatchOperation
from .types.patch_credential_response import PatchCredentialResponse
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def list(
        self,
        owner_id: Id,
        *,
        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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListCredentialsResponse:
        """
        Returns a list of all `Credential` objects belonging to the `Account`, `Integration`, or `IntegrationPoint`, or `OrganizationWebhook` matching
        `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

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

        start_after : typing.Optional[str]
            Return `Credential` 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.

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

        Returns
        -------
        ListCredentialsResponse

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

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.list(
            owner_id="string",
            limit=1,
            start_after="string",
            order="string",
            filter="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListCredentialsResponse,
                    construct_type(
                        type_=ListCredentialsResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetCredentialResponse:
        """
        Returns the `Credential` object matching `{credentialId}` where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

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

        Returns
        -------
        GetCredentialResponse

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

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.get(
            owner_id="string",
            credential_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetCredentialResponse,
                    construct_type(
                        type_=GetCredentialResponse,  # 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 lookup(
        self,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LookupCredentialResponse:
        """
        Returns the `Credential` object matching `{credentialId}`.

        Parameters
        ----------
        credential_id : CredentialId

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

        Returns
        -------
        LookupCredentialResponse

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

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.lookup(
            credential_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/lookup/{jsonable_encoder(credential_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LookupCredentialResponse,
                    construct_type(
                        type_=LookupCredentialResponse,  # 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,
        owner_id: Id,
        *,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        config: typing.Optional[CredentialConfig] = OMIT,
        owner_type: typing.Optional[OwnerType] = OMIT,
        expires: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateCredentialResponse:
        """
        Creates a `Credential` object in the `Account`, `IntegrationPoint`, or `OrganizationWebhook` matching matching
        `{ownerId}`. A `Credential` may only by used by a single `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook`;
        however, `Credential` objects can be shared by multiple `Integrations` within an `Account`.

        Parameters
        ----------
        owner_id : Id

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

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

        config : typing.Optional[CredentialConfig]
            Credential configuration

        owner_type : typing.Optional[OwnerType]
            One of `account` or `integration_point`; defaults to `account` if not specified.

        expires : typing.Optional[dt.datetime]
            Time when this credential expires and can no longer be used again.

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

        Returns
        -------
        CreateCredentialResponse

        Examples
        --------
        import datetime

        from synqly import SynqlyManagement
        from synqly.credentials import CredentialConfig_Aws, OwnerType

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.create(
            owner_id="string",
            name="string",
            fullname="string",
            config=CredentialConfig_Aws(
                access_key_id="string",
                secret_access_key="string",
                session="string",
            ),
            owner_type=OwnerType.ACCOUNT,
            expires=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "config": config,
                "owner_type": owner_type,
                "expires": expires,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateCredentialResponse,
                    construct_type(
                        type_=CreateCredentialResponse,  # 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 update(
        self,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        id: CredentialId,
        owner_type: OwnerType,
        fullname: str,
        managed: ManagedType,
        name: str,
        created_at: dt.datetime,
        updated_at: dt.datetime,
        account_id: typing.Optional[AccountId] = OMIT,
        integration_id: typing.Optional[IntegrationId] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        organization_webhook_id: typing.Optional[WebhookId] = OMIT,
        config: typing.Optional[CredentialConfig] = OMIT,
        expires: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateCredentialResponse:
        """
        Updates the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

        id : CredentialId

        owner_type : OwnerType
            One of `account` or `integration_point`.

        fullname : str
            Human friendly display name for this Credential

        managed : ManagedType
            Field is set by the management process. Determines lifecycle and ownership of the credential.

        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_id : typing.Optional[AccountId]
            Account that manages this credential.

        integration_id : typing.Optional[IntegrationId]
            Integration associated with this credential.

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

        organization_webhook_id : typing.Optional[WebhookId]
            Organization Webhook associated with this credential.

        config : typing.Optional[CredentialConfig]
            Credential configuration

        expires : typing.Optional[dt.datetime]
            Time when this credential expires and can no longer be used again.

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

        Returns
        -------
        UpdateCredentialResponse

        Examples
        --------
        import datetime

        from synqly import SynqlyManagement
        from synqly.credentials import CredentialConfig_Aws, ManagedType, OwnerType

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.update(
            owner_id="string",
            credential_id="string",
            id="string",
            account_id="string",
            integration_id="string",
            integration_point_id="string",
            organization_webhook_id="string",
            owner_type=OwnerType.ACCOUNT,
            fullname="string",
            config=CredentialConfig_Aws(),
            expires=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            managed=ManagedType.MANAGED,
            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/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="PUT",
            json={
                "id": id,
                "account_id": account_id,
                "integration_id": integration_id,
                "integration_point_id": integration_point_id,
                "organization_webhook_id": organization_webhook_id,
                "owner_type": owner_type,
                "fullname": fullname,
                "config": config,
                "expires": expires,
                "managed": managed,
                "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(
                    UpdateCredentialResponse,
                    construct_type(
                        type_=UpdateCredentialResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request: typing.Sequence[PatchOperation],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatchCredentialResponse:
        """
        Patches the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

        request : typing.Sequence[PatchOperation]

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

        Returns
        -------
        PatchCredentialResponse

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

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.patch(
            owner_id="string",
            credential_id="string",
            request=[
                PatchOperation(
                    op=PatchOp.ADD,
                    path="string",
                    from_="string",
                    value={"key": "value"},
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PatchCredentialResponse,
                    construct_type(
                        type_=PatchCredentialResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

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

        Returns
        -------
        None

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

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.credentials.delete(
            owner_id="string",
            credential_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_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 AsyncCredentialsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        owner_id: Id,
        *,
        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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListCredentialsResponse:
        """
        Returns a list of all `Credential` objects belonging to the `Account`, `Integration`, or `IntegrationPoint`, or `OrganizationWebhook` matching
        `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

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

        start_after : typing.Optional[str]
            Return `Credential` 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.

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

        Returns
        -------
        ListCredentialsResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.list(
                owner_id="string",
                limit=1,
                start_after="string",
                order="string",
                filter="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListCredentialsResponse,
                    construct_type(
                        type_=ListCredentialsResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetCredentialResponse:
        """
        Returns the `Credential` object matching `{credentialId}` where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

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

        Returns
        -------
        GetCredentialResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.get(
                owner_id="string",
                credential_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetCredentialResponse,
                    construct_type(
                        type_=GetCredentialResponse,  # 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 lookup(
        self,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LookupCredentialResponse:
        """
        Returns the `Credential` object matching `{credentialId}`.

        Parameters
        ----------
        credential_id : CredentialId

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

        Returns
        -------
        LookupCredentialResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.lookup(
                credential_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/credentials/lookup/{jsonable_encoder(credential_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LookupCredentialResponse,
                    construct_type(
                        type_=LookupCredentialResponse,  # 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,
        owner_id: Id,
        *,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        config: typing.Optional[CredentialConfig] = OMIT,
        owner_type: typing.Optional[OwnerType] = OMIT,
        expires: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateCredentialResponse:
        """
        Creates a `Credential` object in the `Account`, `IntegrationPoint`, or `OrganizationWebhook` matching matching
        `{ownerId}`. A `Credential` may only by used by a single `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook`;
        however, `Credential` objects can be shared by multiple `Integrations` within an `Account`.

        Parameters
        ----------
        owner_id : Id

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

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

        config : typing.Optional[CredentialConfig]
            Credential configuration

        owner_type : typing.Optional[OwnerType]
            One of `account` or `integration_point`; defaults to `account` if not specified.

        expires : typing.Optional[dt.datetime]
            Time when this credential expires and can no longer be used again.

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

        Returns
        -------
        CreateCredentialResponse

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

        from synqly import AsyncSynqlyManagement
        from synqly.credentials import CredentialConfig_Aws, OwnerType

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.create(
                owner_id="string",
                name="string",
                fullname="string",
                config=CredentialConfig_Aws(
                    access_key_id="string",
                    secret_access_key="string",
                    session="string",
                ),
                owner_type=OwnerType.ACCOUNT,
                expires=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "config": config,
                "owner_type": owner_type,
                "expires": expires,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateCredentialResponse,
                    construct_type(
                        type_=CreateCredentialResponse,  # 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 update(
        self,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        id: CredentialId,
        owner_type: OwnerType,
        fullname: str,
        managed: ManagedType,
        name: str,
        created_at: dt.datetime,
        updated_at: dt.datetime,
        account_id: typing.Optional[AccountId] = OMIT,
        integration_id: typing.Optional[IntegrationId] = OMIT,
        integration_point_id: typing.Optional[IntegrationPointId] = OMIT,
        organization_webhook_id: typing.Optional[WebhookId] = OMIT,
        config: typing.Optional[CredentialConfig] = OMIT,
        expires: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateCredentialResponse:
        """
        Updates the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

        id : CredentialId

        owner_type : OwnerType
            One of `account` or `integration_point`.

        fullname : str
            Human friendly display name for this Credential

        managed : ManagedType
            Field is set by the management process. Determines lifecycle and ownership of the credential.

        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_id : typing.Optional[AccountId]
            Account that manages this credential.

        integration_id : typing.Optional[IntegrationId]
            Integration associated with this credential.

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

        organization_webhook_id : typing.Optional[WebhookId]
            Organization Webhook associated with this credential.

        config : typing.Optional[CredentialConfig]
            Credential configuration

        expires : typing.Optional[dt.datetime]
            Time when this credential expires and can no longer be used again.

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

        Returns
        -------
        UpdateCredentialResponse

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

        from synqly import AsyncSynqlyManagement
        from synqly.credentials import CredentialConfig_Aws, ManagedType, OwnerType

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.update(
                owner_id="string",
                credential_id="string",
                id="string",
                account_id="string",
                integration_id="string",
                integration_point_id="string",
                organization_webhook_id="string",
                owner_type=OwnerType.ACCOUNT,
                fullname="string",
                config=CredentialConfig_Aws(),
                expires=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                managed=ManagedType.MANAGED,
                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/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="PUT",
            json={
                "id": id,
                "account_id": account_id,
                "integration_id": integration_id,
                "integration_point_id": integration_point_id,
                "organization_webhook_id": organization_webhook_id,
                "owner_type": owner_type,
                "fullname": fullname,
                "config": config,
                "expires": expires,
                "managed": managed,
                "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(
                    UpdateCredentialResponse,
                    construct_type(
                        type_=UpdateCredentialResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request: typing.Sequence[PatchOperation],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatchCredentialResponse:
        """
        Patches the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

        request : typing.Sequence[PatchOperation]

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

        Returns
        -------
        PatchCredentialResponse

        Examples
        --------
        import asyncio

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

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.credentials.patch(
                owner_id="string",
                credential_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/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_id)}",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PatchCredentialResponse,
                    construct_type(
                        type_=PatchCredentialResponse,  # 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,
        owner_id: Id,
        credential_id: CredentialId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the `Credential` object matching `{credentialId}`, where the
        `Credential` belongs to the `Account`, `Integration`, `IntegrationPoint` or `OrganizationWebhook` matching `{ownerId}`.

        Parameters
        ----------
        owner_id : Id

        credential_id : CredentialId

        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.credentials.delete(
                owner_id="string",
                credential_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/credentials/{jsonable_encoder(owner_id)}/{jsonable_encoder(credential_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)
