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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pagination import AsyncPager, SyncPager
from ..core.pydantic_utilities import pydantic_v1
from ..core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
from ..types.project import Project
from ..types.project_label_config import ProjectLabelConfig
from .exports.client import AsyncExportsClient, ExportsClient
from .types.projects_create_response import ProjectsCreateResponse
from .types.projects_import_tasks_response import ProjectsImportTasksResponse
from .types.projects_list_response import ProjectsListResponse

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


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

    def list(
        self,
        *,
        ordering: typing.Optional[str] = None,
        ids: typing.Optional[str] = None,
        title: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Project]:
        """
        Return a list of the projects within your organization.

        To perform most tasks with the Label Studio API, you must specify the project ID, sometimes referred to as the `pk`. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using this API call.

        To retrieve a list of your Label Studio projects, update the following command to match your own environment.
        Replace the domain name, port, and authorization token, then run the following from the command line:

        ```bash
        curl -X GET https://localhost:8080/api/projects/ -H 'Authorization: Token abc123'
        ```

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

        ids : typing.Optional[str]
            ids

        title : typing.Optional[str]
            title

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

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

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

        Returns
        -------
        SyncPager[Project]


        Examples
        --------
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.list()
        """
        page = page or 1
        _response = self._client_wrapper.httpx_client.request(
            "api/projects/",
            method="GET",
            params={"ordering": ordering, "ids": ids, "title": title, "page": page, "page_size": page_size},
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            _parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json())  # type: ignore
            _has_next = True
            _get_next = lambda: self.list(
                ordering=ordering,
                ids=ids,
                title=title,
                page=page + 1,
                page_size=page_size,
                request_options=request_options,
            )
            _items = _parsed_response.results
            return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
        try:
            _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,
        *,
        title: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        label_config: typing.Optional[str] = OMIT,
        expert_instruction: typing.Optional[str] = OMIT,
        show_instruction: typing.Optional[bool] = OMIT,
        show_skip_button: typing.Optional[bool] = OMIT,
        enable_empty_annotation: typing.Optional[bool] = OMIT,
        show_annotation_history: typing.Optional[bool] = OMIT,
        reveal_preannotations_interactively: typing.Optional[bool] = OMIT,
        show_collab_predictions: typing.Optional[bool] = OMIT,
        maximum_annotations: typing.Optional[int] = OMIT,
        color: typing.Optional[str] = OMIT,
        control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectsCreateResponse:
        """
        Create a project and set up the labeling interface. For more information about setting up projects, see the following:

        - [Create and configure projects](https://labelstud.io/guide/setup_project)
        - [Configure labeling interface](https://labelstud.io/guide/setup)
        - [Project settings](https://labelstud.io/guide/project_settings)

        ```bash
        curl -H Content-Type:application/json -H 'Authorization: Token abc123' -X POST 'https://localhost:8080/api/projects'     --data '{"label_config": "<View>[...]</View>"}'
        ```

        Parameters
        ----------
        title : typing.Optional[str]
            Project title

        description : typing.Optional[str]
            Project description

        label_config : typing.Optional[str]
            Label config in XML format

        expert_instruction : typing.Optional[str]
            Labeling instructions to show to the user

        show_instruction : typing.Optional[bool]
            Show labeling instructions

        show_skip_button : typing.Optional[bool]
            Show skip button

        enable_empty_annotation : typing.Optional[bool]
            Allow empty annotations

        show_annotation_history : typing.Optional[bool]
            Show annotation history

        reveal_preannotations_interactively : typing.Optional[bool]
            Reveal preannotations interactively. If set to True, predictions will be shown to the user only after selecting the area of interest

        show_collab_predictions : typing.Optional[bool]
            Show predictions to annotators

        maximum_annotations : typing.Optional[int]
            Maximum annotations per task

        color : typing.Optional[str]
            Project color in HEX format

        control_weights : typing.Optional[typing.Dict[str, typing.Any]]
            Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}

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

        Returns
        -------
        ProjectsCreateResponse


        Examples
        --------
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.create()
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/projects/",
            method="POST",
            json={
                "title": title,
                "description": description,
                "label_config": label_config,
                "expert_instruction": expert_instruction,
                "show_instruction": show_instruction,
                "show_skip_button": show_skip_button,
                "enable_empty_annotation": enable_empty_annotation,
                "show_annotation_history": show_annotation_history,
                "reveal_preannotations_interactively": reveal_preannotations_interactively,
                "show_collab_predictions": show_collab_predictions,
                "maximum_annotations": maximum_annotations,
                "color": color,
                "control_weights": control_weights,
            },
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json())  # type: ignore
        try:
            _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: int, *, request_options: typing.Optional[RequestOptions] = None) -> Project:
        """
        Retrieve information about a specific project by 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
        -------
        Project
            Project information

        Examples
        --------
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.get(
            id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/", method="GET", request_options=request_options
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Project, _response.json())  # type: ignore
        try:
            _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: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete a project by specified project ID. Deleting a project permanently removes all tasks, annotations, and project data from Label Studio.

        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
        -------
        None

        Examples
        --------
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.delete(
            id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/", method="DELETE", request_options=request_options
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _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: int, *, request: Project, request_options: typing.Optional[RequestOptions] = None) -> Project:
        """
        Update the project settings for a specific project. For more information, see the following:

        - [Create and configure projects](https://labelstud.io/guide/setup_project)
        - [Configure labeling interface](https://labelstud.io/guide/setup)
        - [Project settings](https://labelstud.io/guide/project_settings)

        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).

        <Warning>
        If you are modifying the labeling config for project that has in-progress work, note the following:
        * You cannot remove labels or change the type of labeling being performed unless you delete any existing annotations that are using those labels.
        * If you make changes to the labeling configuration, any tabs that you might have created in the Data Manager are removed.
        </Warning>

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

        request : Project

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

        Returns
        -------
        Project


        Examples
        --------
        from label_studio_sdk import Project
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.update(
            id=1,
            request=Project(),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Project, _response.json())  # type: ignore
        try:
            _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 import_tasks(
        self,
        id: int,
        *,
        request: typing.Sequence[typing.Dict[str, typing.Any]],
        commit_to_project: typing.Optional[bool] = None,
        return_task_ids: typing.Optional[bool] = None,
        preannotated_from_fields: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectsImportTasksResponse:
        """
        Use this API endpoint to import labeling tasks in bulk. Note that each POST request is limited at 250K tasks and 200 MB.
        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](../projects/list).
        
        <Note>
        Imported data is verified against a project *label_config* and must include all variables that were used in the *label_config*.
        
        For example, if the label configuration has a _$text_ variable, then each item in a data object must include a `text` field.
        </Note>
        
        There are three possible ways to import tasks with this endpoint:
        
        #### 1\. **POST with data**
        
        Send JSON tasks as POST data. Only JSON is supported for POSTing files directly.
        
        Update this example to specify your authorization token and Label Studio instance host, then run the following from
        the command line:
        
        ```bash
        curl -H 'Content-Type: application/json' -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' --data '[{"text": "Some text 1"}, {"text": "Some text 2"}]'
        ```
        
        #### 2\. **POST with files**
        
        Send tasks as files. You can attach multiple files with different names.
        
        - **JSON**: text files in JavaScript object notation format
        - **CSV**: text files with tables in Comma Separated Values format
        - **TSV**: text files with tables in Tab Separated Value format
        - **TXT**: simple text files are similar to CSV with one column and no header, supported for projects with one source only
        
        Update this example to specify your authorization token, Label Studio instance host, and file name and path,
        then run the following from the command line:
        
        ```bash
        curl -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' -F ‘file=@path/to/my_file.csv’
        ```
        
        #### 3\. **POST with URL**
        
        You can also provide a URL to a file with labeling tasks. Supported file formats are the same as in option 2.
        
        ```bash
        curl -H 'Content-Type: application/json' -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' \
        --data '[{"url": "http://example.com/test1.csv"}, {"url": "http://example.com/test2.csv"}]'
        ```
        
        <br>
        
        Parameters
        ----------
        id : int
            A unique integer value identifying this project.
        
        request : typing.Sequence[typing.Dict[str, typing.Any]]
        
        commit_to_project : typing.Optional[bool]
            Set to "true" to immediately commit tasks to the project.
        
        return_task_ids : typing.Optional[bool]
            Set to "true" to return task IDs in the response.
        
        preannotated_from_fields : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            List of fields to preannotate from the task data. For example, if you provide a list of `{"text": "text", "prediction": "label"}` items in the request, the system will create a task with the `text` field and a prediction with the `label` field when `preannoted_from_fields=["prediction"]`.
        
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.
        
        Returns
        -------
        ProjectsImportTasksResponse
            Tasks successfully imported
        
        Examples
        --------
        from label_studio_sdk.client import LabelStudio
        
        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.import_tasks(
            id=1,
            request=[{}],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/import",
            method="POST",
            params={
                "commit_to_project": commit_to_project,
                "return_task_ids": return_task_ids,
                "preannotated_from_fields": preannotated_from_fields,
            },
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic_v1.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _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 validate_config(
        self, id: int, *, request: ProjectLabelConfig, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectLabelConfig:
        """
        Determine whether the label configuration for a specific project is valid. For more information about setting up labeling configs, see [Configure labeling interface](https://labelstud.io/guide/setup) and our [Tags reference](https://labelstud.io/tags/).

        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 : ProjectLabelConfig

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

        Returns
        -------
        ProjectLabelConfig


        Examples
        --------
        from label_studio_sdk import ProjectLabelConfig
        from label_studio_sdk.client import LabelStudio

        client = LabelStudio(
            api_key="YOUR_API_KEY",
        )
        client.projects.validate_config(
            id=1,
            request=ProjectLabelConfig(
                label_config="label_config",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/validate/",
            method="POST",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json())  # type: ignore
        try:
            _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 AsyncProjectsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper
        self.exports = AsyncExportsClient(client_wrapper=self._client_wrapper)

    async def list(
        self,
        *,
        ordering: typing.Optional[str] = None,
        ids: typing.Optional[str] = None,
        title: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Project]:
        """
        Return a list of the projects within your organization.

        To perform most tasks with the Label Studio API, you must specify the project ID, sometimes referred to as the `pk`. The project ID can be found in the URL when viewing the project in Label Studio, or you can retrieve all project IDs using this API call.

        To retrieve a list of your Label Studio projects, update the following command to match your own environment.
        Replace the domain name, port, and authorization token, then run the following from the command line:

        ```bash
        curl -X GET https://localhost:8080/api/projects/ -H 'Authorization: Token abc123'
        ```

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

        ids : typing.Optional[str]
            ids

        title : typing.Optional[str]
            title

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

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

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

        Returns
        -------
        AsyncPager[Project]


        Examples
        --------
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.list()
        """
        page = page or 1
        _response = await self._client_wrapper.httpx_client.request(
            "api/projects/",
            method="GET",
            params={"ordering": ordering, "ids": ids, "title": title, "page": page, "page_size": page_size},
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            _parsed_response = pydantic_v1.parse_obj_as(ProjectsListResponse, _response.json())  # type: ignore
            _has_next = True
            _get_next = lambda: self.list(
                ordering=ordering,
                ids=ids,
                title=title,
                page=page + 1,
                page_size=page_size,
                request_options=request_options,
            )
            _items = _parsed_response.results
            return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
        try:
            _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,
        *,
        title: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        label_config: typing.Optional[str] = OMIT,
        expert_instruction: typing.Optional[str] = OMIT,
        show_instruction: typing.Optional[bool] = OMIT,
        show_skip_button: typing.Optional[bool] = OMIT,
        enable_empty_annotation: typing.Optional[bool] = OMIT,
        show_annotation_history: typing.Optional[bool] = OMIT,
        reveal_preannotations_interactively: typing.Optional[bool] = OMIT,
        show_collab_predictions: typing.Optional[bool] = OMIT,
        maximum_annotations: typing.Optional[int] = OMIT,
        color: typing.Optional[str] = OMIT,
        control_weights: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectsCreateResponse:
        """
        Create a project and set up the labeling interface. For more information about setting up projects, see the following:

        - [Create and configure projects](https://labelstud.io/guide/setup_project)
        - [Configure labeling interface](https://labelstud.io/guide/setup)
        - [Project settings](https://labelstud.io/guide/project_settings)

        ```bash
        curl -H Content-Type:application/json -H 'Authorization: Token abc123' -X POST 'https://localhost:8080/api/projects'     --data '{"label_config": "<View>[...]</View>"}'
        ```

        Parameters
        ----------
        title : typing.Optional[str]
            Project title

        description : typing.Optional[str]
            Project description

        label_config : typing.Optional[str]
            Label config in XML format

        expert_instruction : typing.Optional[str]
            Labeling instructions to show to the user

        show_instruction : typing.Optional[bool]
            Show labeling instructions

        show_skip_button : typing.Optional[bool]
            Show skip button

        enable_empty_annotation : typing.Optional[bool]
            Allow empty annotations

        show_annotation_history : typing.Optional[bool]
            Show annotation history

        reveal_preannotations_interactively : typing.Optional[bool]
            Reveal preannotations interactively. If set to True, predictions will be shown to the user only after selecting the area of interest

        show_collab_predictions : typing.Optional[bool]
            Show predictions to annotators

        maximum_annotations : typing.Optional[int]
            Maximum annotations per task

        color : typing.Optional[str]
            Project color in HEX format

        control_weights : typing.Optional[typing.Dict[str, typing.Any]]
            Dict of weights for each control tag in metric calculation. Each control tag (e.g. label or choice) will have its own key in control weight dict with weight for each label and overall weight. For example, if a bounding box annotation with a control tag named my_bbox should be included with 0.33 weight in agreement calculation, and the first label Car should be twice as important as Airplane, then you need to specify: {'my_bbox': {'type': 'RectangleLabels', 'labels': {'Car': 1.0, 'Airplane': 0.5}, 'overall': 0.33}

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

        Returns
        -------
        ProjectsCreateResponse


        Examples
        --------
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.create()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/projects/",
            method="POST",
            json={
                "title": title,
                "description": description,
                "label_config": label_config,
                "expert_instruction": expert_instruction,
                "show_instruction": show_instruction,
                "show_skip_button": show_skip_button,
                "enable_empty_annotation": enable_empty_annotation,
                "show_annotation_history": show_annotation_history,
                "reveal_preannotations_interactively": reveal_preannotations_interactively,
                "show_collab_predictions": show_collab_predictions,
                "maximum_annotations": maximum_annotations,
                "color": color,
                "control_weights": control_weights,
            },
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectsCreateResponse, _response.json())  # type: ignore
        try:
            _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: int, *, request_options: typing.Optional[RequestOptions] = None) -> Project:
        """
        Retrieve information about a specific project by 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
        -------
        Project
            Project information

        Examples
        --------
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.get(
            id=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/", method="GET", request_options=request_options
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Project, _response.json())  # type: ignore
        try:
            _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: int, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete a project by specified project ID. Deleting a project permanently removes all tasks, annotations, and project data from Label Studio.

        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
        -------
        None

        Examples
        --------
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.delete(
            id=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/", method="DELETE", request_options=request_options
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _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: int, *, request: Project, request_options: typing.Optional[RequestOptions] = None
    ) -> Project:
        """
        Update the project settings for a specific project. For more information, see the following:

        - [Create and configure projects](https://labelstud.io/guide/setup_project)
        - [Configure labeling interface](https://labelstud.io/guide/setup)
        - [Project settings](https://labelstud.io/guide/project_settings)

        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).

        <Warning>
        If you are modifying the labeling config for project that has in-progress work, note the following:
        * You cannot remove labels or change the type of labeling being performed unless you delete any existing annotations that are using those labels.
        * If you make changes to the labeling configuration, any tabs that you might have created in the Data Manager are removed.
        </Warning>

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

        request : Project

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

        Returns
        -------
        Project


        Examples
        --------
        from label_studio_sdk import Project
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.update(
            id=1,
            request=Project(),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/",
            method="PATCH",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Project, _response.json())  # type: ignore
        try:
            _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 import_tasks(
        self,
        id: int,
        *,
        request: typing.Sequence[typing.Dict[str, typing.Any]],
        commit_to_project: typing.Optional[bool] = None,
        return_task_ids: typing.Optional[bool] = None,
        preannotated_from_fields: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectsImportTasksResponse:
        """
        Use this API endpoint to import labeling tasks in bulk. Note that each POST request is limited at 250K tasks and 200 MB.
        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](../projects/list).
        
        <Note>
        Imported data is verified against a project *label_config* and must include all variables that were used in the *label_config*.
        
        For example, if the label configuration has a _$text_ variable, then each item in a data object must include a `text` field.
        </Note>
        
        There are three possible ways to import tasks with this endpoint:
        
        #### 1\. **POST with data**
        
        Send JSON tasks as POST data. Only JSON is supported for POSTing files directly.
        
        Update this example to specify your authorization token and Label Studio instance host, then run the following from
        the command line:
        
        ```bash
        curl -H 'Content-Type: application/json' -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' --data '[{"text": "Some text 1"}, {"text": "Some text 2"}]'
        ```
        
        #### 2\. **POST with files**
        
        Send tasks as files. You can attach multiple files with different names.
        
        - **JSON**: text files in JavaScript object notation format
        - **CSV**: text files with tables in Comma Separated Values format
        - **TSV**: text files with tables in Tab Separated Value format
        - **TXT**: simple text files are similar to CSV with one column and no header, supported for projects with one source only
        
        Update this example to specify your authorization token, Label Studio instance host, and file name and path,
        then run the following from the command line:
        
        ```bash
        curl -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' -F ‘file=@path/to/my_file.csv’
        ```
        
        #### 3\. **POST with URL**
        
        You can also provide a URL to a file with labeling tasks. Supported file formats are the same as in option 2.
        
        ```bash
        curl -H 'Content-Type: application/json' -H 'Authorization: Token abc123' \
        -X POST 'https://localhost:8080/api/projects/1/import' \
        --data '[{"url": "http://example.com/test1.csv"}, {"url": "http://example.com/test2.csv"}]'
        ```
        
        <br>
        
        Parameters
        ----------
        id : int
            A unique integer value identifying this project.
        
        request : typing.Sequence[typing.Dict[str, typing.Any]]
        
        commit_to_project : typing.Optional[bool]
            Set to "true" to immediately commit tasks to the project.
        
        return_task_ids : typing.Optional[bool]
            Set to "true" to return task IDs in the response.
        
        preannotated_from_fields : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            List of fields to preannotate from the task data. For example, if you provide a list of `{"text": "text", "prediction": "label"}` items in the request, the system will create a task with the `text` field and a prediction with the `label` field when `preannoted_from_fields=["prediction"]`.
        
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.
        
        Returns
        -------
        ProjectsImportTasksResponse
            Tasks successfully imported
        
        Examples
        --------
        from label_studio_sdk.client import AsyncLabelStudio
        
        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.import_tasks(
            id=1,
            request=[{}],
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/import",
            method="POST",
            params={
                "commit_to_project": commit_to_project,
                "return_task_ids": return_task_ids,
                "preannotated_from_fields": preannotated_from_fields,
            },
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectsImportTasksResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic_v1.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _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 validate_config(
        self, id: int, *, request: ProjectLabelConfig, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectLabelConfig:
        """
        Determine whether the label configuration for a specific project is valid. For more information about setting up labeling configs, see [Configure labeling interface](https://labelstud.io/guide/setup) and our [Tags reference](https://labelstud.io/tags/).

        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 : ProjectLabelConfig

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

        Returns
        -------
        ProjectLabelConfig


        Examples
        --------
        from label_studio_sdk import ProjectLabelConfig
        from label_studio_sdk.client import AsyncLabelStudio

        client = AsyncLabelStudio(
            api_key="YOUR_API_KEY",
        )
        await client.projects.validate_config(
            id=1,
            request=ProjectLabelConfig(
                label_config="label_config",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/projects/{jsonable_encoder(id)}/validate/",
            method="POST",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ProjectLabelConfig, _response.json())  # type: ignore
        try:
            _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)
