Skip to content

Commit 90da631

Browse files
authored
Merge pull request #603 from runloopai/release-please--branches--main--changes--next
release: 0.44.0
2 parents 9b40fb9 + 23a4617 commit 90da631

31 files changed

+357
-245
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
- 'integrated/**'
88
- 'stl-preview-head/**'
99
- 'stl-preview-base/**'
10+
pull_request:
11+
branches-ignore:
12+
- 'stl-preview-head/**'
13+
- 'stl-preview-base/**'
1014

1115
jobs:
1216
lint:

.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.43.0"
2+
".": "0.44.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 91
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-32aaecf1da425c37d534ed04df36003ab9d766a7755cd18f96541929a2a3ea59.yml
3-
openapi_spec_hash: e326c47b99943cbbab473fde3b257221
4-
config_hash: 421e8d0e71c7ef71fdfebede08ea7271
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-ecb3d41adaf06e76fd95f11d6da77c7aa0119387a3f372e736edd1579ec2aa03.yml
3+
openapi_spec_hash: 2671664b7d6b0107a6402746033a65ac
4+
config_hash: c4d0f5cf7262a18f9254da07d289f3ec

CHANGELOG.md

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

3+
## 0.44.0 (2025-06-21)
4+
5+
Full Changelog: [v0.43.0...v0.44.0](https://github.com/runloopai/api-client-python/compare/v0.43.0...v0.44.0)
6+
7+
### Features
8+
9+
* **api:** api update ([8bd0a39](https://github.com/runloopai/api-client-python/commit/8bd0a3937ff3d5b3e03a34ab2fc291377bbc4203))
10+
* **api:** api update ([8ebd055](https://github.com/runloopai/api-client-python/commit/8ebd055bb3760c7a01193df890ca7e56d7ff9c01))
11+
* **client:** add support for aiohttp ([4237321](https://github.com/runloopai/api-client-python/commit/4237321688934fcc89a17588800ce33fb47d9633))
12+
13+
14+
### Bug Fixes
15+
16+
* **tests:** fix: tests which call HTTP endpoints directly with the example parameters ([038fe71](https://github.com/runloopai/api-client-python/commit/038fe71f5d0bee93bdcad12af69a8f5b09b6664f))
17+
18+
19+
### Chores
20+
21+
* **ci:** enable for pull requests ([f64b8a2](https://github.com/runloopai/api-client-python/commit/f64b8a2a52a28a86f25d8b8ad1998e9ce4dda542))
22+
* **internal:** update conftest.py ([d840c86](https://github.com/runloopai/api-client-python/commit/d840c863eb3b080202874080e44b8ab0baa379c4))
23+
* **readme:** update badges ([4b5af3f](https://github.com/runloopai/api-client-python/commit/4b5af3faf2f3cfbcee8474b864335eb0a4c0a78b))
24+
* **tests:** add tests for httpx client instantiation & proxies ([938b9aa](https://github.com/runloopai/api-client-python/commit/938b9aa33ef7ae52809ca6e9111fc3265d70263d))
25+
26+
27+
### Documentation
28+
29+
* **client:** fix httpx.Timeout documentation reference ([b8df915](https://github.com/runloopai/api-client-python/commit/b8df91557df34f77ce5a6f85769305628d9f2a1d))
30+
331
## 0.43.0 (2025-06-14)
432

533
Full Changelog: [v0.42.0...v0.43.0](https://github.com/runloopai/api-client-python/compare/v0.42.0...v0.43.0)

README.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Runloop Python API library
22

3-
[![PyPI version](https://img.shields.io/pypi/v/runloop_api_client.svg)](https://pypi.org/project/runloop_api_client/)
3+
[![PyPI version](<https://img.shields.io/pypi/v/runloop_api_client.svg?label=pypi%20(stable)>)](https://pypi.org/project/runloop_api_client/)
44

55
The Runloop Python library provides convenient access to the Runloop REST API from any Python 3.8+
66
application. The library includes type definitions for all request params and response fields,
@@ -64,6 +64,38 @@ asyncio.run(main())
6464

6565
Functionality between the synchronous and asynchronous clients is otherwise identical.
6666

67+
### With aiohttp
68+
69+
By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.
70+
71+
You can enable this by installing `aiohttp`:
72+
73+
```sh
74+
# install from PyPI
75+
pip install runloop_api_client[aiohttp]
76+
```
77+
78+
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
79+
80+
```python
81+
import os
82+
import asyncio
83+
from runloop_api_client import DefaultAioHttpClient
84+
from runloop_api_client import AsyncRunloop
85+
86+
87+
async def main() -> None:
88+
async with AsyncRunloop(
89+
bearer_token=os.environ.get("RUNLOOP_API_KEY"), # This is the default and can be omitted
90+
http_client=DefaultAioHttpClient(),
91+
) as client:
92+
devbox_view = await client.devboxes.create()
93+
print(devbox_view.id)
94+
95+
96+
asyncio.run(main())
97+
```
98+
6799
## Using types
68100

69101
Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
@@ -235,7 +267,7 @@ client.with_options(max_retries=5).devboxes.create()
235267
### Timeouts
236268

237269
By default requests time out after 1 minute. You can configure this with a `timeout` option,
238-
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
270+
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
239271

240272
```python
241273
from runloop_api_client import Runloop

api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ from runloop_api_client.types import (
268268
ScenarioEnvironment,
269269
ScenarioRunListView,
270270
ScenarioRunView,
271+
ScenarioUpdateParameters,
271272
ScenarioView,
272273
ScoringContract,
273274
ScoringContractResultView,

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "runloop_api_client"
3-
version = "0.43.0"
3+
version = "0.44.0"
44
description = "The official Python library for the runloop API"
55
dynamic = ["readme"]
66
license = "MIT"
@@ -37,6 +37,8 @@ classifiers = [
3737
Homepage = "https://github.com/runloopai/api-client-python"
3838
Repository = "https://github.com/runloopai/api-client-python"
3939

40+
[project.optional-dependencies]
41+
aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.6"]
4042

4143
[tool.rye]
4244
managed = true

requirements-dev.lock

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,24 @@
1010
# universal: false
1111

1212
-e file:.
13+
aiohappyeyeballs==2.6.1
14+
# via aiohttp
15+
aiohttp==3.12.8
16+
# via httpx-aiohttp
17+
# via runloop-api-client
18+
aiosignal==1.3.2
19+
# via aiohttp
1320
annotated-types==0.6.0
1421
# via pydantic
1522
anyio==4.4.0
1623
# via httpx
1724
# via runloop-api-client
1825
argcomplete==3.1.2
1926
# via nox
27+
async-timeout==5.0.1
28+
# via aiohttp
29+
attrs==25.3.0
30+
# via aiohttp
2031
certifi==2023.7.22
2132
# via httpcore
2233
# via httpx
@@ -34,23 +45,33 @@ execnet==2.1.1
3445
# via pytest-xdist
3546
filelock==3.12.4
3647
# via virtualenv
48+
frozenlist==1.6.2
49+
# via aiohttp
50+
# via aiosignal
3751
h11==0.14.0
3852
# via httpcore
3953
httpcore==1.0.2
4054
# via httpx
4155
httpx==0.28.1
56+
# via httpx-aiohttp
4257
# via respx
4358
# via runloop-api-client
59+
httpx-aiohttp==0.1.6
60+
# via runloop-api-client
4461
idna==3.4
4562
# via anyio
4663
# via httpx
64+
# via yarl
4765
importlib-metadata==7.0.0
4866
iniconfig==2.0.0
4967
# via pytest
5068
markdown-it-py==3.0.0
5169
# via rich
5270
mdurl==0.1.2
5371
# via markdown-it-py
72+
multidict==6.4.4
73+
# via aiohttp
74+
# via yarl
5475
mypy==1.14.1
5576
mypy-extensions==1.0.0
5677
# via mypy
@@ -65,6 +86,9 @@ platformdirs==3.11.0
6586
# via virtualenv
6687
pluggy==1.5.0
6788
# via pytest
89+
propcache==0.3.1
90+
# via aiohttp
91+
# via yarl
6892
pydantic==2.10.3
6993
# via runloop-api-client
7094
pydantic-core==2.27.1
@@ -97,12 +121,15 @@ tomli==2.0.2
97121
# via pytest
98122
typing-extensions==4.12.2
99123
# via anyio
124+
# via multidict
100125
# via mypy
101126
# via pydantic
102127
# via pydantic-core
103128
# via pyright
104129
# via runloop-api-client
105130
virtualenv==20.24.5
106131
# via nox
132+
yarl==1.20.0
133+
# via aiohttp
107134
zipp==3.17.0
108135
# via importlib-metadata

requirements.lock

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,51 @@
1010
# universal: false
1111

1212
-e file:.
13+
aiohappyeyeballs==2.6.1
14+
# via aiohttp
15+
aiohttp==3.12.8
16+
# via httpx-aiohttp
17+
# via runloop-api-client
18+
aiosignal==1.3.2
19+
# via aiohttp
1320
annotated-types==0.6.0
1421
# via pydantic
1522
anyio==4.4.0
1623
# via httpx
1724
# via runloop-api-client
25+
async-timeout==5.0.1
26+
# via aiohttp
27+
attrs==25.3.0
28+
# via aiohttp
1829
certifi==2023.7.22
1930
# via httpcore
2031
# via httpx
2132
distro==1.8.0
2233
# via runloop-api-client
2334
exceptiongroup==1.2.2
2435
# via anyio
36+
frozenlist==1.6.2
37+
# via aiohttp
38+
# via aiosignal
2539
h11==0.14.0
2640
# via httpcore
2741
httpcore==1.0.2
2842
# via httpx
2943
httpx==0.28.1
44+
# via httpx-aiohttp
45+
# via runloop-api-client
46+
httpx-aiohttp==0.1.6
3047
# via runloop-api-client
3148
idna==3.4
3249
# via anyio
3350
# via httpx
51+
# via yarl
52+
multidict==6.4.4
53+
# via aiohttp
54+
# via yarl
55+
propcache==0.3.1
56+
# via aiohttp
57+
# via yarl
3458
pydantic==2.10.3
3559
# via runloop-api-client
3660
pydantic-core==2.27.1
@@ -40,6 +64,9 @@ sniffio==1.3.0
4064
# via runloop-api-client
4165
typing-extensions==4.12.2
4266
# via anyio
67+
# via multidict
4368
# via pydantic
4469
# via pydantic-core
4570
# via runloop-api-client
71+
yarl==1.20.0
72+
# via aiohttp

src/runloop_api_client/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
UnprocessableEntityError,
2727
APIResponseValidationError,
2828
)
29-
from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
29+
from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
3030
from ._utils._logs import setup_logging as _setup_logging
3131

3232
__all__ = [
@@ -68,6 +68,7 @@
6868
"DEFAULT_CONNECTION_LIMITS",
6969
"DefaultHttpxClient",
7070
"DefaultAsyncHttpxClient",
71+
"DefaultAioHttpClient",
7172
]
7273

7374
if not _t.TYPE_CHECKING:

src/runloop_api_client/_base_client.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,24 @@ def __init__(self, **kwargs: Any) -> None:
12891289
super().__init__(**kwargs)
12901290

12911291

1292+
try:
1293+
import httpx_aiohttp
1294+
except ImportError:
1295+
1296+
class _DefaultAioHttpClient(httpx.AsyncClient):
1297+
def __init__(self, **_kwargs: Any) -> None:
1298+
raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
1299+
else:
1300+
1301+
class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
1302+
def __init__(self, **kwargs: Any) -> None:
1303+
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
1304+
kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
1305+
kwargs.setdefault("follow_redirects", True)
1306+
1307+
super().__init__(**kwargs)
1308+
1309+
12921310
if TYPE_CHECKING:
12931311
DefaultAsyncHttpxClient = httpx.AsyncClient
12941312
"""An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
@@ -1297,8 +1315,12 @@ def __init__(self, **kwargs: Any) -> None:
12971315
This is useful because overriding the `http_client` with your own instance of
12981316
`httpx.AsyncClient` will result in httpx's defaults being used, not ours.
12991317
"""
1318+
1319+
DefaultAioHttpClient = httpx.AsyncClient
1320+
"""An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
13001321
else:
13011322
DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
1323+
DefaultAioHttpClient = _DefaultAioHttpClient
13021324

13031325

13041326
class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):

src/runloop_api_client/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "runloop_api_client"
4-
__version__ = "0.43.0" # x-release-please-version
4+
__version__ = "0.44.0" # x-release-please-version

0 commit comments

Comments
 (0)