lmnr 0.6.16__py3-none-any.whl → 0.7.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lmnr/__init__.py +6 -15
- lmnr/cli/__init__.py +270 -0
- lmnr/cli/datasets.py +371 -0
- lmnr/{cli.py → cli/evals.py} +20 -102
- lmnr/cli/rules.py +42 -0
- lmnr/opentelemetry_lib/__init__.py +9 -2
- lmnr/opentelemetry_lib/decorators/__init__.py +274 -168
- lmnr/opentelemetry_lib/litellm/__init__.py +352 -38
- lmnr/opentelemetry_lib/litellm/utils.py +82 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py +849 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/config.py +13 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_emitter.py +211 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_models.py +41 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/span_utils.py +401 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/streaming.py +425 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/utils.py +332 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py +1 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/claude_agent/__init__.py +451 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/claude_agent/proxy.py +144 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_agent/__init__.py +100 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/__init__.py +476 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/utils.py +12 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +191 -129
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py +26 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +126 -41
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py +488 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py +8 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_emitter.py +143 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_models.py +41 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/span_utils.py +229 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py +92 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py +1 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/kernel/__init__.py +381 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/kernel/utils.py +36 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +16 -16
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/__init__.py +61 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py +472 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +1185 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +305 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/config.py +16 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +312 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_emitter.py +100 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_models.py +41 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +68 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py +197 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v0/__init__.py +176 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/__init__.py +368 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +325 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +135 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +786 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py +1 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openhands_ai/__init__.py +388 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/opentelemetry/__init__.py +69 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py +59 -61
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py +197 -0
- lmnr/opentelemetry_lib/tracing/__init__.py +119 -18
- lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +124 -25
- lmnr/opentelemetry_lib/tracing/attributes.py +4 -0
- lmnr/opentelemetry_lib/tracing/context.py +200 -0
- lmnr/opentelemetry_lib/tracing/exporter.py +109 -15
- lmnr/opentelemetry_lib/tracing/instruments.py +22 -5
- lmnr/opentelemetry_lib/tracing/processor.py +128 -30
- lmnr/opentelemetry_lib/tracing/span.py +398 -0
- lmnr/opentelemetry_lib/tracing/tracer.py +40 -1
- lmnr/opentelemetry_lib/tracing/utils.py +62 -0
- lmnr/opentelemetry_lib/utils/package_check.py +9 -0
- lmnr/opentelemetry_lib/utils/wrappers.py +11 -0
- lmnr/sdk/browser/background_send_events.py +158 -0
- lmnr/sdk/browser/browser_use_cdp_otel.py +100 -0
- lmnr/sdk/browser/browser_use_otel.py +12 -12
- lmnr/sdk/browser/bubus_otel.py +71 -0
- lmnr/sdk/browser/cdp_utils.py +518 -0
- lmnr/sdk/browser/inject_script.js +514 -0
- lmnr/sdk/browser/patchright_otel.py +18 -44
- lmnr/sdk/browser/playwright_otel.py +104 -187
- lmnr/sdk/browser/pw_utils.py +249 -210
- lmnr/sdk/browser/recorder/record.umd.min.cjs +84 -0
- lmnr/sdk/browser/utils.py +1 -1
- lmnr/sdk/client/asynchronous/async_client.py +47 -15
- lmnr/sdk/client/asynchronous/resources/__init__.py +2 -7
- lmnr/sdk/client/asynchronous/resources/browser_events.py +1 -0
- lmnr/sdk/client/asynchronous/resources/datasets.py +131 -0
- lmnr/sdk/client/asynchronous/resources/evals.py +122 -18
- lmnr/sdk/client/asynchronous/resources/evaluators.py +85 -0
- lmnr/sdk/client/asynchronous/resources/tags.py +4 -10
- lmnr/sdk/client/synchronous/resources/__init__.py +2 -2
- lmnr/sdk/client/synchronous/resources/datasets.py +131 -0
- lmnr/sdk/client/synchronous/resources/evals.py +83 -17
- lmnr/sdk/client/synchronous/resources/evaluators.py +85 -0
- lmnr/sdk/client/synchronous/resources/tags.py +4 -10
- lmnr/sdk/client/synchronous/sync_client.py +47 -15
- lmnr/sdk/datasets/__init__.py +94 -0
- lmnr/sdk/datasets/file_utils.py +91 -0
- lmnr/sdk/decorators.py +103 -23
- lmnr/sdk/evaluations.py +122 -33
- lmnr/sdk/laminar.py +816 -333
- lmnr/sdk/log.py +7 -2
- lmnr/sdk/types.py +124 -143
- lmnr/sdk/utils.py +115 -2
- lmnr/version.py +1 -1
- {lmnr-0.6.16.dist-info → lmnr-0.7.26.dist-info}/METADATA +71 -78
- lmnr-0.7.26.dist-info/RECORD +116 -0
- lmnr-0.7.26.dist-info/WHEEL +4 -0
- lmnr-0.7.26.dist-info/entry_points.txt +3 -0
- lmnr/opentelemetry_lib/tracing/context_properties.py +0 -65
- lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +0 -98
- lmnr/sdk/client/asynchronous/resources/agent.py +0 -329
- lmnr/sdk/client/synchronous/resources/agent.py +0 -323
- lmnr/sdk/datasets.py +0 -60
- lmnr-0.6.16.dist-info/LICENSE +0 -75
- lmnr-0.6.16.dist-info/RECORD +0 -61
- lmnr-0.6.16.dist-info/WHEEL +0 -4
- lmnr-0.6.16.dist-info/entry_points.txt +0 -3
|
@@ -2,10 +2,14 @@ import logging
|
|
|
2
2
|
import uuid
|
|
3
3
|
|
|
4
4
|
from lmnr.opentelemetry_lib.utils.package_check import is_package_installed
|
|
5
|
-
from lmnr.sdk.browser.pw_utils import
|
|
5
|
+
from lmnr.sdk.browser.pw_utils import (
|
|
6
|
+
start_recording_events_async,
|
|
7
|
+
start_recording_events_sync,
|
|
8
|
+
take_full_snapshot,
|
|
9
|
+
take_full_snapshot_async,
|
|
10
|
+
)
|
|
6
11
|
from lmnr.sdk.browser.utils import with_tracer_and_client_wrapper
|
|
7
12
|
from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
|
|
8
|
-
from lmnr.sdk.client.synchronous.sync_client import LaminarClient
|
|
9
13
|
from lmnr.version import __version__
|
|
10
14
|
|
|
11
15
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
@@ -13,29 +17,22 @@ from opentelemetry.instrumentation.utils import unwrap
|
|
|
13
17
|
from opentelemetry.trace import (
|
|
14
18
|
get_tracer,
|
|
15
19
|
Tracer,
|
|
16
|
-
get_current_span,
|
|
17
|
-
Span,
|
|
18
|
-
INVALID_SPAN,
|
|
19
|
-
set_span_in_context,
|
|
20
20
|
)
|
|
21
|
-
from opentelemetry.context import get_current
|
|
22
21
|
from typing import Collection
|
|
23
22
|
from wrapt import wrap_function_wrapper
|
|
24
23
|
|
|
25
24
|
try:
|
|
26
25
|
if is_package_installed("playwright"):
|
|
27
|
-
from playwright.async_api import Browser, BrowserContext
|
|
26
|
+
from playwright.async_api import Browser, BrowserContext
|
|
28
27
|
from playwright.sync_api import (
|
|
29
28
|
Browser as SyncBrowser,
|
|
30
29
|
BrowserContext as SyncBrowserContext,
|
|
31
|
-
Page as SyncPage,
|
|
32
30
|
)
|
|
33
31
|
elif is_package_installed("patchright"):
|
|
34
|
-
from patchright.async_api import Browser, BrowserContext
|
|
32
|
+
from patchright.async_api import Browser, BrowserContext
|
|
35
33
|
from patchright.sync_api import (
|
|
36
34
|
Browser as SyncBrowser,
|
|
37
35
|
BrowserContext as SyncBrowserContext,
|
|
38
|
-
Page as SyncPage,
|
|
39
36
|
)
|
|
40
37
|
else:
|
|
41
38
|
raise ImportError(
|
|
@@ -54,67 +51,26 @@ except ImportError as e:
|
|
|
54
51
|
_instruments = ("playwright >= 1.9.0",)
|
|
55
52
|
logger = logging.getLogger(__name__)
|
|
56
53
|
|
|
57
|
-
_context_spans: dict[str, Span] = {}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@with_tracer_and_client_wrapper
|
|
61
|
-
def _wrap_new_page(
|
|
62
|
-
tracer: Tracer, client: LaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
63
|
-
):
|
|
64
|
-
with tracer.start_as_current_span(
|
|
65
|
-
f"{to_wrap.get('object')}.{to_wrap.get('method')}"
|
|
66
|
-
) as span:
|
|
67
|
-
page = wrapped(*args, **kwargs)
|
|
68
|
-
session_id = str(uuid.uuid4().hex)
|
|
69
|
-
trace_id = format(get_current_span().get_span_context().trace_id, "032x")
|
|
70
|
-
span.set_attribute("lmnr.internal.has_browser_session", True)
|
|
71
|
-
handle_navigation_sync(page, session_id, trace_id, client)
|
|
72
|
-
return page
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@with_tracer_and_client_wrapper
|
|
76
|
-
async def _wrap_new_page_async(
|
|
77
|
-
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
78
|
-
):
|
|
79
|
-
with tracer.start_as_current_span(
|
|
80
|
-
f"{to_wrap.get('object')}.{to_wrap.get('method')}"
|
|
81
|
-
) as span:
|
|
82
|
-
page = await wrapped(*args, **kwargs)
|
|
83
|
-
session_id = str(uuid.uuid4().hex)
|
|
84
|
-
trace_id = format(span.get_span_context().trace_id, "032x")
|
|
85
|
-
span.set_attribute("lmnr.internal.has_browser_session", True)
|
|
86
|
-
await handle_navigation_async(page, session_id, trace_id, client)
|
|
87
|
-
return page
|
|
88
|
-
|
|
89
54
|
|
|
90
55
|
@with_tracer_and_client_wrapper
|
|
91
56
|
def _wrap_new_browser_sync(
|
|
92
|
-
tracer: Tracer, client:
|
|
57
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
93
58
|
):
|
|
94
|
-
global _context_spans
|
|
95
59
|
browser: SyncBrowser = wrapped(*args, **kwargs)
|
|
96
60
|
session_id = str(uuid.uuid4().hex)
|
|
97
|
-
for context in browser.contexts:
|
|
98
|
-
span = get_current_span()
|
|
99
|
-
if span == INVALID_SPAN:
|
|
100
|
-
span = tracer.start_span(
|
|
101
|
-
name=f"{to_wrap.get('object')}.{to_wrap.get('method')}"
|
|
102
|
-
)
|
|
103
|
-
set_span_in_context(span, get_current())
|
|
104
|
-
_context_spans[id(context)] = span
|
|
105
|
-
span.set_attribute("lmnr.internal.has_browser_session", True)
|
|
106
|
-
trace_id = format(span.get_span_context().trace_id, "032x")
|
|
107
|
-
|
|
108
|
-
def handle_page_navigation(page: SyncPage):
|
|
109
|
-
return handle_navigation_sync(page, session_id, trace_id, client)
|
|
110
|
-
|
|
111
|
-
context.on(
|
|
112
|
-
"page",
|
|
113
|
-
handle_page_navigation,
|
|
114
|
-
)
|
|
115
61
|
|
|
62
|
+
def create_page_handler(session_id, client):
|
|
63
|
+
def page_handler(page):
|
|
64
|
+
start_recording_events_sync(page, session_id, client)
|
|
65
|
+
|
|
66
|
+
return page_handler
|
|
67
|
+
|
|
68
|
+
for context in browser.contexts:
|
|
69
|
+
page_handler = create_page_handler(session_id, client)
|
|
70
|
+
context.on("page", page_handler)
|
|
116
71
|
for page in context.pages:
|
|
117
|
-
|
|
72
|
+
start_recording_events_sync(page, session_id, client)
|
|
73
|
+
|
|
118
74
|
return browser
|
|
119
75
|
|
|
120
76
|
|
|
@@ -122,54 +78,41 @@ def _wrap_new_browser_sync(
|
|
|
122
78
|
async def _wrap_new_browser_async(
|
|
123
79
|
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
124
80
|
):
|
|
125
|
-
global _context_spans
|
|
126
81
|
browser: Browser = await wrapped(*args, **kwargs)
|
|
127
82
|
session_id = str(uuid.uuid4().hex)
|
|
83
|
+
|
|
84
|
+
def create_page_handler(session_id, client):
|
|
85
|
+
async def page_handler(page):
|
|
86
|
+
await start_recording_events_async(page, session_id, client)
|
|
87
|
+
|
|
88
|
+
return page_handler
|
|
89
|
+
|
|
128
90
|
for context in browser.contexts:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
span = tracer.start_span(
|
|
132
|
-
name=f"{to_wrap.get('object')}.{to_wrap.get('method')}"
|
|
133
|
-
)
|
|
134
|
-
set_span_in_context(span, get_current())
|
|
135
|
-
_context_spans[id(context)] = span
|
|
136
|
-
span.set_attribute("lmnr.internal.has_browser_session", True)
|
|
137
|
-
trace_id = format(span.get_span_context().trace_id, "032x")
|
|
138
|
-
|
|
139
|
-
async def handle_page_navigation(page: Page):
|
|
140
|
-
return await handle_navigation_async(page, session_id, trace_id, client)
|
|
141
|
-
|
|
142
|
-
context.on("page", handle_page_navigation)
|
|
91
|
+
page_handler = create_page_handler(session_id, client)
|
|
92
|
+
context.on("page", page_handler)
|
|
143
93
|
for page in context.pages:
|
|
144
|
-
await
|
|
94
|
+
await start_recording_events_async(page, session_id, client)
|
|
145
95
|
return browser
|
|
146
96
|
|
|
147
97
|
|
|
148
98
|
@with_tracer_and_client_wrapper
|
|
149
99
|
def _wrap_new_context_sync(
|
|
150
|
-
tracer: Tracer, client:
|
|
100
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
151
101
|
):
|
|
152
102
|
context: SyncBrowserContext = wrapped(*args, **kwargs)
|
|
153
103
|
session_id = str(uuid.uuid4().hex)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def handle_page_navigation(page: SyncPage):
|
|
165
|
-
return handle_navigation_sync(page, session_id, trace_id, client)
|
|
166
|
-
|
|
167
|
-
context.on(
|
|
168
|
-
"page",
|
|
169
|
-
handle_page_navigation,
|
|
170
|
-
)
|
|
104
|
+
|
|
105
|
+
def create_page_handler(session_id, client):
|
|
106
|
+
def page_handler(page):
|
|
107
|
+
start_recording_events_sync(page, session_id, client)
|
|
108
|
+
|
|
109
|
+
return page_handler
|
|
110
|
+
|
|
111
|
+
page_handler = create_page_handler(session_id, client)
|
|
112
|
+
context.on("page", page_handler)
|
|
171
113
|
for page in context.pages:
|
|
172
|
-
|
|
114
|
+
start_recording_events_sync(page, session_id, client)
|
|
115
|
+
|
|
173
116
|
return context
|
|
174
117
|
|
|
175
118
|
|
|
@@ -179,80 +122,58 @@ async def _wrap_new_context_async(
|
|
|
179
122
|
):
|
|
180
123
|
context: BrowserContext = await wrapped(*args, **kwargs)
|
|
181
124
|
session_id = str(uuid.uuid4().hex)
|
|
182
|
-
span = get_current_span()
|
|
183
|
-
if span == INVALID_SPAN:
|
|
184
|
-
span = tracer.start_span(
|
|
185
|
-
name=f"{to_wrap.get('object')}.{to_wrap.get('method')}"
|
|
186
|
-
)
|
|
187
|
-
set_span_in_context(span, get_current())
|
|
188
|
-
_context_spans[id(context)] = span
|
|
189
|
-
span.set_attribute("lmnr.internal.has_browser_session", True)
|
|
190
|
-
trace_id = format(span.get_span_context().trace_id, "032x")
|
|
191
125
|
|
|
192
|
-
|
|
193
|
-
|
|
126
|
+
def create_page_handler(session_id, client):
|
|
127
|
+
async def page_handler(page):
|
|
128
|
+
await start_recording_events_async(page, session_id, client)
|
|
129
|
+
|
|
130
|
+
return page_handler
|
|
194
131
|
|
|
195
|
-
|
|
132
|
+
page_handler = create_page_handler(session_id, client)
|
|
133
|
+
context.on("page", page_handler)
|
|
196
134
|
for page in context.pages:
|
|
197
|
-
await
|
|
135
|
+
await start_recording_events_async(page, session_id, client)
|
|
136
|
+
|
|
198
137
|
return context
|
|
199
138
|
|
|
200
139
|
|
|
201
140
|
@with_tracer_and_client_wrapper
|
|
202
|
-
def
|
|
203
|
-
tracer: Tracer,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
141
|
+
def _wrap_bring_to_front_sync(
|
|
142
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
143
|
+
):
|
|
144
|
+
wrapped(*args, **kwargs)
|
|
145
|
+
take_full_snapshot(instance)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@with_tracer_and_client_wrapper
|
|
149
|
+
async def _wrap_bring_to_front_async(
|
|
150
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
210
151
|
):
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
key = id(context)
|
|
214
|
-
span = _context_spans.get(key)
|
|
215
|
-
if span:
|
|
216
|
-
if span.is_recording():
|
|
217
|
-
span.end()
|
|
218
|
-
_context_spans.pop(key)
|
|
219
|
-
return wrapped(*args, **kwargs)
|
|
152
|
+
await wrapped(*args, **kwargs)
|
|
153
|
+
await take_full_snapshot_async(instance)
|
|
220
154
|
|
|
221
155
|
|
|
222
156
|
@with_tracer_and_client_wrapper
|
|
223
|
-
|
|
224
|
-
tracer: Tracer,
|
|
225
|
-
client: AsyncLaminarClient,
|
|
226
|
-
to_wrap,
|
|
227
|
-
wrapped,
|
|
228
|
-
instance: Browser,
|
|
229
|
-
args,
|
|
230
|
-
kwargs,
|
|
157
|
+
def _wrap_browser_new_page_sync(
|
|
158
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
231
159
|
):
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
160
|
+
page = wrapped(*args, **kwargs)
|
|
161
|
+
session_id = str(uuid.uuid4().hex)
|
|
162
|
+
start_recording_events_sync(page, session_id, client)
|
|
163
|
+
return page
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@with_tracer_and_client_wrapper
|
|
167
|
+
async def _wrap_browser_new_page_async(
|
|
168
|
+
tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
|
|
169
|
+
):
|
|
170
|
+
page = await wrapped(*args, **kwargs)
|
|
171
|
+
session_id = str(uuid.uuid4().hex)
|
|
172
|
+
await start_recording_events_async(page, session_id, client)
|
|
173
|
+
return page
|
|
241
174
|
|
|
242
175
|
|
|
243
176
|
WRAPPED_METHODS = [
|
|
244
|
-
{
|
|
245
|
-
"package": "playwright.sync_api",
|
|
246
|
-
"object": "BrowserContext",
|
|
247
|
-
"method": "new_page",
|
|
248
|
-
"wrapper": _wrap_new_page,
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
"package": "playwright.sync_api",
|
|
252
|
-
"object": "Browser",
|
|
253
|
-
"method": "new_page",
|
|
254
|
-
"wrapper": _wrap_new_page,
|
|
255
|
-
},
|
|
256
177
|
{
|
|
257
178
|
"package": "playwright.sync_api",
|
|
258
179
|
"object": "BrowserType",
|
|
@@ -271,12 +192,6 @@ WRAPPED_METHODS = [
|
|
|
271
192
|
"method": "connect_over_cdp",
|
|
272
193
|
"wrapper": _wrap_new_browser_sync,
|
|
273
194
|
},
|
|
274
|
-
{
|
|
275
|
-
"package": "playwright.sync_api",
|
|
276
|
-
"object": "Browser",
|
|
277
|
-
"method": "close",
|
|
278
|
-
"wrapper": _wrap_close_browser_sync,
|
|
279
|
-
},
|
|
280
195
|
{
|
|
281
196
|
"package": "playwright.sync_api",
|
|
282
197
|
"object": "Browser",
|
|
@@ -289,21 +204,21 @@ WRAPPED_METHODS = [
|
|
|
289
204
|
"method": "launch_persistent_context",
|
|
290
205
|
"wrapper": _wrap_new_context_sync,
|
|
291
206
|
},
|
|
292
|
-
]
|
|
293
|
-
|
|
294
|
-
WRAPPED_METHODS_ASYNC = [
|
|
295
207
|
{
|
|
296
|
-
"package": "playwright.
|
|
297
|
-
"object": "
|
|
298
|
-
"method": "
|
|
299
|
-
"wrapper":
|
|
208
|
+
"package": "playwright.sync_api",
|
|
209
|
+
"object": "Page",
|
|
210
|
+
"method": "bring_to_front",
|
|
211
|
+
"wrapper": _wrap_bring_to_front_sync,
|
|
300
212
|
},
|
|
301
213
|
{
|
|
302
|
-
"package": "playwright.
|
|
214
|
+
"package": "playwright.sync_api",
|
|
303
215
|
"object": "Browser",
|
|
304
216
|
"method": "new_page",
|
|
305
|
-
"wrapper":
|
|
217
|
+
"wrapper": _wrap_browser_new_page_sync,
|
|
306
218
|
},
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
WRAPPED_METHODS_ASYNC = [
|
|
307
222
|
{
|
|
308
223
|
"package": "playwright.async_api",
|
|
309
224
|
"object": "BrowserType",
|
|
@@ -322,12 +237,6 @@ WRAPPED_METHODS_ASYNC = [
|
|
|
322
237
|
"method": "connect_over_cdp",
|
|
323
238
|
"wrapper": _wrap_new_browser_async,
|
|
324
239
|
},
|
|
325
|
-
{
|
|
326
|
-
"package": "playwright.async_api",
|
|
327
|
-
"object": "Browser",
|
|
328
|
-
"method": "close",
|
|
329
|
-
"wrapper": _wrap_close_browser_async,
|
|
330
|
-
},
|
|
331
240
|
{
|
|
332
241
|
"package": "playwright.async_api",
|
|
333
242
|
"object": "Browser",
|
|
@@ -340,13 +249,24 @@ WRAPPED_METHODS_ASYNC = [
|
|
|
340
249
|
"method": "launch_persistent_context",
|
|
341
250
|
"wrapper": _wrap_new_context_async,
|
|
342
251
|
},
|
|
252
|
+
{
|
|
253
|
+
"package": "playwright.async_api",
|
|
254
|
+
"object": "Page",
|
|
255
|
+
"method": "bring_to_front",
|
|
256
|
+
"wrapper": _wrap_bring_to_front_async,
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"package": "playwright.async_api",
|
|
260
|
+
"object": "Browser",
|
|
261
|
+
"method": "new_page",
|
|
262
|
+
"wrapper": _wrap_browser_new_page_async,
|
|
263
|
+
},
|
|
343
264
|
]
|
|
344
265
|
|
|
345
266
|
|
|
346
267
|
class PlaywrightInstrumentor(BaseInstrumentor):
|
|
347
|
-
def __init__(self,
|
|
268
|
+
def __init__(self, async_client: AsyncLaminarClient):
|
|
348
269
|
super().__init__()
|
|
349
|
-
self.client = client
|
|
350
270
|
self.async_client = async_client
|
|
351
271
|
|
|
352
272
|
def instrumentation_dependencies(self) -> Collection[str]:
|
|
@@ -356,6 +276,8 @@ class PlaywrightInstrumentor(BaseInstrumentor):
|
|
|
356
276
|
tracer_provider = kwargs.get("tracer_provider")
|
|
357
277
|
tracer = get_tracer(__name__, __version__, tracer_provider)
|
|
358
278
|
|
|
279
|
+
# Both sync and async methods use async_client because we are using
|
|
280
|
+
# a background asyncio loop for async sends
|
|
359
281
|
for wrapped_method in WRAPPED_METHODS:
|
|
360
282
|
wrap_package = wrapped_method.get("package")
|
|
361
283
|
wrap_object = wrapped_method.get("object")
|
|
@@ -366,7 +288,7 @@ class PlaywrightInstrumentor(BaseInstrumentor):
|
|
|
366
288
|
f"{wrap_object}.{wrap_method}",
|
|
367
289
|
wrapped_method.get("wrapper")(
|
|
368
290
|
tracer,
|
|
369
|
-
self.
|
|
291
|
+
self.async_client,
|
|
370
292
|
wrapped_method,
|
|
371
293
|
),
|
|
372
294
|
)
|
|
@@ -393,13 +315,8 @@ class PlaywrightInstrumentor(BaseInstrumentor):
|
|
|
393
315
|
|
|
394
316
|
def _uninstrument(self, **kwargs):
|
|
395
317
|
# Unwrap methods
|
|
396
|
-
global _context_spans
|
|
397
318
|
for wrapped_method in WRAPPED_METHODS + WRAPPED_METHODS_ASYNC:
|
|
398
319
|
wrap_package = wrapped_method.get("package")
|
|
399
320
|
wrap_object = wrapped_method.get("object")
|
|
400
321
|
wrap_method = wrapped_method.get("method")
|
|
401
322
|
unwrap(wrap_package, f"{wrap_object}.{wrap_method}")
|
|
402
|
-
for span in _context_spans.values():
|
|
403
|
-
if span.is_recording():
|
|
404
|
-
span.end()
|
|
405
|
-
_context_spans = {}
|