Skip to content

Commit e91bc38

Browse files
feat: add POST /browsers/{id}/curl and /curl/raw endpoints
1 parent e566aa5 commit e91bc38

File tree

7 files changed

+323
-5
lines changed

7 files changed

+323
-5
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 111
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-7d048a0d07483d4fa8d1094f5ec172d1758f044b4e5ced1f41f92f1de8b47def.yml
3-
openapi_spec_hash: 0ffef6a95f9d9b1096180fc5e4c5b39c
4-
config_hash: 9818dd634f87b677410eefd013d7a179
1+
configured_endpoints: 112
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-930823e8b25b4644b74098ad5479840f64a329321aa236460f8a9562ae9051bf.yml
3+
openapi_spec_hash: 9f868e67df8fd2fec8d8fc3eb5ba0b26
4+
config_hash: 08d55086449943a8fec212b870061a3f

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ from kernel.types import (
8888
BrowserRetrieveResponse,
8989
BrowserUpdateResponse,
9090
BrowserListResponse,
91+
BrowserCurlResponse,
9192
)
9293
```
9394

@@ -98,6 +99,7 @@ Methods:
9899
- <code title="patch /browsers/{id}">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">update</a>(id, \*\*<a href="src/kernel/types/browser_update_params.py">params</a>) -> <a href="./src/kernel/types/browser_update_response.py">BrowserUpdateResponse</a></code>
99100
- <code title="get /browsers">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">list</a>(\*\*<a href="src/kernel/types/browser_list_params.py">params</a>) -> <a href="./src/kernel/types/browser_list_response.py">SyncOffsetPagination[BrowserListResponse]</a></code>
100101
- <code title="delete /browsers">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">delete</a>(\*\*<a href="src/kernel/types/browser_delete_params.py">params</a>) -> None</code>
102+
- <code title="post /browsers/{id}/curl">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">curl</a>(id, \*\*<a href="src/kernel/types/browser_curl_params.py">params</a>) -> <a href="./src/kernel/types/browser_curl_response.py">BrowserCurlResponse</a></code>
101103
- <code title="delete /browsers/{id}">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">delete_by_id</a>(id) -> None</code>
102104
- <code title="post /browsers/{id}/extensions">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">load_extensions</a>(id, \*\*<a href="src/kernel/types/browser_load_extensions_params.py">params</a>) -> None</code>
103105

src/kernel/resources/browsers/browsers.py

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import typing_extensions
6-
from typing import Mapping, Iterable, Optional, cast
6+
from typing import Dict, Mapping, Iterable, Optional, cast
77
from typing_extensions import Literal
88

99
import httpx
@@ -25,6 +25,7 @@
2525
AsyncFsResourceWithStreamingResponse,
2626
)
2727
from ...types import (
28+
browser_curl_params,
2829
browser_list_params,
2930
browser_create_params,
3031
browser_delete_params,
@@ -76,6 +77,7 @@
7677
)
7778
from ...pagination import SyncOffsetPagination, AsyncOffsetPagination
7879
from ..._base_client import AsyncPaginator, make_request_options
80+
from ...types.browser_curl_response import BrowserCurlResponse
7981
from ...types.browser_list_response import BrowserListResponse
8082
from ...types.browser_create_response import BrowserCreateResponse
8183
from ...types.browser_update_response import BrowserUpdateResponse
@@ -443,6 +445,70 @@ def delete(
443445
cast_to=NoneType,
444446
)
445447

448+
def curl(
449+
self,
450+
id: str,
451+
*,
452+
url: str,
453+
body: str | Omit = omit,
454+
headers: Dict[str, str] | Omit = omit,
455+
method: Literal["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] | Omit = omit,
456+
response_encoding: Literal["utf8", "base64"] | Omit = omit,
457+
timeout_ms: int | Omit = omit,
458+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
459+
# The extra values given here take precedence over values defined on the client or passed to this method.
460+
extra_headers: Headers | None = None,
461+
extra_query: Query | None = None,
462+
extra_body: Body | None = None,
463+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
464+
) -> BrowserCurlResponse:
465+
"""
466+
Sends an HTTP request through Chrome's HTTP request stack, inheriting the
467+
browser's TLS fingerprint, cookies, proxy configuration, and headers. Returns a
468+
structured JSON response with status, headers, body, and timing.
469+
470+
Args:
471+
url: Target URL (must be http or https).
472+
473+
body: Request body (for POST/PUT/PATCH).
474+
475+
headers: Custom headers merged with browser defaults.
476+
477+
method: HTTP method.
478+
479+
response_encoding: Encoding for the response body. Use base64 for binary content.
480+
481+
timeout_ms: Request timeout in milliseconds.
482+
483+
extra_headers: Send extra headers
484+
485+
extra_query: Add additional query parameters to the request
486+
487+
extra_body: Add additional JSON properties to the request
488+
489+
timeout: Override the client-level default timeout for this request, in seconds
490+
"""
491+
if not id:
492+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
493+
return self._post(
494+
path_template("/browsers/{id}/curl", id=id),
495+
body=maybe_transform(
496+
{
497+
"url": url,
498+
"body": body,
499+
"headers": headers,
500+
"method": method,
501+
"response_encoding": response_encoding,
502+
"timeout_ms": timeout_ms,
503+
},
504+
browser_curl_params.BrowserCurlParams,
505+
),
506+
options=make_request_options(
507+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
508+
),
509+
cast_to=BrowserCurlResponse,
510+
)
511+
446512
def delete_by_id(
447513
self,
448514
id: str,
@@ -881,6 +947,70 @@ async def delete(
881947
cast_to=NoneType,
882948
)
883949

950+
async def curl(
951+
self,
952+
id: str,
953+
*,
954+
url: str,
955+
body: str | Omit = omit,
956+
headers: Dict[str, str] | Omit = omit,
957+
method: Literal["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] | Omit = omit,
958+
response_encoding: Literal["utf8", "base64"] | Omit = omit,
959+
timeout_ms: int | Omit = omit,
960+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
961+
# The extra values given here take precedence over values defined on the client or passed to this method.
962+
extra_headers: Headers | None = None,
963+
extra_query: Query | None = None,
964+
extra_body: Body | None = None,
965+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
966+
) -> BrowserCurlResponse:
967+
"""
968+
Sends an HTTP request through Chrome's HTTP request stack, inheriting the
969+
browser's TLS fingerprint, cookies, proxy configuration, and headers. Returns a
970+
structured JSON response with status, headers, body, and timing.
971+
972+
Args:
973+
url: Target URL (must be http or https).
974+
975+
body: Request body (for POST/PUT/PATCH).
976+
977+
headers: Custom headers merged with browser defaults.
978+
979+
method: HTTP method.
980+
981+
response_encoding: Encoding for the response body. Use base64 for binary content.
982+
983+
timeout_ms: Request timeout in milliseconds.
984+
985+
extra_headers: Send extra headers
986+
987+
extra_query: Add additional query parameters to the request
988+
989+
extra_body: Add additional JSON properties to the request
990+
991+
timeout: Override the client-level default timeout for this request, in seconds
992+
"""
993+
if not id:
994+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
995+
return await self._post(
996+
path_template("/browsers/{id}/curl", id=id),
997+
body=await async_maybe_transform(
998+
{
999+
"url": url,
1000+
"body": body,
1001+
"headers": headers,
1002+
"method": method,
1003+
"response_encoding": response_encoding,
1004+
"timeout_ms": timeout_ms,
1005+
},
1006+
browser_curl_params.BrowserCurlParams,
1007+
),
1008+
options=make_request_options(
1009+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1010+
),
1011+
cast_to=BrowserCurlResponse,
1012+
)
1013+
8841014
async def delete_by_id(
8851015
self,
8861016
id: str,
@@ -983,6 +1113,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
9831113
browsers.delete, # pyright: ignore[reportDeprecated],
9841114
)
9851115
)
1116+
self.curl = to_raw_response_wrapper(
1117+
browsers.curl,
1118+
)
9861119
self.delete_by_id = to_raw_response_wrapper(
9871120
browsers.delete_by_id,
9881121
)
@@ -1041,6 +1174,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
10411174
browsers.delete, # pyright: ignore[reportDeprecated],
10421175
)
10431176
)
1177+
self.curl = async_to_raw_response_wrapper(
1178+
browsers.curl,
1179+
)
10441180
self.delete_by_id = async_to_raw_response_wrapper(
10451181
browsers.delete_by_id,
10461182
)
@@ -1099,6 +1235,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
10991235
browsers.delete, # pyright: ignore[reportDeprecated],
11001236
)
11011237
)
1238+
self.curl = to_streamed_response_wrapper(
1239+
browsers.curl,
1240+
)
11021241
self.delete_by_id = to_streamed_response_wrapper(
11031242
browsers.delete_by_id,
11041243
)
@@ -1157,6 +1296,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
11571296
browsers.delete, # pyright: ignore[reportDeprecated],
11581297
)
11591298
)
1299+
self.curl = async_to_streamed_response_wrapper(
1300+
browsers.curl,
1301+
)
11601302
self.delete_by_id = async_to_streamed_response_wrapper(
11611303
browsers.delete_by_id,
11621304
)

src/kernel/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .browser_pool_ref import BrowserPoolRef as BrowserPoolRef
2323
from .app_list_response import AppListResponse as AppListResponse
2424
from .proxy_check_params import ProxyCheckParams as ProxyCheckParams
25+
from .browser_curl_params import BrowserCurlParams as BrowserCurlParams
2526
from .browser_list_params import BrowserListParams as BrowserListParams
2627
from .browser_persistence import BrowserPersistence as BrowserPersistence
2728
from .credential_provider import CredentialProvider as CredentialProvider
@@ -31,6 +32,7 @@
3132
from .proxy_list_response import ProxyListResponse as ProxyListResponse
3233
from .proxy_check_response import ProxyCheckResponse as ProxyCheckResponse
3334
from .browser_create_params import BrowserCreateParams as BrowserCreateParams
35+
from .browser_curl_response import BrowserCurlResponse as BrowserCurlResponse
3436
from .browser_delete_params import BrowserDeleteParams as BrowserDeleteParams
3537
from .browser_list_response import BrowserListResponse as BrowserListResponse
3638
from .browser_update_params import BrowserUpdateParams as BrowserUpdateParams
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import Dict
6+
from typing_extensions import Literal, Required, TypedDict
7+
8+
__all__ = ["BrowserCurlParams"]
9+
10+
11+
class BrowserCurlParams(TypedDict, total=False):
12+
url: Required[str]
13+
"""Target URL (must be http or https)."""
14+
15+
body: str
16+
"""Request body (for POST/PUT/PATCH)."""
17+
18+
headers: Dict[str, str]
19+
"""Custom headers merged with browser defaults."""
20+
21+
method: Literal["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
22+
"""HTTP method."""
23+
24+
response_encoding: Literal["utf8", "base64"]
25+
"""Encoding for the response body. Use base64 for binary content."""
26+
27+
timeout_ms: int
28+
"""Request timeout in milliseconds."""
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Dict, List
4+
5+
from .._models import BaseModel
6+
7+
__all__ = ["BrowserCurlResponse"]
8+
9+
10+
class BrowserCurlResponse(BaseModel):
11+
"""Structured response from the browser curl request."""
12+
13+
body: str
14+
"""Response body (UTF-8 string or base64 depending on request)."""
15+
16+
duration_ms: int
17+
"""Total request duration in milliseconds."""
18+
19+
headers: Dict[str, List[str]]
20+
"""Response headers (multi-value)."""
21+
22+
status: int
23+
"""HTTP status code from target."""

0 commit comments

Comments
 (0)