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

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.datetime_utils import serialize_datetime
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.conflict_error import ConflictError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.approval_policy_cursor_fields import ApprovalPolicyCursorFields
from ..types.approval_policy_resource import ApprovalPolicyResource
from ..types.approval_policy_resource_list import ApprovalPolicyResourceList
from ..types.approval_policy_status import ApprovalPolicyStatus
from ..types.order_enum import OrderEnum
from .types.approval_policies_get_request_status import ApprovalPoliciesGetRequestStatus
from .types.approval_policies_get_request_status_in_item import ApprovalPoliciesGetRequestStatusInItem
from .types.approval_policy_create_script_item import ApprovalPolicyCreateScriptItem
from .types.approval_policy_create_trigger import ApprovalPolicyCreateTrigger
from .types.approval_policy_update_script_item import ApprovalPolicyUpdateScriptItem
from .types.approval_policy_update_trigger import ApprovalPolicyUpdateTrigger

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


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

    def get(
        self,
        *,
        process_id: typing.Optional[str] = None,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[ApprovalPolicyCursorFields] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        status: typing.Optional[ApprovalPoliciesGetRequestStatus] = None,
        status_in: typing.Optional[
            typing.Union[
                ApprovalPoliciesGetRequestStatusInItem, typing.Sequence[ApprovalPoliciesGetRequestStatusInItem]
            ]
        ] = None,
        name: typing.Optional[str] = None,
        name_contains: typing.Optional[str] = None,
        name_ncontains: typing.Optional[str] = None,
        created_by: typing.Optional[str] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        updated_at_gt: typing.Optional[dt.datetime] = None,
        updated_at_lt: typing.Optional[dt.datetime] = None,
        updated_at_gte: typing.Optional[dt.datetime] = None,
        updated_at_lte: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ApprovalPolicyResourceList]:
        """
        Retrieve a list of all approval policies with pagination.

        Parameters
        ----------
        process_id : typing.Optional[str]

        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

        limit : typing.Optional[int]
            The number of items (0 .. 100) to return in a single page of the response. The response may contain fewer items if it is the last or only page.

        pagination_token : typing.Optional[str]
            A pagination token obtained from a previous call to this endpoint. Use it to get the next or previous page of results for your initial query. If `pagination_token` is specified, all other query parameters are ignored and inferred from the initial query.

            If not specified, the first page of results will be returned.

        sort : typing.Optional[ApprovalPolicyCursorFields]
            The field to sort the results by. Typically used together with the `order` parameter.

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        status : typing.Optional[ApprovalPoliciesGetRequestStatus]

        status_in : typing.Optional[typing.Union[ApprovalPoliciesGetRequestStatusInItem, typing.Sequence[ApprovalPoliciesGetRequestStatusInItem]]]

        name : typing.Optional[str]

        name_contains : typing.Optional[str]

        name_ncontains : typing.Optional[str]

        created_by : typing.Optional[str]

        created_at_gt : typing.Optional[dt.datetime]

        created_at_lt : typing.Optional[dt.datetime]

        created_at_gte : typing.Optional[dt.datetime]

        created_at_lte : typing.Optional[dt.datetime]

        updated_at_gt : typing.Optional[dt.datetime]

        updated_at_lt : typing.Optional[dt.datetime]

        updated_at_gte : typing.Optional[dt.datetime]

        updated_at_lte : typing.Optional[dt.datetime]

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

        Returns
        -------
        HttpResponse[ApprovalPolicyResourceList]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "approval_policies",
            method="GET",
            params={
                "process_id": process_id,
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "id__in": id_in,
                "status": status,
                "status__in": status_in,
                "name": name,
                "name__contains": name_contains,
                "name__ncontains": name_ncontains,
                "created_by": created_by,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "updated_at__gt": serialize_datetime(updated_at_gt) if updated_at_gt is not None else None,
                "updated_at__lt": serialize_datetime(updated_at_lt) if updated_at_lt is not None else None,
                "updated_at__gte": serialize_datetime(updated_at_gte) if updated_at_gte is not None else None,
                "updated_at__lte": serialize_datetime(updated_at_lte) if updated_at_lte is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResourceList,
                    parse_obj_as(
                        type_=ApprovalPolicyResourceList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self,
        *,
        name: str,
        script: typing.Sequence[ApprovalPolicyCreateScriptItem],
        description: typing.Optional[str] = OMIT,
        ends_at: typing.Optional[dt.datetime] = OMIT,
        starts_at: typing.Optional[dt.datetime] = OMIT,
        trigger: typing.Optional[ApprovalPolicyCreateTrigger] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ApprovalPolicyResource]:
        """
        Create a new approval policy.

        Parameters
        ----------
        name : str
            The name of the approval policy.

        script : typing.Sequence[ApprovalPolicyCreateScriptItem]
            A list of JSON objects that represents the approval policy script. The script contains the logic that determines whether an action should be sent to approval. This field is required, and it should contain at least one script object.

        description : typing.Optional[str]
            A brief description of the approval policy.

        ends_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy stops being active and stops triggering approval workflows.If `ends_at` is provided in the request, then `starts_at` must also be provided and `ends_at` must be later than `starts_at`. The value will be converted to UTC.

        starts_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy becomes active. Only payables submitted for approval during the policy's active period will trigger this policy. If omitted or `null`, the policy is effective immediately. The value will be converted to UTC.

        trigger : typing.Optional[ApprovalPolicyCreateTrigger]
            A JSON object that represents the trigger for the approval policy. The trigger specifies the event that will trigger the policy to be evaluated.

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

        Returns
        -------
        HttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "approval_policies",
            method="POST",
            json={
                "description": description,
                "ends_at": ends_at,
                "name": name,
                "script": convert_and_respect_annotation_metadata(
                    object_=script, annotation=typing.Sequence[ApprovalPolicyCreateScriptItem], direction="write"
                ),
                "starts_at": starts_at,
                "trigger": convert_and_respect_annotation_metadata(
                    object_=trigger, annotation=ApprovalPolicyCreateTrigger, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_by_id(
        self, approval_policy_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ApprovalPolicyResource]:
        """
        Retrieve a specific approval policy.

        Parameters
        ----------
        approval_policy_id : str

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

        Returns
        -------
        HttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_by_id(
        self, approval_policy_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Delete an existing approval policy.

        Parameters
        ----------
        approval_policy_id : str

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_by_id(
        self,
        approval_policy_id: str,
        *,
        description: typing.Optional[str] = OMIT,
        ends_at: typing.Optional[dt.datetime] = OMIT,
        name: typing.Optional[str] = OMIT,
        script: typing.Optional[typing.Sequence[ApprovalPolicyUpdateScriptItem]] = OMIT,
        starts_at: typing.Optional[dt.datetime] = OMIT,
        status: typing.Optional[ApprovalPolicyStatus] = OMIT,
        trigger: typing.Optional[ApprovalPolicyUpdateTrigger] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ApprovalPolicyResource]:
        """
        Update an existing approval policy.

        Parameters
        ----------
        approval_policy_id : str

        description : typing.Optional[str]
            A brief description of the approval policy.

        ends_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy stops being active and stops triggering approval workflows.If `ends_at` is provided in the request, then `starts_at` must also be provided and `ends_at` must be later than `starts_at`. The value will be converted to UTC.

        name : typing.Optional[str]
            The name of the approval policy.

        script : typing.Optional[typing.Sequence[ApprovalPolicyUpdateScriptItem]]
            A list of JSON objects that represents the approval policy script. The script contains the logic that determines whether an action should be sent to approval. This field is required, and it should contain at least one script object.

        starts_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy becomes active. Only payables submitted for approval during the policy's active period will trigger this policy. If omitted or `null`, the policy is effective immediately. The value will be converted to UTC.

        status : typing.Optional[ApprovalPolicyStatus]
            A string that represents the current status of the approval policy.

        trigger : typing.Optional[ApprovalPolicyUpdateTrigger]
            A JSON object that represents the trigger for the approval policy. The trigger specifies the event that will trigger the policy to be evaluated.

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

        Returns
        -------
        HttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="PATCH",
            json={
                "description": description,
                "ends_at": ends_at,
                "name": name,
                "script": convert_and_respect_annotation_metadata(
                    object_=script, annotation=typing.Sequence[ApprovalPolicyUpdateScriptItem], direction="write"
                ),
                "starts_at": starts_at,
                "status": status,
                "trigger": convert_and_respect_annotation_metadata(
                    object_=trigger, annotation=ApprovalPolicyUpdateTrigger, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def get(
        self,
        *,
        process_id: typing.Optional[str] = None,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[ApprovalPolicyCursorFields] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        status: typing.Optional[ApprovalPoliciesGetRequestStatus] = None,
        status_in: typing.Optional[
            typing.Union[
                ApprovalPoliciesGetRequestStatusInItem, typing.Sequence[ApprovalPoliciesGetRequestStatusInItem]
            ]
        ] = None,
        name: typing.Optional[str] = None,
        name_contains: typing.Optional[str] = None,
        name_ncontains: typing.Optional[str] = None,
        created_by: typing.Optional[str] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        updated_at_gt: typing.Optional[dt.datetime] = None,
        updated_at_lt: typing.Optional[dt.datetime] = None,
        updated_at_gte: typing.Optional[dt.datetime] = None,
        updated_at_lte: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ApprovalPolicyResourceList]:
        """
        Retrieve a list of all approval policies with pagination.

        Parameters
        ----------
        process_id : typing.Optional[str]

        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

        limit : typing.Optional[int]
            The number of items (0 .. 100) to return in a single page of the response. The response may contain fewer items if it is the last or only page.

        pagination_token : typing.Optional[str]
            A pagination token obtained from a previous call to this endpoint. Use it to get the next or previous page of results for your initial query. If `pagination_token` is specified, all other query parameters are ignored and inferred from the initial query.

            If not specified, the first page of results will be returned.

        sort : typing.Optional[ApprovalPolicyCursorFields]
            The field to sort the results by. Typically used together with the `order` parameter.

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        status : typing.Optional[ApprovalPoliciesGetRequestStatus]

        status_in : typing.Optional[typing.Union[ApprovalPoliciesGetRequestStatusInItem, typing.Sequence[ApprovalPoliciesGetRequestStatusInItem]]]

        name : typing.Optional[str]

        name_contains : typing.Optional[str]

        name_ncontains : typing.Optional[str]

        created_by : typing.Optional[str]

        created_at_gt : typing.Optional[dt.datetime]

        created_at_lt : typing.Optional[dt.datetime]

        created_at_gte : typing.Optional[dt.datetime]

        created_at_lte : typing.Optional[dt.datetime]

        updated_at_gt : typing.Optional[dt.datetime]

        updated_at_lt : typing.Optional[dt.datetime]

        updated_at_gte : typing.Optional[dt.datetime]

        updated_at_lte : typing.Optional[dt.datetime]

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

        Returns
        -------
        AsyncHttpResponse[ApprovalPolicyResourceList]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "approval_policies",
            method="GET",
            params={
                "process_id": process_id,
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "id__in": id_in,
                "status": status,
                "status__in": status_in,
                "name": name,
                "name__contains": name_contains,
                "name__ncontains": name_ncontains,
                "created_by": created_by,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "updated_at__gt": serialize_datetime(updated_at_gt) if updated_at_gt is not None else None,
                "updated_at__lt": serialize_datetime(updated_at_lt) if updated_at_lt is not None else None,
                "updated_at__gte": serialize_datetime(updated_at_gte) if updated_at_gte is not None else None,
                "updated_at__lte": serialize_datetime(updated_at_lte) if updated_at_lte is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResourceList,
                    parse_obj_as(
                        type_=ApprovalPolicyResourceList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self,
        *,
        name: str,
        script: typing.Sequence[ApprovalPolicyCreateScriptItem],
        description: typing.Optional[str] = OMIT,
        ends_at: typing.Optional[dt.datetime] = OMIT,
        starts_at: typing.Optional[dt.datetime] = OMIT,
        trigger: typing.Optional[ApprovalPolicyCreateTrigger] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ApprovalPolicyResource]:
        """
        Create a new approval policy.

        Parameters
        ----------
        name : str
            The name of the approval policy.

        script : typing.Sequence[ApprovalPolicyCreateScriptItem]
            A list of JSON objects that represents the approval policy script. The script contains the logic that determines whether an action should be sent to approval. This field is required, and it should contain at least one script object.

        description : typing.Optional[str]
            A brief description of the approval policy.

        ends_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy stops being active and stops triggering approval workflows.If `ends_at` is provided in the request, then `starts_at` must also be provided and `ends_at` must be later than `starts_at`. The value will be converted to UTC.

        starts_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy becomes active. Only payables submitted for approval during the policy's active period will trigger this policy. If omitted or `null`, the policy is effective immediately. The value will be converted to UTC.

        trigger : typing.Optional[ApprovalPolicyCreateTrigger]
            A JSON object that represents the trigger for the approval policy. The trigger specifies the event that will trigger the policy to be evaluated.

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

        Returns
        -------
        AsyncHttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "approval_policies",
            method="POST",
            json={
                "description": description,
                "ends_at": ends_at,
                "name": name,
                "script": convert_and_respect_annotation_metadata(
                    object_=script, annotation=typing.Sequence[ApprovalPolicyCreateScriptItem], direction="write"
                ),
                "starts_at": starts_at,
                "trigger": convert_and_respect_annotation_metadata(
                    object_=trigger, annotation=ApprovalPolicyCreateTrigger, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_by_id(
        self, approval_policy_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ApprovalPolicyResource]:
        """
        Retrieve a specific approval policy.

        Parameters
        ----------
        approval_policy_id : str

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

        Returns
        -------
        AsyncHttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_by_id(
        self, approval_policy_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Delete an existing approval policy.

        Parameters
        ----------
        approval_policy_id : str

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_by_id(
        self,
        approval_policy_id: str,
        *,
        description: typing.Optional[str] = OMIT,
        ends_at: typing.Optional[dt.datetime] = OMIT,
        name: typing.Optional[str] = OMIT,
        script: typing.Optional[typing.Sequence[ApprovalPolicyUpdateScriptItem]] = OMIT,
        starts_at: typing.Optional[dt.datetime] = OMIT,
        status: typing.Optional[ApprovalPolicyStatus] = OMIT,
        trigger: typing.Optional[ApprovalPolicyUpdateTrigger] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ApprovalPolicyResource]:
        """
        Update an existing approval policy.

        Parameters
        ----------
        approval_policy_id : str

        description : typing.Optional[str]
            A brief description of the approval policy.

        ends_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy stops being active and stops triggering approval workflows.If `ends_at` is provided in the request, then `starts_at` must also be provided and `ends_at` must be later than `starts_at`. The value will be converted to UTC.

        name : typing.Optional[str]
            The name of the approval policy.

        script : typing.Optional[typing.Sequence[ApprovalPolicyUpdateScriptItem]]
            A list of JSON objects that represents the approval policy script. The script contains the logic that determines whether an action should be sent to approval. This field is required, and it should contain at least one script object.

        starts_at : typing.Optional[dt.datetime]
            The date and time (in the ISO 8601 format) when the approval policy becomes active. Only payables submitted for approval during the policy's active period will trigger this policy. If omitted or `null`, the policy is effective immediately. The value will be converted to UTC.

        status : typing.Optional[ApprovalPolicyStatus]
            A string that represents the current status of the approval policy.

        trigger : typing.Optional[ApprovalPolicyUpdateTrigger]
            A JSON object that represents the trigger for the approval policy. The trigger specifies the event that will trigger the policy to be evaluated.

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

        Returns
        -------
        AsyncHttpResponse[ApprovalPolicyResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"approval_policies/{jsonable_encoder(approval_policy_id)}",
            method="PATCH",
            json={
                "description": description,
                "ends_at": ends_at,
                "name": name,
                "script": convert_and_respect_annotation_metadata(
                    object_=script, annotation=typing.Sequence[ApprovalPolicyUpdateScriptItem], direction="write"
                ),
                "starts_at": starts_at,
                "status": status,
                "trigger": convert_and_respect_annotation_metadata(
                    object_=trigger, annotation=ApprovalPolicyUpdateTrigger, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ApprovalPolicyResource,
                    parse_obj_as(
                        type_=ApprovalPolicyResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
