# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations import os from typing import TYPE_CHECKING, Any, Union, Mapping from typing_extensions import Self, override import httpx from . import _exceptions from ._qs import Querystring from ._types import ( NOT_GIVEN, Omit, Timeout, NotGiven, Transport, ProxiesTypes, RequestOptions, ) from ._utils import is_given, get_async_library from ._compat import cached_property from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import GroqError, APIStatusError from ._base_client import ( DEFAULT_MAX_RETRIES, SyncAPIClient, AsyncAPIClient, ) if TYPE_CHECKING: from .resources import chat, audio, files, models, batches, embeddings from .resources.files import Files, AsyncFiles from .resources.models import Models, AsyncModels from .resources.batches import Batches, AsyncBatches from .resources.chat.chat import Chat, AsyncChat from .resources.embeddings import Embeddings, AsyncEmbeddings from .resources.audio.audio import Audio, AsyncAudio __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Groq", "AsyncGroq", "Client", "AsyncClient"] class Groq(SyncAPIClient): # client options api_key: str def __init__( self, *, api_key: str | None = None, base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.Client | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: """Construct a new synchronous Groq client instance. This automatically infers the `api_key` argument from the `GROQ_API_KEY` environment variable if it is not provided. """ if api_key is None: api_key = os.environ.get("GROQ_API_KEY") if api_key is None: raise GroqError( "The api_key client option must be set either by passing api_key to the client or by setting the GROQ_API_KEY environment variable" ) self.api_key = api_key if base_url is None: base_url = os.environ.get("GROQ_BASE_URL") if base_url is None: base_url = f"https://api.groq.com" super().__init__( version=__version__, base_url=base_url, max_retries=max_retries, timeout=timeout, http_client=http_client, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, ) @cached_property def chat(self) -> Chat: from .resources.chat import Chat return Chat(self) @cached_property def embeddings(self) -> Embeddings: from .resources.embeddings import Embeddings return Embeddings(self) @cached_property def audio(self) -> Audio: from .resources.audio import Audio return Audio(self) @cached_property def models(self) -> Models: from .resources.models import Models return Models(self) @cached_property def batches(self) -> Batches: from .resources.batches import Batches return Batches(self) @cached_property def files(self) -> Files: from .resources.files import Files return Files(self) @cached_property def with_raw_response(self) -> GroqWithRawResponse: return GroqWithRawResponse(self) @cached_property def with_streaming_response(self) -> GroqWithStreamedResponse: return GroqWithStreamedResponse(self) @property @override def qs(self) -> Querystring: return Querystring(array_format="comma") @property @override def auth_headers(self) -> dict[str, str]: api_key = self.api_key return {"Authorization": f"Bearer {api_key}"} @property @override def default_headers(self) -> dict[str, str | Omit]: return { **super().default_headers, "X-Stainless-Async": "false", **self._custom_headers, } def copy( self, *, api_key: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( api_key=api_key or self.api_key, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class AsyncGroq(AsyncAPIClient): # client options api_key: str def __init__( self, *, api_key: str | None = None, base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, # Configure a custom httpx client. # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details. http_client: httpx.AsyncClient | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. # # This parameter may be removed or changed in the future. # If you rely on this feature, please open a GitHub issue # outlining your use-case to help us decide if it should be # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: """Construct a new async AsyncGroq client instance. This automatically infers the `api_key` argument from the `GROQ_API_KEY` environment variable if it is not provided. """ if api_key is None: api_key = os.environ.get("GROQ_API_KEY") if api_key is None: raise GroqError( "The api_key client option must be set either by passing api_key to the client or by setting the GROQ_API_KEY environment variable" ) self.api_key = api_key if base_url is None: base_url = os.environ.get("GROQ_BASE_URL") if base_url is None: base_url = f"https://api.groq.com" super().__init__( version=__version__, base_url=base_url, max_retries=max_retries, timeout=timeout, http_client=http_client, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, ) @cached_property def chat(self) -> AsyncChat: from .resources.chat import AsyncChat return AsyncChat(self) @cached_property def embeddings(self) -> AsyncEmbeddings: from .resources.embeddings import AsyncEmbeddings return AsyncEmbeddings(self) @cached_property def audio(self) -> AsyncAudio: from .resources.audio import AsyncAudio return AsyncAudio(self) @cached_property def models(self) -> AsyncModels: from .resources.models import AsyncModels return AsyncModels(self) @cached_property def batches(self) -> AsyncBatches: from .resources.batches import AsyncBatches return AsyncBatches(self) @cached_property def files(self) -> AsyncFiles: from .resources.files import AsyncFiles return AsyncFiles(self) @cached_property def with_raw_response(self) -> AsyncGroqWithRawResponse: return AsyncGroqWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncGroqWithStreamedResponse: return AsyncGroqWithStreamedResponse(self) @property @override def qs(self) -> Querystring: return Querystring(array_format="comma") @property @override def auth_headers(self) -> dict[str, str]: api_key = self.api_key return {"Authorization": f"Bearer {api_key}"} @property @override def default_headers(self) -> dict[str, str | Omit]: return { **super().default_headers, "X-Stainless-Async": f"async:{get_async_library()}", **self._custom_headers, } def copy( self, *, api_key: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, default_query: Mapping[str, object] | None = None, set_default_query: Mapping[str, object] | None = None, _extra_kwargs: Mapping[str, Any] = {}, ) -> Self: """ Create a new client instance re-using the same options given to the current client with optional overriding. """ if default_headers is not None and set_default_headers is not None: raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive") if default_query is not None and set_default_query is not None: raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive") headers = self._custom_headers if default_headers is not None: headers = {**headers, **default_headers} elif set_default_headers is not None: headers = set_default_headers params = self._custom_query if default_query is not None: params = {**params, **default_query} elif set_default_query is not None: params = set_default_query http_client = http_client or self._client return self.__class__( api_key=api_key or self.api_key, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, **_extra_kwargs, ) # Alias for `copy` for nicer inline usage, e.g. # client.with_options(timeout=10).foo.create(...) with_options = copy @override def _make_status_error( self, err_msg: str, *, body: object, response: httpx.Response, ) -> APIStatusError: if response.status_code == 400: return _exceptions.BadRequestError(err_msg, response=response, body=body) if response.status_code == 401: return _exceptions.AuthenticationError(err_msg, response=response, body=body) if response.status_code == 403: return _exceptions.PermissionDeniedError(err_msg, response=response, body=body) if response.status_code == 404: return _exceptions.NotFoundError(err_msg, response=response, body=body) if response.status_code == 409: return _exceptions.ConflictError(err_msg, response=response, body=body) if response.status_code == 422: return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body) if response.status_code == 429: return _exceptions.RateLimitError(err_msg, response=response, body=body) if response.status_code >= 500: return _exceptions.InternalServerError(err_msg, response=response, body=body) return APIStatusError(err_msg, response=response, body=body) class GroqWithRawResponse: _client: Groq def __init__(self, client: Groq) -> None: self._client = client @cached_property def chat(self) -> chat.ChatWithRawResponse: from .resources.chat import ChatWithRawResponse return ChatWithRawResponse(self._client.chat) @cached_property def embeddings(self) -> embeddings.EmbeddingsWithRawResponse: from .resources.embeddings import EmbeddingsWithRawResponse return EmbeddingsWithRawResponse(self._client.embeddings) @cached_property def audio(self) -> audio.AudioWithRawResponse: from .resources.audio import AudioWithRawResponse return AudioWithRawResponse(self._client.audio) @cached_property def models(self) -> models.ModelsWithRawResponse: from .resources.models import ModelsWithRawResponse return ModelsWithRawResponse(self._client.models) @cached_property def batches(self) -> batches.BatchesWithRawResponse: from .resources.batches import BatchesWithRawResponse return BatchesWithRawResponse(self._client.batches) @cached_property def files(self) -> files.FilesWithRawResponse: from .resources.files import FilesWithRawResponse return FilesWithRawResponse(self._client.files) class AsyncGroqWithRawResponse: _client: AsyncGroq def __init__(self, client: AsyncGroq) -> None: self._client = client @cached_property def chat(self) -> chat.AsyncChatWithRawResponse: from .resources.chat import AsyncChatWithRawResponse return AsyncChatWithRawResponse(self._client.chat) @cached_property def embeddings(self) -> embeddings.AsyncEmbeddingsWithRawResponse: from .resources.embeddings import AsyncEmbeddingsWithRawResponse return AsyncEmbeddingsWithRawResponse(self._client.embeddings) @cached_property def audio(self) -> audio.AsyncAudioWithRawResponse: from .resources.audio import AsyncAudioWithRawResponse return AsyncAudioWithRawResponse(self._client.audio) @cached_property def models(self) -> models.AsyncModelsWithRawResponse: from .resources.models import AsyncModelsWithRawResponse return AsyncModelsWithRawResponse(self._client.models) @cached_property def batches(self) -> batches.AsyncBatchesWithRawResponse: from .resources.batches import AsyncBatchesWithRawResponse return AsyncBatchesWithRawResponse(self._client.batches) @cached_property def files(self) -> files.AsyncFilesWithRawResponse: from .resources.files import AsyncFilesWithRawResponse return AsyncFilesWithRawResponse(self._client.files) class GroqWithStreamedResponse: _client: Groq def __init__(self, client: Groq) -> None: self._client = client @cached_property def chat(self) -> chat.ChatWithStreamingResponse: from .resources.chat import ChatWithStreamingResponse return ChatWithStreamingResponse(self._client.chat) @cached_property def embeddings(self) -> embeddings.EmbeddingsWithStreamingResponse: from .resources.embeddings import EmbeddingsWithStreamingResponse return EmbeddingsWithStreamingResponse(self._client.embeddings) @cached_property def audio(self) -> audio.AudioWithStreamingResponse: from .resources.audio import AudioWithStreamingResponse return AudioWithStreamingResponse(self._client.audio) @cached_property def models(self) -> models.ModelsWithStreamingResponse: from .resources.models import ModelsWithStreamingResponse return ModelsWithStreamingResponse(self._client.models) @cached_property def batches(self) -> batches.BatchesWithStreamingResponse: from .resources.batches import BatchesWithStreamingResponse return BatchesWithStreamingResponse(self._client.batches) @cached_property def files(self) -> files.FilesWithStreamingResponse: from .resources.files import FilesWithStreamingResponse return FilesWithStreamingResponse(self._client.files) class AsyncGroqWithStreamedResponse: _client: AsyncGroq def __init__(self, client: AsyncGroq) -> None: self._client = client @cached_property def chat(self) -> chat.AsyncChatWithStreamingResponse: from .resources.chat import AsyncChatWithStreamingResponse return AsyncChatWithStreamingResponse(self._client.chat) @cached_property def embeddings(self) -> embeddings.AsyncEmbeddingsWithStreamingResponse: from .resources.embeddings import AsyncEmbeddingsWithStreamingResponse return AsyncEmbeddingsWithStreamingResponse(self._client.embeddings) @cached_property def audio(self) -> audio.AsyncAudioWithStreamingResponse: from .resources.audio import AsyncAudioWithStreamingResponse return AsyncAudioWithStreamingResponse(self._client.audio) @cached_property def models(self) -> models.AsyncModelsWithStreamingResponse: from .resources.models import AsyncModelsWithStreamingResponse return AsyncModelsWithStreamingResponse(self._client.models) @cached_property def batches(self) -> batches.AsyncBatchesWithStreamingResponse: from .resources.batches import AsyncBatchesWithStreamingResponse return AsyncBatchesWithStreamingResponse(self._client.batches) @cached_property def files(self) -> files.AsyncFilesWithStreamingResponse: from .resources.files import AsyncFilesWithStreamingResponse return AsyncFilesWithStreamingResponse(self._client.files) Client = Groq AsyncClient = AsyncGroq