# 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 ...core.jsonable_encoder import jsonable_encoder
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from .types.exports_list_formats_response_item import ExportsListFormatsResponseItem
from ...core.pydantic_utilities import parse_obj_as
from ...types.export import Export
from ...types.user_simple import UserSimple
import datetime as dt
from ...types.export_snapshot_status import ExportSnapshotStatus
from ...types.converted_format import ConvertedFormat
from ...types.task_filter_options import TaskFilterOptions
from ...types.annotation_filter_options import AnnotationFilterOptions
from ...types.serialization_options import SerializationOptions
from ...types.export_snapshot import ExportSnapshot
from ...core.serialization import convert_and_respect_annotation_metadata
from ...types.export_format import ExportFormat
from .types.exports_convert_response import ExportsConvertResponse
from ...core.client_wrapper import AsyncClientWrapper

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


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

    def download_sync(
        self,
        id: int,
        *,
        export_type: typing.Optional[str] = None,
        download_all_tasks: typing.Optional[bool] = None,
        download_resources: typing.Optional[bool] = None,
        ids: typing.Optional[typing.Union[int, typing.Sequence[int]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[bytes]:
        """

        <Note>If you have a large project it's recommended to use export snapshots, this easy export endpoint might have timeouts.</Note>
        Export annotated tasks as a file in a specific format.
        For example, to export JSON annotations for a project to a file called `annotations.json`,
        run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?exportType=JSON -H 'Authorization: Token abc123' --output 'annotations.json'
        ```
        To export all tasks, including skipped tasks and others without annotations, run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?exportType=JSON&download_all_tasks=true -H 'Authorization: Token abc123' --output 'annotations.json'
        ```
        To export specific tasks with IDs of 123 and 345, run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?ids[]=123\&ids[]=345 -H 'Authorization: Token abc123' --output 'annotations.json'
        ```

        You must provide a project ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_type : typing.Optional[str]
            Selected export format (JSON by default)

        download_all_tasks : typing.Optional[bool]

            If true, download all tasks regardless of status. If false, download only annotated tasks.

        download_resources : typing.Optional[bool]

            If true, download all resource files such as images, audio, and others relevant to the tasks.

        ids : typing.Optional[typing.Union[int, typing.Sequence[int]]]

            Specify a list of task IDs to retrieve only the details for those tasks.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Yields
        ------
        typing.Iterator[bytes]
            Exported data in binary format
        """
        with self._client_wrapper.httpx_client.stream(
            f"api/projects/{jsonable_encoder(id)}/export",
            method="GET",
            params={
                "export_type": export_type,
                "download_all_tasks": download_all_tasks,
                "download_resources": download_resources,
                "ids": ids,
            },
            request_options=request_options,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                    for _chunk in _response.iter_bytes(chunk_size=_chunk_size):
                        yield _chunk
                    return
                _response.read()
                _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_formats(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[ExportsListFormatsResponseItem]:
        """

        Before exporting annotations, you can check with formats are supported by the specified project. For more information about export formats, see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You must provide a project ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

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

        Returns
        -------
        typing.List[ExportsListFormatsResponseItem]
            Export formats

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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.exports.list_formats(
            id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/export/formats",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ExportsListFormatsResponseItem],
                    parse_obj_as(
                        type_=typing.List[ExportsListFormatsResponseItem],  # 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 list(self, project_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Export]:
        """

        Returns a list of export file (snapshots) for a specific project by ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

        Included in the response is information about each snapshot, such as who created it and what format it is in.

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

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

        Returns
        -------
        typing.List[Export]


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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.exports.list(
            project_id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Export],
                    parse_obj_as(
                        type_=typing.List[Export],  # 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,
        project_id: int,
        *,
        title: typing.Optional[str] = OMIT,
        id: typing.Optional[int] = OMIT,
        created_by: typing.Optional[UserSimple] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        finished_at: typing.Optional[dt.datetime] = OMIT,
        status: typing.Optional[ExportSnapshotStatus] = OMIT,
        md5: typing.Optional[str] = OMIT,
        counters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        converted_formats: typing.Optional[typing.Sequence[ConvertedFormat]] = OMIT,
        task_filter_options: typing.Optional[TaskFilterOptions] = OMIT,
        annotation_filter_options: typing.Optional[AnnotationFilterOptions] = OMIT,
        serialization_options: typing.Optional[SerializationOptions] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ExportSnapshot:
        """

        Create a new export request to start a background task and generate an export file (snapshot) for a specific project by ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

        A snapshot is a static export of your project's data and annotations at a specific point in time. It captures the current state of your tasks, annotations, and other relevant data, allowing you to download and review them later. Snapshots are particularly useful for large projects as they help avoid timeouts during export operations by processing the data asynchronously.

        For more information, see the [Label Studio documentation on exporting annotations](https://labelstud.io/guide/export.html).

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

        title : typing.Optional[str]

        id : typing.Optional[int]

        created_by : typing.Optional[UserSimple]

        created_at : typing.Optional[dt.datetime]
            Creation time

        finished_at : typing.Optional[dt.datetime]
            Complete or fail time

        status : typing.Optional[ExportSnapshotStatus]

        md5 : typing.Optional[str]

        counters : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        converted_formats : typing.Optional[typing.Sequence[ConvertedFormat]]

        task_filter_options : typing.Optional[TaskFilterOptions]

        annotation_filter_options : typing.Optional[AnnotationFilterOptions]

        serialization_options : typing.Optional[SerializationOptions]

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

        Returns
        -------
        ExportSnapshot


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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.exports.create(
            project_id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports",
            method="POST",
            json={
                "title": title,
                "id": id,
                "created_by": convert_and_respect_annotation_metadata(
                    object_=created_by, annotation=UserSimple, direction="write"
                ),
                "created_at": created_at,
                "finished_at": finished_at,
                "status": status,
                "md5": md5,
                "counters": counters,
                "converted_formats": convert_and_respect_annotation_metadata(
                    object_=converted_formats, annotation=typing.Sequence[ConvertedFormat], direction="write"
                ),
                "task_filter_options": convert_and_respect_annotation_metadata(
                    object_=task_filter_options, annotation=TaskFilterOptions, direction="write"
                ),
                "annotation_filter_options": convert_and_respect_annotation_metadata(
                    object_=annotation_filter_options, annotation=AnnotationFilterOptions, direction="write"
                ),
                "serialization_options": convert_and_respect_annotation_metadata(
                    object_=serialization_options, annotation=SerializationOptions, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ExportSnapshot,
                    parse_obj_as(
                        type_=ExportSnapshot,  # 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 download(
        self,
        project_id: int,
        export_pk: str,
        *,
        export_type: typing.Optional[ExportFormat] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[bytes]:
        """

        Download an export snapshot as a file in a specified format. To see what formats are supported, you can use [Get export formats](list-formats) or see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You will need to provide the project ID and export ID (`export_pk`). The export ID is returned when you create the export or you can use [List all export snapshots](list).

        The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

        export_type : typing.Optional[ExportFormat]
            Selected export format. JSON is available by default. For other formats, you need to convert the export first.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Yields
        ------
        typing.Iterator[bytes]
            Exported data in binary format
        """
        with self._client_wrapper.httpx_client.stream(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}/download",
            method="GET",
            params={
                "exportType": export_type,
            },
            request_options=request_options,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                    for _chunk in _response.iter_bytes(chunk_size=_chunk_size):
                        yield _chunk
                    return
                _response.read()
                _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, project_id: int, export_pk: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> Export:
        """

        Retrieve information about a specific export file (snapshot).

        You will need the export ID. You can find this in the response when you [create the snapshot via the API](create) or using [List all export snapshots](list).

        You will also need the project ID. This can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

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

        Returns
        -------
        Export


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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.exports.get(
            project_id=1,
            export_pk="export_pk",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Export,
                    parse_obj_as(
                        type_=Export,  # 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, project_id: int, export_pk: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """

        Delete an export file by specified export ID.

        You will need the export ID. You can find this in the response when you [create the snapshot via the API](create) or using [List all export snapshots](list).

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

        export_pk : str
            Primary key identifying the export file.

        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.projects.exports.delete(
            project_id=1,
            export_pk="export_pk",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}",
            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 convert(
        self,
        project_id: int,
        export_pk: str,
        *,
        export_type: typing.Optional[ExportFormat] = OMIT,
        download_resources: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ExportsConvertResponse:
        """

        You can use this to convert an export snapshot into the selected format.

        To see what formats are supported, you can use [Get export formats](list-formats) or see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You will need to provide the project ID and export ID (`export_pk`). The export ID is returned when you create the export or you can use [List all export snapshots](list).

        The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

        export_type : typing.Optional[ExportFormat]

        download_resources : typing.Optional[bool]
            If true, download all resource files such as images, audio, and others relevant to the tasks.

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

        Returns
        -------
        ExportsConvertResponse


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

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.exports.convert(
            project_id=1,
            export_pk="export_pk",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}/convert",
            method="POST",
            json={
                "export_type": export_type,
                "download_resources": download_resources,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ExportsConvertResponse,
                    parse_obj_as(
                        type_=ExportsConvertResponse,  # 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 AsyncExportsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def download_sync(
        self,
        id: int,
        *,
        export_type: typing.Optional[str] = None,
        download_all_tasks: typing.Optional[bool] = None,
        download_resources: typing.Optional[bool] = None,
        ids: typing.Optional[typing.Union[int, typing.Sequence[int]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[bytes]:
        """

        <Note>If you have a large project it's recommended to use export snapshots, this easy export endpoint might have timeouts.</Note>
        Export annotated tasks as a file in a specific format.
        For example, to export JSON annotations for a project to a file called `annotations.json`,
        run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?exportType=JSON -H 'Authorization: Token abc123' --output 'annotations.json'
        ```
        To export all tasks, including skipped tasks and others without annotations, run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?exportType=JSON&download_all_tasks=true -H 'Authorization: Token abc123' --output 'annotations.json'
        ```
        To export specific tasks with IDs of 123 and 345, run the following from the command line:
        ```bash
        curl -X GET https://localhost:8080/api/projects/{id}/export?ids[]=123\&ids[]=345 -H 'Authorization: Token abc123' --output 'annotations.json'
        ```

        You must provide a project ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_type : typing.Optional[str]
            Selected export format (JSON by default)

        download_all_tasks : typing.Optional[bool]

            If true, download all tasks regardless of status. If false, download only annotated tasks.

        download_resources : typing.Optional[bool]

            If true, download all resource files such as images, audio, and others relevant to the tasks.

        ids : typing.Optional[typing.Union[int, typing.Sequence[int]]]

            Specify a list of task IDs to retrieve only the details for those tasks.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Yields
        ------
        typing.AsyncIterator[bytes]
            Exported data in binary format
        """
        async with self._client_wrapper.httpx_client.stream(
            f"api/projects/{jsonable_encoder(id)}/export",
            method="GET",
            params={
                "export_type": export_type,
                "download_all_tasks": download_all_tasks,
                "download_resources": download_resources,
                "ids": ids,
            },
            request_options=request_options,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                    async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size):
                        yield _chunk
                    return
                await _response.aread()
                _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_formats(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[ExportsListFormatsResponseItem]:
        """

        Before exporting annotations, you can check with formats are supported by the specified project. For more information about export formats, see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You must provide a project ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

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

        Returns
        -------
        typing.List[ExportsListFormatsResponseItem]
            Export formats

        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.exports.list_formats(
                id=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/export/formats",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ExportsListFormatsResponseItem],
                    parse_obj_as(
                        type_=typing.List[ExportsListFormatsResponseItem],  # 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 list(
        self, project_id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Export]:
        """

        Returns a list of export file (snapshots) for a specific project by ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

        Included in the response is information about each snapshot, such as who created it and what format it is in.

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

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

        Returns
        -------
        typing.List[Export]


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.exports.list(
                project_id=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Export],
                    parse_obj_as(
                        type_=typing.List[Export],  # 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,
        project_id: int,
        *,
        title: typing.Optional[str] = OMIT,
        id: typing.Optional[int] = OMIT,
        created_by: typing.Optional[UserSimple] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        finished_at: typing.Optional[dt.datetime] = OMIT,
        status: typing.Optional[ExportSnapshotStatus] = OMIT,
        md5: typing.Optional[str] = OMIT,
        counters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        converted_formats: typing.Optional[typing.Sequence[ConvertedFormat]] = OMIT,
        task_filter_options: typing.Optional[TaskFilterOptions] = OMIT,
        annotation_filter_options: typing.Optional[AnnotationFilterOptions] = OMIT,
        serialization_options: typing.Optional[SerializationOptions] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ExportSnapshot:
        """

        Create a new export request to start a background task and generate an export file (snapshot) for a specific project by ID. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

        A snapshot is a static export of your project's data and annotations at a specific point in time. It captures the current state of your tasks, annotations, and other relevant data, allowing you to download and review them later. Snapshots are particularly useful for large projects as they help avoid timeouts during export operations by processing the data asynchronously.

        For more information, see the [Label Studio documentation on exporting annotations](https://labelstud.io/guide/export.html).

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

        title : typing.Optional[str]

        id : typing.Optional[int]

        created_by : typing.Optional[UserSimple]

        created_at : typing.Optional[dt.datetime]
            Creation time

        finished_at : typing.Optional[dt.datetime]
            Complete or fail time

        status : typing.Optional[ExportSnapshotStatus]

        md5 : typing.Optional[str]

        counters : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        converted_formats : typing.Optional[typing.Sequence[ConvertedFormat]]

        task_filter_options : typing.Optional[TaskFilterOptions]

        annotation_filter_options : typing.Optional[AnnotationFilterOptions]

        serialization_options : typing.Optional[SerializationOptions]

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

        Returns
        -------
        ExportSnapshot


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.exports.create(
                project_id=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports",
            method="POST",
            json={
                "title": title,
                "id": id,
                "created_by": convert_and_respect_annotation_metadata(
                    object_=created_by, annotation=UserSimple, direction="write"
                ),
                "created_at": created_at,
                "finished_at": finished_at,
                "status": status,
                "md5": md5,
                "counters": counters,
                "converted_formats": convert_and_respect_annotation_metadata(
                    object_=converted_formats, annotation=typing.Sequence[ConvertedFormat], direction="write"
                ),
                "task_filter_options": convert_and_respect_annotation_metadata(
                    object_=task_filter_options, annotation=TaskFilterOptions, direction="write"
                ),
                "annotation_filter_options": convert_and_respect_annotation_metadata(
                    object_=annotation_filter_options, annotation=AnnotationFilterOptions, direction="write"
                ),
                "serialization_options": convert_and_respect_annotation_metadata(
                    object_=serialization_options, annotation=SerializationOptions, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ExportSnapshot,
                    parse_obj_as(
                        type_=ExportSnapshot,  # 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 download(
        self,
        project_id: int,
        export_pk: str,
        *,
        export_type: typing.Optional[ExportFormat] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[bytes]:
        """

        Download an export snapshot as a file in a specified format. To see what formats are supported, you can use [Get export formats](list-formats) or see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You will need to provide the project ID and export ID (`export_pk`). The export ID is returned when you create the export or you can use [List all export snapshots](list).

        The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

        export_type : typing.Optional[ExportFormat]
            Selected export format. JSON is available by default. For other formats, you need to convert the export first.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Yields
        ------
        typing.AsyncIterator[bytes]
            Exported data in binary format
        """
        async with self._client_wrapper.httpx_client.stream(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}/download",
            method="GET",
            params={
                "exportType": export_type,
            },
            request_options=request_options,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                    async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size):
                        yield _chunk
                    return
                await _response.aread()
                _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, project_id: int, export_pk: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> Export:
        """

        Retrieve information about a specific export file (snapshot).

        You will need the export ID. You can find this in the response when you [create the snapshot via the API](create) or using [List all export snapshots](list).

        You will also need the project ID. This can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

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

        Returns
        -------
        Export


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.exports.get(
                project_id=1,
                export_pk="export_pk",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    Export,
                    parse_obj_as(
                        type_=Export,  # 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, project_id: int, export_pk: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """

        Delete an export file by specified export ID.

        You will need the export ID. You can find this in the response when you [create the snapshot via the API](create) or using [List all export snapshots](list).

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

        export_pk : str
            Primary key identifying the export file.

        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.projects.exports.delete(
                project_id=1,
                export_pk="export_pk",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}",
            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 convert(
        self,
        project_id: int,
        export_pk: str,
        *,
        export_type: typing.Optional[ExportFormat] = OMIT,
        download_resources: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ExportsConvertResponse:
        """

        You can use this to convert an export snapshot into the selected format.

        To see what formats are supported, you can use [Get export formats](list-formats) or see [Export formats supported by Label Studio](https://labelstud.io/guide/export#Export-formats-supported-by-Label-Studio).

        You will need to provide the project ID and export ID (`export_pk`). The export ID is returned when you create the export or you can use [List all export snapshots](list).

        The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using [List all projects](../list).

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

        export_pk : str
            Primary key identifying the export file.

        export_type : typing.Optional[ExportFormat]

        download_resources : typing.Optional[bool]
            If true, download all resource files such as images, audio, and others relevant to the tasks.

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

        Returns
        -------
        ExportsConvertResponse


        Examples
        --------
        import asyncio

        from label_studio_sdk import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.projects.exports.convert(
                project_id=1,
                export_pk="export_pk",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(project_id)}/exports/{jsonable_encoder(export_pk)}/convert",
            method="POST",
            json={
                "export_type": export_type,
                "download_resources": download_resources,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ExportsConvertResponse,
                    parse_obj_as(
                        type_=ExportsConvertResponse,  # 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)
