Skip to content

Commit 93a9613

Browse files
feat(api): api update
1 parent bd6977a commit 93a9613

File tree

9 files changed

+360
-21
lines changed

9 files changed

+360
-21
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/cas-parser-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/cas-parser-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/cas-parser-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 == 'CASParser/cas-parser-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: 4
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-7e6397bddc220d1a59b5e2c7e7c3ff38f1a6eb174f4e383e03bc49cf78c8c44f.yml
3-
openapi_spec_hash: cb852eeb4ce89c80f4246815cbe21f72
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-ce2296c4b14d27c141bb2745607d2456c923fdca3ae0a0a0800c26e564333850.yml
3+
openapi_spec_hash: 8eb586ccf16b534c0c15ff6a22274c7d
44
config_hash: cb5d75abef6264b5d86448caf7295afa

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ and offers both synchronous and asynchronous clients powered by [httpx](https://
99

1010
It is generated with [Stainless](https://www.stainless.com/).
1111

12+
## MCP Server
13+
14+
Use the Cas Parser MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
15+
16+
[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cas-parser-node-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNhcy1wYXJzZXItbm9kZS1tY3AiXX0)
17+
[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cas-parser-node-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cas-parser-node-mcp%22%5D%7D)
18+
19+
> Note: You may need to set environment variables in your MCP client.
20+
1221
## Documentation
1322

1423
The REST API documentation can be found on [docs.casparser.in](https://docs.casparser.in/reference). The full API of this library can be found in [api.md](api.md).

src/cas_parser/_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(

0 commit comments

Comments
 (0)