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

import typing

import httpx
from .analyze_async.client import AnalyzeAsyncClient, AsyncAnalyzeAsyncClient
from .assets.client import AssetsClient, AsyncAssetsClient
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .core.request_options import RequestOptions
from .embed.client import AsyncEmbedClient, EmbedClient
from .entity_collections.client import AsyncEntityCollectionsClient, EntityCollectionsClient
from .environment import TwelveLabsEnvironment
from .indexes.client import AsyncIndexesClient, IndexesClient
from .multipart_upload.client import AsyncMultipartUploadClient, MultipartUploadClient
from .raw_base_client import AsyncRawBaseClient, RawBaseClient
from .search.client import AsyncSearchClient, SearchClient
from .tasks.client import AsyncTasksClient, TasksClient
from .types.analyze_max_tokens import AnalyzeMaxTokens
from .types.analyze_temperature import AnalyzeTemperature
from .types.analyze_text_prompt import AnalyzeTextPrompt
from .types.non_stream_analyze_response import NonStreamAnalyzeResponse
from .types.response_format import ResponseFormat
from .types.stream_analyze_response import StreamAnalyzeResponse
from .types.video_context import VideoContext

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


class BaseClient:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : TwelveLabsEnvironment
        The environment to use for requests from the client. from .environment import TwelveLabsEnvironment



        Defaults to TwelveLabsEnvironment.DEFAULT



    api_key : str
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.Client]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from twelvelabs import TwelveLabs

    client = TwelveLabs(
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: TwelveLabsEnvironment = TwelveLabsEnvironment.DEFAULT,
        api_key: str,
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.Client] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.Client(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._raw_client = RawBaseClient(client_wrapper=self._client_wrapper)
        self.tasks = TasksClient(client_wrapper=self._client_wrapper)
        self.indexes = IndexesClient(client_wrapper=self._client_wrapper)
        self.assets = AssetsClient(client_wrapper=self._client_wrapper)
        self.multipart_upload = MultipartUploadClient(client_wrapper=self._client_wrapper)
        self.entity_collections = EntityCollectionsClient(client_wrapper=self._client_wrapper)
        self.embed = EmbedClient(client_wrapper=self._client_wrapper)
        self.search = SearchClient(client_wrapper=self._client_wrapper)
        self.analyze_async = AnalyzeAsyncClient(client_wrapper=self._client_wrapper)

    @property
    def with_raw_response(self) -> RawBaseClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawBaseClient
        """
        return self._raw_client

    def analyze_stream(
        self,
        *,
        prompt: AnalyzeTextPrompt,
        video_id: typing.Optional[str] = OMIT,
        video: typing.Optional[VideoContext] = OMIT,
        temperature: typing.Optional[AnalyzeTemperature] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        max_tokens: typing.Optional[AnalyzeMaxTokens] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[StreamAnalyzeResponse]:
        """
        This method synchronously analyzes your videos and generates fully customizable text based on your prompts.

        <Accordion title="Input requirements">
        - Minimum duration: 4 seconds
        - Maximum duration: 1 hour
        - Formats: [FFmpeg supported formats](https://ffmpeg.org/ffmpeg-formats.html)
        - Resolution: 360x360 to 5184x2160 pixels
        - Aspect ratio: Between 1:1 and 1:2.4, or between 2.4:1 and 1:1.
        </Accordion>

        **When to use this method**:
        - Analyze videos up to 1 hour
        - Retrieve immediate results without waiting for asynchronous processing
        - Stream text fragments in real-time for immediate processing and feedback

        **Do not use this method for**:
        - Videos longer than 1 hour. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.

        <Note title="Notes">
        - This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        prompt : AnalyzeTextPrompt

        video_id : typing.Optional[str]
            The unique identifier of the video to analyze.

            <Info> This parameter will be deprecated and removed in a future version. Use the [`video`](/v1.3/api-reference/analyze-videos/sync-analysis#request.body.video) parameter instead.</Info>

        video : typing.Optional[VideoContext]

        temperature : typing.Optional[AnalyzeTemperature]

        response_format : typing.Optional[ResponseFormat]

        max_tokens : typing.Optional[AnalyzeMaxTokens]

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

        Yields
        ------
        typing.Iterator[StreamAnalyzeResponse]


        Examples
        --------
        from twelvelabs import ResponseFormat, TwelveLabs

        client = TwelveLabs(
            api_key="YOUR_API_KEY",
        )
        response = client.analyze_stream(
            video_id="6298d673f1090f1100476d4c",
            prompt="I want to generate a description for my video with the following format - Title of the video, followed by a summary in 2-3 sentences, highlighting the main topic, key events, and concluding remarks.",
            temperature=0.2,
            response_format=ResponseFormat(
                type="json_schema",
                json_schema={
                    "type": "object",
                    "properties": {
                        "title": {"type": "string"},
                        "summary": {"type": "string"},
                        "keywords": {"type": "array", "items": {"type": "string"}},
                    },
                },
            ),
            max_tokens=2000,
        )
        for chunk in response:
            yield chunk
        """
        with self._raw_client.analyze_stream(
            prompt=prompt,
            video_id=video_id,
            video=video,
            temperature=temperature,
            response_format=response_format,
            max_tokens=max_tokens,
            request_options=request_options,
        ) as r:
            yield from r.data

    def analyze(
        self,
        *,
        prompt: AnalyzeTextPrompt,
        video_id: typing.Optional[str] = OMIT,
        video: typing.Optional[VideoContext] = OMIT,
        temperature: typing.Optional[AnalyzeTemperature] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        max_tokens: typing.Optional[AnalyzeMaxTokens] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> NonStreamAnalyzeResponse:
        """
        This method synchronously analyzes your videos and generates fully customizable text based on your prompts.

        <Accordion title="Input requirements">
        - Minimum duration: 4 seconds
        - Maximum duration: 1 hour
        - Formats: [FFmpeg supported formats](https://ffmpeg.org/ffmpeg-formats.html)
        - Resolution: 360x360 to 5184x2160 pixels
        - Aspect ratio: Between 1:1 and 1:2.4, or between 2.4:1 and 1:1.
        </Accordion>

        **When to use this method**:
        - Analyze videos up to 1 hour
        - Retrieve immediate results without waiting for asynchronous processing
        - Stream text fragments in real-time for immediate processing and feedback

        **Do not use this method for**:
        - Videos longer than 1 hour. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.

        <Note title="Notes">
        - This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        prompt : AnalyzeTextPrompt

        video_id : typing.Optional[str]
            The unique identifier of the video to analyze.

            <Info> This parameter will be deprecated and removed in a future version. Use the [`video`](/v1.3/api-reference/analyze-videos/sync-analysis#request.body.video) parameter instead.</Info>

        video : typing.Optional[VideoContext]

        temperature : typing.Optional[AnalyzeTemperature]

        response_format : typing.Optional[ResponseFormat]

        max_tokens : typing.Optional[AnalyzeMaxTokens]

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

        Returns
        -------
        NonStreamAnalyzeResponse


        Examples
        --------
        from twelvelabs import ResponseFormat, TwelveLabs

        client = TwelveLabs(
            api_key="YOUR_API_KEY",
        )
        client.analyze(
            video_id="6298d673f1090f1100476d4c",
            prompt="I want to generate a description for my video with the following format - Title of the video, followed by a summary in 2-3 sentences, highlighting the main topic, key events, and concluding remarks.",
            temperature=0.2,
            response_format=ResponseFormat(
                type="json_schema",
                json_schema={
                    "type": "object",
                    "properties": {
                        "title": {"type": "string"},
                        "summary": {"type": "string"},
                        "keywords": {"type": "array", "items": {"type": "string"}},
                    },
                },
            ),
            max_tokens=2000,
        )
        """
        _response = self._raw_client.analyze(
            prompt=prompt,
            video_id=video_id,
            video=video,
            temperature=temperature,
            response_format=response_format,
            max_tokens=max_tokens,
            request_options=request_options,
        )
        return _response.data


class AsyncBaseClient:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : TwelveLabsEnvironment
        The environment to use for requests from the client. from .environment import TwelveLabsEnvironment



        Defaults to TwelveLabsEnvironment.DEFAULT



    api_key : str
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.AsyncClient]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from twelvelabs import AsyncTwelveLabs

    client = AsyncTwelveLabs(
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: TwelveLabsEnvironment = TwelveLabsEnvironment.DEFAULT,
        api_key: str,
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._raw_client = AsyncRawBaseClient(client_wrapper=self._client_wrapper)
        self.tasks = AsyncTasksClient(client_wrapper=self._client_wrapper)
        self.indexes = AsyncIndexesClient(client_wrapper=self._client_wrapper)
        self.assets = AsyncAssetsClient(client_wrapper=self._client_wrapper)
        self.multipart_upload = AsyncMultipartUploadClient(client_wrapper=self._client_wrapper)
        self.entity_collections = AsyncEntityCollectionsClient(client_wrapper=self._client_wrapper)
        self.embed = AsyncEmbedClient(client_wrapper=self._client_wrapper)
        self.search = AsyncSearchClient(client_wrapper=self._client_wrapper)
        self.analyze_async = AsyncAnalyzeAsyncClient(client_wrapper=self._client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawBaseClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawBaseClient
        """
        return self._raw_client

    async def analyze_stream(
        self,
        *,
        prompt: AnalyzeTextPrompt,
        video_id: typing.Optional[str] = OMIT,
        video: typing.Optional[VideoContext] = OMIT,
        temperature: typing.Optional[AnalyzeTemperature] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        max_tokens: typing.Optional[AnalyzeMaxTokens] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[StreamAnalyzeResponse]:
        """
        This method synchronously analyzes your videos and generates fully customizable text based on your prompts.

        <Accordion title="Input requirements">
        - Minimum duration: 4 seconds
        - Maximum duration: 1 hour
        - Formats: [FFmpeg supported formats](https://ffmpeg.org/ffmpeg-formats.html)
        - Resolution: 360x360 to 5184x2160 pixels
        - Aspect ratio: Between 1:1 and 1:2.4, or between 2.4:1 and 1:1.
        </Accordion>

        **When to use this method**:
        - Analyze videos up to 1 hour
        - Retrieve immediate results without waiting for asynchronous processing
        - Stream text fragments in real-time for immediate processing and feedback

        **Do not use this method for**:
        - Videos longer than 1 hour. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.

        <Note title="Notes">
        - This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        prompt : AnalyzeTextPrompt

        video_id : typing.Optional[str]
            The unique identifier of the video to analyze.

            <Info> This parameter will be deprecated and removed in a future version. Use the [`video`](/v1.3/api-reference/analyze-videos/sync-analysis#request.body.video) parameter instead.</Info>

        video : typing.Optional[VideoContext]

        temperature : typing.Optional[AnalyzeTemperature]

        response_format : typing.Optional[ResponseFormat]

        max_tokens : typing.Optional[AnalyzeMaxTokens]

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

        Yields
        ------
        typing.AsyncIterator[StreamAnalyzeResponse]


        Examples
        --------
        import asyncio

        from twelvelabs import AsyncTwelveLabs, ResponseFormat

        client = AsyncTwelveLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            response = await client.analyze_stream(
                video_id="6298d673f1090f1100476d4c",
                prompt="I want to generate a description for my video with the following format - Title of the video, followed by a summary in 2-3 sentences, highlighting the main topic, key events, and concluding remarks.",
                temperature=0.2,
                response_format=ResponseFormat(
                    type="json_schema",
                    json_schema={
                        "type": "object",
                        "properties": {
                            "title": {"type": "string"},
                            "summary": {"type": "string"},
                            "keywords": {"type": "array", "items": {"type": "string"}},
                        },
                    },
                ),
                max_tokens=2000,
            )
            async for chunk in response:
                yield chunk


        asyncio.run(main())
        """
        async with self._raw_client.analyze_stream(
            prompt=prompt,
            video_id=video_id,
            video=video,
            temperature=temperature,
            response_format=response_format,
            max_tokens=max_tokens,
            request_options=request_options,
        ) as r:
            async for _chunk in r.data:
                yield _chunk

    async def analyze(
        self,
        *,
        prompt: AnalyzeTextPrompt,
        video_id: typing.Optional[str] = OMIT,
        video: typing.Optional[VideoContext] = OMIT,
        temperature: typing.Optional[AnalyzeTemperature] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        max_tokens: typing.Optional[AnalyzeMaxTokens] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> NonStreamAnalyzeResponse:
        """
        This method synchronously analyzes your videos and generates fully customizable text based on your prompts.

        <Accordion title="Input requirements">
        - Minimum duration: 4 seconds
        - Maximum duration: 1 hour
        - Formats: [FFmpeg supported formats](https://ffmpeg.org/ffmpeg-formats.html)
        - Resolution: 360x360 to 5184x2160 pixels
        - Aspect ratio: Between 1:1 and 1:2.4, or between 2.4:1 and 1:1.
        </Accordion>

        **When to use this method**:
        - Analyze videos up to 1 hour
        - Retrieve immediate results without waiting for asynchronous processing
        - Stream text fragments in real-time for immediate processing and feedback

        **Do not use this method for**:
        - Videos longer than 1 hour. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.

        <Note title="Notes">
        - This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
        </Note>

        Parameters
        ----------
        prompt : AnalyzeTextPrompt

        video_id : typing.Optional[str]
            The unique identifier of the video to analyze.

            <Info> This parameter will be deprecated and removed in a future version. Use the [`video`](/v1.3/api-reference/analyze-videos/sync-analysis#request.body.video) parameter instead.</Info>

        video : typing.Optional[VideoContext]

        temperature : typing.Optional[AnalyzeTemperature]

        response_format : typing.Optional[ResponseFormat]

        max_tokens : typing.Optional[AnalyzeMaxTokens]

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

        Returns
        -------
        NonStreamAnalyzeResponse


        Examples
        --------
        import asyncio

        from twelvelabs import AsyncTwelveLabs, ResponseFormat

        client = AsyncTwelveLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.analyze(
                video_id="6298d673f1090f1100476d4c",
                prompt="I want to generate a description for my video with the following format - Title of the video, followed by a summary in 2-3 sentences, highlighting the main topic, key events, and concluding remarks.",
                temperature=0.2,
                response_format=ResponseFormat(
                    type="json_schema",
                    json_schema={
                        "type": "object",
                        "properties": {
                            "title": {"type": "string"},
                            "summary": {"type": "string"},
                            "keywords": {"type": "array", "items": {"type": "string"}},
                        },
                    },
                ),
                max_tokens=2000,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.analyze(
            prompt=prompt,
            video_id=video_id,
            video=video,
            temperature=temperature,
            response_format=response_format,
            max_tokens=max_tokens,
            request_options=request_options,
        )
        return _response.data


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: TwelveLabsEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
