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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pagination import AsyncPager, SyncPager
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.data_directory import DataDirectory
from ..types.data_directory_manifest import DataDirectoryManifest
from ..types.empty_response import EmptyResponse
from ..types.file_info import FileInfo
from ..types.get_data_directory_response import GetDataDirectoryResponse
from ..types.get_signed_ur_ls_response import GetSignedUrLsResponse
from ..types.list_data_directories_response import ListDataDirectoriesResponse
from ..types.list_files_response import ListFilesResponse
from ..types.multi_part_upload_response import MultiPartUploadResponse
from ..types.operation import Operation

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


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

    def get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetDataDirectoryResponse]:
        """
        Get a data directory by its ID.

        Args:
            id (str): The ID of the data directory to retrieve
            user_info: Current authenticated user info

        Returns:
            DataDirectoryResponse: Response containing the retrieved data directory

        Parameters
        ----------
        id : str

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

        Returns
        -------
        HttpResponse[GetDataDirectoryResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/ml/v1/data-directories/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetDataDirectoryResponse,
                    parse_obj_as(
                        type_=GetDataDirectoryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete(
        self,
        id: str,
        *,
        delete_contents: typing.Optional[bool] = False,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EmptyResponse]:
        """
        Delete a data directory and optionally its contents.

        Args:
            id: Unique identifier of the data directory to delete
            delete_contents: If True, also deletes the data directory's contents
            user_info: Authenticated user information

        Returns:
            EmptyResponse: Empty response indicating successful deletion

        Parameters
        ----------
        id : str

        delete_contents : typing.Optional[bool]

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

        Returns
        -------
        HttpResponse[EmptyResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/ml/v1/data-directories/{jsonable_encoder(id)}",
            method="DELETE",
            params={
                "delete_contents": delete_contents,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmptyResponse,
                    parse_obj_as(
                        type_=EmptyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list(
        self,
        *,
        fqn: typing.Optional[str] = None,
        ml_repo_id: typing.Optional[str] = None,
        name: typing.Optional[str] = None,
        limit: typing.Optional[int] = 100,
        offset: typing.Optional[int] = 0,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[DataDirectory, ListDataDirectoriesResponse]:
        """
        List all data directories with optional filtering and pagination.

        Args:
            filters: Query parameters for filtering and pagination
                - ml_repo_id: Filter data directories by ml repo ID
                - name: Optional filter data directories by name
                - limit: Optional maximum number of data directories to return
                - offset: Optional number of data directories to skip
            user_info: Authenticated user information

        Returns:
            ListDataDirectoriesResponse: List of data directories and pagination info

        Parameters
        ----------
        fqn : typing.Optional[str]

        ml_repo_id : typing.Optional[str]

        name : typing.Optional[str]

        limit : typing.Optional[int]

        offset : typing.Optional[int]

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

        Returns
        -------
        SyncPager[DataDirectory, ListDataDirectoriesResponse]
            Successful Response
        """
        offset = offset if offset is not None else 0

        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories",
            method="GET",
            params={
                "fqn": fqn,
                "ml_repo_id": ml_repo_id,
                "name": name,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListDataDirectoriesResponse,
                    parse_obj_as(
                        type_=ListDataDirectoriesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True
                _get_next = lambda: self.list(
                    fqn=fqn,
                    ml_repo_id=ml_repo_id,
                    name=name,
                    limit=limit,
                    offset=offset + len(_items),
                    request_options=request_options,
                )
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_or_update(
        self, *, manifest: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetDataDirectoryResponse]:
        """
        Parameters
        ----------
        manifest : DataDirectoryManifest

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

        Returns
        -------
        HttpResponse[GetDataDirectoryResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories",
            method="PUT",
            json={
                "manifest": convert_and_respect_annotation_metadata(
                    object_=manifest, annotation=DataDirectoryManifest, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetDataDirectoryResponse,
                    parse_obj_as(
                        type_=GetDataDirectoryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_files(
        self,
        *,
        id: str,
        path: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        page_token: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[FileInfo, ListFilesResponse]:
        """
        List files in a dataset.

        Args:
            request_dto: Request containing dataset ID, path, page token and limit
            user_info: Authenticated user information

        Returns:
            ListFilesResponse: Response containing files and pagination info

        Parameters
        ----------
        id : str

        path : typing.Optional[str]

        limit : typing.Optional[int]

        page_token : typing.Optional[str]

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

        Returns
        -------
        SyncPager[FileInfo, ListFilesResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/files",
            method="POST",
            json={
                "id": id,
                "path": path,
                "limit": limit,
                "pageToken": page_token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListFilesResponse,
                    parse_obj_as(
                        type_=ListFilesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = False
                _get_next = None
                if _parsed_response.pagination is not None:
                    _parsed_next = _parsed_response.pagination.next_page_token
                    _has_next = _parsed_next is not None and _parsed_next != ""
                    _get_next = lambda: self.list_files(
                        id=id,
                        path=path,
                        limit=limit,
                        page_token=_parsed_next,
                        request_options=request_options,
                    )
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_files(
        self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[EmptyResponse]:
        """
        Delete files from the dataset.

        Args:
            request_dto: Request containing dataset ID and paths
            user_info: Authenticated user information

        Returns:
            EmptyResponse: Empty response indicating successful deletion

        Parameters
        ----------
        id : str

        paths : typing.Sequence[str]

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

        Returns
        -------
        HttpResponse[EmptyResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/files",
            method="DELETE",
            json={
                "id": id,
                "paths": paths,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmptyResponse,
                    parse_obj_as(
                        type_=EmptyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_signed_urls(
        self,
        *,
        id: str,
        paths: typing.Sequence[str],
        operation: Operation,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[GetSignedUrLsResponse]:
        """
        Get signed URLs for a dataset.

        Args:
            request_dto: Request containing dataset ID, paths and operation
            user_info: Authenticated user information

        Returns:
            GetSignedURLsResponse: Response containing signed URLs

        Parameters
        ----------
        id : str

        paths : typing.Sequence[str]

        operation : Operation

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

        Returns
        -------
        HttpResponse[GetSignedUrLsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/signed-urls",
            method="POST",
            json={
                "id": id,
                "paths": paths,
                "operation": operation,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetSignedUrLsResponse,
                    parse_obj_as(
                        type_=GetSignedUrLsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_multipart_upload(
        self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[MultiPartUploadResponse]:
        """
        Create a multipart upload for a dataset

        Args:
            request_dto: Request containing dataset ID, path and number of parts
            user_info: Authenticated user information

        Returns:
            MultiPartUploadResponse: Response containing multipart upload info

        Parameters
        ----------
        id : str

        path : str

        num_parts : int

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

        Returns
        -------
        HttpResponse[MultiPartUploadResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/signed-urls/multipart",
            method="POST",
            json={
                "id": id,
                "path": path,
                "num_parts": num_parts,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    MultiPartUploadResponse,
                    parse_obj_as(
                        type_=MultiPartUploadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetDataDirectoryResponse]:
        """
        Get a data directory by its ID.

        Args:
            id (str): The ID of the data directory to retrieve
            user_info: Current authenticated user info

        Returns:
            DataDirectoryResponse: Response containing the retrieved data directory

        Parameters
        ----------
        id : str

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

        Returns
        -------
        AsyncHttpResponse[GetDataDirectoryResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/ml/v1/data-directories/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetDataDirectoryResponse,
                    parse_obj_as(
                        type_=GetDataDirectoryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete(
        self,
        id: str,
        *,
        delete_contents: typing.Optional[bool] = False,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EmptyResponse]:
        """
        Delete a data directory and optionally its contents.

        Args:
            id: Unique identifier of the data directory to delete
            delete_contents: If True, also deletes the data directory's contents
            user_info: Authenticated user information

        Returns:
            EmptyResponse: Empty response indicating successful deletion

        Parameters
        ----------
        id : str

        delete_contents : typing.Optional[bool]

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

        Returns
        -------
        AsyncHttpResponse[EmptyResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/ml/v1/data-directories/{jsonable_encoder(id)}",
            method="DELETE",
            params={
                "delete_contents": delete_contents,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmptyResponse,
                    parse_obj_as(
                        type_=EmptyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list(
        self,
        *,
        fqn: typing.Optional[str] = None,
        ml_repo_id: typing.Optional[str] = None,
        name: typing.Optional[str] = None,
        limit: typing.Optional[int] = 100,
        offset: typing.Optional[int] = 0,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[DataDirectory, ListDataDirectoriesResponse]:
        """
        List all data directories with optional filtering and pagination.

        Args:
            filters: Query parameters for filtering and pagination
                - ml_repo_id: Filter data directories by ml repo ID
                - name: Optional filter data directories by name
                - limit: Optional maximum number of data directories to return
                - offset: Optional number of data directories to skip
            user_info: Authenticated user information

        Returns:
            ListDataDirectoriesResponse: List of data directories and pagination info

        Parameters
        ----------
        fqn : typing.Optional[str]

        ml_repo_id : typing.Optional[str]

        name : typing.Optional[str]

        limit : typing.Optional[int]

        offset : typing.Optional[int]

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

        Returns
        -------
        AsyncPager[DataDirectory, ListDataDirectoriesResponse]
            Successful Response
        """
        offset = offset if offset is not None else 0

        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories",
            method="GET",
            params={
                "fqn": fqn,
                "ml_repo_id": ml_repo_id,
                "name": name,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListDataDirectoriesResponse,
                    parse_obj_as(
                        type_=ListDataDirectoriesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True

                async def _get_next():
                    return await self.list(
                        fqn=fqn,
                        ml_repo_id=ml_repo_id,
                        name=name,
                        limit=limit,
                        offset=offset + len(_items),
                        request_options=request_options,
                    )

                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_or_update(
        self, *, manifest: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetDataDirectoryResponse]:
        """
        Parameters
        ----------
        manifest : DataDirectoryManifest

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

        Returns
        -------
        AsyncHttpResponse[GetDataDirectoryResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories",
            method="PUT",
            json={
                "manifest": convert_and_respect_annotation_metadata(
                    object_=manifest, annotation=DataDirectoryManifest, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetDataDirectoryResponse,
                    parse_obj_as(
                        type_=GetDataDirectoryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_files(
        self,
        *,
        id: str,
        path: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        page_token: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[FileInfo, ListFilesResponse]:
        """
        List files in a dataset.

        Args:
            request_dto: Request containing dataset ID, path, page token and limit
            user_info: Authenticated user information

        Returns:
            ListFilesResponse: Response containing files and pagination info

        Parameters
        ----------
        id : str

        path : typing.Optional[str]

        limit : typing.Optional[int]

        page_token : typing.Optional[str]

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

        Returns
        -------
        AsyncPager[FileInfo, ListFilesResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/files",
            method="POST",
            json={
                "id": id,
                "path": path,
                "limit": limit,
                "pageToken": page_token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListFilesResponse,
                    parse_obj_as(
                        type_=ListFilesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = False
                _get_next = None
                if _parsed_response.pagination is not None:
                    _parsed_next = _parsed_response.pagination.next_page_token
                    _has_next = _parsed_next is not None and _parsed_next != ""

                    async def _get_next():
                        return await self.list_files(
                            id=id,
                            path=path,
                            limit=limit,
                            page_token=_parsed_next,
                            request_options=request_options,
                        )

                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_files(
        self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[EmptyResponse]:
        """
        Delete files from the dataset.

        Args:
            request_dto: Request containing dataset ID and paths
            user_info: Authenticated user information

        Returns:
            EmptyResponse: Empty response indicating successful deletion

        Parameters
        ----------
        id : str

        paths : typing.Sequence[str]

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

        Returns
        -------
        AsyncHttpResponse[EmptyResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/files",
            method="DELETE",
            json={
                "id": id,
                "paths": paths,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmptyResponse,
                    parse_obj_as(
                        type_=EmptyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_signed_urls(
        self,
        *,
        id: str,
        paths: typing.Sequence[str],
        operation: Operation,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[GetSignedUrLsResponse]:
        """
        Get signed URLs for a dataset.

        Args:
            request_dto: Request containing dataset ID, paths and operation
            user_info: Authenticated user information

        Returns:
            GetSignedURLsResponse: Response containing signed URLs

        Parameters
        ----------
        id : str

        paths : typing.Sequence[str]

        operation : Operation

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

        Returns
        -------
        AsyncHttpResponse[GetSignedUrLsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/signed-urls",
            method="POST",
            json={
                "id": id,
                "paths": paths,
                "operation": operation,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetSignedUrLsResponse,
                    parse_obj_as(
                        type_=GetSignedUrLsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_multipart_upload(
        self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[MultiPartUploadResponse]:
        """
        Create a multipart upload for a dataset

        Args:
            request_dto: Request containing dataset ID, path and number of parts
            user_info: Authenticated user information

        Returns:
            MultiPartUploadResponse: Response containing multipart upload info

        Parameters
        ----------
        id : str

        path : str

        num_parts : int

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

        Returns
        -------
        AsyncHttpResponse[MultiPartUploadResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/ml/v1/data-directories/signed-urls/multipart",
            method="POST",
            json={
                "id": id,
                "path": path,
                "num_parts": num_parts,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    MultiPartUploadResponse,
                    parse_obj_as(
                        type_=MultiPartUploadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
