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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.unchecked_base_model import construct_type
from ..errors.bad_request_error import BadRequestError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.error import Error
from ..types.extend_error import ExtendError
from ..types.json_object import JsonObject
from ..types.max_page_size import MaxPageSize
from ..types.next_page_token import NextPageToken
from ..types.sort_by_enum import SortByEnum
from ..types.sort_dir_enum import SortDirEnum
from ..types.workflow_run_file_input import WorkflowRunFileInput
from ..types.workflow_status import WorkflowStatus
from .types.workflow_run_create_response import WorkflowRunCreateResponse
from .types.workflow_run_delete_response import WorkflowRunDeleteResponse
from .types.workflow_run_get_response import WorkflowRunGetResponse
from .types.workflow_run_list_response import WorkflowRunListResponse
from .types.workflow_run_update_response import WorkflowRunUpdateResponse

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


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

    def list(
        self,
        *,
        status: typing.Optional[WorkflowStatus] = None,
        workflow_id: typing.Optional[str] = None,
        batch_id: typing.Optional[str] = None,
        file_name_contains: typing.Optional[str] = None,
        sort_by: typing.Optional[SortByEnum] = None,
        sort_dir: typing.Optional[SortDirEnum] = None,
        next_page_token: typing.Optional[NextPageToken] = None,
        max_page_size: typing.Optional[MaxPageSize] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[WorkflowRunListResponse]:
        """
        List runs of a Workflow. Workflows are sequences of steps that process files and data in a specific order to achieve a desired outcome. A WorkflowRun represents a single execution of a workflow against a file.

        Parameters
        ----------
        status : typing.Optional[WorkflowStatus]
            Filters workflow runs by their status. If not provided, no filter is applied.

             The status of a workflow run:
             * `"PENDING"` - The workflow run has not started yet
             * `"PROCESSING"` - The workflow run is in progress
             * `"NEEDS_REVIEW"` - The workflow run requires manual review
             * `"REJECTED"` - The workflow run was rejected during manual review
             * `"PROCESSED"` - The workflow run completed successfully
             * `"FAILED"` - The workflow run encountered an error

        workflow_id : typing.Optional[str]
            Filters workflow runs by the workflow ID. If not provided, runs for all workflows are returned.

            Example: `"workflow_BMdfq_yWM3sT-ZzvCnA3f"`

        batch_id : typing.Optional[str]
            Filters workflow runs by the batch ID. This is useful for fetching all runs for a given batch created via the [Batch Run Workflow](/developers/api-reference/workflow-endpoints/batch-run-workflow) endpoint.

            Example: `"batch_7Ws31-F5"`

        file_name_contains : typing.Optional[str]
            Filters workflow runs by the name of the file. Only returns workflow runs where the file name contains this string.

            Example: `"invoice"`

        sort_by : typing.Optional[SortByEnum]
            Sorts the workflow runs by the given field.

        sort_dir : typing.Optional[SortDirEnum]
            Sorts the workflow runs in ascending or descending order. Ascending order means the earliest workflow run is returned first.

        next_page_token : typing.Optional[NextPageToken]

        max_page_size : typing.Optional[MaxPageSize]

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

        Returns
        -------
        HttpResponse[WorkflowRunListResponse]
            You will get a list of summaries for each workflow run. These are shortened versions of the full WorkflowRun object.

            To get the full object, use the [Get WorkflowRun](/developers/api-reference/workflow-endpoints/get-workflow-run) endpoint.
        """
        _response = self._client_wrapper.httpx_client.request(
            "workflow_runs",
            method="GET",
            params={
                "status": status,
                "workflowId": workflow_id,
                "batchId": batch_id,
                "fileNameContains": file_name_contains,
                "sortBy": sort_by,
                "sortDir": sort_dir,
                "nextPageToken": next_page_token,
                "maxPageSize": max_page_size,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunListResponse,
                    construct_type(
                        type_=WorkflowRunListResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # 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,
        *,
        workflow_id: str,
        files: typing.Optional[typing.Sequence[WorkflowRunFileInput]] = OMIT,
        raw_texts: typing.Optional[typing.Sequence[str]] = OMIT,
        version: typing.Optional[str] = OMIT,
        priority: typing.Optional[int] = OMIT,
        metadata: typing.Optional[JsonObject] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[WorkflowRunCreateResponse]:
        """
        Run a Workflow with files. A Workflow is a sequence of steps that process files and data in a specific order to achieve a desired outcome. A WorkflowRun will be created for each file processed. A WorkflowRun represents a single execution of a workflow against a file.

        Parameters
        ----------
        workflow_id : str
            The ID of the workflow to run.

            Example: `"workflow_BMdfq_yWM3sT-ZzvCnA3f"`

        files : typing.Optional[typing.Sequence[WorkflowRunFileInput]]
            An array of files to process through the workflow. Either the `files` array or `rawTexts` array must be provided. Supported file types can be found [here](/product/supported-file-types). There is a limit if 50 files that can be processed at once using this endpoint. If you wish to process more at a time, consider using the [Batch Run Workflow](/developers/api-reference/workflow-endpoints/batch-run-workflow) endpoint.

        raw_texts : typing.Optional[typing.Sequence[str]]
            An array of raw strings. Can be used in place of files when passing raw data. The raw data will be converted to `.txt` files and run through the workflow. If the data follows a specific format, it is recommended to use the files parameter instead. Either `files` or `rawTexts` must be provided.

        version : typing.Optional[str]
            An optional version of the workflow that files will be run through. This number can be found when viewing the workflow on the Extend platform. When a version number is not supplied, the most recent published version of the workflow will be used. If no published versions exist, the draft version will be used. To run the `"draft"` version of a workflow, use `"draft"` as the version.

            Examples:
            - `"3"` - Run version 3 of the workflow
            - `"draft"` - Run the draft version of the workflow

        priority : typing.Optional[int]
            An optional value used to determine the relative order of WorkflowRuns when rate limiting is in effect. Lower values will be prioritized before higher values.

        metadata : typing.Optional[JsonObject]
            A optional metadata object that can be assigned to a specific WorkflowRun to help identify it. It will be returned in the response and webhooks. You can place any arbitrary `key : value` pairs in this object.

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

        Returns
        -------
        HttpResponse[WorkflowRunCreateResponse]
            Successfully created workflow runs
        """
        _response = self._client_wrapper.httpx_client.request(
            "workflow_runs",
            method="POST",
            json={
                "workflowId": workflow_id,
                "files": convert_and_respect_annotation_metadata(
                    object_=files, annotation=typing.Sequence[WorkflowRunFileInput], direction="write"
                ),
                "rawTexts": raw_texts,
                "version": version,
                "priority": priority,
                "metadata": metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunCreateResponse,
                    construct_type(
                        type_=WorkflowRunCreateResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # 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(
        self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[WorkflowRunGetResponse]:
        """
        Once a workflow has been run, you can check the status and output of a specific WorkflowRun.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the WorkflowRun that was outputted after a Workflow was run through the API.

            Example: `"workflow_run_8k9m-xyzAB_Pqrst-Nvw4"`

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

        Returns
        -------
        HttpResponse[WorkflowRunGetResponse]
            Successfully retrieved workflow run
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunGetResponse,
                    construct_type(
                        type_=WorkflowRunGetResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            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(
        self,
        workflow_run_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        metadata: typing.Optional[JsonObject] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[WorkflowRunUpdateResponse]:
        """
        You can update the name and metadata of an in progress WorkflowRun at any time using this endpoint.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the WorkflowRun. This ID will start with "workflow_run". This ID can be found in the API response when creating a Workflow Run, or in the "history" tab of a workflow on the Extend platform.

            Example: `"workflow_run_8k9m-xyzAB_Pqrst-Nvw4"`

        name : typing.Optional[str]
            An optional name that can be assigned to a specific WorkflowRun

        metadata : typing.Optional[JsonObject]
            A metadata object that can be assigned to a specific WorkflowRun. If metadata already exists on this WorkflowRun, the newly incoming metadata will be merged with the existing metadata, with the incoming metadata taking field precedence.

            You can include any arbitrary `key : value` pairs in this object.

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

        Returns
        -------
        HttpResponse[WorkflowRunUpdateResponse]
            Successfully updated workflow run
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="POST",
            json={
                "name": name,
                "metadata": metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunUpdateResponse,
                    construct_type(
                        type_=WorkflowRunUpdateResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            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(
        self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[WorkflowRunDeleteResponse]:
        """
        Delete a workflow run and all associated data from Extend. This operation is permanent and cannot be undone.

        This endpoint can be used if you'd like to manage data retention on your own rather than automated data retention policies. Or make one-off deletions for your downstream customers.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the workflow run to delete.

            Example: `"workflow_run_xKm9pNv3qWsY_jL2tR5Dh"`

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

        Returns
        -------
        HttpResponse[WorkflowRunDeleteResponse]
            Successfully deleted workflow run
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunDeleteResponse,
                    construct_type(
                        type_=WorkflowRunDeleteResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ExtendError,
                        construct_type(
                            type_=ExtendError,  # 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 AsyncRawWorkflowRunClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        status: typing.Optional[WorkflowStatus] = None,
        workflow_id: typing.Optional[str] = None,
        batch_id: typing.Optional[str] = None,
        file_name_contains: typing.Optional[str] = None,
        sort_by: typing.Optional[SortByEnum] = None,
        sort_dir: typing.Optional[SortDirEnum] = None,
        next_page_token: typing.Optional[NextPageToken] = None,
        max_page_size: typing.Optional[MaxPageSize] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[WorkflowRunListResponse]:
        """
        List runs of a Workflow. Workflows are sequences of steps that process files and data in a specific order to achieve a desired outcome. A WorkflowRun represents a single execution of a workflow against a file.

        Parameters
        ----------
        status : typing.Optional[WorkflowStatus]
            Filters workflow runs by their status. If not provided, no filter is applied.

             The status of a workflow run:
             * `"PENDING"` - The workflow run has not started yet
             * `"PROCESSING"` - The workflow run is in progress
             * `"NEEDS_REVIEW"` - The workflow run requires manual review
             * `"REJECTED"` - The workflow run was rejected during manual review
             * `"PROCESSED"` - The workflow run completed successfully
             * `"FAILED"` - The workflow run encountered an error

        workflow_id : typing.Optional[str]
            Filters workflow runs by the workflow ID. If not provided, runs for all workflows are returned.

            Example: `"workflow_BMdfq_yWM3sT-ZzvCnA3f"`

        batch_id : typing.Optional[str]
            Filters workflow runs by the batch ID. This is useful for fetching all runs for a given batch created via the [Batch Run Workflow](/developers/api-reference/workflow-endpoints/batch-run-workflow) endpoint.

            Example: `"batch_7Ws31-F5"`

        file_name_contains : typing.Optional[str]
            Filters workflow runs by the name of the file. Only returns workflow runs where the file name contains this string.

            Example: `"invoice"`

        sort_by : typing.Optional[SortByEnum]
            Sorts the workflow runs by the given field.

        sort_dir : typing.Optional[SortDirEnum]
            Sorts the workflow runs in ascending or descending order. Ascending order means the earliest workflow run is returned first.

        next_page_token : typing.Optional[NextPageToken]

        max_page_size : typing.Optional[MaxPageSize]

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

        Returns
        -------
        AsyncHttpResponse[WorkflowRunListResponse]
            You will get a list of summaries for each workflow run. These are shortened versions of the full WorkflowRun object.

            To get the full object, use the [Get WorkflowRun](/developers/api-reference/workflow-endpoints/get-workflow-run) endpoint.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "workflow_runs",
            method="GET",
            params={
                "status": status,
                "workflowId": workflow_id,
                "batchId": batch_id,
                "fileNameContains": file_name_contains,
                "sortBy": sort_by,
                "sortDir": sort_dir,
                "nextPageToken": next_page_token,
                "maxPageSize": max_page_size,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunListResponse,
                    construct_type(
                        type_=WorkflowRunListResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # 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,
        *,
        workflow_id: str,
        files: typing.Optional[typing.Sequence[WorkflowRunFileInput]] = OMIT,
        raw_texts: typing.Optional[typing.Sequence[str]] = OMIT,
        version: typing.Optional[str] = OMIT,
        priority: typing.Optional[int] = OMIT,
        metadata: typing.Optional[JsonObject] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[WorkflowRunCreateResponse]:
        """
        Run a Workflow with files. A Workflow is a sequence of steps that process files and data in a specific order to achieve a desired outcome. A WorkflowRun will be created for each file processed. A WorkflowRun represents a single execution of a workflow against a file.

        Parameters
        ----------
        workflow_id : str
            The ID of the workflow to run.

            Example: `"workflow_BMdfq_yWM3sT-ZzvCnA3f"`

        files : typing.Optional[typing.Sequence[WorkflowRunFileInput]]
            An array of files to process through the workflow. Either the `files` array or `rawTexts` array must be provided. Supported file types can be found [here](/product/supported-file-types). There is a limit if 50 files that can be processed at once using this endpoint. If you wish to process more at a time, consider using the [Batch Run Workflow](/developers/api-reference/workflow-endpoints/batch-run-workflow) endpoint.

        raw_texts : typing.Optional[typing.Sequence[str]]
            An array of raw strings. Can be used in place of files when passing raw data. The raw data will be converted to `.txt` files and run through the workflow. If the data follows a specific format, it is recommended to use the files parameter instead. Either `files` or `rawTexts` must be provided.

        version : typing.Optional[str]
            An optional version of the workflow that files will be run through. This number can be found when viewing the workflow on the Extend platform. When a version number is not supplied, the most recent published version of the workflow will be used. If no published versions exist, the draft version will be used. To run the `"draft"` version of a workflow, use `"draft"` as the version.

            Examples:
            - `"3"` - Run version 3 of the workflow
            - `"draft"` - Run the draft version of the workflow

        priority : typing.Optional[int]
            An optional value used to determine the relative order of WorkflowRuns when rate limiting is in effect. Lower values will be prioritized before higher values.

        metadata : typing.Optional[JsonObject]
            A optional metadata object that can be assigned to a specific WorkflowRun to help identify it. It will be returned in the response and webhooks. You can place any arbitrary `key : value` pairs in this object.

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

        Returns
        -------
        AsyncHttpResponse[WorkflowRunCreateResponse]
            Successfully created workflow runs
        """
        _response = await self._client_wrapper.httpx_client.request(
            "workflow_runs",
            method="POST",
            json={
                "workflowId": workflow_id,
                "files": convert_and_respect_annotation_metadata(
                    object_=files, annotation=typing.Sequence[WorkflowRunFileInput], direction="write"
                ),
                "rawTexts": raw_texts,
                "version": version,
                "priority": priority,
                "metadata": metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunCreateResponse,
                    construct_type(
                        type_=WorkflowRunCreateResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # 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(
        self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[WorkflowRunGetResponse]:
        """
        Once a workflow has been run, you can check the status and output of a specific WorkflowRun.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the WorkflowRun that was outputted after a Workflow was run through the API.

            Example: `"workflow_run_8k9m-xyzAB_Pqrst-Nvw4"`

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

        Returns
        -------
        AsyncHttpResponse[WorkflowRunGetResponse]
            Successfully retrieved workflow run
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunGetResponse,
                    construct_type(
                        type_=WorkflowRunGetResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            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(
        self,
        workflow_run_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        metadata: typing.Optional[JsonObject] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[WorkflowRunUpdateResponse]:
        """
        You can update the name and metadata of an in progress WorkflowRun at any time using this endpoint.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the WorkflowRun. This ID will start with "workflow_run". This ID can be found in the API response when creating a Workflow Run, or in the "history" tab of a workflow on the Extend platform.

            Example: `"workflow_run_8k9m-xyzAB_Pqrst-Nvw4"`

        name : typing.Optional[str]
            An optional name that can be assigned to a specific WorkflowRun

        metadata : typing.Optional[JsonObject]
            A metadata object that can be assigned to a specific WorkflowRun. If metadata already exists on this WorkflowRun, the newly incoming metadata will be merged with the existing metadata, with the incoming metadata taking field precedence.

            You can include any arbitrary `key : value` pairs in this object.

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

        Returns
        -------
        AsyncHttpResponse[WorkflowRunUpdateResponse]
            Successfully updated workflow run
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="POST",
            json={
                "name": name,
                "metadata": metadata,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunUpdateResponse,
                    construct_type(
                        type_=WorkflowRunUpdateResponse,  # 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],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        construct_type(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            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(
        self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[WorkflowRunDeleteResponse]:
        """
        Delete a workflow run and all associated data from Extend. This operation is permanent and cannot be undone.

        This endpoint can be used if you'd like to manage data retention on your own rather than automated data retention policies. Or make one-off deletions for your downstream customers.

        Parameters
        ----------
        workflow_run_id : str
            The ID of the workflow run to delete.

            Example: `"workflow_run_xKm9pNv3qWsY_jL2tR5Dh"`

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

        Returns
        -------
        AsyncHttpResponse[WorkflowRunDeleteResponse]
            Successfully deleted workflow run
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workflow_runs/{jsonable_encoder(workflow_run_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkflowRunDeleteResponse,
                    construct_type(
                        type_=WorkflowRunDeleteResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ExtendError,
                        construct_type(
                            type_=ExtendError,  # 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)
