Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b788927
codegen metadata
stainless-app[bot] Jan 2, 2026
2eefb3c
codegen metadata
stainless-app[bot] Jan 2, 2026
288bcf3
feat(api): api update
stainless-app[bot] Jan 2, 2026
07039a1
feat(client): add support for binary request streaming
stainless-app[bot] Jan 13, 2026
eda3841
codegen metadata
stainless-app[bot] Jan 15, 2026
1841bbe
codegen metadata
stainless-app[bot] Jan 15, 2026
9cbc3e2
codegen metadata
stainless-app[bot] Jan 15, 2026
05659dd
codegen metadata
stainless-app[bot] Jan 15, 2026
1f5d0b3
codegen metadata
stainless-app[bot] Jan 15, 2026
91dea31
codegen metadata
stainless-app[bot] Jan 15, 2026
4595651
codegen metadata
stainless-app[bot] Jan 15, 2026
d5a5120
codegen metadata
stainless-app[bot] Jan 15, 2026
21b1aad
codegen metadata
stainless-app[bot] Jan 15, 2026
9365429
codegen metadata
stainless-app[bot] Jan 15, 2026
654c0f2
codegen metadata
stainless-app[bot] Jan 15, 2026
51d0aa1
codegen metadata
stainless-app[bot] Jan 16, 2026
9a56dc8
codegen metadata
stainless-app[bot] Jan 16, 2026
af8aa94
codegen metadata
stainless-app[bot] Jan 16, 2026
29a2cb2
codegen metadata
stainless-app[bot] Jan 16, 2026
06eb711
codegen metadata
stainless-app[bot] Jan 16, 2026
a110c5f
codegen metadata
stainless-app[bot] Jan 16, 2026
73086ca
codegen metadata
stainless-app[bot] Jan 16, 2026
49a3479
codegen metadata
stainless-app[bot] Jan 16, 2026
db4d66f
codegen metadata
stainless-app[bot] Jan 16, 2026
af173d3
codegen metadata
stainless-app[bot] Jan 16, 2026
85af380
chore(internal): update `actions/checkout` version
stainless-app[bot] Jan 16, 2026
68e9184
codegen metadata
stainless-app[bot] Jan 16, 2026
8669268
codegen metadata
stainless-app[bot] Jan 16, 2026
11fc725
codegen metadata
stainless-app[bot] Jan 16, 2026
9ee73ee
codegen metadata
stainless-app[bot] Jan 17, 2026
14307ca
codegen metadata
stainless-app[bot] Jan 17, 2026
14bc379
codegen metadata
stainless-app[bot] Jan 17, 2026
087d694
codegen metadata
stainless-app[bot] Jan 17, 2026
a7ab3cc
codegen metadata
stainless-app[bot] Jan 17, 2026
13fcfee
codegen metadata
stainless-app[bot] Jan 17, 2026
e2c9b35
codegen metadata
stainless-app[bot] Jan 17, 2026
95573eb
codegen metadata
stainless-app[bot] Jan 17, 2026
fff3369
codegen metadata
stainless-app[bot] Jan 17, 2026
0a099f1
codegen metadata
stainless-app[bot] Jan 17, 2026
22ad0ca
codegen metadata
stainless-app[bot] Jan 17, 2026
020550b
codegen metadata
stainless-app[bot] Jan 17, 2026
01ec923
codegen metadata
stainless-app[bot] Jan 17, 2026
35bec01
codegen metadata
stainless-app[bot] Jan 17, 2026
4e761b8
codegen metadata
stainless-app[bot] Jan 18, 2026
ccc0a0d
codegen metadata
stainless-app[bot] Jan 18, 2026
3ca8cbc
codegen metadata
stainless-app[bot] Jan 18, 2026
2d86499
codegen metadata
stainless-app[bot] Jan 18, 2026
3b094cb
codegen metadata
stainless-app[bot] Jan 18, 2026
7defdb4
codegen metadata
stainless-app[bot] Jan 18, 2026
1885f7b
codegen metadata
stainless-app[bot] Jan 18, 2026
ba1f223
codegen metadata
stainless-app[bot] Jan 18, 2026
20460f4
codegen metadata
stainless-app[bot] Jan 18, 2026
aa4a0f1
codegen metadata
stainless-app[bot] Jan 18, 2026
c2401fb
codegen metadata
stainless-app[bot] Jan 18, 2026
9e75e57
codegen metadata
stainless-app[bot] Jan 19, 2026
d52a8bd
codegen metadata
stainless-app[bot] Jan 19, 2026
7d06e79
codegen metadata
stainless-app[bot] Jan 19, 2026
a1a831b
release: 0.9.0
stainless-app[bot] Jan 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/agentex-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Install Rye
run: |
Expand All @@ -44,7 +44,7 @@ jobs:
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/agentex-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Install Rye
run: |
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/agentex-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Install Rye
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Install Rye
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
if: github.repository == 'scaleapi/scale-agentex-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Check release environment
run: |
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.8.2"
".": "0.9.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 35
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp%2Fagentex-sdk-43921054bad3c6969dc10f5899faa5924f3c029ccffb55965bbb6e7c9a0f22c6.yml
openapi_spec_hash: 17b74748a86bc159767dbb66ba46f54d
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp%2Fagentex-sdk-c9b5ca9e03141b62fa981944af1c880cd4562f0b697ed5f110c0e0e754f455ba.yml
openapi_spec_hash: 9ed347fceac28248d2a0acb49c4eb356
config_hash: 32eb65911c08ac84d117cecdf2759869
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.9.0 (2026-01-19)

