lmnr 0.5.1a0__py3-none-any.whl → 0.5.3__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.
Files changed (50) hide show
  1. lmnr/__init__.py +2 -10
  2. lmnr/cli.py +10 -8
  3. lmnr/{openllmetry_sdk → opentelemetry_lib}/__init__.py +8 -36
  4. lmnr/{openllmetry_sdk → opentelemetry_lib}/decorators/base.py +27 -20
  5. lmnr/{openllmetry_sdk → opentelemetry_lib}/instruments.py +2 -0
  6. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +454 -0
  7. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +9 -0
  8. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +216 -0
  9. lmnr/opentelemetry_lib/tracing/__init__.py +1 -0
  10. lmnr/opentelemetry_lib/tracing/context_manager.py +13 -0
  11. lmnr/{openllmetry_sdk → opentelemetry_lib}/tracing/tracing.py +253 -257
  12. lmnr/sdk/browser/browser_use_otel.py +20 -3
  13. lmnr/sdk/browser/patchright_otel.py +177 -0
  14. lmnr/sdk/browser/playwright_otel.py +55 -62
  15. lmnr/sdk/browser/pw_utils.py +122 -116
  16. lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +98 -0
  17. lmnr/sdk/client/asynchronous/async_client.py +0 -34
  18. lmnr/sdk/client/asynchronous/resources/__init__.py +0 -4
  19. lmnr/sdk/client/asynchronous/resources/agent.py +115 -6
  20. lmnr/sdk/client/synchronous/resources/__init__.py +1 -3
  21. lmnr/sdk/client/synchronous/resources/agent.py +112 -6
  22. lmnr/sdk/client/synchronous/sync_client.py +0 -36
  23. lmnr/sdk/decorators.py +19 -5
  24. lmnr/sdk/eval_control.py +3 -2
  25. lmnr/sdk/evaluations.py +8 -14
  26. lmnr/sdk/laminar.py +10 -10
  27. lmnr/sdk/types.py +86 -170
  28. lmnr/sdk/utils.py +8 -1
  29. lmnr/version.py +1 -1
  30. {lmnr-0.5.1a0.dist-info → lmnr-0.5.3.dist-info}/METADATA +58 -58
  31. lmnr-0.5.3.dist-info/RECORD +55 -0
  32. {lmnr-0.5.1a0.dist-info → lmnr-0.5.3.dist-info}/WHEEL +1 -1
  33. lmnr/openllmetry_sdk/tracing/__init__.py +0 -0
  34. lmnr/sdk/browser/rrweb/rrweb.min.js +0 -18
  35. lmnr/sdk/client/asynchronous/resources/pipeline.py +0 -89
  36. lmnr/sdk/client/asynchronous/resources/semantic_search.py +0 -60
  37. lmnr/sdk/client/synchronous/resources/pipeline.py +0 -89
  38. lmnr/sdk/client/synchronous/resources/semantic_search.py +0 -60
  39. lmnr-0.5.1a0.dist-info/RECORD +0 -54
  40. /lmnr/{openllmetry_sdk → opentelemetry_lib}/.flake8 +0 -0
  41. /lmnr/{openllmetry_sdk → opentelemetry_lib}/config/__init__.py +0 -0
  42. /lmnr/{openllmetry_sdk → opentelemetry_lib}/decorators/__init__.py +0 -0
  43. /lmnr/{openllmetry_sdk → opentelemetry_lib}/tracing/attributes.py +0 -0
  44. /lmnr/{openllmetry_sdk → opentelemetry_lib}/tracing/content_allow_list.py +0 -0
  45. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/__init__.py +0 -0
  46. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/in_memory_span_exporter.py +0 -0
  47. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/json_encoder.py +0 -0
  48. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/package_check.py +0 -0
  49. {lmnr-0.5.1a0.dist-info → lmnr-0.5.3.dist-info}/LICENSE +0 -0
  50. {lmnr-0.5.1a0.dist-info → lmnr-0.5.3.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- from lmnr.openllmetry_sdk.decorators.base import json_dumps
1
+ from lmnr.opentelemetry_lib.decorators.base import json_dumps
2
2
  from lmnr.sdk.browser.utils import with_tracer_wrapper
3
3
  from lmnr.sdk.utils import get_input_from_func_args
4
4
  from lmnr.version import __version__
@@ -8,6 +8,16 @@ from opentelemetry.instrumentation.utils import unwrap
8
8
  from opentelemetry.trace import get_tracer, Tracer
9
9
  from typing import Collection
10
10
  from wrapt import wrap_function_wrapper
11
+ import pydantic
12
+
13
+ try:
14
+ from browser_use import AgentHistoryList
15
+ except ImportError as e:
16
+ raise ImportError(
17
+ f"Attempted to import {__file__}, but it is designed "
18
+ "to patch Browser Use, which is not installed. Use `pip install browser-use` "
19
+ "to install Browser Use or remove this import."
20
+ ) from e
11
21
 
12
22
  _instruments = ("browser-use >= 0.1.0",)
13
23
 
@@ -18,7 +28,7 @@ WRAPPED_METHODS = [
18
28
  "method": "run",
19
29
  "span_name": "agent.run",
20
30
  "ignore_input": False,
21
- "ignore_output": True,
31
+ "ignore_output": False,
22
32
  "span_type": "DEFAULT",
23
33
  },
24
34
  {
@@ -73,7 +83,14 @@ async def _wrap(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
73
83
  span.set_attributes(attributes)
74
84
  result = await wrapped(*args, **kwargs)
75
85
  if not to_wrap.get("ignore_output"):
76
- span.set_attribute("lmnr.span.output", json_dumps(result))
86
+ if isinstance(result, AgentHistoryList):
87
+ result = result.final_result()
88
+ serialized = (
89
+ result.model_dump_json()
90
+ if isinstance(result, pydantic.BaseModel)
91
+ else json_dumps(result)
92
+ )
93
+ span.set_attribute("lmnr.span.output", serialized)
77
94
  return result
78
95
 
79
96
 
@@ -0,0 +1,177 @@
1
+ from lmnr.sdk.browser.playwright_otel import (
2
+ _wrap_new_page,
3
+ _wrap_new_page_async,
4
+ _wrap_new_browser_sync,
5
+ _wrap_new_browser_async,
6
+ _wrap_new_context_sync,
7
+ _wrap_new_context_async,
8
+ _wrap_close_browser_sync,
9
+ _wrap_close_browser_async,
10
+ )
11
+ from lmnr.sdk.client.synchronous.sync_client import LaminarClient
12
+ from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
13
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
14
+ from opentelemetry.instrumentation.utils import unwrap
15
+ from opentelemetry.trace import get_tracer
16
+ from lmnr.version import __version__
17
+ from typing import Collection
18
+ from wrapt import wrap_function_wrapper
19
+
20
+ _instruments = ("patchright >= 1.9.0",)
21
+
22
+ WRAPPED_METHODS = [
23
+ {
24
+ "package": "patchright.sync_api",
25
+ "object": "BrowserContext",
26
+ "method": "new_page",
27
+ "wrapper": _wrap_new_page,
28
+ },
29
+ {
30
+ "package": "patchright.sync_api",
31
+ "object": "Browser",
32
+ "method": "new_page",
33
+ "wrapper": _wrap_new_page,
34
+ },
35
+ {
36
+ "package": "patchright.sync_api",
37
+ "object": "BrowserType",
38
+ "method": "launch",
39
+ "wrapper": _wrap_new_browser_sync,
40
+ },
41
+ {
42
+ "package": "patchright.sync_api",
43
+ "object": "BrowserType",
44
+ "method": "connect",
45
+ "wrapper": _wrap_new_browser_sync,
46
+ },
47
+ {
48
+ "package": "patchright.sync_api",
49
+ "object": "BrowserType",
50
+ "method": "connect_over_cdp",
51
+ "wrapper": _wrap_new_browser_sync,
52
+ },
53
+ {
54
+ "package": "patchright.sync_api",
55
+ "object": "Browser",
56
+ "method": "close",
57
+ "wrapper": _wrap_close_browser_sync,
58
+ },
59
+ {
60
+ "package": "patchright.sync_api",
61
+ "object": "Browser",
62
+ "method": "new_context",
63
+ "wrapper": _wrap_new_context_sync,
64
+ },
65
+ {
66
+ "package": "patchright.sync_api",
67
+ "object": "BrowserType",
68
+ "method": "launch_persistent_context",
69
+ "wrapper": _wrap_new_context_sync,
70
+ },
71
+ ]
72
+
73
+ WRAPPED_METHODS_ASYNC = [
74
+ {
75
+ "package": "patchright.async_api",
76
+ "object": "BrowserContext",
77
+ "method": "new_page",
78
+ "wrapper": _wrap_new_page_async,
79
+ },
80
+ {
81
+ "package": "patchright.async_api",
82
+ "object": "Browser",
83
+ "method": "new_page",
84
+ "wrapper": _wrap_new_page_async,
85
+ },
86
+ {
87
+ "package": "patchright.async_api",
88
+ "object": "BrowserType",
89
+ "method": "launch",
90
+ "wrapper": _wrap_new_browser_async,
91
+ },
92
+ {
93
+ "package": "patchright.async_api",
94
+ "object": "BrowserType",
95
+ "method": "connect",
96
+ "wrapper": _wrap_new_browser_async,
97
+ },
98
+ {
99
+ "package": "patchright.async_api",
100
+ "object": "BrowserType",
101
+ "method": "connect_over_cdp",
102
+ "wrapper": _wrap_new_browser_async,
103
+ },
104
+ {
105
+ "package": "patchright.async_api",
106
+ "object": "Browser",
107
+ "method": "close",
108
+ "wrapper": _wrap_close_browser_async,
109
+ },
110
+ {
111
+ "package": "patchright.async_api",
112
+ "object": "Browser",
113
+ "method": "new_context",
114
+ "wrapper": _wrap_new_context_async,
115
+ },
116
+ {
117
+ "package": "patchright.async_api",
118
+ "object": "BrowserType",
119
+ "method": "launch_persistent_context",
120
+ "wrapper": _wrap_new_context_async,
121
+ },
122
+ ]
123
+
124
+
125
+ class PatchrightInstrumentor(BaseInstrumentor):
126
+ def __init__(self, client: LaminarClient, async_client: AsyncLaminarClient):
127
+ super().__init__()
128
+ self.client = client
129
+ self.async_client = async_client
130
+
131
+ def instrumentation_dependencies(self) -> Collection[str]:
132
+ return _instruments
133
+
134
+ def _instrument(self, **kwargs):
135
+ tracer_provider = kwargs.get("tracer_provider")
136
+ tracer = get_tracer(__name__, __version__, tracer_provider)
137
+
138
+ for wrapped_method in WRAPPED_METHODS:
139
+ wrap_package = wrapped_method.get("package")
140
+ wrap_object = wrapped_method.get("object")
141
+ wrap_method = wrapped_method.get("method")
142
+ try:
143
+ wrap_function_wrapper(
144
+ wrap_package,
145
+ f"{wrap_object}.{wrap_method}",
146
+ wrapped_method.get("wrapper")(
147
+ tracer,
148
+ self.client,
149
+ wrapped_method,
150
+ ),
151
+ )
152
+ except ModuleNotFoundError:
153
+ pass
154
+
155
+ for wrapped_method in WRAPPED_METHODS_ASYNC:
156
+ wrap_package = wrapped_method.get("package")
157
+ wrap_object = wrapped_method.get("object")
158
+ wrap_method = wrapped_method.get("method")
159
+ try:
160
+ wrap_function_wrapper(
161
+ wrap_package,
162
+ f"{wrap_object}.{wrap_method}",
163
+ wrapped_method.get("wrapper")(
164
+ tracer,
165
+ self.async_client,
166
+ wrapped_method,
167
+ ),
168
+ )
169
+ except ModuleNotFoundError:
170
+ pass
171
+
172
+ def _uninstrument(self, **kwargs):
173
+ for wrapped_method in WRAPPED_METHODS + WRAPPED_METHODS_ASYNC:
174
+ wrap_package = wrapped_method.get("package")
175
+ wrap_object = wrapped_method.get("object")
176
+ wrap_method = wrapped_method.get("method")
177
+ unwrap(wrap_package, f"{wrap_object}.{wrap_method}")
@@ -2,7 +2,9 @@ import logging
2
2
  import uuid
3
3
 
4
4
  from lmnr.sdk.browser.pw_utils import handle_navigation_async, handle_navigation_sync
5
- from lmnr.sdk.browser.utils import with_tracer_wrapper
5
+ from lmnr.sdk.browser.utils import with_tracer_and_client_wrapper
6
+ from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
7
+ from lmnr.sdk.client.synchronous.sync_client import LaminarClient
6
8
  from lmnr.version import __version__
7
9
 
8
10
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
@@ -16,14 +18,15 @@ from opentelemetry.trace import (
16
18
  set_span_in_context,
17
19
  )
18
20
  from opentelemetry.context import get_current
19
- from typing import Collection, Optional
21
+ from typing import Collection
20
22
  from wrapt import wrap_function_wrapper
21
23
 
22
24
  try:
23
- from playwright.async_api import Browser
25
+ from playwright.async_api import Browser, BrowserContext, Page
24
26
  from playwright.sync_api import (
25
27
  Browser as SyncBrowser,
26
28
  BrowserContext as SyncBrowserContext,
29
+ Page as SyncPage,
27
30
  )
28
31
  except ImportError as e:
29
32
  raise ImportError(
@@ -37,12 +40,12 @@ _instruments = ("playwright >= 1.9.0",)
37
40
  logger = logging.getLogger(__name__)
38
41
 
39
42
  _context_spans: dict[str, Span] = {}
40
- _project_api_key: Optional[str] = None
41
- _base_http_url: Optional[str] = None
42
43
 
43
44
 
44
- @with_tracer_wrapper
45
- def _wrap_new_page(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
45
+ @with_tracer_and_client_wrapper
46
+ def _wrap_new_page(
47
+ tracer: Tracer, client: LaminarClient, to_wrap, wrapped, instance, args, kwargs
48
+ ):
46
49
  with tracer.start_as_current_span(
47
50
  f"{to_wrap.get('object')}.{to_wrap.get('method')}"
48
51
  ) as span:
@@ -50,15 +53,13 @@ def _wrap_new_page(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
50
53
  session_id = str(uuid.uuid4().hex)
51
54
  trace_id = format(get_current_span().get_span_context().trace_id, "032x")
52
55
  span.set_attribute("lmnr.internal.has_browser_session", True)
53
- handle_navigation_sync(
54
- page, session_id, trace_id, _project_api_key, _base_http_url
55
- )
56
+ handle_navigation_sync(page, session_id, trace_id, client)
56
57
  return page
57
58
 
58
59
 
59
- @with_tracer_wrapper
60
+ @with_tracer_and_client_wrapper
60
61
  async def _wrap_new_page_async(
61
- tracer: Tracer, to_wrap, wrapped, instance, args, kwargs
62
+ tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
62
63
  ):
63
64
  with tracer.start_as_current_span(
64
65
  f"{to_wrap.get('object')}.{to_wrap.get('method')}"
@@ -67,14 +68,14 @@ async def _wrap_new_page_async(
67
68
  session_id = str(uuid.uuid4().hex)
68
69
  trace_id = format(span.get_span_context().trace_id, "032x")
69
70
  span.set_attribute("lmnr.internal.has_browser_session", True)
70
- await handle_navigation_async(
71
- page, session_id, trace_id, _project_api_key, _base_http_url
72
- )
71
+ await handle_navigation_async(page, session_id, trace_id, client)
73
72
  return page
74
73
 
75
74
 
76
- @with_tracer_wrapper
77
- def _wrap_new_browser_sync(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
75
+ @with_tracer_and_client_wrapper
76
+ def _wrap_new_browser_sync(
77
+ tracer: Tracer, client: LaminarClient, to_wrap, wrapped, instance, args, kwargs
78
+ ):
78
79
  global _context_spans
79
80
  browser: SyncBrowser = wrapped(*args, **kwargs)
80
81
  session_id = str(uuid.uuid4().hex)
@@ -88,22 +89,23 @@ def _wrap_new_browser_sync(tracer: Tracer, to_wrap, wrapped, instance, args, kwa
88
89
  _context_spans[id(context)] = span
89
90
  span.set_attribute("lmnr.internal.has_browser_session", True)
90
91
  trace_id = format(span.get_span_context().trace_id, "032x")
92
+
93
+ def handle_page_navigation(page: SyncPage):
94
+ return handle_navigation_sync(page, session_id, trace_id, client)
95
+
91
96
  context.on(
92
97
  "page",
93
- lambda page: handle_navigation_sync(
94
- page, session_id, trace_id, _project_api_key, _base_http_url
95
- ),
98
+ handle_page_navigation,
96
99
  )
100
+
97
101
  for page in context.pages:
98
- handle_navigation_sync(
99
- page, session_id, trace_id, _project_api_key, _base_http_url
100
- )
102
+ handle_navigation_sync(page, session_id, trace_id, client)
101
103
  return browser
102
104
 
103
105
 
104
- @with_tracer_wrapper
106
+ @with_tracer_and_client_wrapper
105
107
  async def _wrap_new_browser_async(
106
- tracer: Tracer, to_wrap, wrapped, instance, args, kwargs
108
+ tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
107
109
  ):
108
110
  global _context_spans
109
111
  browser: Browser = await wrapped(*args, **kwargs)
@@ -119,21 +121,19 @@ async def _wrap_new_browser_async(
119
121
  span.set_attribute("lmnr.internal.has_browser_session", True)
120
122
  trace_id = format(span.get_span_context().trace_id, "032x")
121
123
 
122
- async def handle_page_navigation(page):
123
- return await handle_navigation_async(
124
- page, session_id, trace_id, _project_api_key, _base_http_url
125
- )
124
+ async def handle_page_navigation(page: Page):
125
+ return await handle_navigation_async(page, session_id, trace_id, client)
126
126
 
127
127
  context.on("page", handle_page_navigation)
128
128
  for page in context.pages:
129
- await handle_navigation_async(
130
- page, session_id, trace_id, _project_api_key, _base_http_url
131
- )
129
+ await handle_navigation_async(page, session_id, trace_id, client)
132
130
  return browser
133
131
 
134
132
 
135
- @with_tracer_wrapper
136
- def _wrap_new_context_sync(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
133
+ @with_tracer_and_client_wrapper
134
+ def _wrap_new_context_sync(
135
+ tracer: Tracer, client: LaminarClient, to_wrap, wrapped, instance, args, kwargs
136
+ ):
137
137
  context: SyncBrowserContext = wrapped(*args, **kwargs)
138
138
  session_id = str(uuid.uuid4().hex)
139
139
  span = get_current_span()
@@ -146,24 +146,23 @@ def _wrap_new_context_sync(tracer: Tracer, to_wrap, wrapped, instance, args, kwa
146
146
  span.set_attribute("lmnr.internal.has_browser_session", True)
147
147
  trace_id = format(span.get_span_context().trace_id, "032x")
148
148
 
149
+ def handle_page_navigation(page: SyncPage):
150
+ return handle_navigation_sync(page, session_id, trace_id, client)
151
+
149
152
  context.on(
150
153
  "page",
151
- lambda page: handle_navigation_sync(
152
- page, session_id, trace_id, _project_api_key, _base_http_url
153
- ),
154
+ handle_page_navigation,
154
155
  )
155
156
  for page in context.pages:
156
- handle_navigation_sync(
157
- page, session_id, trace_id, _project_api_key, _base_http_url
158
- )
157
+ handle_navigation_sync(page, session_id, trace_id, client)
159
158
  return context
160
159
 
161
160
 
162
- @with_tracer_wrapper
161
+ @with_tracer_and_client_wrapper
163
162
  async def _wrap_new_context_async(
164
- tracer: Tracer, to_wrap, wrapped, instance, args, kwargs
163
+ tracer: Tracer, client: AsyncLaminarClient, to_wrap, wrapped, instance, args, kwargs
165
164
  ):
166
- context: SyncBrowserContext = await wrapped(*args, **kwargs)
165
+ context: BrowserContext = await wrapped(*args, **kwargs)
167
166
  session_id = str(uuid.uuid4().hex)
168
167
  span = get_current_span()
169
168
  if span == INVALID_SPAN:
@@ -176,21 +175,18 @@ async def _wrap_new_context_async(
176
175
  trace_id = format(span.get_span_context().trace_id, "032x")
177
176
 
178
177
  async def handle_page_navigation(page):
179
- return await handle_navigation_async(
180
- page, session_id, trace_id, _project_api_key, _base_http_url
181
- )
178
+ return await handle_navigation_async(page, session_id, trace_id, client)
182
179
 
183
180
  context.on("page", handle_page_navigation)
184
181
  for page in context.pages:
185
- await handle_navigation_async(
186
- page, session_id, trace_id, _project_api_key, _base_http_url
187
- )
182
+ await handle_navigation_async(page, session_id, trace_id, client)
188
183
  return context
189
184
 
190
185
 
191
- @with_tracer_wrapper
186
+ @with_tracer_and_client_wrapper
192
187
  def _wrap_close_browser_sync(
193
188
  tracer: Tracer,
189
+ client: LaminarClient,
194
190
  to_wrap,
195
191
  wrapped,
196
192
  instance: SyncBrowser,
@@ -208,9 +204,10 @@ def _wrap_close_browser_sync(
208
204
  return wrapped(*args, **kwargs)
209
205
 
210
206
 
211
- @with_tracer_wrapper
207
+ @with_tracer_and_client_wrapper
212
208
  async def _wrap_close_browser_async(
213
209
  tracer: Tracer,
210
+ client: AsyncLaminarClient,
214
211
  to_wrap,
215
212
  wrapped,
216
213
  instance: Browser,
@@ -323,33 +320,27 @@ WRAPPED_METHODS_ASYNC = [
323
320
  "wrapper": _wrap_new_context_async,
324
321
  },
325
322
  {
326
- "package": "playwright.sync_api",
323
+ "package": "playwright.async_api",
327
324
  "object": "BrowserType",
328
325
  "method": "launch_persistent_context",
329
- "wrapper": _wrap_new_context_sync,
326
+ "wrapper": _wrap_new_context_async,
330
327
  },
331
328
  ]
332
329
 
333
330
 
334
331
  class PlaywrightInstrumentor(BaseInstrumentor):
335
- def __init__(self):
332
+ def __init__(self, client: LaminarClient, async_client: AsyncLaminarClient):
336
333
  super().__init__()
334
+ self.client = client
335
+ self.async_client = async_client
337
336
 
338
337
  def instrumentation_dependencies(self) -> Collection[str]:
339
338
  return _instruments
340
339
 
341
340
  def _instrument(self, **kwargs):
342
- global _project_api_key, _base_http_url
343
-
344
341
  tracer_provider = kwargs.get("tracer_provider")
345
342
  tracer = get_tracer(__name__, __version__, tracer_provider)
346
343
 
347
- if kwargs.get("project_api_key"):
348
- _project_api_key = kwargs.get("project_api_key")
349
-
350
- if kwargs.get("base_http_url"):
351
- _base_http_url = kwargs.get("base_http_url")
352
-
353
344
  for wrapped_method in WRAPPED_METHODS:
354
345
  wrap_package = wrapped_method.get("package")
355
346
  wrap_object = wrapped_method.get("object")
@@ -360,6 +351,7 @@ class PlaywrightInstrumentor(BaseInstrumentor):
360
351
  f"{wrap_object}.{wrap_method}",
361
352
  wrapped_method.get("wrapper")(
362
353
  tracer,
354
+ self.client,
363
355
  wrapped_method,
364
356
  ),
365
357
  )
@@ -377,6 +369,7 @@ class PlaywrightInstrumentor(BaseInstrumentor):
377
369
  f"{wrap_object}.{wrap_method}",
378
370
  wrapped_method.get("wrapper")(
379
371
  tracer,
372
+ self.async_client,
380
373
  wrapped_method,
381
374
  ),
382
375
  )