Skip to content

Commit fa2e13b

Browse files
release: 0.13.0 (#135)
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent c32a996 commit fa2e13b

File tree

17 files changed

+147
-125
lines changed

17 files changed

+147
-125
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.12.0"
2+
".": "0.13.0"
33
}

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 7
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/groqcloud%2Fgroqcloud-2e2427d7a1c97af4cb989c736fabccf1531532dd3487d330c851db96d6c5da1c.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/groqcloud%2Fgroqcloud-98874226a7dcad763f5fb96534de25a43f9187733a5293fa278b0b61bf71a9b3.yml

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Changelog
22

3+
## 0.13.0 (2024-11-28)
4+
5+
Full Changelog: [v0.12.0...v0.13.0](https://github.com/groq/groq-python/compare/v0.12.0...v0.13.0)
6+
7+
### Features
8+
9+
* **api:** api update ([#134](https://github.com/groq/groq-python/issues/134)) ([fde3a90](https://github.com/groq/groq-python/commit/fde3a90bf0d3d37dc46765198445becaf588ee96))
10+
11+
12+
### Bug Fixes
13+
14+
* **client:** compat with new httpx 0.28.0 release ([#142](https://github.com/groq/groq-python/issues/142)) ([b8abf89](https://github.com/groq/groq-python/commit/b8abf8961949a9698c7eb666562acbaab15ce9ea))
15+
16+
17+
### Chores
18+
19+
* **internal:** exclude mypy from running on tests ([#141](https://github.com/groq/groq-python/issues/141)) ([fb4456e](https://github.com/groq/groq-python/commit/fb4456e36a6630a3a07e9f1fec09ae335b0554d7))
20+
* **internal:** fix compat model_dump method when warnings are passed ([#138](https://github.com/groq/groq-python/issues/138)) ([91402fd](https://github.com/groq/groq-python/commit/91402fd2ac19b0be2ec1b360e541c891cb4d651f))
21+
* rebuild project due to codegen change ([#136](https://github.com/groq/groq-python/issues/136)) ([b79c1f9](https://github.com/groq/groq-python/commit/b79c1f96496074cc38c489f4b79fa63b871354b7))
22+
* rebuild project due to codegen change ([#137](https://github.com/groq/groq-python/issues/137)) ([2899a88](https://github.com/groq/groq-python/commit/2899a88502cb48aaf99fdc3a277c925ec1137583))
23+
* remove now unused `cached-property` dep ([#140](https://github.com/groq/groq-python/issues/140)) ([d001e95](https://github.com/groq/groq-python/commit/d001e95f7d3f8882eb741c87f66422ef6343260f))
24+
25+
26+
### Documentation
27+
28+
* add info log level to readme ([#139](https://github.com/groq/groq-python/issues/139)) ([804a891](https://github.com/groq/groq-python/commit/804a8910914001d9e21cff974b281011979352f3))
29+
330
## 0.12.0 (2024-11-12)
431

532
Full Changelog: [v0.11.0...v0.12.0](https://github.com/groq/groq-python/compare/v0.11.0...v0.12.0)

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,14 @@ Note that requests that time out are [retried twice by default](#retries).
220220

221221
We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.
222222

223-
You can enable logging by setting the environment variable `GROQ_LOG` to `debug`.
223+
You can enable logging by setting the environment variable `GROQ_LOG` to `info`.
224224

225225
```shell
226-
$ export GROQ_LOG=debug
226+
$ export GROQ_LOG=info
227227
```
228228

229+
Or to `debug` for more verbose logging.
230+
229231
### How to tell whether `None` means `null` or missing
230232

231233
In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:

mypy.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ show_error_codes = True
55
# Exclude _files.py because mypy isn't smart enough to apply
66
# the correct type narrowing and as this is an internal module
77
# it's fine to just use Pyright.
8-
exclude = ^(src/groq/_files\.py|_dev/.*\.py)$
8+
#
9+
# We also exclude our `tests` as mypy doesn't always infer
10+
# types correctly and Pyright will still catch any type errors.
11+
exclude = ^(src/groq/_files\.py|_dev/.*\.py|tests/.*)$
912

1013
strict_equality = True
1114
implicit_reexport = True

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "groq"
3-
version = "0.12.0"
3+
version = "0.13.0"
44
description = "The official Python library for the groq API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"
@@ -14,7 +14,6 @@ dependencies = [
1414
"anyio>=3.5.0, <5",
1515
"distro>=1.7.0, <2",
1616
"sniffio",
17-
"cached-property; python_version < '3.8'",
1817
]
1918
requires-python = ">= 3.8"
2019
classifiers = [
@@ -55,6 +54,7 @@ dev-dependencies = [
5554
"dirty-equals>=0.6.0",
5655
"importlib-metadata>=6.7.0",
5756
"rich>=13.7.1",
57+
"nest_asyncio==1.6.0"
5858
]
5959

6060
[tool.rye.scripts]

requirements-dev.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mdurl==0.1.2
5151
mypy==1.13.0
5252
mypy-extensions==1.0.0
5353
# via mypy
54+
nest-asyncio==1.6.0
5455
nodeenv==1.8.0
5556
# via pyright
5657
nox==2023.4.22

src/groq/_base_client.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ def __init__(
792792
custom_query: Mapping[str, object] | None = None,
793793
_strict_response_validation: bool,
794794
) -> None:
795+
kwargs: dict[str, Any] = {}
795796
if limits is not None:
796797
warnings.warn(
797798
"The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead",
@@ -804,6 +805,7 @@ def __init__(
804805
limits = DEFAULT_CONNECTION_LIMITS
805806

806807
if transport is not None:
808+
kwargs["transport"] = transport
807809
warnings.warn(
808810
"The `transport` argument is deprecated. The `http_client` argument should be passed instead",
809811
category=DeprecationWarning,
@@ -813,6 +815,7 @@ def __init__(
813815
raise ValueError("The `http_client` argument is mutually exclusive with `transport`")
814816

815817
if proxies is not None:
818+
kwargs["proxies"] = proxies
816819
warnings.warn(
817820
"The `proxies` argument is deprecated. The `http_client` argument should be passed instead",
818821
category=DeprecationWarning,
@@ -856,10 +859,9 @@ def __init__(
856859
base_url=base_url,
857860
# cast to a valid type because mypy doesn't understand our type narrowing
858861
timeout=cast(Timeout, timeout),
859-
proxies=proxies,
860-
transport=transport,
861862
limits=limits,
862863
follow_redirects=True,
864+
**kwargs, # type: ignore
863865
)
864866

865867
def is_closed(self) -> bool:
@@ -1358,6 +1360,7 @@ def __init__(
13581360
custom_headers: Mapping[str, str] | None = None,
13591361
custom_query: Mapping[str, object] | None = None,
13601362
) -> None:
1363+
kwargs: dict[str, Any] = {}
13611364
if limits is not None:
13621365
warnings.warn(
13631366
"The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead",
@@ -1370,6 +1373,7 @@ def __init__(
13701373
limits = DEFAULT_CONNECTION_LIMITS
13711374

13721375
if transport is not None:
1376+
kwargs["transport"] = transport
13731377
warnings.warn(
13741378
"The `transport` argument is deprecated. The `http_client` argument should be passed instead",
13751379
category=DeprecationWarning,
@@ -1379,6 +1383,7 @@ def __init__(
13791383
raise ValueError("The `http_client` argument is mutually exclusive with `transport`")
13801384

13811385
if proxies is not None:
1386+
kwargs["proxies"] = proxies
13821387
warnings.warn(
13831388
"The `proxies` argument is deprecated. The `http_client` argument should be passed instead",
13841389
category=DeprecationWarning,
@@ -1422,10 +1427,9 @@ def __init__(
14221427
base_url=base_url,
14231428
# cast to a valid type because mypy doesn't understand our type narrowing
14241429
timeout=cast(Timeout, timeout),
1425-
proxies=proxies,
1426-
transport=transport,
14271430
limits=limits,
14281431
follow_redirects=True,
1432+
**kwargs, # type: ignore
14291433
)
14301434

14311435
def is_closed(self) -> bool:

src/groq/_compat.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ def model_dump(
145145
exclude=exclude,
146146
exclude_unset=exclude_unset,
147147
exclude_defaults=exclude_defaults,
148-
warnings=warnings,
148+
# warnings are not supported in Pydantic v1
149+
warnings=warnings if PYDANTIC_V2 else True,
149150
)
150151
return cast(
151152
"dict[str, Any]",
@@ -213,9 +214,6 @@ def __set_name__(self, owner: type[Any], name: str) -> None: ...
213214
# __set__ is not defined at runtime, but @cached_property is designed to be settable
214215
def __set__(self, instance: object, value: _T) -> None: ...
215216
else:
216-
try:
217-
from functools import cached_property as cached_property
218-
except ImportError:
219-
from cached_property import cached_property as cached_property
217+
from functools import cached_property as cached_property
220218

221219
typed_cached_property = cached_property

src/groq/_utils/_sync.py

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,62 @@
11
from __future__ import annotations
22

3+
import sys
4+
import asyncio
35
import functools
4-
from typing import TypeVar, Callable, Awaitable
6+
import contextvars
7+
from typing import Any, TypeVar, Callable, Awaitable
58
from typing_extensions import ParamSpec
69

7-
import anyio
8-
import anyio.to_thread
9-
10-
from ._reflection import function_has_argument
11-
1210
T_Retval = TypeVar("T_Retval")
1311
T_ParamSpec = ParamSpec("T_ParamSpec")
1412

1513

16-
# copied from `asyncer`, https://github.com/tiangolo/asyncer
17-
def asyncify(
18-
function: Callable[T_ParamSpec, T_Retval],
19-
*,
20-
cancellable: bool = False,
21-
limiter: anyio.CapacityLimiter | None = None,
22-
) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
14+
if sys.version_info >= (3, 9):
15+
to_thread = asyncio.to_thread
16+
else:
17+
# backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
18+
# for Python 3.8 support
19+
async def to_thread(
20+
func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
21+
) -> Any:
22+
"""Asynchronously run function *func* in a separate thread.
23+
24+
Any *args and **kwargs supplied for this function are directly passed
25+
to *func*. Also, the current :class:`contextvars.Context` is propagated,
26+
allowing context variables from the main thread to be accessed in the
27+
separate thread.
28+
29+
Returns a coroutine that can be awaited to get the eventual result of *func*.
30+
"""
31+
loop = asyncio.events.get_running_loop()
32+
ctx = contextvars.copy_context()
33+
func_call = functools.partial(ctx.run, func, *args, **kwargs)
34+
return await loop.run_in_executor(None, func_call)
35+
36+
37+
# inspired by `asyncer`, https://github.com/tiangolo/asyncer
38+
def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
2339
"""
2440
Take a blocking function and create an async one that receives the same
25-
positional and keyword arguments, and that when called, calls the original function
26-
in a worker thread using `anyio.to_thread.run_sync()`. Internally,
27-
`asyncer.asyncify()` uses the same `anyio.to_thread.run_sync()`, but it supports
28-
keyword arguments additional to positional arguments and it adds better support for
29-
autocompletion and inline errors for the arguments of the function called and the
30-
return value.
31-
32-
If the `cancellable` option is enabled and the task waiting for its completion is
33-
cancelled, the thread will still run its course but its return value (or any raised
34-
exception) will be ignored.
41+
positional and keyword arguments. For python version 3.9 and above, it uses
42+
asyncio.to_thread to run the function in a separate thread. For python version
43+
3.8, it uses locally defined copy of the asyncio.to_thread function which was
44+
introduced in python 3.9.
3545
36-
Use it like this:
46+
Usage:
3747
38-
```Python
39-
def do_work(arg1, arg2, kwarg1="", kwarg2="") -> str:
40-
# Do work
41-
return "Some result"
48+
```python
49+
def blocking_func(arg1, arg2, kwarg1=None):
50+
# blocking code
51+
return result
4252
4353
44-
result = await to_thread.asyncify(do_work)("spam", "ham", kwarg1="a", kwarg2="b")
45-
print(result)
54+
result = asyncify(blocking_function)(arg1, arg2, kwarg1=value1)
4655
```
4756
4857
## Arguments
4958
5059
`function`: a blocking regular callable (e.g. a function)
51-
`cancellable`: `True` to allow cancellation of the operation
52-
`limiter`: capacity limiter to use to limit the total amount of threads running
53-
(if omitted, the default limiter is used)
5460
5561
## Return
5662
@@ -60,22 +66,6 @@ def do_work(arg1, arg2, kwarg1="", kwarg2="") -> str:
6066
"""
6167

6268
async def wrapper(*args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs) -> T_Retval:
63-
partial_f = functools.partial(function, *args, **kwargs)
64-
65-
# In `v4.1.0` anyio added the `abandon_on_cancel` argument and deprecated the old
66-
# `cancellable` argument, so we need to use the new `abandon_on_cancel` to avoid
67-
# surfacing deprecation warnings.
68-
if function_has_argument(anyio.to_thread.run_sync, "abandon_on_cancel"):
69-
return await anyio.to_thread.run_sync(
70-
partial_f,
71-
abandon_on_cancel=cancellable,
72-
limiter=limiter,
73-
)
74-
75-
return await anyio.to_thread.run_sync(
76-
partial_f,
77-
cancellable=cancellable,
78-
limiter=limiter,
79-
)
69+
return await to_thread(function, *args, **kwargs)
8070

8171
return wrapper

0 commit comments

Comments
 (0)