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

import datetime as dt
import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.annotation import Annotation
from ..types.last_action_enum import LastActionEnum
from ..types.selected_items_request import SelectedItemsRequest
from .raw_client import AsyncRawAnnotationsClient, RawAnnotationsClient
from .types.create_bulk_annotations_response_item import CreateBulkAnnotationsResponseItem

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


class AnnotationsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawAnnotationsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawAnnotationsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawAnnotationsClient
        """
        return self._raw_client

    def create_bulk(
        self,
        *,
        bulk_created: typing.Optional[bool] = OMIT,
        completed_by: typing.Optional[int] = OMIT,
        draft_created_at: typing.Optional[dt.datetime] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        import_id: typing.Optional[int] = OMIT,
        last_action: typing.Optional[LastActionEnum] = OMIT,
        last_created_by: typing.Optional[int] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        parent_annotation: typing.Optional[int] = OMIT,
        parent_prediction: typing.Optional[int] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        selected_items: typing.Optional[SelectedItemsRequest] = OMIT,
        task: typing.Optional[int] = OMIT,
        tasks: typing.Optional[typing.Sequence[int]] = OMIT,
        unique_id: typing.Optional[str] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[CreateBulkAnnotationsResponseItem]:
        """
        Create multiple annotations at once

        Parameters
        ----------
        bulk_created : typing.Optional[bool]
            Annotation was created in bulk mode

        completed_by : typing.Optional[int]

        draft_created_at : typing.Optional[dt.datetime]
            Draft creation time

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth (ground_truth)

        import_id : typing.Optional[int]
            Original annotation ID that was at the import step or NULL if this annotation wasn't imported

        last_action : typing.Optional[LastActionEnum]
            Action which was performed in the last annotation history item

            * `prediction` - Created from prediction
            * `propagated_annotation` - Created from another annotation
            * `imported` - Imported
            * `submitted` - Submitted
            * `updated` - Updated
            * `skipped` - Skipped
            * `accepted` - Accepted
            * `rejected` - Rejected
            * `fixed_and_accepted` - Fixed and accepted
            * `deleted_review` - Deleted review

        last_created_by : typing.Optional[int]
            User who created the last annotation history item

        lead_time : typing.Optional[float]
            How much time it took to annotate the task

        parent_annotation : typing.Optional[int]
            Points to the parent annotation from which this annotation was created

        parent_prediction : typing.Optional[int]
            Points to the prediction from which this annotation was created

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            List of annotation results for the task

        selected_items : typing.Optional[SelectedItemsRequest]

        task : typing.Optional[int]
            Corresponding task for this annotation

        tasks : typing.Optional[typing.Sequence[int]]

        unique_id : typing.Optional[str]

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        typing.List[CreateBulkAnnotationsResponseItem]
            Bulk annotations created successfully

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.annotations.create_bulk()
        """
        _response = self._raw_client.create_bulk(
            bulk_created=bulk_created,
            completed_by=completed_by,
            draft_created_at=draft_created_at,
            ground_truth=ground_truth,
            import_id=import_id,
            last_action=last_action,
            last_created_by=last_created_by,
            lead_time=lead_time,
            parent_annotation=parent_annotation,
            parent_prediction=parent_prediction,
            project=project,
            result=result,
            selected_items=selected_items,
            task=task,
            tasks=tasks,
            unique_id=unique_id,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data

    def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Annotation:
        """
        Retrieve a specific annotation for a task using the annotation result ID.

        Parameters
        ----------
        id : int

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

        Returns
        -------
        Annotation
            Retrieved annotation

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.annotations.get(
            id=1,
        )
        """
        _response = self._raw_client.get(id, request_options=request_options)
        return _response.data

    def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete an annotation. This action can't be undone!

        Parameters
        ----------
        id : int

        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.annotations.delete(
            id=1,
        )
        """
        _response = self._raw_client.delete(id, request_options=request_options)
        return _response.data

    def update(
        self,
        id: int,
        *,
        completed_by: typing.Optional[int] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        task: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Annotation:
        """
        Update existing attributes on an annotation.

        Parameters
        ----------
        id : int

        completed_by : typing.Optional[int]
            User ID of the person who created this annotation

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth

        lead_time : typing.Optional[float]
            How much time it took to annotate the task (in seconds)

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            Labeling result in JSON format. Read more about the format in [the Label Studio documentation.](https://labelstud.io/guide/task_format)

        task : typing.Optional[int]
            Corresponding task for this annotation

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        Annotation
            Updated annotation

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.annotations.update(
            id=1,
            ground_truth=True,
            result=[
                {
                    "from_name": "bboxes",
                    "image_rotation": 0,
                    "original_height": 1080,
                    "original_width": 1920,
                    "to_name": "image",
                    "type": "rectanglelabels",
                    "value": {
                        "height": 60,
                        "rotation": 0,
                        "values": {"rectanglelabels": ["Person"]},
                        "width": 50,
                        "x": 20,
                        "y": 30,
                    },
                }
            ],
            was_cancelled=False,
        )
        """
        _response = self._raw_client.update(
            id,
            completed_by=completed_by,
            ground_truth=ground_truth,
            lead_time=lead_time,
            project=project,
            result=result,
            task=task,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data

    def list(
        self, id: int, *, ordering: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Annotation]:
        """
        List all annotations for a task.

        Parameters
        ----------
        id : int
            Task ID

        ordering : typing.Optional[str]
            Which field to use when ordering the results.

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

        Returns
        -------
        typing.List[Annotation]
            Annotation

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.annotations.list(
            id=1,
        )
        """
        _response = self._raw_client.list(id, ordering=ordering, request_options=request_options)
        return _response.data

    def create(
        self,
        id: int,
        *,
        completed_by: typing.Optional[int] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        task: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Annotation:
        """

                Add annotations to a task like an annotator does. The content of the result field depends on your
                labeling configuration. For example, send the following data as part of your POST
                request to send an empty annotation with the ID of the user who completed the task:

                ```json
                {
                "result": {},
                "was_cancelled": true,
                "ground_truth": true,
                "lead_time": 0,
                "task": 0
                "completed_by": 123
                }
                ```


        Parameters
        ----------
        id : int
            Task ID

        completed_by : typing.Optional[int]
            User ID of the person who created this annotation

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth

        lead_time : typing.Optional[float]
            How much time it took to annotate the task (in seconds)

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            Labeling result in JSON format. Read more about the format in [the Label Studio documentation.](https://labelstud.io/guide/task_format)

        task : typing.Optional[int]
            Corresponding task for this annotation

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        Annotation
            Created annotation

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.annotations.create(
            id=1,
            ground_truth=True,
            result=[
                {
                    "from_name": "bboxes",
                    "image_rotation": 0,
                    "original_height": 1080,
                    "original_width": 1920,
                    "to_name": "image",
                    "type": "rectanglelabels",
                    "value": {
                        "height": 60,
                        "rotation": 0,
                        "values": {"rectanglelabels": ["Person"]},
                        "width": 50,
                        "x": 20,
                        "y": 30,
                    },
                }
            ],
            was_cancelled=False,
        )
        """
        _response = self._raw_client.create(
            id,
            completed_by=completed_by,
            ground_truth=ground_truth,
            lead_time=lead_time,
            project=project,
            result=result,
            task=task,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data


class AsyncAnnotationsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAnnotationsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawAnnotationsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawAnnotationsClient
        """
        return self._raw_client

    async def create_bulk(
        self,
        *,
        bulk_created: typing.Optional[bool] = OMIT,
        completed_by: typing.Optional[int] = OMIT,
        draft_created_at: typing.Optional[dt.datetime] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        import_id: typing.Optional[int] = OMIT,
        last_action: typing.Optional[LastActionEnum] = OMIT,
        last_created_by: typing.Optional[int] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        parent_annotation: typing.Optional[int] = OMIT,
        parent_prediction: typing.Optional[int] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        selected_items: typing.Optional[SelectedItemsRequest] = OMIT,
        task: typing.Optional[int] = OMIT,
        tasks: typing.Optional[typing.Sequence[int]] = OMIT,
        unique_id: typing.Optional[str] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[CreateBulkAnnotationsResponseItem]:
        """
        Create multiple annotations at once

        Parameters
        ----------
        bulk_created : typing.Optional[bool]
            Annotation was created in bulk mode

        completed_by : typing.Optional[int]

        draft_created_at : typing.Optional[dt.datetime]
            Draft creation time

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth (ground_truth)

        import_id : typing.Optional[int]
            Original annotation ID that was at the import step or NULL if this annotation wasn't imported

        last_action : typing.Optional[LastActionEnum]
            Action which was performed in the last annotation history item

            * `prediction` - Created from prediction
            * `propagated_annotation` - Created from another annotation
            * `imported` - Imported
            * `submitted` - Submitted
            * `updated` - Updated
            * `skipped` - Skipped
            * `accepted` - Accepted
            * `rejected` - Rejected
            * `fixed_and_accepted` - Fixed and accepted
            * `deleted_review` - Deleted review

        last_created_by : typing.Optional[int]
            User who created the last annotation history item

        lead_time : typing.Optional[float]
            How much time it took to annotate the task

        parent_annotation : typing.Optional[int]
            Points to the parent annotation from which this annotation was created

        parent_prediction : typing.Optional[int]
            Points to the prediction from which this annotation was created

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            List of annotation results for the task

        selected_items : typing.Optional[SelectedItemsRequest]

        task : typing.Optional[int]
            Corresponding task for this annotation

        tasks : typing.Optional[typing.Sequence[int]]

        unique_id : typing.Optional[str]

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        typing.List[CreateBulkAnnotationsResponseItem]
            Bulk annotations created successfully

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.annotations.create_bulk()


        asyncio.run(main())
        """
        _response = await self._raw_client.create_bulk(
            bulk_created=bulk_created,
            completed_by=completed_by,
            draft_created_at=draft_created_at,
            ground_truth=ground_truth,
            import_id=import_id,
            last_action=last_action,
            last_created_by=last_created_by,
            lead_time=lead_time,
            parent_annotation=parent_annotation,
            parent_prediction=parent_prediction,
            project=project,
            result=result,
            selected_items=selected_items,
            task=task,
            tasks=tasks,
            unique_id=unique_id,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data

    async def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Annotation:
        """
        Retrieve a specific annotation for a task using the annotation result ID.

        Parameters
        ----------
        id : int

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

        Returns
        -------
        Annotation
            Retrieved annotation

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


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


        asyncio.run(main())
        """
        _response = await self._raw_client.get(id, request_options=request_options)
        return _response.data

    async def delete(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete an annotation. This action can't be undone!

        Parameters
        ----------
        id : int

        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.annotations.delete(
                id=1,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete(id, request_options=request_options)
        return _response.data

    async def update(
        self,
        id: int,
        *,
        completed_by: typing.Optional[int] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        task: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Annotation:
        """
        Update existing attributes on an annotation.

        Parameters
        ----------
        id : int

        completed_by : typing.Optional[int]
            User ID of the person who created this annotation

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth

        lead_time : typing.Optional[float]
            How much time it took to annotate the task (in seconds)

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            Labeling result in JSON format. Read more about the format in [the Label Studio documentation.](https://labelstud.io/guide/task_format)

        task : typing.Optional[int]
            Corresponding task for this annotation

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        Annotation
            Updated annotation

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.annotations.update(
                id=1,
                ground_truth=True,
                result=[
                    {
                        "from_name": "bboxes",
                        "image_rotation": 0,
                        "original_height": 1080,
                        "original_width": 1920,
                        "to_name": "image",
                        "type": "rectanglelabels",
                        "value": {
                            "height": 60,
                            "rotation": 0,
                            "values": {"rectanglelabels": ["Person"]},
                            "width": 50,
                            "x": 20,
                            "y": 30,
                        },
                    }
                ],
                was_cancelled=False,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            id,
            completed_by=completed_by,
            ground_truth=ground_truth,
            lead_time=lead_time,
            project=project,
            result=result,
            task=task,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data

    async def list(
        self, id: int, *, ordering: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Annotation]:
        """
        List all annotations for a task.

        Parameters
        ----------
        id : int
            Task ID

        ordering : typing.Optional[str]
            Which field to use when ordering the results.

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

        Returns
        -------
        typing.List[Annotation]
            Annotation

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


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


        asyncio.run(main())
        """
        _response = await self._raw_client.list(id, ordering=ordering, request_options=request_options)
        return _response.data

    async def create(
        self,
        id: int,
        *,
        completed_by: typing.Optional[int] = OMIT,
        ground_truth: typing.Optional[bool] = OMIT,
        lead_time: typing.Optional[float] = OMIT,
        project: typing.Optional[int] = OMIT,
        result: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
        task: typing.Optional[int] = OMIT,
        updated_by: typing.Optional[int] = OMIT,
        was_cancelled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Annotation:
        """

                Add annotations to a task like an annotator does. The content of the result field depends on your
                labeling configuration. For example, send the following data as part of your POST
                request to send an empty annotation with the ID of the user who completed the task:

                ```json
                {
                "result": {},
                "was_cancelled": true,
                "ground_truth": true,
                "lead_time": 0,
                "task": 0
                "completed_by": 123
                }
                ```


        Parameters
        ----------
        id : int
            Task ID

        completed_by : typing.Optional[int]
            User ID of the person who created this annotation

        ground_truth : typing.Optional[bool]
            This annotation is a Ground Truth

        lead_time : typing.Optional[float]
            How much time it took to annotate the task (in seconds)

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

        result : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
            Labeling result in JSON format. Read more about the format in [the Label Studio documentation.](https://labelstud.io/guide/task_format)

        task : typing.Optional[int]
            Corresponding task for this annotation

        updated_by : typing.Optional[int]
            Last user who updated this annotation

        was_cancelled : typing.Optional[bool]
            User skipped the task

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

        Returns
        -------
        Annotation
            Created annotation

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.annotations.create(
                id=1,
                ground_truth=True,
                result=[
                    {
                        "from_name": "bboxes",
                        "image_rotation": 0,
                        "original_height": 1080,
                        "original_width": 1920,
                        "to_name": "image",
                        "type": "rectanglelabels",
                        "value": {
                            "height": 60,
                            "rotation": 0,
                            "values": {"rectanglelabels": ["Person"]},
                            "width": 50,
                            "x": 20,
                            "y": 30,
                        },
                    }
                ],
                was_cancelled=False,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            id,
            completed_by=completed_by,
            ground_truth=ground_truth,
            lead_time=lead_time,
            project=project,
            result=result,
            task=task,
            updated_by=updated_by,
            was_cancelled=was_cancelled,
            request_options=request_options,
        )
        return _response.data
