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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.project_import import ProjectImport
from ..core.jsonable_encoder import jsonable_encoder
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from .types.tasks_list_request_fields import TasksListRequestFields
from ..core.pagination import SyncPager
from ..types.role_based_task import RoleBasedTask
from ..types.paginated_role_based_task_list import PaginatedRoleBasedTaskList
from ..errors.bad_request_error import BadRequestError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.forbidden_error import ForbiddenError
import datetime as dt
from ..types.lse_task import LseTask
from ..core.client_wrapper import AsyncClientWrapper
from ..core.pagination import AsyncPager

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


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

    def create_many_status(
        self, id: int, import_pk: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectImport:
        """
        Return data related to async project import operation

        Parameters
        ----------
        id : int
            A unique integer value identifying this project import.

        import_pk : int

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

        Returns
        -------
        ProjectImport


        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.create_many_status(
            id=1,
            import_pk=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/imports/{jsonable_encoder(import_pk)}/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectImport,
                    construct_type(
                        type_=ProjectImport,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_all_tasks(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete all tasks from a specific project.

        Parameters
        ----------
        id : int
            A unique integer value identifying this project.

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

        Returns
        -------
        None

        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.delete_all_tasks(
            id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/tasks/",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list(
        self,
        *,
        fields: typing.Optional[TasksListRequestFields] = None,
        include: typing.Optional[str] = None,
        only_annotated: typing.Optional[bool] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        project: typing.Optional[int] = None,
        query: typing.Optional[str] = None,
        resolve_uri: typing.Optional[bool] = None,
        review: typing.Optional[bool] = None,
        selected_items: typing.Optional[str] = None,
        view: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[RoleBasedTask]:
        """
        Retrieve a paginated list of tasks. The response format varies based on the user's role in the organization:
        - **Admin/Owner**: Full task details with all annotations, reviews, and metadata
        - **Reviewer**: Task details optimized for review workflow
        - **Annotator**: Task details filtered to show only user's own annotations and assignments

        Parameters
        ----------
        fields : typing.Optional[TasksListRequestFields]
            Set to "all" if you want to include annotations and predictions in the response. Defaults to task_only

        include : typing.Optional[str]
            Specify which fields to include in the response

        only_annotated : typing.Optional[bool]
            Filter to show only tasks that have annotations

        page : typing.Optional[int]
            A page number within the paginated result set.

        page_size : typing.Optional[int]
            Number of results to return per page.

        project : typing.Optional[int]
            Project ID

        query : typing.Optional[str]
            Additional query to filter tasks. It must be JSON encoded string of dict containing one of the following parameters: {"filters": ..., "selectedItems": ..., "ordering": ...}. Check Data Manager > Create View > see data field for more details about filters, selectedItems and ordering.

            filters: dict with "conjunction" string ("or" or "and") and list of filters in "items" array. Each filter is a dictionary with keys: "filter", "operator", "type", "value". Read more about available filters
            Example: {"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}
            selectedItems: dictionary with keys: "all", "included", "excluded". If "all" is false, "included" must be used. If "all" is true, "excluded" must be used.
            Examples: {"all": false, "included": [1, 2, 3]} or {"all": true, "excluded": [4, 5]}
            ordering: list of fields to order by. Currently, ordering is supported by only one parameter.
            Example: ["completed_at"]

        resolve_uri : typing.Optional[bool]
            Resolve task data URIs using Cloud Storage

        review : typing.Optional[bool]
            Get tasks for review

        selected_items : typing.Optional[str]
            JSON string of selected task IDs for review workflow

        view : typing.Optional[int]
            View ID

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

        Returns
        -------
        SyncPager[RoleBasedTask]


        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        response = client.tasks.list()
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        page = page if page is not None else 1
        _response = self._client_wrapper.httpx_client.request(
            "api/tasks/",
            method="GET",
            params={
                "fields": fields,
                "include": include,
                "only_annotated": only_annotated,
                "page": page,
                "page_size": page_size,
                "project": project,
                "query": query,
                "resolve_uri": resolve_uri,
                "review": review,
                "selectedItems": selected_items,
                "view": view,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    PaginatedRoleBasedTaskList,
                    construct_type(
                        type_=PaginatedRoleBasedTaskList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _has_next = True
                _get_next = lambda: self.list(
                    fields=fields,
                    include=include,
                    only_annotated=only_annotated,
                    page=page + 1,
                    page_size=page_size,
                    project=project,
                    query=query,
                    resolve_uri=resolve_uri,
                    review=review,
                    selected_items=selected_items,
                    view=view,
                    request_options=request_options,
                )
                _items = _parsed_response.tasks
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            if _response.status_code == 400:
                raise BadRequestError(
                    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(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        *,
        cancelled_annotations: typing.Optional[int] = OMIT,
        comment_authors: typing.Optional[typing.Sequence[int]] = OMIT,
        comment_count: typing.Optional[int] = OMIT,
        data: typing.Optional[typing.Any] = OMIT,
        file_upload: typing.Optional[int] = OMIT,
        inner_id: typing.Optional[int] = OMIT,
        is_labeled: typing.Optional[bool] = OMIT,
        last_comment_updated_at: typing.Optional[dt.datetime] = OMIT,
        meta: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        overlap: typing.Optional[int] = OMIT,
        project: typing.Optional[int] = OMIT,
        total_annotations: typing.Optional[int] = OMIT,
        total_predictions: typing.Optional[int] = OMIT,
        unresolved_comment_count: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LseTask:
        """
        Create a new task

        Parameters
        ----------
        cancelled_annotations : typing.Optional[int]
            Number of total cancelled annotations for the current task

        comment_authors : typing.Optional[typing.Sequence[int]]
            Users who wrote comments

        comment_count : typing.Optional[int]
            Number of comments in the task including all annotations

        data : typing.Optional[typing.Any]

        file_upload : typing.Optional[int]
            Uploaded file used as data source for this task

        inner_id : typing.Optional[int]
            Internal task ID in the project, starts with 1

        is_labeled : typing.Optional[bool]
            True if the number of annotations for this task is greater than or equal to the number of maximum_completions for the project

        last_comment_updated_at : typing.Optional[dt.datetime]
            When the last comment was updated

        meta : typing.Optional[typing.Optional[typing.Any]]

        overlap : typing.Optional[int]
            Number of distinct annotators that processed the current task

        project : typing.Optional[int]
            Project ID for this task

        total_annotations : typing.Optional[int]
            Number of total annotations for the current task except cancelled annotations

        total_predictions : typing.Optional[int]
            Number of total predictions for the current task

        unresolved_comment_count : typing.Optional[int]
            Number of unresolved comments in the task including all annotations

        updated_by : typing.Optional[int]
            Last annotator or reviewer who updated this task

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

        Returns
        -------
        LseTask


        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.create(
            data={"key": "value"},
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/tasks/",
            method="POST",
            json={
                "cancelled_annotations": cancelled_annotations,
                "comment_authors": comment_authors,
                "comment_count": comment_count,
                "data": data,
                "file_upload": file_upload,
                "inner_id": inner_id,
                "is_labeled": is_labeled,
                "last_comment_updated_at": last_comment_updated_at,
                "meta": meta,
                "overlap": overlap,
                "project": project,
                "total_annotations": total_annotations,
                "total_predictions": total_predictions,
                "unresolved_comment_count": unresolved_comment_count,
                "updated_by": updated_by,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LseTask,
                    construct_type(
                        type_=LseTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> RoleBasedTask:
        """
        Get task data, metadata, annotations and other attributes for a specific labeling task by task ID.

        Parameters
        ----------
        id : str
            Task ID

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

        Returns
        -------
        RoleBasedTask


        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.get(
            id="id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RoleBasedTask,
                    construct_type(
                        type_=RoleBasedTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete a task in Label Studio. This action cannot be undone!

        Parameters
        ----------
        id : str
            Task ID

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

        Returns
        -------
        None

        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.delete(
            id="id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self,
        id: str,
        *,
        avg_lead_time: typing.Optional[float] = OMIT,
        cancelled_annotations: typing.Optional[int] = OMIT,
        comment_count: typing.Optional[int] = OMIT,
        completed_at: typing.Optional[dt.datetime] = OMIT,
        data: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        draft_exists: typing.Optional[bool] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        inner_id: typing.Optional[int] = OMIT,
        is_labeled: typing.Optional[bool] = OMIT,
        last_comment_updated_at: typing.Optional[dt.datetime] = OMIT,
        meta: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        overlap: typing.Optional[int] = OMIT,
        predictions_score: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        reviewed: typing.Optional[bool] = OMIT,
        reviews_accepted: typing.Optional[int] = OMIT,
        reviews_rejected: typing.Optional[int] = OMIT,
        total_annotations: typing.Optional[int] = OMIT,
        total_predictions: typing.Optional[int] = OMIT,
        unresolved_comment_count: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RoleBasedTask:
        """
        Update the attributes of an existing labeling task.

        Parameters
        ----------
        id : str
            Task ID

        avg_lead_time : typing.Optional[float]

        cancelled_annotations : typing.Optional[int]

        comment_count : typing.Optional[int]
            Number of comments in the task including all annotations

        completed_at : typing.Optional[dt.datetime]

        data : typing.Optional[typing.Optional[typing.Any]]

        draft_exists : typing.Optional[bool]

        ground_truth : typing.Optional[bool]

        inner_id : typing.Optional[int]

        is_labeled : typing.Optional[bool]
            True if the number of annotations for this task is greater than or equal to the number of maximum_completions for the project

        last_comment_updated_at : typing.Optional[dt.datetime]
            When the last comment was updated

        meta : typing.Optional[typing.Optional[typing.Any]]

        overlap : typing.Optional[int]
            Number of distinct annotators that processed the current task

        predictions_score : typing.Optional[float]

        project : typing.Optional[int]
            Project ID for this task

        reviewed : typing.Optional[bool]

        reviews_accepted : typing.Optional[int]

        reviews_rejected : typing.Optional[int]

        total_annotations : typing.Optional[int]

        total_predictions : typing.Optional[int]

        unresolved_comment_count : typing.Optional[int]
            Number of unresolved comments in the task including all annotations

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

        Returns
        -------
        RoleBasedTask


        Examples
        --------
        from label_studio_sdk import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.tasks.update(
            id="id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="PATCH",
            json={
                "avg_lead_time": avg_lead_time,
                "cancelled_annotations": cancelled_annotations,
                "comment_count": comment_count,
                "completed_at": completed_at,
                "data": data,
                "draft_exists": draft_exists,
                "ground_truth": ground_truth,
                "inner_id": inner_id,
                "is_labeled": is_labeled,
                "last_comment_updated_at": last_comment_updated_at,
                "meta": meta,
                "overlap": overlap,
                "predictions_score": predictions_score,
                "project": project,
                "reviewed": reviewed,
                "reviews_accepted": reviews_accepted,
                "reviews_rejected": reviews_rejected,
                "total_annotations": total_annotations,
                "total_predictions": total_predictions,
                "unresolved_comment_count": unresolved_comment_count,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RoleBasedTask,
                    construct_type(
                        type_=RoleBasedTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def create_many_status(
        self, id: int, import_pk: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectImport:
        """
        Return data related to async project import operation

        Parameters
        ----------
        id : int
            A unique integer value identifying this project import.

        import_pk : int

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

        Returns
        -------
        ProjectImport


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.create_many_status(
                id=1,
                import_pk=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/imports/{jsonable_encoder(import_pk)}/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ProjectImport,
                    construct_type(
                        type_=ProjectImport,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_all_tasks(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete all tasks from a specific project.

        Parameters
        ----------
        id : int
            A unique integer value identifying this project.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.delete_all_tasks(
                id=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/tasks/",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list(
        self,
        *,
        fields: typing.Optional[TasksListRequestFields] = None,
        include: typing.Optional[str] = None,
        only_annotated: typing.Optional[bool] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        project: typing.Optional[int] = None,
        query: typing.Optional[str] = None,
        resolve_uri: typing.Optional[bool] = None,
        review: typing.Optional[bool] = None,
        selected_items: typing.Optional[str] = None,
        view: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[RoleBasedTask]:
        """
        Retrieve a paginated list of tasks. The response format varies based on the user's role in the organization:
        - **Admin/Owner**: Full task details with all annotations, reviews, and metadata
        - **Reviewer**: Task details optimized for review workflow
        - **Annotator**: Task details filtered to show only user's own annotations and assignments

        Parameters
        ----------
        fields : typing.Optional[TasksListRequestFields]
            Set to "all" if you want to include annotations and predictions in the response. Defaults to task_only

        include : typing.Optional[str]
            Specify which fields to include in the response

        only_annotated : typing.Optional[bool]
            Filter to show only tasks that have annotations

        page : typing.Optional[int]
            A page number within the paginated result set.

        page_size : typing.Optional[int]
            Number of results to return per page.

        project : typing.Optional[int]
            Project ID

        query : typing.Optional[str]
            Additional query to filter tasks. It must be JSON encoded string of dict containing one of the following parameters: {"filters": ..., "selectedItems": ..., "ordering": ...}. Check Data Manager > Create View > see data field for more details about filters, selectedItems and ordering.

            filters: dict with "conjunction" string ("or" or "and") and list of filters in "items" array. Each filter is a dictionary with keys: "filter", "operator", "type", "value". Read more about available filters
            Example: {"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}
            selectedItems: dictionary with keys: "all", "included", "excluded". If "all" is false, "included" must be used. If "all" is true, "excluded" must be used.
            Examples: {"all": false, "included": [1, 2, 3]} or {"all": true, "excluded": [4, 5]}
            ordering: list of fields to order by. Currently, ordering is supported by only one parameter.
            Example: ["completed_at"]

        resolve_uri : typing.Optional[bool]
            Resolve task data URIs using Cloud Storage

        review : typing.Optional[bool]
            Get tasks for review

        selected_items : typing.Optional[str]
            JSON string of selected task IDs for review workflow

        view : typing.Optional[int]
            View ID

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

        Returns
        -------
        AsyncPager[RoleBasedTask]


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            response = await client.tasks.list()
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        page = page if page is not None else 1
        _response = await self._client_wrapper.httpx_client.request(
            "api/tasks/",
            method="GET",
            params={
                "fields": fields,
                "include": include,
                "only_annotated": only_annotated,
                "page": page,
                "page_size": page_size,
                "project": project,
                "query": query,
                "resolve_uri": resolve_uri,
                "review": review,
                "selectedItems": selected_items,
                "view": view,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    PaginatedRoleBasedTaskList,
                    construct_type(
                        type_=PaginatedRoleBasedTaskList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _has_next = True
                _get_next = lambda: self.list(
                    fields=fields,
                    include=include,
                    only_annotated=only_annotated,
                    page=page + 1,
                    page_size=page_size,
                    project=project,
                    query=query,
                    resolve_uri=resolve_uri,
                    review=review,
                    selected_items=selected_items,
                    view=view,
                    request_options=request_options,
                )
                _items = _parsed_response.tasks
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            if _response.status_code == 400:
                raise BadRequestError(
                    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(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        *,
        cancelled_annotations: typing.Optional[int] = OMIT,
        comment_authors: typing.Optional[typing.Sequence[int]] = OMIT,
        comment_count: typing.Optional[int] = OMIT,
        data: typing.Optional[typing.Any] = OMIT,
        file_upload: typing.Optional[int] = OMIT,
        inner_id: typing.Optional[int] = OMIT,
        is_labeled: typing.Optional[bool] = OMIT,
        last_comment_updated_at: typing.Optional[dt.datetime] = OMIT,
        meta: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        overlap: typing.Optional[int] = OMIT,
        project: typing.Optional[int] = OMIT,
        total_annotations: typing.Optional[int] = OMIT,
        total_predictions: typing.Optional[int] = OMIT,
        unresolved_comment_count: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LseTask:
        """
        Create a new task

        Parameters
        ----------
        cancelled_annotations : typing.Optional[int]
            Number of total cancelled annotations for the current task

        comment_authors : typing.Optional[typing.Sequence[int]]
            Users who wrote comments

        comment_count : typing.Optional[int]
            Number of comments in the task including all annotations

        data : typing.Optional[typing.Any]

        file_upload : typing.Optional[int]
            Uploaded file used as data source for this task

        inner_id : typing.Optional[int]
            Internal task ID in the project, starts with 1

        is_labeled : typing.Optional[bool]
            True if the number of annotations for this task is greater than or equal to the number of maximum_completions for the project

        last_comment_updated_at : typing.Optional[dt.datetime]
            When the last comment was updated

        meta : typing.Optional[typing.Optional[typing.Any]]

        overlap : typing.Optional[int]
            Number of distinct annotators that processed the current task

        project : typing.Optional[int]
            Project ID for this task

        total_annotations : typing.Optional[int]
            Number of total annotations for the current task except cancelled annotations

        total_predictions : typing.Optional[int]
            Number of total predictions for the current task

        unresolved_comment_count : typing.Optional[int]
            Number of unresolved comments in the task including all annotations

        updated_by : typing.Optional[int]
            Last annotator or reviewer who updated this task

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

        Returns
        -------
        LseTask


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.create(
                data={"key": "value"},
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/tasks/",
            method="POST",
            json={
                "cancelled_annotations": cancelled_annotations,
                "comment_authors": comment_authors,
                "comment_count": comment_count,
                "data": data,
                "file_upload": file_upload,
                "inner_id": inner_id,
                "is_labeled": is_labeled,
                "last_comment_updated_at": last_comment_updated_at,
                "meta": meta,
                "overlap": overlap,
                "project": project,
                "total_annotations": total_annotations,
                "total_predictions": total_predictions,
                "unresolved_comment_count": unresolved_comment_count,
                "updated_by": updated_by,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    LseTask,
                    construct_type(
                        type_=LseTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> RoleBasedTask:
        """
        Get task data, metadata, annotations and other attributes for a specific labeling task by task ID.

        Parameters
        ----------
        id : str
            Task ID

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

        Returns
        -------
        RoleBasedTask


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.get(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RoleBasedTask,
                    construct_type(
                        type_=RoleBasedTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete a task in Label Studio. This action cannot be undone!

        Parameters
        ----------
        id : str
            Task ID

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.delete(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self,
        id: str,
        *,
        avg_lead_time: typing.Optional[float] = OMIT,
        cancelled_annotations: typing.Optional[int] = OMIT,
        comment_count: typing.Optional[int] = OMIT,
        completed_at: typing.Optional[dt.datetime] = OMIT,
        data: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        draft_exists: typing.Optional[bool] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        inner_id: typing.Optional[int] = OMIT,
        is_labeled: typing.Optional[bool] = OMIT,
        last_comment_updated_at: typing.Optional[dt.datetime] = OMIT,
        meta: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        overlap: typing.Optional[int] = OMIT,
        predictions_score: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        reviewed: typing.Optional[bool] = OMIT,
        reviews_accepted: typing.Optional[int] = OMIT,
        reviews_rejected: typing.Optional[int] = OMIT,
        total_annotations: typing.Optional[int] = OMIT,
        total_predictions: typing.Optional[int] = OMIT,
        unresolved_comment_count: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RoleBasedTask:
        """
        Update the attributes of an existing labeling task.

        Parameters
        ----------
        id : str
            Task ID

        avg_lead_time : typing.Optional[float]

        cancelled_annotations : typing.Optional[int]

        comment_count : typing.Optional[int]
            Number of comments in the task including all annotations

        completed_at : typing.Optional[dt.datetime]

        data : typing.Optional[typing.Optional[typing.Any]]

        draft_exists : typing.Optional[bool]

        ground_truth : typing.Optional[bool]

        inner_id : typing.Optional[int]

        is_labeled : typing.Optional[bool]
            True if the number of annotations for this task is greater than or equal to the number of maximum_completions for the project

        last_comment_updated_at : typing.Optional[dt.datetime]
            When the last comment was updated

        meta : typing.Optional[typing.Optional[typing.Any]]

        overlap : typing.Optional[int]
            Number of distinct annotators that processed the current task

        predictions_score : typing.Optional[float]

        project : typing.Optional[int]
            Project ID for this task

        reviewed : typing.Optional[bool]

        reviews_accepted : typing.Optional[int]

        reviews_rejected : typing.Optional[int]

        total_annotations : typing.Optional[int]

        total_predictions : typing.Optional[int]

        unresolved_comment_count : typing.Optional[int]
            Number of unresolved comments in the task including all annotations

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

        Returns
        -------
        RoleBasedTask


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tasks.update(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/tasks/{jsonable_encoder(id)}/",
            method="PATCH",
            json={
                "avg_lead_time": avg_lead_time,
                "cancelled_annotations": cancelled_annotations,
                "comment_count": comment_count,
                "completed_at": completed_at,
                "data": data,
                "draft_exists": draft_exists,
                "ground_truth": ground_truth,
                "inner_id": inner_id,
                "is_labeled": is_labeled,
                "last_comment_updated_at": last_comment_updated_at,
                "meta": meta,
                "overlap": overlap,
                "predictions_score": predictions_score,
                "project": project,
                "reviewed": reviewed,
                "reviews_accepted": reviews_accepted,
                "reviews_rejected": reviews_rejected,
                "total_annotations": total_annotations,
                "total_predictions": total_predictions,
                "unresolved_comment_count": unresolved_comment_count,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RoleBasedTask,
                    construct_type(
                        type_=RoleBasedTask,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
