beekeeper-monitors-watsonx 1.0.7__py3-none-any.whl → 1.1.0.post1__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.
@@ -576,7 +576,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
576
576
  request_records=[
577
577
  {
578
578
  "context1": "value_context1",
579
- "context2": "value_context1",
579
+ "context2": "value_context2",
580
580
  "input_query": "What's Beekeeper Framework?",
581
581
  "generated_text": "Beekeeper is a data framework to make AI easier to work with.",
582
582
  "input_token_count": 25,
@@ -663,6 +663,119 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
663
663
 
664
664
  return [data["scoring_id"] + "-1" for data in payload_data]
665
665
 
666
+ def store_feedback_records(
667
+ self,
668
+ request_records: List[Dict],
669
+ subscription_id: str = None,
670
+ ) -> Dict:
671
+ """
672
+ Stores records to the feedback logging system.
673
+
674
+ Note:
675
+ Feedback data for external prompt **must include** the model output named `generated_text`.
676
+
677
+ Args:
678
+ request_records (List[Dict]): A list of records to be logged, where each record is represented as a dictionary.
679
+ subscription_id (str, optional): The subscription ID associated with the records being logged.
680
+
681
+ Example:
682
+ ```python
683
+ wxgov_client.store_feedback_records(
684
+ request_records=[
685
+ {
686
+ "context1": "value_context1",
687
+ "context2": "value_context2",
688
+ "input_query": "What's Beekeeper Framework?",
689
+ "reference_output": "Beekeeper is a data framework to make AI easier to work with."
690
+ "generated_text": "Beekeeper is a data framework to make AI easier to work with.",
691
+ }
692
+ ],
693
+ subscription_id="5d62977c-a53d-4b6d-bda1-7b79b3b9d1a0",
694
+ )
695
+ ```
696
+ """
697
+ from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
698
+ from ibm_watson_openscale import APIClient as WosAPIClient
699
+ from ibm_watson_openscale.supporting_classes.enums import (
700
+ DataSetTypes,
701
+ TargetTypes,
702
+ )
703
+
704
+ # Expected behavior: Prefer using fn `subscription_id`.
705
+ # Fallback to `self.subscription_id` if `subscription_id` None or empty.
706
+ _subscription_id = subscription_id or self.subscription_id
707
+
708
+ if _subscription_id is None or _subscription_id == "":
709
+ raise ValueError(
710
+ "Unexpected value for 'subscription_id': Cannot be None or empty string."
711
+ )
712
+
713
+ if not self._wos_client:
714
+ try:
715
+ if hasattr(self, "_wos_cpd_creds") and self._wos_cpd_creds:
716
+ from ibm_cloud_sdk_core.authenticators import (
717
+ CloudPakForDataAuthenticator, # type: ignore
718
+ )
719
+
720
+ authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
721
+ self._wos_client = WosAPIClient(
722
+ authenticator=authenticator,
723
+ service_url=self._wos_cpd_creds["url"],
724
+ )
725
+
726
+ else:
727
+ from ibm_cloud_sdk_core.authenticators import (
728
+ IAMAuthenticator, # type: ignore
729
+ )
730
+
731
+ authenticator = IAMAuthenticator(apikey=self._api_key)
732
+ self._wos_client = WosAPIClient(
733
+ authenticator=authenticator,
734
+ service_url=self.region.openscale,
735
+ )
736
+
737
+ except Exception as e:
738
+ logging.error(
739
+ f"Error connecting to IBM watsonx.governance (openscale): {e}",
740
+ )
741
+ raise
742
+
743
+ subscription_details = self._wos_client.subscriptions.get(
744
+ _subscription_id,
745
+ ).result
746
+ subscription_details = json.loads(str(subscription_details))
747
+
748
+ feature_fields = subscription_details["entity"]["asset_properties"][
749
+ "feature_fields"
750
+ ]
751
+
752
+ # Rename generated_text to _original_prediction (expected by WOS feedback dataset)
753
+ # Validate required fields for detached/external monitor
754
+ for i, d in enumerate(request_records):
755
+ d["_original_prediction"] = d.pop("generated_text", None)
756
+ request_records[i] = validate_and_filter_dict(
757
+ d, feature_fields, ["_original_prediction"]
758
+ )
759
+
760
+ feedback_data_set_id = (
761
+ self._wos_client.data_sets.list(
762
+ type=DataSetTypes.FEEDBACK,
763
+ target_target_id=_subscription_id,
764
+ target_target_type=TargetTypes.SUBSCRIPTION,
765
+ )
766
+ .result.data_sets[0]
767
+ .metadata.id
768
+ )
769
+
770
+ suppress_output(
771
+ self._wos_client.data_sets.store_records,
772
+ data_set_id=feedback_data_set_id,
773
+ request_body=request_records,
774
+ background_mode=False,
775
+ )
776
+
777
+ return {"status": "success"}
778
+
666
779
  def __call__(self, payload: PayloadRecord) -> None:
667
780
  if self.prompt_template:
668
781
  template_vars = extract_template_vars(
@@ -1141,7 +1254,7 @@ class WatsonxPromptMonitor(PromptMonitor):
1141
1254
  request_records=[
1142
1255
  {
1143
1256
  "context1": "value_context1",
1144
- "context2": "value_context1",
1257
+ "context2": "value_context2",
1145
1258
  "input_query": "What's Beekeeper Framework?",
1146
1259
  "generated_text": "Beekeeper is a data framework to make AI easier to work with.",
1147
1260
  "input_token_count": 25,
@@ -1229,6 +1342,116 @@ class WatsonxPromptMonitor(PromptMonitor):
1229
1342
 
1230
1343
  return [data["scoring_id"] + "-1" for data in payload_data]
1231
1344
 
1345
+ def store_feedback_records(
1346
+ self,
1347
+ request_records: List[Dict],
1348
+ subscription_id: str = None,
1349
+ ) -> Dict:
1350
+ """
1351
+ Stores records to the feedback logging system.
1352
+
1353
+ Args:
1354
+ request_records (List[Dict]): A list of records to be logged, where each record is represented as a dictionary.
1355
+ subscription_id (str, optional): The subscription ID associated with the records being logged.
1356
+
1357
+ Example:
1358
+ ```python
1359
+ wxgov_client.store_feedback_records(
1360
+ request_records=[
1361
+ {
1362
+ "context1": "value_context1",
1363
+ "context2": "value_context2",
1364
+ "input_query": "What's Beekeeper Framework?",
1365
+ "reference_output": "Beekeeper is a data framework to make AI easier to work with."
1366
+ "generated_text": "Beekeeper is a data framework to make AI easier to work with.",
1367
+ }
1368
+ ],
1369
+ subscription_id="5d62977c-a53d-4b6d-bda1-7b79b3b9d1a0",
1370
+ )
1371
+ ```
1372
+ """
1373
+ from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
1374
+ from ibm_watson_openscale import APIClient as WosAPIClient
1375
+ from ibm_watson_openscale.supporting_classes.enums import (
1376
+ DataSetTypes,
1377
+ TargetTypes,
1378
+ )
1379
+
1380
+ # Expected behavior: Prefer using fn `subscription_id`.
1381
+ # Fallback to `self.subscription_id` if `subscription_id` None or empty.
1382
+ _subscription_id = subscription_id or self.subscription_id
1383
+
1384
+ if _subscription_id is None or _subscription_id == "":
1385
+ raise ValueError(
1386
+ "Unexpected value for 'subscription_id': Cannot be None or empty string."
1387
+ )
1388
+
1389
+ if not self._wos_client:
1390
+ try:
1391
+ if hasattr(self, "_wos_cpd_creds") and self._wos_cpd_creds:
1392
+ from ibm_cloud_sdk_core.authenticators import (
1393
+ CloudPakForDataAuthenticator, # type: ignore
1394
+ )
1395
+
1396
+ authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
1397
+ self._wos_client = WosAPIClient(
1398
+ authenticator=authenticator,
1399
+ service_url=self._wos_cpd_creds["url"],
1400
+ )
1401
+
1402
+ else:
1403
+ from ibm_cloud_sdk_core.authenticators import (
1404
+ IAMAuthenticator, # type: ignore
1405
+ )
1406
+
1407
+ authenticator = IAMAuthenticator(apikey=self._api_key)
1408
+ self._wos_client = WosAPIClient(
1409
+ authenticator=authenticator,
1410
+ service_url=self.region.openscale,
1411
+ )
1412
+
1413
+ except Exception as e:
1414
+ logging.error(
1415
+ f"Error connecting to IBM watsonx.governance (openscale): {e}",
1416
+ )
1417
+ raise
1418
+
1419
+ subscription_details = self._wos_client.subscriptions.get(
1420
+ _subscription_id,
1421
+ ).result
1422
+ subscription_details = json.loads(str(subscription_details))
1423
+
1424
+ feature_fields = subscription_details["entity"]["asset_properties"][
1425
+ "feature_fields"
1426
+ ]
1427
+
1428
+ # Rename generated_text to _original_prediction (expected by WOS feedback dataset)
1429
+ # Validate required fields for detached/external monitor
1430
+ for i, d in enumerate(request_records):
1431
+ d["_original_prediction"] = d.pop("generated_text", None)
1432
+ request_records[i] = validate_and_filter_dict(
1433
+ d, [*feature_fields, "_original_prediction"]
1434
+ )
1435
+
1436
+ feedback_data_set_id = (
1437
+ self._wos_client.data_sets.list(
1438
+ type=DataSetTypes.FEEDBACK,
1439
+ target_target_id=_subscription_id,
1440
+ target_target_type=TargetTypes.SUBSCRIPTION,
1441
+ )
1442
+ .result.data_sets[0]
1443
+ .metadata.id
1444
+ )
1445
+
1446
+ suppress_output(
1447
+ self._wos_client.data_sets.store_records,
1448
+ data_set_id=feedback_data_set_id,
1449
+ request_body=request_records,
1450
+ background_mode=False,
1451
+ )
1452
+
1453
+ return {"status": "success"}
1454
+
1232
1455
  def __call__(self, payload: PayloadRecord) -> None:
1233
1456
  if self.prompt_template:
1234
1457
  template_vars = extract_template_vars(
@@ -338,7 +338,7 @@ class WatsonxCustomMetricsManager:
338
338
  }
339
339
 
340
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.",
341
+ reason="'add_observer_instance()' is deprecated and will be removed in a future version. Use 'associate_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
342
342
  version="1.0.5",
343
343
  action="always",
344
344
  )
@@ -348,14 +348,14 @@ class WatsonxCustomMetricsManager:
348
348
  monitor_definition_id: str,
349
349
  subscription_id: str,
350
350
  ):
351
- return self.attach_monitor_instance(
351
+ return self.associate_monitor_instance(
352
352
  integrated_system_id=integrated_system_id,
353
353
  monitor_definition_id=monitor_definition_id,
354
354
  subscription_id=subscription_id,
355
355
  )
356
356
 
357
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.",
358
+ reason="'add_monitor_instance()' is deprecated and will be removed in a future version. Use 'associate_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
359
359
  version="1.0.6",
360
360
  action="always",
361
361
  )
@@ -365,20 +365,37 @@ class WatsonxCustomMetricsManager:
365
365
  monitor_definition_id: str,
366
366
  subscription_id: str,
367
367
  ):
368
- return self.attach_monitor_instance(
368
+ return self.associate_monitor_instance(
369
369
  integrated_system_id=integrated_system_id,
370
370
  monitor_definition_id=monitor_definition_id,
371
371
  subscription_id=subscription_id,
372
372
  )
373
373
 
374
+ @deprecated(
375
+ reason="'attach_monitor_instance()' is deprecated and will be removed in a future version. Use 'associate_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
376
+ version="1.1.0",
377
+ action="always",
378
+ )
374
379
  def attach_monitor_instance(
375
380
  self,
376
381
  integrated_system_id: str,
377
382
  monitor_definition_id: str,
378
383
  subscription_id: str,
384
+ ):
385
+ return self.associate_monitor_instance(
386
+ integrated_system_id=integrated_system_id,
387
+ monitor_definition_id=monitor_definition_id,
388
+ subscription_id=subscription_id,
389
+ )
390
+
391
+ def associate_monitor_instance(
392
+ self,
393
+ integrated_system_id: str,
394
+ monitor_definition_id: str,
395
+ subscription_id: str,
379
396
  ):
380
397
  """
381
- Attaches the specified monitor definition to the specified subscription.
398
+ Associate the specified monitor definition to the specified subscription.
382
399
 
383
400
  Args:
384
401
  integrated_system_id (str): The ID of the integrated system.
@@ -387,7 +404,7 @@ class WatsonxCustomMetricsManager:
387
404
 
388
405
  Example:
389
406
  ```python
390
- wxgov_client.attach_monitor_instance(
407
+ wxgov_client.associate_monitor_instance(
391
408
  integrated_system_id="019667ca-5687-7838-8d29-4ff70c2b36b0",
392
409
  monitor_definition_id="custom_llm_quality",
393
410
  subscription_id="0195e95d-03a4-7000-b954-b607db10fe9e",
@@ -434,14 +451,31 @@ class WatsonxCustomMetricsManager:
434
451
 
435
452
  return monitor_instance_details
436
453
 
454
+ @deprecated(
455
+ reason="'publish_metrics()' is deprecated and will be removed in a future version. Use 'store_metric_data()'",
456
+ version="1.1.0",
457
+ action="always",
458
+ )
437
459
  def publish_metrics(
438
460
  self,
439
461
  monitor_instance_id: str,
440
462
  run_id: str,
441
463
  request_records: Dict[str, Union[float, int]],
464
+ ):
465
+ return self.store_metric_data(
466
+ monitor_instance_id=monitor_instance_id,
467
+ run_id=run_id,
468
+ request_records=request_records,
469
+ )
470
+
471
+ def store_metric_data(
472
+ self,
473
+ monitor_instance_id: str,
474
+ run_id: str,
475
+ request_records: Dict[str, Union[float, int]],
442
476
  ):
443
477
  """
444
- Publishes computed metrics to the specified global monitor instance.
478
+ Stores computed metrics data to the specified monitor instance.
445
479
 
446
480
  Args:
447
481
  monitor_instance_id (str): The unique ID of the monitor instance.
@@ -450,7 +484,7 @@ class WatsonxCustomMetricsManager:
450
484
 
451
485
  Example:
452
486
  ```python
453
- wxgov_client.publish_metrics(
487
+ wxgov_client.put_metrics(
454
488
  monitor_instance_id="01966801-f9ee-7248-a706-41de00a8a998",
455
489
  run_id="RUN_ID",
456
490
  request_records={"context_quality": 0.914, "sensitivity": 0.85},
@@ -583,13 +617,28 @@ class WatsonxCustomMetricsManager:
583
617
  background_mode=False,
584
618
  ).result.metadata.id
585
619
 
620
+ @deprecated(
621
+ reason="'publish_local_metrics()' is deprecated and will be removed in a future version. Use 'store_local_metric_data()'",
622
+ version="1.1.0",
623
+ action="always",
624
+ )
586
625
  def publish_local_metrics(
587
626
  self,
588
627
  metric_instance_id: str,
589
628
  request_records: List[Dict],
629
+ ):
630
+ return self.store_local_metric_data(
631
+ metric_instance_id=metric_instance_id,
632
+ request_records=request_records,
633
+ )
634
+
635
+ def store_local_metric_data(
636
+ self,
637
+ metric_instance_id: str,
638
+ request_records: List[Dict],
590
639
  ):
591
640
  """
592
- Publishes computed metrics to the specified transaction record.
641
+ Stores computed metrics data to the specified transaction record.
593
642
 
594
643
  Args:
595
644
  metric_instance_id (str): The unique ID of the custom transaction metric.
@@ -597,7 +646,7 @@ class WatsonxCustomMetricsManager:
597
646
 
598
647
  Example:
599
648
  ```python
600
- wxgov_client.publish_local_metrics(
649
+ wxgov_client.store_local_metric_data(
601
650
  metric_instance_id="0196ad39-1b75-7e77-bddb-cc5393d575c2",
602
651
  request_records=[
603
652
  {
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beekeeper-monitors-watsonx
3
- Version: 1.0.7
3
+ Version: 1.1.0.post1
4
4
  Summary: beekeeper monitors watsonx extension
5
5
  Author-email: Leonardo Furnielis <leonardofurnielis@outlook.com>
6
6
  License: Apache-2.0
7
7
  Requires-Python: <4.0,>=3.10
8
- Requires-Dist: beekeeper-core<2.0.0,>=1.0.4
8
+ Requires-Dist: beekeeper-core<2.0.0,>=1.0.5
9
9
  Requires-Dist: certifi<2026.0.0,>=2025.4.26
10
10
  Requires-Dist: ibm-aigov-facts-client<1.0.97,>=1.0.96
11
11
  Requires-Dist: ibm-watson-openscale<3.1.0,>=3.0.49
@@ -1,12 +1,12 @@
1
1
  beekeeper/monitors/watsonx/__init__.py,sha256=iJv6D68IT00ZC40TNSVYtqyFTen9sWoDqUtxvVVJjOE,789
2
- beekeeper/monitors/watsonx/base.py,sha256=_nCOD09F46O64T9964gvCyhmX8hFupb0T9DDZlRftBs,47075
3
- beekeeper/monitors/watsonx/custom_metric.py,sha256=eoosf2WKdru28ShhLEdlj5ldjyYGl3Feop6TA1U3gZY,22185
2
+ beekeeper/monitors/watsonx/base.py,sha256=jtgUGIWKWGQDsdEbeHm4iRmXp2-aErj97IKH0P3_Ayw,55775
3
+ beekeeper/monitors/watsonx/custom_metric.py,sha256=QCkNDNLK_IehZIdXyczDM7RuDdyvCJN2IaTc-xsm-Lk,23827
4
4
  beekeeper/monitors/watsonx/supporting_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  beekeeper/monitors/watsonx/supporting_classes/credentials.py,sha256=x4rYoOFvx0pWDhFZfuy6fM0rj7JCivaSYn_jYFXlV8U,5190
6
6
  beekeeper/monitors/watsonx/supporting_classes/enums.py,sha256=7HkSrjU7D8pFPCRdYk_1oE27r_sZ_nIL6cuShIdtmR8,1895
7
7
  beekeeper/monitors/watsonx/supporting_classes/metric.py,sha256=iERXRi0iBFHITFaLtonoV97nNUCPXbieD7Z1wX6bvX8,3370
8
8
  beekeeper/monitors/watsonx/utils/data_utils.py,sha256=qBLYtHGY0MJ0JJ8BpFDT2YIjA3QOYJQNemLvpA3DMz0,1252
9
9
  beekeeper/monitors/watsonx/utils/instrumentation.py,sha256=ztgR1kZ9h-JvASzRA47AYHdc-Isv33EQum9XBLg-dQk,525
10
- beekeeper_monitors_watsonx-1.0.7.dist-info/METADATA,sha256=NHZe3EfiayFDVoY4TK7Qoo9U0mqPyyqxEXxncEgnefM,716
11
- beekeeper_monitors_watsonx-1.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- beekeeper_monitors_watsonx-1.0.7.dist-info/RECORD,,
10
+ beekeeper_monitors_watsonx-1.1.0.post1.dist-info/METADATA,sha256=CeEXAqhnYUi0qbbhx6EfkB3-tlkAbFNLMde-t0Bp6L4,722
11
+ beekeeper_monitors_watsonx-1.1.0.post1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ beekeeper_monitors_watsonx-1.1.0.post1.dist-info/RECORD,,