From 46c87674696ba966576c063d6d6e3e53e0140f81 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 03:46:57 +0000 Subject: [PATCH 1/6] chore: use lazy imports for resources --- src/groq/_client.py | 315 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 253 insertions(+), 62 deletions(-) diff --git a/src/groq/_client.py b/src/groq/_client.py index 6c7f997..ee203f0 100644 --- a/src/groq/_client.py +++ b/src/groq/_client.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, Union, Mapping +from typing import TYPE_CHECKING, Any, Union, Mapping from typing_extensions import Self, override import httpx @@ -20,8 +20,8 @@ RequestOptions, ) from ._utils import is_given, get_async_library +from ._compat import cached_property from ._version import __version__ -from .resources import files, models, batches, embeddings from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import GroqError, APIStatusError from ._base_client import ( @@ -29,22 +29,20 @@ SyncAPIClient, AsyncAPIClient, ) -from .resources.chat import chat -from .resources.audio import audio + +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): - chat: chat.Chat - embeddings: embeddings.Embeddings - audio: audio.Audio - models: models.Models - batches: batches.Batches - files: files.Files - with_raw_response: GroqWithRawResponse - with_streaming_response: GroqWithStreamedResponse - # client options api_key: str @@ -99,14 +97,49 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.chat = chat.Chat(self) - self.embeddings = embeddings.Embeddings(self) - self.audio = audio.Audio(self) - self.models = models.Models(self) - self.batches = batches.Batches(self) - self.files = files.Files(self) - self.with_raw_response = GroqWithRawResponse(self) - self.with_streaming_response = GroqWithStreamedResponse(self) + @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 @@ -214,15 +247,6 @@ def _make_status_error( class AsyncGroq(AsyncAPIClient): - chat: chat.AsyncChat - embeddings: embeddings.AsyncEmbeddings - audio: audio.AsyncAudio - models: models.AsyncModels - batches: batches.AsyncBatches - files: files.AsyncFiles - with_raw_response: AsyncGroqWithRawResponse - with_streaming_response: AsyncGroqWithStreamedResponse - # client options api_key: str @@ -277,14 +301,49 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.chat = chat.AsyncChat(self) - self.embeddings = embeddings.AsyncEmbeddings(self) - self.audio = audio.AsyncAudio(self) - self.models = models.AsyncModels(self) - self.batches = batches.AsyncBatches(self) - self.files = files.AsyncFiles(self) - self.with_raw_response = AsyncGroqWithRawResponse(self) - self.with_streaming_response = AsyncGroqWithStreamedResponse(self) + @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 @@ -392,43 +451,175 @@ def _make_status_error( class GroqWithRawResponse: + _client: Groq + def __init__(self, client: Groq) -> None: - self.chat = chat.ChatWithRawResponse(client.chat) - self.embeddings = embeddings.EmbeddingsWithRawResponse(client.embeddings) - self.audio = audio.AudioWithRawResponse(client.audio) - self.models = models.ModelsWithRawResponse(client.models) - self.batches = batches.BatchesWithRawResponse(client.batches) - self.files = files.FilesWithRawResponse(client.files) + 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.chat = chat.AsyncChatWithRawResponse(client.chat) - self.embeddings = embeddings.AsyncEmbeddingsWithRawResponse(client.embeddings) - self.audio = audio.AsyncAudioWithRawResponse(client.audio) - self.models = models.AsyncModelsWithRawResponse(client.models) - self.batches = batches.AsyncBatchesWithRawResponse(client.batches) - self.files = files.AsyncFilesWithRawResponse(client.files) + 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.chat = chat.ChatWithStreamingResponse(client.chat) - self.embeddings = embeddings.EmbeddingsWithStreamingResponse(client.embeddings) - self.audio = audio.AudioWithStreamingResponse(client.audio) - self.models = models.ModelsWithStreamingResponse(client.models) - self.batches = batches.BatchesWithStreamingResponse(client.batches) - self.files = files.FilesWithStreamingResponse(client.files) + 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.chat = chat.AsyncChatWithStreamingResponse(client.chat) - self.embeddings = embeddings.AsyncEmbeddingsWithStreamingResponse(client.embeddings) - self.audio = audio.AsyncAudioWithStreamingResponse(client.audio) - self.models = models.AsyncModelsWithStreamingResponse(client.models) - self.batches = batches.AsyncBatchesWithStreamingResponse(client.batches) - self.files = files.AsyncFilesWithStreamingResponse(client.files) + 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 From 1122aa0662ec7af88799530de50f002645ccb5d0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 23:04:56 +0000 Subject: [PATCH 2/6] feat(api): api update --- .stats.yml | 4 +- README.md | 22 ------ src/groq/resources/chat/completions.py | 26 +++---- .../types/chat/completion_create_params.py | 75 ++++++++++++++++--- tests/api_resources/chat/test_completions.py | 4 +- 5 files changed, 82 insertions(+), 49 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7a7d45c..47a711c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 17 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/groqcloud%2Fgroqcloud-e4cd6fe4e6ac62707635fac8fb7d966a0360868e467b578ddd7cc04a9459ff26.yml -openapi_spec_hash: e618e809624bb2f3b36995638c3ba791 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/groqcloud%2Fgroqcloud-e08e435f65aeb7c4e773503f15f04eb488d2cf6ec4e122f406e32599eb2861f3.yml +openapi_spec_hash: ff68a1ae02aa5cabe33c0cc0379f4611 config_hash: 6b1c374dcc1ffa3165dd22f52a77ff89 diff --git a/README.md b/README.md index 4321c9c..a465d1a 100644 --- a/README.md +++ b/README.md @@ -89,28 +89,6 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`. -## Nested params - -Nested parameters are dictionaries, typed using `TypedDict`, for example: - -```python -from groq import Groq - -client = Groq() - -chat_completion = client.chat.completions.create( - messages=[ - { - "content": "content", - "role": "system", - } - ], - model="string", - response_format={"type": "json_object"}, -) -print(chat_completion.response_format) -``` - ## File uploads Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`. diff --git a/src/groq/resources/chat/completions.py b/src/groq/resources/chat/completions.py index 42576ea..bdabc10 100644 --- a/src/groq/resources/chat/completions.py +++ b/src/groq/resources/chat/completions.py @@ -283,13 +283,12 @@ def create( reasoning_format: Specifies how to output reasoning tokens - response_format: An object specifying the format that the model must output. - - Setting to `{ "type": "json_object" }` enables JSON mode, which guarantees the - message the model generates is valid JSON. - - **Important:** when using JSON mode, you **must** also instruct the model to - produce JSON yourself via a system or user message. + response_format: An object specifying the format that the model must output. Setting to + `{ "type": "json_schema", "json_schema": {...} }` enables Structured Outputs + which ensures the model will match your supplied JSON schema. Setting to + `{ "type": "json_object" }` enables the older JSON mode, which ensures the + message the model generates is valid JSON. Using `json_schema` is preferred for + models that support it. seed: If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same `seed` and parameters should return @@ -650,13 +649,12 @@ async def create( reasoning_format: Specifies how to output reasoning tokens - response_format: An object specifying the format that the model must output. - - Setting to `{ "type": "json_object" }` enables JSON mode, which guarantees the - message the model generates is valid JSON. - - **Important:** when using JSON mode, you **must** also instruct the model to - produce JSON yourself via a system or user message. + response_format: An object specifying the format that the model must output. Setting to + `{ "type": "json_schema", "json_schema": {...} }` enables Structured Outputs + which ensures the model will match your supplied JSON schema. Setting to + `{ "type": "json_object" }` enables the older JSON mode, which ensures the + message the model generates is valid JSON. Using `json_schema` is preferred for + models that support it. seed: If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same `seed` and parameters should return diff --git a/src/groq/types/chat/completion_create_params.py b/src/groq/types/chat/completion_create_params.py index 428fb5c..16cd6c9 100644 --- a/src/groq/types/chat/completion_create_params.py +++ b/src/groq/types/chat/completion_create_params.py @@ -11,7 +11,16 @@ from .chat_completion_tool_choice_option_param import ChatCompletionToolChoiceOptionParam from .chat_completion_function_call_option_param import ChatCompletionFunctionCallOptionParam -__all__ = ["CompletionCreateParams", "FunctionCall", "Function", "ResponseFormat"] +__all__ = [ + "CompletionCreateParams", + "FunctionCall", + "Function", + "ResponseFormat", + "ResponseFormatResponseFormatText", + "ResponseFormatResponseFormatJsonSchema", + "ResponseFormatResponseFormatJsonSchemaJsonSchema", + "ResponseFormatResponseFormatJsonObject", +] class CompletionCreateParams(TypedDict, total=False): @@ -128,11 +137,11 @@ class CompletionCreateParams(TypedDict, total=False): response_format: Optional[ResponseFormat] """An object specifying the format that the model must output. - Setting to `{ "type": "json_object" }` enables JSON mode, which guarantees the - message the model generates is valid JSON. - - **Important:** when using JSON mode, you **must** also instruct the model to - produce JSON yourself via a system or user message. + Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured + Outputs which ensures the model will match your supplied JSON schema. Setting to + `{ "type": "json_object" }` enables the older JSON mode, which ensures the + message the model generates is valid JSON. Using `json_schema` is preferred for + models that support it. """ seed: Optional[int] @@ -249,6 +258,54 @@ class Function(TypedDict, total=False): """ -class ResponseFormat(TypedDict, total=False): - type: Literal["text", "json_object"] - """Must be one of `text` or `json_object`.""" +class ResponseFormatResponseFormatText(TypedDict, total=False): + type: Required[Literal["text"]] + """The type of response format being defined. Always `text`.""" + + +class ResponseFormatResponseFormatJsonSchemaJsonSchema(TypedDict, total=False): + name: Required[str] + """The name of the response format. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + description: str + """ + A description of what the response format is for, used by the model to determine + how to respond in the format. + """ + + schema: Dict[str, object] + """ + The schema for the response format, described as a JSON Schema object. Learn how + to build JSON schemas [here](https://json-schema.org/). + """ + + strict: Optional[bool] + """Whether to enable strict schema adherence when generating the output. + + If set to true, the model will always follow the exact schema defined in the + `schema` field. Only a subset of JSON Schema is supported when `strict` is + `true`. To learn more, read the + [Structured Outputs guide](/docs/guides/structured-outputs). + """ + + +class ResponseFormatResponseFormatJsonSchema(TypedDict, total=False): + json_schema: Required[ResponseFormatResponseFormatJsonSchemaJsonSchema] + """Structured Outputs configuration options, including a JSON Schema.""" + + type: Required[Literal["json_schema"]] + """The type of response format being defined. Always `json_schema`.""" + + +class ResponseFormatResponseFormatJsonObject(TypedDict, total=False): + type: Required[Literal["json_object"]] + """The type of response format being defined. Always `json_object`.""" + + +ResponseFormat: TypeAlias = Union[ + ResponseFormatResponseFormatText, ResponseFormatResponseFormatJsonSchema, ResponseFormatResponseFormatJsonObject +] diff --git a/tests/api_resources/chat/test_completions.py b/tests/api_resources/chat/test_completions.py index 0f65ce0..d1380f3 100644 --- a/tests/api_resources/chat/test_completions.py +++ b/tests/api_resources/chat/test_completions.py @@ -61,7 +61,7 @@ def test_method_create_with_all_params(self, client: Groq) -> None: parallel_tool_calls=True, presence_penalty=-2, reasoning_format="hidden", - response_format={"type": "json_object"}, + response_format={"type": "text"}, seed=0, service_tier="auto", stop="\n", @@ -169,7 +169,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGroq) -> N parallel_tool_calls=True, presence_penalty=-2, reasoning_format="hidden", - response_format={"type": "json_object"}, + response_format={"type": "text"}, seed=0, service_tier="auto", stop="\n", From c6d457878f231efba49f83a1c6f8cfd513b82cb9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 04:24:20 +0000 Subject: [PATCH 3/6] chore(internal): avoid errors for isinstance checks on proxies --- src/groq/_utils/_proxy.py | 5 ++++- tests/test_utils/test_proxy.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/groq/_utils/_proxy.py b/src/groq/_utils/_proxy.py index ffd883e..0f239a3 100644 --- a/src/groq/_utils/_proxy.py +++ b/src/groq/_utils/_proxy.py @@ -46,7 +46,10 @@ def __dir__(self) -> Iterable[str]: @property # type: ignore @override def __class__(self) -> type: # pyright: ignore - proxied = self.__get_proxied__() + try: + proxied = self.__get_proxied__() + except Exception: + return type(self) if issubclass(type(proxied), LazyProxy): return type(proxied) return proxied.__class__ diff --git a/tests/test_utils/test_proxy.py b/tests/test_utils/test_proxy.py index 2fa9c4a..4c48c14 100644 --- a/tests/test_utils/test_proxy.py +++ b/tests/test_utils/test_proxy.py @@ -21,3 +21,14 @@ def test_recursive_proxy() -> None: assert dir(proxy) == [] assert type(proxy).__name__ == "RecursiveLazyProxy" assert type(operator.attrgetter("name.foo.bar.baz")(proxy)).__name__ == "RecursiveLazyProxy" + + +def test_isinstance_does_not_error() -> None: + class AlwaysErrorProxy(LazyProxy[Any]): + @override + def __load__(self) -> Any: + raise RuntimeError("Mocking missing dependency") + + proxy = AlwaysErrorProxy() + assert not isinstance(proxy, dict) + assert isinstance(proxy, LazyProxy) From 9d81d352a3b1c0c7092444617f64b8096b05f08d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 04:36:09 +0000 Subject: [PATCH 4/6] docs: remove or fix invalid readme examples --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a465d1a..e37bf22 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ chat_completion = client.chat.completions.create( ], model="llama3-8b-8192", ) -print(chat_completion.choices[0].message.content) +print(chat_completion.id) ``` While you can provide an `api_key` keyword argument, @@ -72,7 +72,7 @@ async def main() -> None: ], model="llama3-8b-8192", ) - print(chat_completion.choices[0].message.content) + print(chat_completion.id) asyncio.run(main()) From 82bfd684a24d39e838e11612e060e3d6b1a4aac2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 10 May 2025 03:43:36 +0000 Subject: [PATCH 5/6] fix(package): support direct resource imports --- src/groq/__init__.py | 5 +++++ src/groq/_utils/_resources_proxy.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/groq/_utils/_resources_proxy.py diff --git a/src/groq/__init__.py b/src/groq/__init__.py index 07f77a6..9ad2b0e 100644 --- a/src/groq/__init__.py +++ b/src/groq/__init__.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +import typing as _t + from . import types from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes from ._utils import file_from_path @@ -68,6 +70,9 @@ "DefaultAsyncHttpxClient", ] +if not _t.TYPE_CHECKING: + from ._utils._resources_proxy import resources as resources + _setup_logging() # Update the __module__ attribute for exported symbols so that diff --git a/src/groq/_utils/_resources_proxy.py b/src/groq/_utils/_resources_proxy.py new file mode 100644 index 0000000..4c4c876 --- /dev/null +++ b/src/groq/_utils/_resources_proxy.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from typing import Any +from typing_extensions import override + +from ._proxy import LazyProxy + + +class ResourcesProxy(LazyProxy[Any]): + """A proxy for the `groq.resources` module. + + This is used so that we can lazily import `groq.resources` only when + needed *and* so that users can just import `groq` and reference `groq.resources` + """ + + @override + def __load__(self) -> Any: + import importlib + + mod = importlib.import_module("groq.resources") + return mod + + +resources = ResourcesProxy().__as_proxied__() From d7784f1f8e55396f301a43f9b5b1a315e9481e0d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 10 May 2025 03:43:52 +0000 Subject: [PATCH 6/6] release: 0.25.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 24 ++++++++++++++++++++++++ pyproject.toml | 2 +- src/groq/_version.py | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d2d60a3..a36746b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.24.0" + ".": "0.25.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e3945..0b5b57b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## 0.25.0 (2025-05-10) + +Full Changelog: [v0.24.0...v0.25.0](https://github.com/groq/groq-python/compare/v0.24.0...v0.25.0) + +### Features + +* **api:** api update ([1122aa0](https://github.com/groq/groq-python/commit/1122aa0662ec7af88799530de50f002645ccb5d0)) + + +### Bug Fixes + +* **package:** support direct resource imports ([82bfd68](https://github.com/groq/groq-python/commit/82bfd684a24d39e838e11612e060e3d6b1a4aac2)) + + +### Chores + +* **internal:** avoid errors for isinstance checks on proxies ([c6d4578](https://github.com/groq/groq-python/commit/c6d457878f231efba49f83a1c6f8cfd513b82cb9)) +* use lazy imports for resources ([46c8767](https://github.com/groq/groq-python/commit/46c87674696ba966576c063d6d6e3e53e0140f81)) + + +### Documentation + +* remove or fix invalid readme examples ([9d81d35](https://github.com/groq/groq-python/commit/9d81d352a3b1c0c7092444617f64b8096b05f08d)) + ## 0.24.0 (2025-05-02) Full Changelog: [v0.23.1...v0.24.0](https://github.com/groq/groq-python/compare/v0.23.1...v0.24.0) diff --git a/pyproject.toml b/pyproject.toml index 8d1ca7b..45df707 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "groq" -version = "0.24.0" +version = "0.25.0" description = "The official Python library for the groq API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/groq/_version.py b/src/groq/_version.py index 28652de..a9df67c 100644 --- a/src/groq/_version.py +++ b/src/groq/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "groq" -__version__ = "0.24.0" # x-release-please-version +__version__ = "0.25.0" # x-release-please-version