beekeeper-monitors-watsonx 1.0.5.post1__py3-none-any.whl → 1.0.7__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.
- beekeeper/monitors/watsonx/__init__.py +11 -3
- beekeeper/monitors/watsonx/base.py +128 -889
- beekeeper/monitors/watsonx/custom_metric.py +645 -0
- beekeeper/monitors/watsonx/supporting_classes/__init__.py +0 -0
- beekeeper/monitors/watsonx/supporting_classes/credentials.py +137 -0
- beekeeper/monitors/watsonx/supporting_classes/enums.py +71 -0
- beekeeper/monitors/watsonx/supporting_classes/metric.py +109 -0
- beekeeper/monitors/watsonx/utils/data_utils.py +31 -0
- {beekeeper_monitors_watsonx-1.0.5.post1.dist-info → beekeeper_monitors_watsonx-1.0.7.dist-info}/METADATA +1 -1
- beekeeper_monitors_watsonx-1.0.7.dist-info/RECORD +12 -0
- beekeeper_monitors_watsonx-1.0.5.post1.dist-info/RECORD +0 -6
- /beekeeper/monitors/watsonx/{instrumentation.py → utils/instrumentation.py} +0 -0
- {beekeeper_monitors_watsonx-1.0.5.post1.dist-info → beekeeper_monitors_watsonx-1.0.7.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import logging
|
|
3
|
+
import uuid
|
|
4
|
+
from typing import Any, Dict, List, Literal, Union
|
|
5
|
+
|
|
6
|
+
from beekeeper.monitors.watsonx.supporting_classes.credentials import (
|
|
7
|
+
CloudPakforDataCredentials,
|
|
8
|
+
IntegratedSystemCredentials,
|
|
9
|
+
)
|
|
10
|
+
from beekeeper.monitors.watsonx.supporting_classes.enums import Region
|
|
11
|
+
from beekeeper.monitors.watsonx.supporting_classes.metric import (
|
|
12
|
+
WatsonxLocalMetric,
|
|
13
|
+
WatsonxMetric,
|
|
14
|
+
)
|
|
15
|
+
from beekeeper.monitors.watsonx.utils.data_utils import validate_and_filter_dict
|
|
16
|
+
from beekeeper.monitors.watsonx.utils.instrumentation import suppress_output
|
|
17
|
+
from deprecated import deprecated
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class WatsonxCustomMetricsManager:
|
|
21
|
+
"""
|
|
22
|
+
Provides functionality to set up a custom metric to measure your model's performance with IBM watsonx.governance.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
api_key (str): The API key for IBM watsonx.governance.
|
|
26
|
+
region (Region, optional): The region where watsonx.governance is hosted when using IBM Cloud.
|
|
27
|
+
Defaults to `us-south`.
|
|
28
|
+
cpd_creds (CloudPakforDataCredentials, optional): IBM Cloud Pak for Data environment credentials.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
```python
|
|
32
|
+
from beekeeper.monitors.watsonx import (
|
|
33
|
+
WatsonxCustomMetricsManager,
|
|
34
|
+
CloudPakforDataCredentials,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# watsonx.governance (IBM Cloud)
|
|
38
|
+
wxgov_client = WatsonxCustomMetricsManager(api_key="API_KEY")
|
|
39
|
+
|
|
40
|
+
# watsonx.governance (CP4D)
|
|
41
|
+
cpd_creds = CloudPakforDataCredentials(
|
|
42
|
+
url="CPD_URL",
|
|
43
|
+
username="USERNAME",
|
|
44
|
+
password="PASSWORD",
|
|
45
|
+
version="5.0",
|
|
46
|
+
instance_id="openshift",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
wxgov_client = WatsonxCustomMetricsManager(cpd_creds=cpd_creds)
|
|
50
|
+
```
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
api_key: str = None,
|
|
56
|
+
region: Union[Region, str] = Region.US_SOUTH,
|
|
57
|
+
cpd_creds: Union[CloudPakforDataCredentials, Dict] = None,
|
|
58
|
+
) -> None:
|
|
59
|
+
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator # type: ignore
|
|
60
|
+
from ibm_watson_openscale import APIClient as WosAPIClient # type: ignore
|
|
61
|
+
|
|
62
|
+
self.region = Region.from_value(region)
|
|
63
|
+
self._api_key = api_key
|
|
64
|
+
self._wos_client = None
|
|
65
|
+
|
|
66
|
+
if cpd_creds:
|
|
67
|
+
self._wos_cpd_creds = validate_and_filter_dict(
|
|
68
|
+
cpd_creds.to_dict(),
|
|
69
|
+
["username", "password", "api_key", "disable_ssl_verification"],
|
|
70
|
+
["url"],
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if not self._wos_client:
|
|
74
|
+
try:
|
|
75
|
+
if hasattr(self, "_wos_cpd_creds") and self._wos_cpd_creds:
|
|
76
|
+
from ibm_cloud_sdk_core.authenticators import (
|
|
77
|
+
CloudPakForDataAuthenticator, # type: ignore
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
|
|
81
|
+
|
|
82
|
+
self._wos_client = WosAPIClient(
|
|
83
|
+
authenticator=authenticator,
|
|
84
|
+
service_url=self._wos_cpd_creds["url"],
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
else:
|
|
88
|
+
from ibm_cloud_sdk_core.authenticators import (
|
|
89
|
+
IAMAuthenticator, # type: ignore
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
authenticator = IAMAuthenticator(apikey=self._api_key)
|
|
93
|
+
self._wos_client = WosAPIClient(
|
|
94
|
+
authenticator=authenticator,
|
|
95
|
+
service_url=self.region.openscale,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
logging.error(
|
|
100
|
+
f"Error connecting to IBM watsonx.governance (openscale): {e}",
|
|
101
|
+
)
|
|
102
|
+
raise
|
|
103
|
+
|
|
104
|
+
def _add_integrated_system(
|
|
105
|
+
self,
|
|
106
|
+
credentials: IntegratedSystemCredentials,
|
|
107
|
+
name: str,
|
|
108
|
+
endpoint: str,
|
|
109
|
+
) -> str:
|
|
110
|
+
custom_metrics_integrated_system = self._wos_client.integrated_systems.add(
|
|
111
|
+
name=name,
|
|
112
|
+
description="Integrated system created by Beekeeper.",
|
|
113
|
+
type="custom_metrics_provider",
|
|
114
|
+
credentials=credentials.to_dict(),
|
|
115
|
+
connection={"display_name": name, "endpoint": endpoint},
|
|
116
|
+
).result
|
|
117
|
+
|
|
118
|
+
return custom_metrics_integrated_system.metadata.id
|
|
119
|
+
|
|
120
|
+
def _add_monitor_definitions(
|
|
121
|
+
self,
|
|
122
|
+
name: str,
|
|
123
|
+
metrics: List[WatsonxMetric],
|
|
124
|
+
schedule: bool,
|
|
125
|
+
):
|
|
126
|
+
from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
|
|
127
|
+
ApplicabilitySelection,
|
|
128
|
+
MonitorInstanceSchedule,
|
|
129
|
+
MonitorMetricRequest,
|
|
130
|
+
MonitorRuntime,
|
|
131
|
+
ScheduleStartTime,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
_metrics = [MonitorMetricRequest(**metric.to_dict()) for metric in metrics]
|
|
135
|
+
_monitor_runtime = None
|
|
136
|
+
_monitor_schedule = None
|
|
137
|
+
|
|
138
|
+
if schedule:
|
|
139
|
+
_monitor_runtime = MonitorRuntime(type="custom_metrics_provider")
|
|
140
|
+
_monitor_schedule = MonitorInstanceSchedule(
|
|
141
|
+
repeat_interval=1,
|
|
142
|
+
repeat_unit="hour",
|
|
143
|
+
start_time=ScheduleStartTime(
|
|
144
|
+
type="relative",
|
|
145
|
+
delay_unit="minute",
|
|
146
|
+
delay=30,
|
|
147
|
+
),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
custom_monitor_details = self._wos_client.monitor_definitions.add(
|
|
151
|
+
name=name,
|
|
152
|
+
metrics=_metrics,
|
|
153
|
+
tags=[],
|
|
154
|
+
schedule=_monitor_schedule,
|
|
155
|
+
applies_to=ApplicabilitySelection(input_data_type=["unstructured_text"]),
|
|
156
|
+
monitor_runtime=_monitor_runtime,
|
|
157
|
+
background_mode=False,
|
|
158
|
+
).result
|
|
159
|
+
|
|
160
|
+
return custom_monitor_details.metadata.id
|
|
161
|
+
|
|
162
|
+
def _get_monitor_instance(self, subscription_id: str, monitor_definition_id: str):
|
|
163
|
+
monitor_instances = self._wos_client.monitor_instances.list(
|
|
164
|
+
monitor_definition_id=monitor_definition_id,
|
|
165
|
+
target_target_id=subscription_id,
|
|
166
|
+
).result.monitor_instances
|
|
167
|
+
|
|
168
|
+
if len(monitor_instances) == 1:
|
|
169
|
+
return monitor_instances[0]
|
|
170
|
+
else:
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
def _update_monitor_instance(
|
|
174
|
+
self,
|
|
175
|
+
integrated_system_id: str,
|
|
176
|
+
custom_monitor_id: str,
|
|
177
|
+
):
|
|
178
|
+
payload = [
|
|
179
|
+
{
|
|
180
|
+
"op": "replace",
|
|
181
|
+
"path": "/parameters",
|
|
182
|
+
"value": {
|
|
183
|
+
"custom_metrics_provider_id": integrated_system_id,
|
|
184
|
+
"custom_metrics_wait_time": 60,
|
|
185
|
+
"enable_custom_metric_runs": True,
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
return self._wos_client.monitor_instances.update(
|
|
191
|
+
custom_monitor_id,
|
|
192
|
+
payload,
|
|
193
|
+
update_metadata_only=True,
|
|
194
|
+
).result
|
|
195
|
+
|
|
196
|
+
def _get_patch_request_field(
|
|
197
|
+
self,
|
|
198
|
+
field_path: str,
|
|
199
|
+
field_value: Any,
|
|
200
|
+
op_name: str = "replace",
|
|
201
|
+
) -> Dict:
|
|
202
|
+
return {"op": op_name, "path": field_path, "value": field_value}
|
|
203
|
+
|
|
204
|
+
def _get_dataset_id(
|
|
205
|
+
self,
|
|
206
|
+
subscription_id: str,
|
|
207
|
+
data_set_type: Literal["feedback", "payload_logging"],
|
|
208
|
+
) -> str:
|
|
209
|
+
data_sets = self._wos_client.data_sets.list(
|
|
210
|
+
target_target_id=subscription_id,
|
|
211
|
+
type=data_set_type,
|
|
212
|
+
).result.data_sets
|
|
213
|
+
data_set_id = None
|
|
214
|
+
if len(data_sets) > 0:
|
|
215
|
+
data_set_id = data_sets[0].metadata.id
|
|
216
|
+
return data_set_id
|
|
217
|
+
|
|
218
|
+
def _get_dataset_data(self, data_set_id: str):
|
|
219
|
+
json_data = self._wos_client.data_sets.get_list_of_records(
|
|
220
|
+
data_set_id=data_set_id,
|
|
221
|
+
format="list",
|
|
222
|
+
).result
|
|
223
|
+
|
|
224
|
+
if not json_data.get("records"):
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
return json_data["records"][0]
|
|
228
|
+
|
|
229
|
+
def _get_existing_data_mart(self):
|
|
230
|
+
data_marts = self._wos_client.data_marts.list().result.data_marts
|
|
231
|
+
if len(data_marts) == 0:
|
|
232
|
+
raise Exception(
|
|
233
|
+
"No data marts found. Please ensure at least one data mart is available.",
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
return data_marts[0].metadata.id
|
|
237
|
+
|
|
238
|
+
# ===== Global Custom Metrics =====
|
|
239
|
+
@deprecated(
|
|
240
|
+
reason="'add_metric_definition()' is deprecated and will be removed in a future version. Use 'create_metric_definition()' instead.",
|
|
241
|
+
version="1.0.6",
|
|
242
|
+
action="always",
|
|
243
|
+
)
|
|
244
|
+
def add_metric_definition(
|
|
245
|
+
self,
|
|
246
|
+
name: str,
|
|
247
|
+
metrics: List[WatsonxMetric],
|
|
248
|
+
integrated_system_url: str,
|
|
249
|
+
integrated_system_credentials: IntegratedSystemCredentials,
|
|
250
|
+
schedule: bool = False,
|
|
251
|
+
):
|
|
252
|
+
return self.create_metric_definition(
|
|
253
|
+
name=name,
|
|
254
|
+
metrics=metrics,
|
|
255
|
+
integrated_system_url=integrated_system_url,
|
|
256
|
+
integrated_system_credentials=integrated_system_credentials,
|
|
257
|
+
schedule=schedule,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def create_metric_definition(
|
|
261
|
+
self,
|
|
262
|
+
name: str,
|
|
263
|
+
metrics: List[WatsonxMetric],
|
|
264
|
+
integrated_system_url: str,
|
|
265
|
+
integrated_system_credentials: IntegratedSystemCredentials,
|
|
266
|
+
schedule: bool = False,
|
|
267
|
+
):
|
|
268
|
+
"""
|
|
269
|
+
Creates a custom metric definition for IBM watsonx.governance.
|
|
270
|
+
|
|
271
|
+
This must be done before using custom metrics.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
name (str): The name of the custom metric group.
|
|
275
|
+
metrics (List[WatsonxMetric]): A list of metrics to be measured.
|
|
276
|
+
schedule (bool, optional): Enable or disable the scheduler. Defaults to `False`.
|
|
277
|
+
integrated_system_url (str): The URL of the external metric provider.
|
|
278
|
+
integrated_system_credentials (IntegratedSystemCredentials): The credentials for the integrated system.
|
|
279
|
+
|
|
280
|
+
Example:
|
|
281
|
+
```python
|
|
282
|
+
from beekeeper.monitors.watsonx import (
|
|
283
|
+
WatsonxMetric,
|
|
284
|
+
IntegratedSystemCredentials,
|
|
285
|
+
WatsonxMetricThreshold,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
wxgov_client.create_metric_definition(
|
|
289
|
+
name="Custom Metric - Custom LLM Quality",
|
|
290
|
+
metrics=[
|
|
291
|
+
WatsonxMetric(
|
|
292
|
+
name="context_quality",
|
|
293
|
+
applies_to=[
|
|
294
|
+
"retrieval_augmented_generation",
|
|
295
|
+
"summarization",
|
|
296
|
+
],
|
|
297
|
+
thresholds=[
|
|
298
|
+
WatsonxMetricThreshold(
|
|
299
|
+
threshold_type="lower_limit", default_value=0.75
|
|
300
|
+
)
|
|
301
|
+
],
|
|
302
|
+
)
|
|
303
|
+
],
|
|
304
|
+
integrated_system_url="IS_URL", # URL to the endpoint computing the metric
|
|
305
|
+
integrated_system_credentials=IntegratedSystemCredentials(
|
|
306
|
+
auth_type="basic", username="USERNAME", password="PASSWORD"
|
|
307
|
+
),
|
|
308
|
+
)
|
|
309
|
+
```
|
|
310
|
+
"""
|
|
311
|
+
integrated_system_id = self._add_integrated_system(
|
|
312
|
+
integrated_system_credentials,
|
|
313
|
+
name,
|
|
314
|
+
integrated_system_url,
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
external_monitor_id = suppress_output(
|
|
318
|
+
self._add_monitor_definitions,
|
|
319
|
+
name,
|
|
320
|
+
metrics,
|
|
321
|
+
schedule,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# Associate the external monitor with the integrated system
|
|
325
|
+
payload = [
|
|
326
|
+
{
|
|
327
|
+
"op": "add",
|
|
328
|
+
"path": "/parameters",
|
|
329
|
+
"value": {"monitor_definition_ids": [external_monitor_id]},
|
|
330
|
+
},
|
|
331
|
+
]
|
|
332
|
+
|
|
333
|
+
self._wos_client.integrated_systems.update(integrated_system_id, payload)
|
|
334
|
+
|
|
335
|
+
return {
|
|
336
|
+
"integrated_system_id": integrated_system_id,
|
|
337
|
+
"monitor_definition_id": external_monitor_id,
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@deprecated(
|
|
341
|
+
reason="'add_observer_instance()' is deprecated and will be removed in a future version. Use 'attach_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
|
|
342
|
+
version="1.0.5",
|
|
343
|
+
action="always",
|
|
344
|
+
)
|
|
345
|
+
def add_observer_instance(
|
|
346
|
+
self,
|
|
347
|
+
integrated_system_id: str,
|
|
348
|
+
monitor_definition_id: str,
|
|
349
|
+
subscription_id: str,
|
|
350
|
+
):
|
|
351
|
+
return self.attach_monitor_instance(
|
|
352
|
+
integrated_system_id=integrated_system_id,
|
|
353
|
+
monitor_definition_id=monitor_definition_id,
|
|
354
|
+
subscription_id=subscription_id,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
@deprecated(
|
|
358
|
+
reason="'add_monitor_instance()' is deprecated and will be removed in a future version. Use 'attach_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
|
|
359
|
+
version="1.0.6",
|
|
360
|
+
action="always",
|
|
361
|
+
)
|
|
362
|
+
def add_monitor_instance(
|
|
363
|
+
self,
|
|
364
|
+
integrated_system_id: str,
|
|
365
|
+
monitor_definition_id: str,
|
|
366
|
+
subscription_id: str,
|
|
367
|
+
):
|
|
368
|
+
return self.attach_monitor_instance(
|
|
369
|
+
integrated_system_id=integrated_system_id,
|
|
370
|
+
monitor_definition_id=monitor_definition_id,
|
|
371
|
+
subscription_id=subscription_id,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
def attach_monitor_instance(
|
|
375
|
+
self,
|
|
376
|
+
integrated_system_id: str,
|
|
377
|
+
monitor_definition_id: str,
|
|
378
|
+
subscription_id: str,
|
|
379
|
+
):
|
|
380
|
+
"""
|
|
381
|
+
Attaches the specified monitor definition to the specified subscription.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
integrated_system_id (str): The ID of the integrated system.
|
|
385
|
+
monitor_definition_id (str): The ID of the custom metric monitor instance.
|
|
386
|
+
subscription_id (str): The ID of the subscription to associate the monitor with.
|
|
387
|
+
|
|
388
|
+
Example:
|
|
389
|
+
```python
|
|
390
|
+
wxgov_client.attach_monitor_instance(
|
|
391
|
+
integrated_system_id="019667ca-5687-7838-8d29-4ff70c2b36b0",
|
|
392
|
+
monitor_definition_id="custom_llm_quality",
|
|
393
|
+
subscription_id="0195e95d-03a4-7000-b954-b607db10fe9e",
|
|
394
|
+
)
|
|
395
|
+
```
|
|
396
|
+
"""
|
|
397
|
+
from ibm_watson_openscale.base_classes.watson_open_scale_v2 import Target
|
|
398
|
+
|
|
399
|
+
data_marts = self._wos_client.data_marts.list().result.data_marts
|
|
400
|
+
if len(data_marts) == 0:
|
|
401
|
+
raise Exception(
|
|
402
|
+
"No data marts found. Please ensure at least one data mart is available.",
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
data_mart_id = data_marts[0].metadata.id
|
|
406
|
+
existing_monitor_instance = self._get_monitor_instance(
|
|
407
|
+
subscription_id,
|
|
408
|
+
monitor_definition_id,
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
if existing_monitor_instance is None:
|
|
412
|
+
target = Target(target_type="subscription", target_id=subscription_id)
|
|
413
|
+
|
|
414
|
+
parameters = {
|
|
415
|
+
"custom_metrics_provider_id": integrated_system_id,
|
|
416
|
+
"custom_metrics_wait_time": 60,
|
|
417
|
+
"enable_custom_metric_runs": True,
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
monitor_instance_details = suppress_output(
|
|
421
|
+
self._wos_client.monitor_instances.create,
|
|
422
|
+
data_mart_id=data_mart_id,
|
|
423
|
+
background_mode=False,
|
|
424
|
+
monitor_definition_id=monitor_definition_id,
|
|
425
|
+
target=target,
|
|
426
|
+
parameters=parameters,
|
|
427
|
+
).result
|
|
428
|
+
else:
|
|
429
|
+
existing_instance_id = existing_monitor_instance.metadata.id
|
|
430
|
+
monitor_instance_details = self._update_monitor_instance(
|
|
431
|
+
integrated_system_id,
|
|
432
|
+
existing_instance_id,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
return monitor_instance_details
|
|
436
|
+
|
|
437
|
+
def publish_metrics(
|
|
438
|
+
self,
|
|
439
|
+
monitor_instance_id: str,
|
|
440
|
+
run_id: str,
|
|
441
|
+
request_records: Dict[str, Union[float, int]],
|
|
442
|
+
):
|
|
443
|
+
"""
|
|
444
|
+
Publishes computed metrics to the specified global monitor instance.
|
|
445
|
+
|
|
446
|
+
Args:
|
|
447
|
+
monitor_instance_id (str): The unique ID of the monitor instance.
|
|
448
|
+
run_id (str): The ID of the monitor run that generated the metrics.
|
|
449
|
+
request_records (Dict[str | float | int]): Dict containing the metrics to be published.
|
|
450
|
+
|
|
451
|
+
Example:
|
|
452
|
+
```python
|
|
453
|
+
wxgov_client.publish_metrics(
|
|
454
|
+
monitor_instance_id="01966801-f9ee-7248-a706-41de00a8a998",
|
|
455
|
+
run_id="RUN_ID",
|
|
456
|
+
request_records={"context_quality": 0.914, "sensitivity": 0.85},
|
|
457
|
+
)
|
|
458
|
+
```
|
|
459
|
+
"""
|
|
460
|
+
from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
|
|
461
|
+
MonitorMeasurementRequest,
|
|
462
|
+
Runs,
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
measurement_request = MonitorMeasurementRequest(
|
|
466
|
+
timestamp=datetime.datetime.now(datetime.timezone.utc).strftime(
|
|
467
|
+
"%Y-%m-%dT%H:%M:%S.%fZ",
|
|
468
|
+
),
|
|
469
|
+
run_id=run_id,
|
|
470
|
+
metrics=[request_records],
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
self._wos_client.monitor_instances.add_measurements(
|
|
474
|
+
monitor_instance_id=monitor_instance_id,
|
|
475
|
+
monitor_measurement_request=[measurement_request],
|
|
476
|
+
).result
|
|
477
|
+
|
|
478
|
+
run = Runs(watson_open_scale=self._wos_client)
|
|
479
|
+
patch_payload = []
|
|
480
|
+
patch_payload.append(self._get_patch_request_field("/status/state", "finished"))
|
|
481
|
+
patch_payload.append(
|
|
482
|
+
self._get_patch_request_field(
|
|
483
|
+
"/status/completed_at",
|
|
484
|
+
datetime.datetime.now(datetime.timezone.utc).strftime(
|
|
485
|
+
"%Y-%m-%dT%H:%M:%S.%fZ",
|
|
486
|
+
),
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
return run.update(
|
|
491
|
+
monitor_instance_id=monitor_instance_id,
|
|
492
|
+
monitoring_run_id=run_id,
|
|
493
|
+
json_patch_operation=patch_payload,
|
|
494
|
+
).result
|
|
495
|
+
|
|
496
|
+
# ===== Local Custom Metrics =====
|
|
497
|
+
@deprecated(
|
|
498
|
+
reason="'add_local_metric_definition()' is deprecated and will be removed in a future version. Use 'create_local_metric_definition()' from 'beekeeper-monitors-watsonx' instead.",
|
|
499
|
+
version="1.0.6",
|
|
500
|
+
action="always",
|
|
501
|
+
)
|
|
502
|
+
def add_local_metric_definition(
|
|
503
|
+
self,
|
|
504
|
+
name: str,
|
|
505
|
+
metrics: List[WatsonxMetric],
|
|
506
|
+
subscription_id: str,
|
|
507
|
+
):
|
|
508
|
+
return self.create_local_metric_definition(
|
|
509
|
+
name=name,
|
|
510
|
+
metrics=metrics,
|
|
511
|
+
subscription_id=subscription_id,
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
def create_local_metric_definition(
|
|
515
|
+
self,
|
|
516
|
+
name: str,
|
|
517
|
+
metrics: List[WatsonxLocalMetric],
|
|
518
|
+
subscription_id: str,
|
|
519
|
+
) -> str:
|
|
520
|
+
"""
|
|
521
|
+
Creates a custom metric definition to compute metrics at the local (transaction) level for IBM watsonx.governance.
|
|
522
|
+
|
|
523
|
+
Args:
|
|
524
|
+
name (str): The name of the custom transaction metric group.
|
|
525
|
+
metrics (List[WatsonxLocalMetric]): A list of metrics to be monitored at the local (transaction) level.
|
|
526
|
+
subscription_id (str): The IBM watsonx.governance subscription ID associated with the metric definition.
|
|
527
|
+
|
|
528
|
+
Example:
|
|
529
|
+
```python
|
|
530
|
+
from beekeeper.monitors.watsonx import WatsonxLocalMetric
|
|
531
|
+
|
|
532
|
+
wxgov_client.create_local_metric_definition(
|
|
533
|
+
name="Custom LLM Local Metric",
|
|
534
|
+
subscription_id="019674ca-0c38-745f-8e9b-58546e95174e",
|
|
535
|
+
metrics=[
|
|
536
|
+
WatsonxLocalMetric(name="context_quality", data_type="double")
|
|
537
|
+
],
|
|
538
|
+
)
|
|
539
|
+
```
|
|
540
|
+
"""
|
|
541
|
+
from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
|
|
542
|
+
LocationTableName,
|
|
543
|
+
SparkStruct,
|
|
544
|
+
SparkStructFieldPrimitive,
|
|
545
|
+
Target,
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
target = Target(target_id=subscription_id, target_type="subscription")
|
|
549
|
+
data_mart_id = self._get_existing_data_mart()
|
|
550
|
+
metrics = [SparkStructFieldPrimitive(**metric.to_dict()) for metric in metrics]
|
|
551
|
+
|
|
552
|
+
schema_fields = [
|
|
553
|
+
SparkStructFieldPrimitive(
|
|
554
|
+
name="scoring_id",
|
|
555
|
+
type="string",
|
|
556
|
+
nullable=False,
|
|
557
|
+
),
|
|
558
|
+
SparkStructFieldPrimitive(
|
|
559
|
+
name="run_id",
|
|
560
|
+
type="string",
|
|
561
|
+
nullable=True,
|
|
562
|
+
),
|
|
563
|
+
SparkStructFieldPrimitive(
|
|
564
|
+
name="computed_on",
|
|
565
|
+
type="string",
|
|
566
|
+
nullable=False,
|
|
567
|
+
),
|
|
568
|
+
]
|
|
569
|
+
|
|
570
|
+
schema_fields.extend(metrics)
|
|
571
|
+
|
|
572
|
+
data_schema = SparkStruct(type="struct", fields=schema_fields)
|
|
573
|
+
|
|
574
|
+
return self._wos_client.data_sets.add(
|
|
575
|
+
target=target,
|
|
576
|
+
name=name,
|
|
577
|
+
type="custom",
|
|
578
|
+
data_schema=data_schema,
|
|
579
|
+
data_mart_id=data_mart_id,
|
|
580
|
+
location=LocationTableName(
|
|
581
|
+
table_name=name.lower().replace(" ", "_") + "_" + str(uuid.uuid4())[:8],
|
|
582
|
+
),
|
|
583
|
+
background_mode=False,
|
|
584
|
+
).result.metadata.id
|
|
585
|
+
|
|
586
|
+
def publish_local_metrics(
|
|
587
|
+
self,
|
|
588
|
+
metric_instance_id: str,
|
|
589
|
+
request_records: List[Dict],
|
|
590
|
+
):
|
|
591
|
+
"""
|
|
592
|
+
Publishes computed metrics to the specified transaction record.
|
|
593
|
+
|
|
594
|
+
Args:
|
|
595
|
+
metric_instance_id (str): The unique ID of the custom transaction metric.
|
|
596
|
+
request_records (List[Dict]): A list of dictionaries containing the records to be stored.
|
|
597
|
+
|
|
598
|
+
Example:
|
|
599
|
+
```python
|
|
600
|
+
wxgov_client.publish_local_metrics(
|
|
601
|
+
metric_instance_id="0196ad39-1b75-7e77-bddb-cc5393d575c2",
|
|
602
|
+
request_records=[
|
|
603
|
+
{
|
|
604
|
+
"scoring_id": "304a9270-44a1-4c4d-bfd4-f756541011f8",
|
|
605
|
+
"run_id": "RUN_ID",
|
|
606
|
+
"computed_on": "payload",
|
|
607
|
+
"context_quality": 0.786,
|
|
608
|
+
}
|
|
609
|
+
],
|
|
610
|
+
)
|
|
611
|
+
```
|
|
612
|
+
"""
|
|
613
|
+
return self._wos_client.data_sets.store_records(
|
|
614
|
+
data_set_id=metric_instance_id,
|
|
615
|
+
request_body=request_records,
|
|
616
|
+
).result
|
|
617
|
+
|
|
618
|
+
def list_local_metrics(
|
|
619
|
+
self,
|
|
620
|
+
metric_instance_id: str,
|
|
621
|
+
):
|
|
622
|
+
"""
|
|
623
|
+
Lists records from a custom local metric definition.
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
metric_instance_id (str): The unique ID of the custom transaction metric.
|
|
627
|
+
|
|
628
|
+
Example:
|
|
629
|
+
```python
|
|
630
|
+
wxgov_client.list_local_metrics(
|
|
631
|
+
metric_instance_id="0196ad47-c505-73c0-9d7b-91c082b697e3"
|
|
632
|
+
)
|
|
633
|
+
```
|
|
634
|
+
"""
|
|
635
|
+
return self._get_dataset_data(metric_instance_id)
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
@deprecated(
|
|
639
|
+
reason="'WatsonxCustomMetric()' is deprecated and will be removed in a future version. "
|
|
640
|
+
"Use 'WatsonxCustomMetricsManager' instead.",
|
|
641
|
+
version="1.0.6",
|
|
642
|
+
action="always",
|
|
643
|
+
)
|
|
644
|
+
class WatsonxCustomMetric(WatsonxCustomMetricsManager):
|
|
645
|
+
pass
|
|
File without changes
|