Skip to content

Commit 9a84bff

Browse files
feat: Add GET /browsers/{id}/telemetry/events (read from S2)
1 parent e330f60 commit 9a84bff

8 files changed

Lines changed: 400 additions & 6 deletions

File tree

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 121
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-01f7f21a2fc892da284edf6b7cfd340d2ce5d0a9eb7ad2b39a8daec27b093134.yml
3-
openapi_spec_hash: 21972930082b23d985faf285fd656c31
4-
config_hash: 3a50aee540dce69a53bb8942f5086f5e
1+
configured_endpoints: 122
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-7cde13c82c71b7a5fd64b592f853a7c999c0e0c02dce161e6126d0e99df3412b.yml
3+
openapi_spec_hash: 52cda226c70a248cbea3af6c52822b44
4+
config_hash: 99b2b2a25e8067ad9c9214e38e01d64c

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,14 @@ from kernel.types.browsers import (
146146
BrowserTelemetryCategoryConfig,
147147
BrowserTelemetryConfig,
148148
BrowserTelemetryEvent,
149+
TelemetryEventsResponse,
149150
TelemetryStreamResponse,
150151
)
151152
```
152153

153154
Methods:
154155

156+
- <code title="get /browsers/{id}/telemetry/events">client.browsers.telemetry.<a href="./src/kernel/resources/browsers/telemetry.py">events</a>(id, \*\*<a href="src/kernel/types/browsers/telemetry_events_params.py">params</a>) -> <a href="./src/kernel/types/browsers/telemetry_events_response.py">SyncOffsetPagination[TelemetryEventsResponse]</a></code>
155157
- <code title="get /browsers/{id}/telemetry/stream">client.browsers.telemetry.<a href="./src/kernel/resources/browsers/telemetry.py">stream</a>(id, \*\*<a href="src/kernel/types/browsers/telemetry_stream_params.py">params</a>) -> <a href="./src/kernel/types/browsers/telemetry_stream_response.py">TelemetryStreamResponse</a></code>
156158

157159
## Replays

src/kernel/resources/browsers/telemetry.py

Lines changed: 189 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
from __future__ import annotations
44

5+
from typing import List
6+
from typing_extensions import Literal
7+
58
import httpx
69

710
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
@@ -15,8 +18,10 @@
1518
async_to_streamed_response_wrapper,
1619
)
1720
from ..._streaming import Stream, AsyncStream
18-
from ..._base_client import make_request_options
19-
from ...types.browsers import telemetry_stream_params
21+
from ...pagination import SyncOffsetPagination, AsyncOffsetPagination
22+
from ..._base_client import AsyncPaginator, make_request_options
23+
from ...types.browsers import telemetry_events_params, telemetry_stream_params
24+
from ...types.browsers.telemetry_events_response import TelemetryEventsResponse
2025
from ...types.browsers.telemetry_stream_response import TelemetryStreamResponse
2126

2227
__all__ = ["TelemetryResource", "AsyncTelemetryResource"]
@@ -44,6 +49,91 @@ def with_streaming_response(self) -> TelemetryResourceWithStreamingResponse:
4449
"""
4550
return TelemetryResourceWithStreamingResponse(self)
4651

52+
def events(
53+
self,
54+
id: str,
55+
*,
56+
category: List[
57+
Literal[
58+
"console",
59+
"network",
60+
"page",
61+
"interaction",
62+
"control",
63+
"connection",
64+
"system",
65+
"screenshot",
66+
"captcha",
67+
"monitor",
68+
]
69+
]
70+
| Omit = omit,
71+
limit: int | Omit = omit,
72+
offset: int | Omit = omit,
73+
since: str | Omit = omit,
74+
until: str | Omit = omit,
75+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
76+
# The extra values given here take precedence over values defined on the client or passed to this method.
77+
extra_headers: Headers | None = None,
78+
extra_query: Query | None = None,
79+
extra_body: Body | None = None,
80+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
81+
) -> SyncOffsetPagination[TelemetryEventsResponse]:
82+
"""
83+
Reads a page of telemetry events for the browser session in ascending sequence
84+
order. To page through results, pass the X-Next-Offset value from the previous
85+
response as offset and repeat while X-Has-More is true. Returns an empty list
86+
when telemetry data is unavailable.
87+
88+
Args:
89+
category: Restrict results to these event categories. Repeat the parameter for multiple
90+
values.
91+
92+
limit: Maximum number of events per page. Defaults to 20.
93+
94+
offset: Opaque pagination cursor: pass the X-Next-Offset value from the previous
95+
response to fetch the next page. When set, paging continues from this cursor and
96+
since is ignored, while until still bounds the page. It is not an event's seq
97+
field, so do not derive it from the response body.
98+
99+
since: Start of the window: an RFC-3339 timestamp, or a duration like 5m meaning that
100+
long ago. Defaults to 5m. Ignored when offset is set.
101+
102+
until: End of the window (exclusive): an RFC-3339 timestamp, or a duration like 5m
103+
meaning that long ago.
104+
105+
extra_headers: Send extra headers
106+
107+
extra_query: Add additional query parameters to the request
108+
109+
extra_body: Add additional JSON properties to the request
110+
111+
timeout: Override the client-level default timeout for this request, in seconds
112+
"""
113+
if not id:
114+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
115+
return self._get_api_list(
116+
path_template("/browsers/{id}/telemetry/events", id=id),
117+
page=SyncOffsetPagination[TelemetryEventsResponse],
118+
options=make_request_options(
119+
extra_headers=extra_headers,
120+
extra_query=extra_query,
121+
extra_body=extra_body,
122+
timeout=timeout,
123+
query=maybe_transform(
124+
{
125+
"category": category,
126+
"limit": limit,
127+
"offset": offset,
128+
"since": since,
129+
"until": until,
130+
},
131+
telemetry_events_params.TelemetryEventsParams,
132+
),
133+
),
134+
model=TelemetryEventsResponse,
135+
)
136+
47137
def stream(
48138
self,
49139
id: str,
@@ -123,6 +213,91 @@ def with_streaming_response(self) -> AsyncTelemetryResourceWithStreamingResponse
123213
"""
124214
return AsyncTelemetryResourceWithStreamingResponse(self)
125215

216+
def events(
217+
self,
218+
id: str,
219+
*,
220+
category: List[
221+
Literal[
222+
"console",
223+
"network",
224+
"page",
225+
"interaction",
226+
"control",
227+
"connection",
228+
"system",
229+
"screenshot",
230+
"captcha",
231+
"monitor",
232+
]
233+
]
234+
| Omit = omit,
235+
limit: int | Omit = omit,
236+
offset: int | Omit = omit,
237+
since: str | Omit = omit,
238+
until: str | Omit = omit,
239+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
240+
# The extra values given here take precedence over values defined on the client or passed to this method.
241+
extra_headers: Headers | None = None,
242+
extra_query: Query | None = None,
243+
extra_body: Body | None = None,
244+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
245+
) -> AsyncPaginator[TelemetryEventsResponse, AsyncOffsetPagination[TelemetryEventsResponse]]:
246+
"""
247+
Reads a page of telemetry events for the browser session in ascending sequence
248+
order. To page through results, pass the X-Next-Offset value from the previous
249+
response as offset and repeat while X-Has-More is true. Returns an empty list
250+
when telemetry data is unavailable.
251+
252+
Args:
253+
category: Restrict results to these event categories. Repeat the parameter for multiple
254+
values.
255+
256+
limit: Maximum number of events per page. Defaults to 20.
257+
258+
offset: Opaque pagination cursor: pass the X-Next-Offset value from the previous
259+
response to fetch the next page. When set, paging continues from this cursor and
260+
since is ignored, while until still bounds the page. It is not an event's seq
261+
field, so do not derive it from the response body.
262+
263+
since: Start of the window: an RFC-3339 timestamp, or a duration like 5m meaning that
264+
long ago. Defaults to 5m. Ignored when offset is set.
265+
266+
until: End of the window (exclusive): an RFC-3339 timestamp, or a duration like 5m
267+
meaning that long ago.
268+
269+
extra_headers: Send extra headers
270+
271+
extra_query: Add additional query parameters to the request
272+
273+
extra_body: Add additional JSON properties to the request
274+
275+
timeout: Override the client-level default timeout for this request, in seconds
276+
"""
277+
if not id:
278+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
279+
return self._get_api_list(
280+
path_template("/browsers/{id}/telemetry/events", id=id),
281+
page=AsyncOffsetPagination[TelemetryEventsResponse],
282+
options=make_request_options(
283+
extra_headers=extra_headers,
284+
extra_query=extra_query,
285+
extra_body=extra_body,
286+
timeout=timeout,
287+
query=maybe_transform(
288+
{
289+
"category": category,
290+
"limit": limit,
291+
"offset": offset,
292+
"since": since,
293+
"until": until,
294+
},
295+
telemetry_events_params.TelemetryEventsParams,
296+
),
297+
),
298+
model=TelemetryEventsResponse,
299+
)
300+
126301
async def stream(
127302
self,
128303
id: str,
@@ -184,6 +359,9 @@ class TelemetryResourceWithRawResponse:
184359
def __init__(self, telemetry: TelemetryResource) -> None:
185360
self._telemetry = telemetry
186361

362+
self.events = to_raw_response_wrapper(
363+
telemetry.events,
364+
)
187365
self.stream = to_raw_response_wrapper(
188366
telemetry.stream,
189367
)
@@ -193,6 +371,9 @@ class AsyncTelemetryResourceWithRawResponse:
193371
def __init__(self, telemetry: AsyncTelemetryResource) -> None:
194372
self._telemetry = telemetry
195373

374+
self.events = async_to_raw_response_wrapper(
375+
telemetry.events,
376+
)
196377
self.stream = async_to_raw_response_wrapper(
197378
telemetry.stream,
198379
)
@@ -202,6 +383,9 @@ class TelemetryResourceWithStreamingResponse:
202383
def __init__(self, telemetry: TelemetryResource) -> None:
203384
self._telemetry = telemetry
204385

386+
self.events = to_streamed_response_wrapper(
387+
telemetry.events,
388+
)
205389
self.stream = to_streamed_response_wrapper(
206390
telemetry.stream,
207391
)
@@ -211,6 +395,9 @@ class AsyncTelemetryResourceWithStreamingResponse:
211395
def __init__(self, telemetry: AsyncTelemetryResource) -> None:
212396
self._telemetry = telemetry
213397

398+
self.events = async_to_streamed_response_wrapper(
399+
telemetry.events,
400+
)
214401
self.stream = async_to_streamed_response_wrapper(
215402
telemetry.stream,
216403
)

src/kernel/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,11 @@
111111
browsers.browser_call_stack.BrowserCallStack.update_forward_refs() # type: ignore
112112
browsers.browser_console_error_event.BrowserConsoleErrorEvent.update_forward_refs() # type: ignore
113113
browsers.browser_console_log_event.BrowserConsoleLogEvent.update_forward_refs() # type: ignore
114+
browsers.telemetry_events_response.TelemetryEventsResponse.update_forward_refs() # type: ignore
114115
browsers.telemetry_stream_response.TelemetryStreamResponse.update_forward_refs() # type: ignore
115116
else:
116117
browsers.browser_call_stack.BrowserCallStack.model_rebuild(_parent_namespace_depth=0)
117118
browsers.browser_console_error_event.BrowserConsoleErrorEvent.model_rebuild(_parent_namespace_depth=0)
118119
browsers.browser_console_log_event.BrowserConsoleLogEvent.model_rebuild(_parent_namespace_depth=0)
120+
browsers.telemetry_events_response.TelemetryEventsResponse.model_rebuild(_parent_namespace_depth=0)
119121
browsers.telemetry_stream_response.TelemetryStreamResponse.model_rebuild(_parent_namespace_depth=0)

src/kernel/types/browsers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from .browser_telemetry_event import BrowserTelemetryEvent as BrowserTelemetryEvent
3838
from .process_resize_response import ProcessResizeResponse as ProcessResizeResponse
3939
from .process_status_response import ProcessStatusResponse as ProcessStatusResponse
40+
from .telemetry_events_params import TelemetryEventsParams as TelemetryEventsParams
4041
from .telemetry_stream_params import TelemetryStreamParams as TelemetryStreamParams
4142
from .browser_telemetry_config import BrowserTelemetryConfig as BrowserTelemetryConfig
4243
from .browser_cdp_connect_event import BrowserCdpConnectEvent as BrowserCdpConnectEvent
@@ -47,6 +48,7 @@
4748
from .f_delete_directory_params import FDeleteDirectoryParams as FDeleteDirectoryParams
4849
from .f_download_dir_zip_params import FDownloadDirZipParams as FDownloadDirZipParams
4950
from .playwright_execute_params import PlaywrightExecuteParams as PlaywrightExecuteParams
51+
from .telemetry_events_response import TelemetryEventsResponse as TelemetryEventsResponse
5052
from .telemetry_stream_response import TelemetryStreamResponse as TelemetryStreamResponse
5153
from .browser_network_idle_event import BrowserNetworkIdleEvent as BrowserNetworkIdleEvent
5254
from .computer_drag_mouse_params import ComputerDragMouseParams as ComputerDragMouseParams
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 List
6+
from typing_extensions import Literal, TypedDict
7+
8+
__all__ = ["TelemetryEventsParams"]
9+
10+
11+
class TelemetryEventsParams(TypedDict, total=False):
12+
category: List[
13+
Literal[
14+
"console",
15+
"network",
16+
"page",
17+
"interaction",
18+
"control",
19+
"connection",
20+
"system",
21+
"screenshot",
22+
"captcha",
23+
"monitor",
24+
]
25+
]
26+
"""Restrict results to these event categories.
27+
28+
Repeat the parameter for multiple values.
29+
"""
30+
31+
limit: int
32+
"""Maximum number of events per page. Defaults to 20."""
33+
34+
offset: int
35+
"""
36+
Opaque pagination cursor: pass the X-Next-Offset value from the previous
37+
response to fetch the next page. When set, paging continues from this cursor and
38+
since is ignored, while until still bounds the page. It is not an event's seq
39+
field, so do not derive it from the response body.
40+
"""
41+
42+
since: str
43+
"""
44+
Start of the window: an RFC-3339 timestamp, or a duration like 5m meaning that
45+
long ago. Defaults to 5m. Ignored when offset is set.
46+
"""
47+
48+
until: str
49+
"""
50+
End of the window (exclusive): an RFC-3339 timestamp, or a duration like 5m
51+
meaning that long ago.
52+
"""
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from ..._models import BaseModel
6+
7+
__all__ = ["TelemetryEventsResponse"]
8+
9+
10+
class TelemetryEventsResponse(BaseModel):
11+
"""Envelope wrapping a browser telemetry event with its monotonic sequence number.
12+
13+
Each SSE data: frame carries one envelope as JSON. The seq value is also emitted as the SSE id: field so clients can pass it as Last-Event-ID on reconnect.
14+
"""
15+
16+
event: "BrowserTelemetryEvent"
17+
"""Union type representing any browser telemetry event.
18+
19+
Discriminated on `type`. Each event's `category` determines when it is captured.
20+
The CDP collector-health events (monitor_disconnected, monitor_reconnected,
21+
monitor_reconnect_failed, monitor_init_failed) use the `monitor` category, which
22+
is not user-configurable: it flows automatically whenever any CDP category
23+
(console, network, page, interaction) is captured, and is silent otherwise.
24+
monitor_screenshot uses the opt-in `screenshot` category. All other event types
25+
are controlled by their per-category enable/disable flags.
26+
"""
27+
28+
seq: int
29+
"""Process-monotonic sequence number assigned by the browser VM.
30+
31+
Pass as Last-Event-ID on reconnect to resume without gaps. Gaps in received seq
32+
values indicate dropped events.
33+
"""
34+
35+
36+
from .browser_telemetry_event import BrowserTelemetryEvent

0 commit comments

Comments
 (0)