Full Changelog: [v0.8.2...v0.9.0](https://github.com/scaleapi/scale-agentex-python/compare/v0.8.2...v0.9.0)

### Features

* **api:** api update ([288bcf3](https://github.com/scaleapi/scale-agentex-python/commit/288bcf3fcad0c50043ffa19b25f9f13128341362))
* **client:** add support for binary request streaming ([07039a1](https://github.com/scaleapi/scale-agentex-python/commit/07039a13dabeb375ca833bc98705d49aac1b69ed))


### Chores

* **internal:** update `actions/checkout` version ([85af380](https://github.com/scaleapi/scale-agentex-python/commit/85af38015fa7739569ea64ce1bf1f24384533773))

## 0.8.2 (2026-01-02)

Full Changelog: [v0.8.1...v0.8.2](https://github.com/scaleapi/scale-agentex-python/compare/v0.8.1...v0.8.2)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agentex-sdk"
version = "0.8.2"
version = "0.9.0"
description = "The official Python library for the agentex API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
145 changes: 134 additions & 11 deletions src/agentex/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import inspect
import logging
import platform
import warnings
import email.utils
from types import TracebackType
from random import random
Expand Down Expand Up @@ -51,9 +52,11 @@
ResponseT,
AnyMapping,
PostParser,
BinaryTypes,
RequestFiles,
HttpxSendArgs,
RequestOptions,
AsyncBinaryTypes,
HttpxRequestFiles,
ModelBuilderProtocol,
not_given,
Expand Down Expand Up @@ -477,8 +480,19 @@ def _build_request(
retries_taken: int = 0,
) -> httpx.Request:
if log.isEnabledFor(logging.DEBUG):
log.debug("Request options: %s", model_dump(options, exclude_unset=True))

log.debug(
"Request options: %s",
model_dump(
options,
exclude_unset=True,
# Pydantic v1 can't dump every type we support in content, so we exclude it for now.
exclude={
"content",
}
if PYDANTIC_V1
else {},
),
)
kwargs: dict[str, Any] = {}

json_data = options.json_data
Expand Down Expand Up @@ -532,7 +546,13 @@ def _build_request(
is_body_allowed = options.method.lower() != "get"

if is_body_allowed:
if isinstance(json_data, bytes):
if options.content is not None and json_data is not None:
raise TypeError("Passing both `content` and `json_data` is not supported")
if options.content is not None and files is not None:
raise TypeError("Passing both `content` and `files` is not supported")
if options.content is not None:
kwargs["content"] = options.content
elif isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
Expand Down Expand Up @@ -1194,6 +1214,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: Literal[False] = False,
Expand All @@ -1206,6 +1227,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: Literal[True],
Expand All @@ -1219,6 +1241,7 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: bool,
Expand All @@ -1231,13 +1254,25 @@ def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},
files: RequestFiles | None = None,
stream: bool = False,
stream_cls: type[_StreamT] | None = None,
) -> ResponseT | _StreamT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="post", url=path, json_data=body, files=to_httpx_files(files), **options
method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))

Expand All @@ -1247,11 +1282,23 @@ def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return self.request(cast_to, opts)

Expand All @@ -1261,11 +1308,23 @@ def put(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="put", url=path, json_data=body, files=to_httpx_files(files), **options
method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return self.request(cast_to, opts)

Expand All @@ -1275,9 +1334,19 @@ def delete(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},
) -> ResponseT:
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
return self.request(cast_to, opts)

def get_api_list(
Expand Down Expand Up @@ -1717,6 +1786,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: Literal[False] = False,
Expand All @@ -1729,6 +1799,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: Literal[True],
Expand All @@ -1742,6 +1813,7 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: bool,
Expand All @@ -1754,13 +1826,25 @@ async def post(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
stream: bool = False,
stream_cls: type[_AsyncStreamT] | None = None,
) -> ResponseT | _AsyncStreamT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options
method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
)
return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)

Expand All @@ -1770,11 +1854,28 @@ async def patch(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options
method="patch",
url=path,
json_data=body,
content=content,
files=await async_to_httpx_files(files),
**options,
)
return await self.request(cast_to, opts)

Expand All @@ -1784,11 +1885,23 @@ async def put(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options
method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
)
return await self.request(cast_to, opts)

Expand All @@ -1798,9 +1911,19 @@ async def delete(
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: AsyncBinaryTypes | None = None,
options: RequestOptions = {},
) -> ResponseT:
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
return await self.request(cast_to, opts)

def get_api_list(
Expand Down
Loading