# 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.pydantic_utilities import pydantic_v1
from ...core.request_options import RequestOptions
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.structured_data_extractor_reponse import StructuredDataExtractorReponse

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


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

    def invoke(
        self,
        *,
        asset_ids: typing.Sequence[str],
        json_schema: typing.Dict[str, typing.Any],
        map_: typing.Optional[bool] = OMIT,
        reduce: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None
    ) -> StructuredDataExtractorReponse:
        """
        Coming soon! Extract structured data from assets of arbitrary length.

        Parameters
        ----------
        asset_ids : typing.Sequence[str]
            The IDs of the assets from which to extract structured data matching `json_schema`.

        json_schema : typing.Dict[str, typing.Any]
            The JSON schema to use for validation (version draft 2020-12).  See the docs [here](https://json-schema.org/learn/getting-started-step-by-step).

        map_ : typing.Optional[bool]
            Whether to split the asset into chunks and attempt to extract the schema from each chunk.  Set to false if you know the asset is small.

        reduce : typing.Optional[bool]
            If `map`, whether to reduce the chunks to a single structured object (true) or return the full list (false).  Use True unless you want to preserve duplicates from each page or expect the object to overflow the output context.

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

        Returns
        -------
        StructuredDataExtractorReponse
            Successful Response

        Examples
        --------
        from athena.client import Athena

        client = Athena(
            api_key="YOUR_API_KEY",
        )
        client.tools.structured_data_extractor.invoke(
            asset_ids=["asset_ids"],
            json_schema={"key": "value"},
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/v0/tools/structured-data-extractor/invoke",
            method="POST",
            json={"asset_ids": asset_ids, "json_schema": json_schema, "map": map_, "reduce": reduce},
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(StructuredDataExtractorReponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic_v1.parse_obj_as(typing.Any, _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 AsyncStructuredDataExtractorClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def invoke(
        self,
        *,
        asset_ids: typing.Sequence[str],
        json_schema: typing.Dict[str, typing.Any],
        map_: typing.Optional[bool] = OMIT,
        reduce: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None
    ) -> StructuredDataExtractorReponse:
        """
        Coming soon! Extract structured data from assets of arbitrary length.

        Parameters
        ----------
        asset_ids : typing.Sequence[str]
            The IDs of the assets from which to extract structured data matching `json_schema`.

        json_schema : typing.Dict[str, typing.Any]
            The JSON schema to use for validation (version draft 2020-12).  See the docs [here](https://json-schema.org/learn/getting-started-step-by-step).

        map_ : typing.Optional[bool]
            Whether to split the asset into chunks and attempt to extract the schema from each chunk.  Set to false if you know the asset is small.

        reduce : typing.Optional[bool]
            If `map`, whether to reduce the chunks to a single structured object (true) or return the full list (false).  Use True unless you want to preserve duplicates from each page or expect the object to overflow the output context.

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

        Returns
        -------
        StructuredDataExtractorReponse
            Successful Response

        Examples
        --------
        from athena.client import AsyncAthena

        client = AsyncAthena(
            api_key="YOUR_API_KEY",
        )
        await client.tools.structured_data_extractor.invoke(
            asset_ids=["asset_ids"],
            json_schema={"key": "value"},
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/v0/tools/structured-data-extractor/invoke",
            method="POST",
            json={"asset_ids": asset_ids, "json_schema": json_schema, "map": map_, "reduce": reduce},
            request_options=request_options,
            omit=OMIT,
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(StructuredDataExtractorReponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic_v1.parse_obj_as(typing.Any, _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)
