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

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...types.prompt_request_input import PromptRequestInput
from ...types.vellum_variable import VellumVariable
from ...types.prompt_parameters import PromptParameters
from ...types.prompt_block import PromptBlock
from ...types.prompt_settings import PromptSettings
from ...types.function_definition import FunctionDefinition
from ...types.ad_hoc_expand_meta import AdHocExpandMeta
from ...core.request_options import RequestOptions
from ...types.ad_hoc_execute_prompt_event import AdHocExecutePromptEvent
from ...core.serialization import convert_and_respect_annotation_metadata
from ...core.pydantic_utilities import parse_obj_as
from ...errors.bad_request_error import BadRequestError
from ...errors.forbidden_error import ForbiddenError
from ...errors.internal_server_error import InternalServerError
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
import json
from ...core.client_wrapper import AsyncClientWrapper

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


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

    def adhoc_execute_prompt(
        self,
        *,
        ml_model: str,
        input_values: typing.Sequence[PromptRequestInput],
        input_variables: typing.Sequence[VellumVariable],
        parameters: PromptParameters,
        blocks: typing.Sequence[PromptBlock],
        settings: typing.Optional[PromptSettings] = OMIT,
        functions: typing.Optional[typing.Sequence[FunctionDefinition]] = OMIT,
        expand_meta: typing.Optional[AdHocExpandMeta] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AdHocExecutePromptEvent:
        """
        Parameters
        ----------
        ml_model : str

        input_values : typing.Sequence[PromptRequestInput]

        input_variables : typing.Sequence[VellumVariable]

        parameters : PromptParameters

        blocks : typing.Sequence[PromptBlock]

        settings : typing.Optional[PromptSettings]

        functions : typing.Optional[typing.Sequence[FunctionDefinition]]

        expand_meta : typing.Optional[AdHocExpandMeta]

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

        Returns
        -------
        AdHocExecutePromptEvent


        Examples
        --------
        from vellum import (
            JinjaPromptBlock,
            PromptParameters,
            PromptRequestStringInput,
            Vellum,
            VellumVariable,
        )

        client = Vellum(
            api_key="YOUR_API_KEY",
        )
        client.ad_hoc.adhoc_execute_prompt(
            ml_model="ml_model",
            input_values=[
                PromptRequestStringInput(
                    key="key",
                    value="value",
                )
            ],
            input_variables=[
                VellumVariable(
                    id="id",
                    key="key",
                    type="STRING",
                )
            ],
            parameters=PromptParameters(),
            blocks=[
                JinjaPromptBlock(
                    template="template",
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/ad-hoc/execute-prompt",
            base_url=self._client_wrapper.get_environment().default,
            method="POST",
            json={
                "ml_model": ml_model,
                "input_values": convert_and_respect_annotation_metadata(
                    object_=input_values, annotation=typing.Sequence[PromptRequestInput], direction="write"
                ),
                "input_variables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
                ),
                "parameters": convert_and_respect_annotation_metadata(
                    object_=parameters, annotation=PromptParameters, direction="write"
                ),
                "settings": convert_and_respect_annotation_metadata(
                    object_=settings, annotation=PromptSettings, direction="write"
                ),
                "blocks": convert_and_respect_annotation_metadata(
                    object_=blocks, annotation=typing.Sequence[PromptBlock], direction="write"
                ),
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[FunctionDefinition], direction="write"
                ),
                "expand_meta": convert_and_respect_annotation_metadata(
                    object_=expand_meta, annotation=AdHocExpandMeta, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AdHocExecutePromptEvent,
                    parse_obj_as(
                        type_=AdHocExecutePromptEvent,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def adhoc_execute_prompt_stream(
        self,
        *,
        ml_model: str,
        input_values: typing.Sequence[PromptRequestInput],
        input_variables: typing.Sequence[VellumVariable],
        parameters: PromptParameters,
        blocks: typing.Sequence[PromptBlock],
        settings: typing.Optional[PromptSettings] = OMIT,
        functions: typing.Optional[typing.Sequence[FunctionDefinition]] = OMIT,
        expand_meta: typing.Optional[AdHocExpandMeta] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[AdHocExecutePromptEvent]:
        """
        Parameters
        ----------
        ml_model : str

        input_values : typing.Sequence[PromptRequestInput]

        input_variables : typing.Sequence[VellumVariable]

        parameters : PromptParameters

        blocks : typing.Sequence[PromptBlock]

        settings : typing.Optional[PromptSettings]

        functions : typing.Optional[typing.Sequence[FunctionDefinition]]

        expand_meta : typing.Optional[AdHocExpandMeta]

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

        Yields
        ------
        typing.Iterator[AdHocExecutePromptEvent]


        Examples
        --------
        from vellum import (
            JinjaPromptBlock,
            PromptParameters,
            PromptRequestStringInput,
            Vellum,
            VellumVariable,
        )

        client = Vellum(
            api_key="YOUR_API_KEY",
        )
        response = client.ad_hoc.adhoc_execute_prompt_stream(
            ml_model="ml_model",
            input_values=[
                PromptRequestStringInput(
                    key="key",
                    value="value",
                )
            ],
            input_variables=[
                VellumVariable(
                    id="id",
                    key="key",
                    type="STRING",
                )
            ],
            parameters=PromptParameters(),
            blocks=[
                JinjaPromptBlock(
                    template="template",
                )
            ],
        )
        for chunk in response:
            yield chunk
        """
        with self._client_wrapper.httpx_client.stream(
            "v1/ad-hoc/execute-prompt-stream",
            base_url=self._client_wrapper.get_environment().predict,
            method="POST",
            json={
                "ml_model": ml_model,
                "input_values": convert_and_respect_annotation_metadata(
                    object_=input_values, annotation=typing.Sequence[PromptRequestInput], direction="write"
                ),
                "input_variables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
                ),
                "parameters": convert_and_respect_annotation_metadata(
                    object_=parameters, annotation=PromptParameters, direction="write"
                ),
                "settings": convert_and_respect_annotation_metadata(
                    object_=settings, annotation=PromptSettings, direction="write"
                ),
                "blocks": convert_and_respect_annotation_metadata(
                    object_=blocks, annotation=typing.Sequence[PromptBlock], direction="write"
                ),
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[FunctionDefinition], direction="write"
                ),
                "expand_meta": convert_and_respect_annotation_metadata(
                    object_=expand_meta, annotation=AdHocExpandMeta, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    for _text in _response.iter_lines():
                        try:
                            if len(_text) == 0:
                                continue
                            yield typing.cast(
                                AdHocExecutePromptEvent,
                                parse_obj_as(
                                    type_=AdHocExecutePromptEvent,  # type: ignore
                                    object_=json.loads(_text),
                                ),
                            )
                        except Exception:
                            pass
                    return
                _response.read()
                if _response.status_code == 400:
                    raise BadRequestError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 403:
                    raise ForbiddenError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 500:
                    raise InternalServerError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def adhoc_execute_prompt(
        self,
        *,
        ml_model: str,
        input_values: typing.Sequence[PromptRequestInput],
        input_variables: typing.Sequence[VellumVariable],
        parameters: PromptParameters,
        blocks: typing.Sequence[PromptBlock],
        settings: typing.Optional[PromptSettings] = OMIT,
        functions: typing.Optional[typing.Sequence[FunctionDefinition]] = OMIT,
        expand_meta: typing.Optional[AdHocExpandMeta] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AdHocExecutePromptEvent:
        """
        Parameters
        ----------
        ml_model : str

        input_values : typing.Sequence[PromptRequestInput]

        input_variables : typing.Sequence[VellumVariable]

        parameters : PromptParameters

        blocks : typing.Sequence[PromptBlock]

        settings : typing.Optional[PromptSettings]

        functions : typing.Optional[typing.Sequence[FunctionDefinition]]

        expand_meta : typing.Optional[AdHocExpandMeta]

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

        Returns
        -------
        AdHocExecutePromptEvent


        Examples
        --------
        import asyncio

        from vellum import (
            AsyncVellum,
            JinjaPromptBlock,
            PromptParameters,
            PromptRequestStringInput,
            VellumVariable,
        )

        client = AsyncVellum(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.ad_hoc.adhoc_execute_prompt(
                ml_model="ml_model",
                input_values=[
                    PromptRequestStringInput(
                        key="key",
                        value="value",
                    )
                ],
                input_variables=[
                    VellumVariable(
                        id="id",
                        key="key",
                        type="STRING",
                    )
                ],
                parameters=PromptParameters(),
                blocks=[
                    JinjaPromptBlock(
                        template="template",
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/ad-hoc/execute-prompt",
            base_url=self._client_wrapper.get_environment().default,
            method="POST",
            json={
                "ml_model": ml_model,
                "input_values": convert_and_respect_annotation_metadata(
                    object_=input_values, annotation=typing.Sequence[PromptRequestInput], direction="write"
                ),
                "input_variables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
                ),
                "parameters": convert_and_respect_annotation_metadata(
                    object_=parameters, annotation=PromptParameters, direction="write"
                ),
                "settings": convert_and_respect_annotation_metadata(
                    object_=settings, annotation=PromptSettings, direction="write"
                ),
                "blocks": convert_and_respect_annotation_metadata(
                    object_=blocks, annotation=typing.Sequence[PromptBlock], direction="write"
                ),
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[FunctionDefinition], direction="write"
                ),
                "expand_meta": convert_and_respect_annotation_metadata(
                    object_=expand_meta, annotation=AdHocExpandMeta, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    AdHocExecutePromptEvent,
                    parse_obj_as(
                        type_=AdHocExecutePromptEvent,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def adhoc_execute_prompt_stream(
        self,
        *,
        ml_model: str,
        input_values: typing.Sequence[PromptRequestInput],
        input_variables: typing.Sequence[VellumVariable],
        parameters: PromptParameters,
        blocks: typing.Sequence[PromptBlock],
        settings: typing.Optional[PromptSettings] = OMIT,
        functions: typing.Optional[typing.Sequence[FunctionDefinition]] = OMIT,
        expand_meta: typing.Optional[AdHocExpandMeta] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AdHocExecutePromptEvent]:
        """
        Parameters
        ----------
        ml_model : str

        input_values : typing.Sequence[PromptRequestInput]

        input_variables : typing.Sequence[VellumVariable]

        parameters : PromptParameters

        blocks : typing.Sequence[PromptBlock]

        settings : typing.Optional[PromptSettings]

        functions : typing.Optional[typing.Sequence[FunctionDefinition]]

        expand_meta : typing.Optional[AdHocExpandMeta]

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

        Yields
        ------
        typing.AsyncIterator[AdHocExecutePromptEvent]


        Examples
        --------
        import asyncio

        from vellum import (
            AsyncVellum,
            JinjaPromptBlock,
            PromptParameters,
            PromptRequestStringInput,
            VellumVariable,
        )

        client = AsyncVellum(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            response = await client.ad_hoc.adhoc_execute_prompt_stream(
                ml_model="ml_model",
                input_values=[
                    PromptRequestStringInput(
                        key="key",
                        value="value",
                    )
                ],
                input_variables=[
                    VellumVariable(
                        id="id",
                        key="key",
                        type="STRING",
                    )
                ],
                parameters=PromptParameters(),
                blocks=[
                    JinjaPromptBlock(
                        template="template",
                    )
                ],
            )
            async for chunk in response:
                yield chunk


        asyncio.run(main())
        """
        async with self._client_wrapper.httpx_client.stream(
            "v1/ad-hoc/execute-prompt-stream",
            base_url=self._client_wrapper.get_environment().predict,
            method="POST",
            json={
                "ml_model": ml_model,
                "input_values": convert_and_respect_annotation_metadata(
                    object_=input_values, annotation=typing.Sequence[PromptRequestInput], direction="write"
                ),
                "input_variables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
                ),
                "parameters": convert_and_respect_annotation_metadata(
                    object_=parameters, annotation=PromptParameters, direction="write"
                ),
                "settings": convert_and_respect_annotation_metadata(
                    object_=settings, annotation=PromptSettings, direction="write"
                ),
                "blocks": convert_and_respect_annotation_metadata(
                    object_=blocks, annotation=typing.Sequence[PromptBlock], direction="write"
                ),
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[FunctionDefinition], direction="write"
                ),
                "expand_meta": convert_and_respect_annotation_metadata(
                    object_=expand_meta, annotation=AdHocExpandMeta, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    async for _text in _response.aiter_lines():
                        try:
                            if len(_text) == 0:
                                continue
                            yield typing.cast(
                                AdHocExecutePromptEvent,
                                parse_obj_as(
                                    type_=AdHocExecutePromptEvent,  # type: ignore
                                    object_=json.loads(_text),
                                ),
                            )
                        except Exception:
                            pass
                    return
                await _response.aread()
                if _response.status_code == 400:
                    raise BadRequestError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 403:
                    raise ForbiddenError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 500:
                    raise InternalServerError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            parse_obj_as(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)
