Skip to content

Commit 5dbbf4f

Browse files
feat(api): api update
1 parent 44dd397 commit 5dbbf4f

File tree

9 files changed

+351
-22
lines changed

9 files changed

+351
-22
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
runs-on: ${{ github.repository == 'stainless-sdks/asktable-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
2020
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
2121
steps:
22-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@v6
2323

2424
- name: Install Rye
2525
run: |
@@ -44,7 +44,7 @@ jobs:
4444
id-token: write
4545
runs-on: ${{ github.repository == 'stainless-sdks/asktable-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
4646
steps:
47-
- uses: actions/checkout@v4
47+
- uses: actions/checkout@v6
4848

4949
- name: Install Rye
5050
run: |
@@ -81,7 +81,7 @@ jobs:
8181
runs-on: ${{ github.repository == 'stainless-sdks/asktable-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
8282
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
8383
steps:
84-
- uses: actions/checkout@v4
84+
- uses: actions/checkout@v6
8585

8686
- name: Install Rye
8787
run: |

.github/workflows/publish-pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515

1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v6
1818

1919
- name: Install Rye
2020
run: |

.github/workflows/release-doctor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
if: github.repository == 'DataMini/asktable-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
1313

1414
steps:
15-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@v6
1616

1717
- name: Check release environment
1818
run: |

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 105
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/datamini%2Fasktable-39e6a02a4b1efbdc298cc690c13278116fc24056874c9d9e67ffa7f716a37689.yml
3-
openapi_spec_hash: 6cd27ccd9e4616130078dcd0d7c95ba4
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/datamini%2Fasktable-f3bda395c29259f9059f182277574a0a665d6fd12a7d4002803cf35d045dedaf.yml
3+
openapi_spec_hash: 351d7b616d2d0cc2fdf8074f51187b87
44
config_hash: acdf4142177ed1932c2d82372693f811

src/asktable/_base_client.py

Lines changed: 134 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import inspect
1010
import logging
1111
import platform
12+
import warnings
1213
import email.utils
1314
from types import TracebackType
1415
from random import random
@@ -51,9 +52,11 @@
5152
ResponseT,
5253
AnyMapping,
5354
PostParser,
55+
BinaryTypes,
5456
RequestFiles,
5557
HttpxSendArgs,
5658
RequestOptions,
59+
AsyncBinaryTypes,
5760
HttpxRequestFiles,
5861
ModelBuilderProtocol,
5962
not_given,
@@ -477,8 +480,19 @@ def _build_request(
477480
retries_taken: int = 0,
478481
) -> httpx.Request:
479482
if log.isEnabledFor(logging.DEBUG):
480-
log.debug("Request options: %s", model_dump(options, exclude_unset=True))
481-
483+
log.debug(
484+
"Request options: %s",
485+
model_dump(
486+
options,
487+
exclude_unset=True,
488+
# Pydantic v1 can't dump every type we support in content, so we exclude it for now.
489+
exclude={
490+
"content",
491+
}
492+
if PYDANTIC_V1
493+
else {},
494+
),
495+
)
482496
kwargs: dict[str, Any] = {}
483497

484498
json_data = options.json_data
@@ -532,7 +546,13 @@ def _build_request(
532546
is_body_allowed = options.method.lower() != "get"
533547

534548
if is_body_allowed:
535-
if isinstance(json_data, bytes):
549+
if options.content is not None and json_data is not None:
550+
raise TypeError("Passing both `content` and `json_data` is not supported")
551+
if options.content is not None and files is not None:
552+
raise TypeError("Passing both `content` and `files` is not supported")
553+
if options.content is not None:
554+
kwargs["content"] = options.content
555+
elif isinstance(json_data, bytes):
536556
kwargs["content"] = json_data
537557
else:
538558
kwargs["json"] = json_data if is_given(json_data) else None
@@ -1194,6 +1214,7 @@ def post(
11941214
*,
11951215
cast_to: Type[ResponseT],
11961216
body: Body | None = None,
1217+
content: BinaryTypes | None = None,
11971218
options: RequestOptions = {},
11981219
files: RequestFiles | None = None,
11991220
stream: Literal[False] = False,
@@ -1206,6 +1227,7 @@ def post(
12061227
*,
12071228
cast_to: Type[ResponseT],
12081229
body: Body | None = None,
1230+
content: BinaryTypes | None = None,
12091231
options: RequestOptions = {},
12101232
files: RequestFiles | None = None,
12111233
stream: Literal[True],
@@ -1219,6 +1241,7 @@ def post(
12191241
*,
12201242
cast_to: Type[ResponseT],
12211243
body: Body | None = None,
1244+
content: BinaryTypes | None = None,
12221245
options: RequestOptions = {},
12231246
files: RequestFiles | None = None,
12241247
stream: bool,
@@ -1231,13 +1254,25 @@ def post(
12311254
*,
12321255
cast_to: Type[ResponseT],
12331256
body: Body | None = None,
1257+
content: BinaryTypes | None = None,
12341258
options: RequestOptions = {},
12351259
files: RequestFiles | None = None,
12361260
stream: bool = False,
12371261
stream_cls: type[_StreamT] | None = None,
12381262
) -> ResponseT | _StreamT:
1263+
if body is not None and content is not None:
1264+
raise TypeError("Passing both `body` and `content` is not supported")
1265+
if files is not None and content is not None:
1266+
raise TypeError("Passing both `files` and `content` is not supported")
1267+
if isinstance(body, bytes):
1268+
warnings.warn(
1269+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1270+
"Please pass raw bytes via the `content` parameter instead.",
1271+
DeprecationWarning,
1272+
stacklevel=2,
1273+
)
12391274
opts = FinalRequestOptions.construct(
1240-
method="post", url=path, json_data=body, files=to_httpx_files(files), **options
1275+
method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
12411276
)
12421277
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
12431278

@@ -1247,11 +1282,23 @@ def patch(
12471282
*,
12481283
cast_to: Type[ResponseT],
12491284
body: Body | None = None,
1285+
content: BinaryTypes | None = None,
12501286
files: RequestFiles | None = None,
12511287
options: RequestOptions = {},
12521288
) -> ResponseT:
1289+
if body is not None and content is not None:
1290+
raise TypeError("Passing both `body` and `content` is not supported")
1291+
if files is not None and content is not None:
1292+
raise TypeError("Passing both `files` and `content` is not supported")
1293+
if isinstance(body, bytes):
1294+
warnings.warn(
1295+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1296+
"Please pass raw bytes via the `content` parameter instead.",
1297+
DeprecationWarning,
1298+
stacklevel=2,
1299+
)
12531300
opts = FinalRequestOptions.construct(
1254-
method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
1301+
method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
12551302
)
12561303
return self.request(cast_to, opts)
12571304

@@ -1261,11 +1308,23 @@ def put(
12611308
*,
12621309
cast_to: Type[ResponseT],
12631310
body: Body | None = None,
1311+
content: BinaryTypes | None = None,
12641312
files: RequestFiles | None = None,
12651313
options: RequestOptions = {},
12661314
) -> ResponseT:
1315+
if body is not None and content is not None:
1316+
raise TypeError("Passing both `body` and `content` is not supported")
1317+
if files is not None and content is not None:
1318+
raise TypeError("Passing both `files` and `content` is not supported")
1319+
if isinstance(body, bytes):
1320+
warnings.warn(
1321+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1322+
"Please pass raw bytes via the `content` parameter instead.",
1323+
DeprecationWarning,
1324+
stacklevel=2,
1325+
)
12671326
opts = FinalRequestOptions.construct(
1268-
method="put", url=path, json_data=body, files=to_httpx_files(files), **options
1327+
method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
12691328
)
12701329
return self.request(cast_to, opts)
12711330

@@ -1275,9 +1334,19 @@ def delete(
12751334
*,
12761335
cast_to: Type[ResponseT],
12771336
body: Body | None = None,
1337+
content: BinaryTypes | None = None,
12781338
options: RequestOptions = {},
12791339
) -> ResponseT:
1280-
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
1340+
if body is not None and content is not None:
1341+
raise TypeError("Passing both `body` and `content` is not supported")
1342+
if isinstance(body, bytes):
1343+
warnings.warn(
1344+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1345+
"Please pass raw bytes via the `content` parameter instead.",
1346+
DeprecationWarning,
1347+
stacklevel=2,
1348+
)
1349+
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
12811350
return self.request(cast_to, opts)
12821351

12831352
def get_api_list(
@@ -1717,6 +1786,7 @@ async def post(
17171786
*,
17181787
cast_to: Type[ResponseT],
17191788
body: Body | None = None,
1789+
content: AsyncBinaryTypes | None = None,
17201790
files: RequestFiles | None = None,
17211791
options: RequestOptions = {},
17221792
stream: Literal[False] = False,
@@ -1729,6 +1799,7 @@ async def post(
17291799
*,
17301800
cast_to: Type[ResponseT],
17311801
body: Body | None = None,
1802+
content: AsyncBinaryTypes | None = None,
17321803
files: RequestFiles | None = None,
17331804
options: RequestOptions = {},
17341805
stream: Literal[True],
@@ -1742,6 +1813,7 @@ async def post(
17421813
*,
17431814
cast_to: Type[ResponseT],
17441815
body: Body | None = None,
1816+
content: AsyncBinaryTypes | None = None,
17451817
files: RequestFiles | None = None,
17461818
options: RequestOptions = {},
17471819
stream: bool,
@@ -1754,13 +1826,25 @@ async def post(
17541826
*,
17551827
cast_to: Type[ResponseT],
17561828
body: Body | None = None,
1829+
content: AsyncBinaryTypes | None = None,
17571830
files: RequestFiles | None = None,
17581831
options: RequestOptions = {},
17591832
stream: bool = False,
17601833
stream_cls: type[_AsyncStreamT] | None = None,
17611834
) -> ResponseT | _AsyncStreamT:
1835+
if body is not None and content is not None:
1836+
raise TypeError("Passing both `body` and `content` is not supported")
1837+
if files is not None and content is not None:
1838+
raise TypeError("Passing both `files` and `content` is not supported")
1839+
if isinstance(body, bytes):
1840+
warnings.warn(
1841+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1842+
"Please pass raw bytes via the `content` parameter instead.",
1843+
DeprecationWarning,
1844+
stacklevel=2,
1845+
)
17621846
opts = FinalRequestOptions.construct(
1763-
method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1847+
method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
17641848
)
17651849
return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
17661850

@@ -1770,11 +1854,28 @@ async def patch(
17701854
*,
17711855
cast_to: Type[ResponseT],
17721856
body: Body | None = None,
1857+
content: AsyncBinaryTypes | None = None,
17731858
files: RequestFiles | None = None,
17741859
options: RequestOptions = {},
17751860
) -> ResponseT:
1861+
if body is not None and content is not None:
1862+
raise TypeError("Passing both `body` and `content` is not supported")
1863+
if files is not None and content is not None:
1864+
raise TypeError("Passing both `files` and `content` is not supported")
1865+
if isinstance(body, bytes):
1866+
warnings.warn(
1867+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1868+
"Please pass raw bytes via the `content` parameter instead.",
1869+
DeprecationWarning,
1870+
stacklevel=2,
1871+
)
17761872
opts = FinalRequestOptions.construct(
1777-
method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1873+
method="patch",
1874+
url=path,
1875+
json_data=body,
1876+
content=content,
1877+
files=await async_to_httpx_files(files),
1878+
**options,
17781879
)
17791880
return await self.request(cast_to, opts)
17801881

@@ -1784,11 +1885,23 @@ async def put(
17841885
*,
17851886
cast_to: Type[ResponseT],
17861887
body: Body | None = None,
1888+
content: AsyncBinaryTypes | None = None,
17871889
files: RequestFiles | None = None,
17881890
options: RequestOptions = {},
17891891
) -> ResponseT:
1892+
if body is not None and content is not None:
1893+
raise TypeError("Passing both `body` and `content` is not supported")
1894+
if files is not None and content is not None:
1895+
raise TypeError("Passing both `files` and `content` is not supported")
1896+
if isinstance(body, bytes):
1897+
warnings.warn(
1898+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1899+
"Please pass raw bytes via the `content` parameter instead.",
1900+
DeprecationWarning,
1901+
stacklevel=2,
1902+
)
17901903
opts = FinalRequestOptions.construct(
1791-
method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1904+
method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
17921905
)
17931906
return await self.request(cast_to, opts)
17941907

@@ -1798,9 +1911,19 @@ async def delete(
17981911
*,
17991912
cast_to: Type[ResponseT],
18001913
body: Body | None = None,
1914+
content: AsyncBinaryTypes | None = None,
18011915
options: RequestOptions = {},
18021916
) -> ResponseT:
1803-
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
1917+
if body is not None and content is not None:
1918+
raise TypeError("Passing both `body` and `content` is not supported")
1919+
if isinstance(body, bytes):
1920+
warnings.warn(
1921+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1922+
"Please pass raw bytes via the `content` parameter instead.",
1923+
DeprecationWarning,
1924+
stacklevel=2,
1925+
)
1926+
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
18041927
return await self.request(cast_to, opts)
18051928

18061929
def get_api_list(

src/asktable/_models.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,20 @@
33
import os
44
import inspect
55
import weakref
6-
from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
6+
from typing import (
7+
IO,
8+
TYPE_CHECKING,
9+
Any,
10+
Type,
11+
Union,
12+
Generic,
13+
TypeVar,
14+
Callable,
15+
Iterable,
16+
Optional,
17+
AsyncIterable,
18+
cast,
19+
)
720
from datetime import date, datetime
821
from typing_extensions import (
922
List,
@@ -787,6 +800,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
787800
timeout: float | Timeout | None
788801
files: HttpxRequestFiles | None
789802
idempotency_key: str
803+
content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]
790804
json_data: Body
791805
extra_json: AnyMapping
792806
follow_redirects: bool
@@ -805,6 +819,7 @@ class FinalRequestOptions(pydantic.BaseModel):
805819
post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
806820
follow_redirects: Union[bool, None] = None
807821

822+
content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None
808823
# It should be noted that we cannot use `json` here as that would override
809824
# a BaseModel method in an incompatible fashion.
810825
json_data: Union[Body, None] = None

0 commit comments

Comments
 (0)