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.
@@ -1,64 +1,25 @@
1
- import datetime
2
1
  import json
3
2
  import logging
4
3
  import os
5
4
  import uuid
6
- from typing import Any, Dict, List, Literal, Optional, Union
5
+ from typing import Dict, List, Literal, Union
7
6
 
8
7
  import certifi
9
8
  from beekeeper.core.monitors import PromptMonitor
10
9
  from beekeeper.core.monitors.types import PayloadRecord
11
10
  from beekeeper.core.prompts.utils import extract_template_vars
12
- from beekeeper.monitors.watsonx.instrumentation import suppress_output
11
+ from beekeeper.monitors.watsonx.supporting_classes.credentials import (
12
+ CloudPakforDataCredentials,
13
+ )
14
+ from beekeeper.monitors.watsonx.supporting_classes.enums import Region
15
+ from beekeeper.monitors.watsonx.utils.data_utils import validate_and_filter_dict
16
+ from beekeeper.monitors.watsonx.utils.instrumentation import suppress_output
13
17
  from deprecated import deprecated
14
- from pydantic.v1 import BaseModel
15
18
 
16
19
  os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
17
20
  logging.getLogger("ibm_watsonx_ai.client").setLevel(logging.ERROR)
18
21
  logging.getLogger("ibm_watsonx_ai.wml_resource").setLevel(logging.ERROR)
19
22
 
20
- REGIONS_URL = {
21
- "us-south": {
22
- "wml": "https://us-south.ml.cloud.ibm.com",
23
- "wos": "https://api.aiopenscale.cloud.ibm.com",
24
- "factsheet": None,
25
- },
26
- "eu-de": {
27
- "wml": "https://eu-de.ml.cloud.ibm.com",
28
- "wos": "https://eu-de.api.aiopenscale.cloud.ibm.com",
29
- "factsheet": "frankfurt",
30
- },
31
- "au-syd": {
32
- "wml": "https://au-syd.ml.cloud.ibm.com",
33
- "wos": "https://au-syd.api.aiopenscale.cloud.ibm.com",
34
- "factsheet": "sydney",
35
- },
36
- }
37
-
38
-
39
- def _filter_dict(original_dict: Dict, optional_keys: List, required_keys: List = []):
40
- """
41
- Filters a dictionary to keep only the specified keys and checks for required keys.
42
-
43
- Args:
44
- original_dict (Dict): The original dictionary.
45
- optional_keys (list): A list of keys to retain.
46
- required_keys (list, optional): A list of keys that must be present in the dictionary. Defaults to None.
47
- """
48
- # Ensure all required keys are in the source dict
49
- missing_keys = [key for key in required_keys if key not in original_dict]
50
- if missing_keys:
51
- raise KeyError(f"Missing required parameter: {missing_keys}")
52
-
53
- all_keys_to_keep = set(required_keys + optional_keys)
54
-
55
- # Create a new dictionary with only the key-value pairs where the key is in 'keys' and value is not None
56
- return {
57
- key: original_dict[key]
58
- for key in all_keys_to_keep
59
- if key in original_dict and original_dict[key] is not None
60
- }
61
-
62
23
 
63
24
  def _convert_payload_format(
64
25
  records: List[Dict],
@@ -93,145 +54,9 @@ def _convert_payload_format(
93
54
  return payload_data
94
55
 
95
56
 
96
- # ===== Credentials Classes =====
97
- class CloudPakforDataCredentials(BaseModel):
98
- """
99
- Encapsulates the credentials required for IBM Cloud Pak for Data.
100
-
101
- Attributes:
102
- url (str): The host URL of the Cloud Pak for Data environment.
103
- api_key (str, optional): The API key for the environment, if IAM is enabled.
104
- username (str, optional): The username for the environment.
105
- password (str, optional): The password for the environment.
106
- bedrock_url (str, optional): The Bedrock URL. Required only when IAM integration is enabled on CP4D 4.0.x clusters.
107
- instance_id (str, optional): The instance ID.
108
- version (str, optional): The version of Cloud Pak for Data.
109
- disable_ssl_verification (bool, optional): Indicates whether to disable SSL certificate verification.
110
- Defaults to `True`.
111
- """
112
-
113
- url: str
114
- api_key: Optional[str] = None
115
- username: Optional[str] = None
116
- password: Optional[str] = None
117
- bedrock_url: Optional[str] = None
118
- instance_id: Optional[Literal["icp", "openshift"]] = None
119
- version: Optional[str] = None
120
- disable_ssl_verification: bool = True
121
-
122
- def __init__(
123
- self,
124
- url: str,
125
- api_key: Optional[str] = None,
126
- username: Optional[str] = None,
127
- password: Optional[str] = None,
128
- bedrock_url: Optional[str] = None,
129
- instance_id: Optional[Literal["icp", "openshift"]] = None,
130
- version: Optional[str] = None,
131
- disable_ssl_verification: bool = True,
132
- ) -> None:
133
- super().__init__(
134
- url=url,
135
- api_key=api_key,
136
- username=username,
137
- password=password,
138
- bedrock_url=bedrock_url,
139
- instance_id=instance_id,
140
- version=version,
141
- disable_ssl_verification=disable_ssl_verification,
142
- )
143
-
144
- def to_dict(self) -> Dict[str, Any]:
145
- cpd_creds = dict([(k, v) for k, v in self.__dict__.items()]) # noqa: C404
146
-
147
- if "instance_id" in cpd_creds and self.instance_id.lower() not in [
148
- "icp",
149
- "openshift",
150
- ]:
151
- cpd_creds.pop("instance_id")
152
-
153
- return cpd_creds
154
-
155
-
156
- class IntegratedSystemCredentials(BaseModel):
157
- """
158
- Encapsulates the credentials for an Integrated System based on the authentication type.
159
-
160
- Depending on the `auth_type`, only a subset of the properties is required.
161
-
162
- Attributes:
163
- auth_type (str): The type of authentication. Currently supports "basic" and "bearer".
164
- username (str, optional): The username for Basic Authentication.
165
- password (str, optional): The password for Basic Authentication.
166
- token_url (str, optional): The URL of the authentication endpoint used to request a Bearer token.
167
- token_method (str, optional): The HTTP method (e.g., "POST", "GET") used to request the Bearer token.
168
- Defaults to "POST".
169
- token_headers (Dict, optional): Optional headers to include when requesting the Bearer token.
170
- Defaults to `None`.
171
- token_payload (str | dict, optional): The body or payload to send when requesting the Bearer token.
172
- Can be a string (e.g., raw JSON). Defaults to `None`.
173
- """
174
-
175
- auth_type: Literal["basic", "bearer"]
176
- username: Optional[str] # basic
177
- password: Optional[str] # basic
178
- token_url: Optional[str] # bearer
179
- token_method: Optional[str] = "POST" # bearer
180
- token_headers: Optional[Dict] = {} # bearer
181
- token_payload: Optional[Union[str, Dict]] = None # bearer
182
-
183
- def __init__(
184
- self,
185
- auth_type: Literal["basic", "bearer"],
186
- username: str = None,
187
- password: str = None,
188
- token_url: str = None,
189
- token_method: str = "POST",
190
- token_headers: Dict = {},
191
- token_payload: Union[str, Dict] = None,
192
- ) -> None:
193
- if auth_type == "basic":
194
- if not username or not password:
195
- raise ValueError(
196
- "`username` and `password` are required for auth_type = 'basic'.",
197
- )
198
- elif auth_type == "bearer":
199
- if not token_url:
200
- raise ValueError(
201
- "`token_url` are required for auth_type = 'bearer'.",
202
- )
203
-
204
- super().__init__(
205
- auth_type=auth_type,
206
- username=username,
207
- password=password,
208
- token_url=token_url,
209
- token_method=token_method,
210
- token_headers=token_headers,
211
- token_payload=token_payload,
212
- )
213
-
214
- def to_dict(self) -> Dict:
215
- integrated_system_creds = {"auth_type": self.auth_type}
216
-
217
- if self.auth_type == "basic":
218
- integrated_system_creds["username"] = self.username
219
- integrated_system_creds["password"] = self.password
220
- elif self.auth_type == "bearer":
221
- integrated_system_creds["token_info"] = {
222
- "url": self.token_url,
223
- "method": self.token_method,
224
- "headers": self.token_headers,
225
- "payload": self.token_payload,
226
- }
227
-
228
- return integrated_system_creds
229
-
230
-
231
- # ===== Monitor Classes =====
232
57
  class WatsonxExternalPromptMonitor(PromptMonitor):
233
58
  """
234
- Provides functionality to interact with IBM watsonx.governance for monitoring external LLMs.
59
+ Provides functionality to interact with IBM watsonx.governance for monitoring prompts executed on external LLMs.
235
60
 
236
61
  Note:
237
62
  One of the following parameters is required to create a prompt monitor:
@@ -241,7 +66,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
241
66
  api_key (str): The API key for IBM watsonx.governance.
242
67
  space_id (str, optional): The space ID in watsonx.governance.
243
68
  project_id (str, optional): The project ID in watsonx.governance.
244
- region (str, optional): The region where watsonx.governance is hosted when using IBM Cloud.
69
+ region (Region, optional): The region where watsonx.governance is hosted when using IBM Cloud.
245
70
  Defaults to `us-south`.
246
71
  cpd_creds (CloudPakforDataCredentials, optional): The Cloud Pak for Data environment credentials.
247
72
  subscription_id (str, optional): The subscription ID associated with the records being logged.
@@ -278,8 +103,8 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
278
103
  api_key: str = None,
279
104
  space_id: str = None,
280
105
  project_id: str = None,
281
- region: Literal["us-south", "eu-de", "au-syd"] = "us-south",
282
- cpd_creds: CloudPakforDataCredentials | Dict = None,
106
+ region: Union[Region, str] = Region.US_SOUTH,
107
+ cpd_creds: Union[CloudPakforDataCredentials, Dict] = None,
283
108
  subscription_id: str = None,
284
109
  **kwargs,
285
110
  ) -> None:
@@ -292,7 +117,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
292
117
 
293
118
  self.space_id = space_id
294
119
  self.project_id = project_id
295
- self.region = region
120
+ self.region = Region.from_value(region)
296
121
  self.subscription_id = subscription_id
297
122
  self._api_key = api_key
298
123
  self._wos_client = None
@@ -302,18 +127,18 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
302
127
  self._deployment_stage = "production" if space_id else "development"
303
128
 
304
129
  if cpd_creds:
305
- self._wos_cpd_creds = _filter_dict(
130
+ self._wos_cpd_creds = validate_and_filter_dict(
306
131
  cpd_creds.to_dict(),
307
132
  ["username", "password", "api_key", "disable_ssl_verification"],
308
133
  ["url"],
309
134
  )
310
- self._fact_cpd_creds = _filter_dict(
135
+ self._fact_cpd_creds = validate_and_filter_dict(
311
136
  cpd_creds.to_dict(),
312
137
  ["username", "password", "api_key", "bedrock_url"],
313
138
  ["url"],
314
139
  )
315
140
  self._fact_cpd_creds["service_url"] = self._fact_cpd_creds.pop("url")
316
- self._wml_cpd_creds = _filter_dict(
141
+ self._wml_cpd_creds = validate_and_filter_dict(
317
142
  cpd_creds.to_dict(),
318
143
  [
319
144
  "username",
@@ -356,7 +181,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
356
181
  container_id=self._container_id,
357
182
  container_type=self._container_type,
358
183
  disable_tracing=True,
359
- region=REGIONS_URL[self.region]["factsheet"],
184
+ region=self.region.factsheet,
360
185
  )
361
186
 
362
187
  except Exception as e:
@@ -385,7 +210,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
385
210
 
386
211
  else:
387
212
  creds = Credentials(
388
- url=REGIONS_URL[self.region]["wml"],
213
+ url=self.region.watsonxai,
389
214
  api_key=self._api_key,
390
215
  )
391
216
  wml_client = APIClient(creds)
@@ -411,7 +236,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
411
236
  return wml_client.deployments.get_uid(created_deployment)
412
237
 
413
238
  @deprecated(
414
- reason="'add_prompt_observer()' is deprecated and will be removed in a future version. Use 'add_prompt_monitor()' instead.",
239
+ reason="'add_prompt_observer()' is deprecated and will be removed in a future version. Use 'create_prompt_monitor()' instead.",
415
240
  version="1.0.5",
416
241
  action="always",
417
242
  )
@@ -439,7 +264,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
439
264
  context_fields: List[str] = None,
440
265
  question_field: str = None,
441
266
  ) -> Dict:
442
- return self.add_prompt_monitor(
267
+ return self.create_prompt_monitor(
443
268
  name=name,
444
269
  model_id=model_id,
445
270
  task_id=task_id,
@@ -457,6 +282,11 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
457
282
  question_field=question_field,
458
283
  )
459
284
 
285
+ @deprecated(
286
+ reason="'add_prompt_monitor()' is deprecated and will be removed in a future version. Use 'create_prompt_monitor()' instead.",
287
+ version="1.0.6",
288
+ action="always",
289
+ )
460
290
  def add_prompt_monitor(
461
291
  self,
462
292
  name: str,
@@ -480,9 +310,51 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
480
310
  input_text: str = None,
481
311
  context_fields: List[str] = None,
482
312
  question_field: str = None,
313
+ ) -> Dict:
314
+ return self.create_prompt_monitor(
315
+ name=name,
316
+ model_id=model_id,
317
+ task_id=task_id,
318
+ detached_model_provider=detached_model_provider,
319
+ description=description,
320
+ model_parameters=model_parameters,
321
+ detached_model_name=detached_model_name,
322
+ detached_model_url=detached_model_url,
323
+ detached_prompt_url=detached_prompt_url,
324
+ detached_prompt_additional_info=detached_prompt_additional_info,
325
+ prompt_variables=prompt_variables,
326
+ locale=locale,
327
+ input_text=input_text,
328
+ context_fields=context_fields,
329
+ question_field=question_field,
330
+ )
331
+
332
+ def create_prompt_monitor(
333
+ self,
334
+ name: str,
335
+ model_id: str,
336
+ task_id: Literal[
337
+ "extraction",
338
+ "generation",
339
+ "question_answering",
340
+ "retrieval_augmented_generation",
341
+ "summarization",
342
+ ],
343
+ detached_model_provider: str,
344
+ description: str = "",
345
+ model_parameters: Dict = None,
346
+ detached_model_name: str = None,
347
+ detached_model_url: str = None,
348
+ detached_prompt_url: str = None,
349
+ detached_prompt_additional_info: Dict = None,
350
+ prompt_variables: List[str] = None,
351
+ locale: str = "en",
352
+ input_text: str = None,
353
+ context_fields: List[str] = None,
354
+ question_field: str = None,
483
355
  ) -> Dict:
484
356
  """
485
- Creates a Detached/External Prompt Template Asset and setup monitor for a given prompt template asset.
357
+ Creates a detached (external) prompt template asset and attaches a monitor to the specified prompt template asset.
486
358
 
487
359
  Args:
488
360
  name (str): The name of the External Prompt Template Asset.
@@ -505,7 +377,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
505
377
 
506
378
  Example:
507
379
  ```python
508
- wxgov_client.add_prompt_monitor(
380
+ wxgov_client.create_prompt_monitor(
509
381
  name="Detached prompt (model AWS Anthropic)",
510
382
  model_id="anthropic.claude-v2",
511
383
  task_id="retrieval_augmented_generation",
@@ -582,7 +454,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
582
454
  authenticator = IAMAuthenticator(apikey=self._api_key)
583
455
  self._wos_client = WosAPIClient(
584
456
  authenticator=authenticator,
585
- service_url=REGIONS_URL[self.region]["wos"],
457
+ service_url=self.region.openscale,
586
458
  )
587
459
 
588
460
  except Exception as e:
@@ -591,19 +463,19 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
591
463
  )
592
464
  raise
593
465
 
594
- detached_details = _filter_dict(
466
+ detached_details = validate_and_filter_dict(
595
467
  prompt_metadata,
596
468
  ["model_name", "model_url", "prompt_url", "prompt_additional_info"],
597
469
  ["model_id", "model_provider"],
598
470
  )
599
471
  detached_details["prompt_id"] = "detached_prompt_" + str(uuid.uuid4())
600
472
 
601
- prompt_details = _filter_dict(
473
+ prompt_details = validate_and_filter_dict(
602
474
  prompt_metadata,
603
475
  ["prompt_variables", "input", "model_parameters"],
604
476
  )
605
477
 
606
- detached_asset_details = _filter_dict(
478
+ detached_asset_details = validate_and_filter_dict(
607
479
  prompt_metadata,
608
480
  ["description"],
609
481
  ["name", "model_id", "task_id"],
@@ -752,7 +624,7 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
752
624
  authenticator = IAMAuthenticator(apikey=self._api_key)
753
625
  self._wos_client = WosAPIClient(
754
626
  authenticator=authenticator,
755
- service_url=REGIONS_URL[self.region]["wos"],
627
+ service_url=self.region.openscale,
756
628
  )
757
629
 
758
630
  except Exception as e:
@@ -805,7 +677,8 @@ class WatsonxExternalPromptMonitor(PromptMonitor):
805
677
 
806
678
  class WatsonxPromptMonitor(PromptMonitor):
807
679
  """
808
- Provides functionality to interact with IBM watsonx.governance for monitoring IBM watsonx.ai LLMs.
680
+ Provides functionality to interact with IBM watsonx.governance for monitoring prompts executed within
681
+ IBM watsonx.ai LLMs.
809
682
 
810
683
  Note:
811
684
  One of the following parameters is required to create a prompt monitor:
@@ -815,7 +688,7 @@ class WatsonxPromptMonitor(PromptMonitor):
815
688
  api_key (str): The API key for IBM watsonx.governance.
816
689
  space_id (str, optional): The space ID in watsonx.governance.
817
690
  project_id (str, optional): The project ID in watsonx.governance.
818
- region (str, optional): The region where watsonx.governance is hosted when using IBM Cloud.
691
+ region (Region, optional): The region where watsonx.governance is hosted when using IBM Cloud.
819
692
  Defaults to `us-south`.
820
693
  cpd_creds (CloudPakforDataCredentials, optional): The Cloud Pak for Data environment credentials.
821
694
  subscription_id (str, optional): The subscription ID associated with the records being logged.
@@ -848,8 +721,8 @@ class WatsonxPromptMonitor(PromptMonitor):
848
721
  api_key: str = None,
849
722
  space_id: str = None,
850
723
  project_id: str = None,
851
- region: Literal["us-south", "eu-de", "au-syd"] = "us-south",
852
- cpd_creds: CloudPakforDataCredentials | Dict = None,
724
+ region: Union[Region, str] = Region.US_SOUTH,
725
+ cpd_creds: Union[CloudPakforDataCredentials, Dict] = None,
853
726
  subscription_id: str = None,
854
727
  **kwargs,
855
728
  ) -> None:
@@ -862,7 +735,7 @@ class WatsonxPromptMonitor(PromptMonitor):
862
735
 
863
736
  self.space_id = space_id
864
737
  self.project_id = project_id
865
- self.region = region
738
+ self.region = Region.from_value(region)
866
739
  self.subscription_id = subscription_id
867
740
  self._api_key = api_key
868
741
  self._wos_client = None
@@ -872,18 +745,18 @@ class WatsonxPromptMonitor(PromptMonitor):
872
745
  self._deployment_stage = "production" if space_id else "development"
873
746
 
874
747
  if cpd_creds:
875
- self._wos_cpd_creds = _filter_dict(
748
+ self._wos_cpd_creds = validate_and_filter_dict(
876
749
  cpd_creds.to_dict(),
877
750
  ["username", "password", "api_key", "disable_ssl_verification"],
878
751
  ["url"],
879
752
  )
880
- self._fact_cpd_creds = _filter_dict(
753
+ self._fact_cpd_creds = validate_and_filter_dict(
881
754
  cpd_creds.to_dict(),
882
755
  ["username", "password", "api_key", "bedrock_url"],
883
756
  ["url"],
884
757
  )
885
758
  self._fact_cpd_creds["service_url"] = self._fact_cpd_creds.pop("url")
886
- self._wml_cpd_creds = _filter_dict(
759
+ self._wml_cpd_creds = validate_and_filter_dict(
887
760
  cpd_creds.to_dict(),
888
761
  [
889
762
  "username",
@@ -924,7 +797,7 @@ class WatsonxPromptMonitor(PromptMonitor):
924
797
  container_id=self._container_id,
925
798
  container_type=self._container_type,
926
799
  disable_tracing=True,
927
- region=REGIONS_URL[self.region]["factsheet"],
800
+ region=self.region.factsheet,
928
801
  )
929
802
 
930
803
  except Exception as e:
@@ -953,7 +826,7 @@ class WatsonxPromptMonitor(PromptMonitor):
953
826
 
954
827
  else:
955
828
  creds = Credentials(
956
- url=REGIONS_URL[self.region]["wml"],
829
+ url=self.region.watsonxai,
957
830
  api_key=self._api_key,
958
831
  )
959
832
 
@@ -980,7 +853,7 @@ class WatsonxPromptMonitor(PromptMonitor):
980
853
  return wml_client.deployments.get_uid(created_deployment)
981
854
 
982
855
  @deprecated(
983
- reason="'add_prompt_observer()' is deprecated and will be removed in a future version. Use 'add_prompt_monitor()' instead.",
856
+ reason="'add_prompt_observer()' is deprecated and will be removed in a future version. Use 'create_prompt_monitor()' instead.",
984
857
  version="1.0.5",
985
858
  action="always",
986
859
  )
@@ -1003,7 +876,7 @@ class WatsonxPromptMonitor(PromptMonitor):
1003
876
  context_fields: List[str] = None,
1004
877
  question_field: str = None,
1005
878
  ) -> Dict:
1006
- return self.add_prompt_monitor(
879
+ return self.create_prompt_monitor(
1007
880
  name=name,
1008
881
  model_id=model_id,
1009
882
  task_id=task_id,
@@ -1016,6 +889,11 @@ class WatsonxPromptMonitor(PromptMonitor):
1016
889
  question_field=question_field,
1017
890
  )
1018
891
 
892
+ @deprecated(
893
+ reason="'add_prompt_observer()' is deprecated and will be removed in a future version. Use 'create_prompt_monitor()' instead.",
894
+ version="1.0.6",
895
+ action="always",
896
+ )
1019
897
  def add_prompt_monitor(
1020
898
  self,
1021
899
  name: str,
@@ -1034,6 +912,38 @@ class WatsonxPromptMonitor(PromptMonitor):
1034
912
  input_text: str = None,
1035
913
  context_fields: List[str] = None,
1036
914
  question_field: str = None,
915
+ ) -> Dict:
916
+ return self.create_prompt_monitor(
917
+ name=name,
918
+ model_id=model_id,
919
+ task_id=task_id,
920
+ description=description,
921
+ model_parameters=model_parameters,
922
+ prompt_variables=prompt_variables,
923
+ locale=locale,
924
+ input_text=input_text,
925
+ context_fields=context_fields,
926
+ question_field=question_field,
927
+ )
928
+
929
+ def create_prompt_monitor(
930
+ self,
931
+ name: str,
932
+ model_id: str,
933
+ task_id: Literal[
934
+ "extraction",
935
+ "generation",
936
+ "question_answering",
937
+ "retrieval_augmented_generation",
938
+ "summarization",
939
+ ],
940
+ description: str = "",
941
+ model_parameters: Dict = None,
942
+ prompt_variables: List[str] = None,
943
+ locale: str = "en",
944
+ input_text: str = None,
945
+ context_fields: List[str] = None,
946
+ question_field: str = None,
1037
947
  ) -> Dict:
1038
948
  """
1039
949
  Creates an IBM Prompt Template Asset and ssetup monitor for the given prompt template asset.
@@ -1054,7 +964,7 @@ class WatsonxPromptMonitor(PromptMonitor):
1054
964
 
1055
965
  Example:
1056
966
  ```python
1057
- wxgov_client.add_prompt_monitor(
967
+ wxgov_client.create_prompt_monitor(
1058
968
  name="IBM prompt template",
1059
969
  model_id="ibm/granite-3-2b-instruct",
1060
970
  task_id="retrieval_augmented_generation",
@@ -1119,7 +1029,7 @@ class WatsonxPromptMonitor(PromptMonitor):
1119
1029
  authenticator = IAMAuthenticator(apikey=self._api_key)
1120
1030
  self._wos_client = WosAPIClient(
1121
1031
  authenticator=authenticator,
1122
- service_url=REGIONS_URL[self.region]["wos"],
1032
+ service_url=self.region.openscale,
1123
1033
  )
1124
1034
 
1125
1035
  except Exception as e:
@@ -1128,12 +1038,12 @@ class WatsonxPromptMonitor(PromptMonitor):
1128
1038
  )
1129
1039
  raise
1130
1040
 
1131
- prompt_details = _filter_dict(
1041
+ prompt_details = validate_and_filter_dict(
1132
1042
  prompt_metadata,
1133
1043
  ["prompt_variables", "input", "model_parameters"],
1134
1044
  )
1135
1045
 
1136
- asset_details = _filter_dict(
1046
+ asset_details = validate_and_filter_dict(
1137
1047
  prompt_metadata,
1138
1048
  ["description"],
1139
1049
  ["name", "model_id", "task_id"],
@@ -1280,7 +1190,7 @@ class WatsonxPromptMonitor(PromptMonitor):
1280
1190
  authenticator = IAMAuthenticator(apikey=self._api_key)
1281
1191
  self._wos_client = WosAPIClient(
1282
1192
  authenticator=authenticator,
1283
- service_url=REGIONS_URL[self.region]["wos"],
1193
+ service_url=self.region.openscale,
1284
1194
  )
1285
1195
 
1286
1196
  except Exception as e:
@@ -1329,674 +1239,3 @@ class WatsonxPromptMonitor(PromptMonitor):
1329
1239
  self.store_payload_records([payload.model_dump()])
1330
1240
  else:
1331
1241
  self.store_payload_records([{**payload.model_dump(), **template_vars}])
1332
-
1333
-
1334
- # ===== Supporting Classes =====
1335
- class WatsonxLocalMetric(BaseModel):
1336
- """
1337
- Provides the IBM watsonx.governance local monitor metric definition.
1338
-
1339
- Attributes:
1340
- name (str): The name of the metric.
1341
- data_type (str): The data type of the metric. Currently supports "string", "integer", "double", and "timestamp".
1342
- nullable (bool, optional): Indicates whether the metric can be null. Defaults to `False`.
1343
-
1344
- Example:
1345
- ```python
1346
- from beekeeper.monitors.watsonx import WatsonxLocalMetric
1347
-
1348
- WatsonxLocalMetric(name="context_quality", data_type="double")
1349
- ```
1350
- """
1351
-
1352
- name: str
1353
- data_type: Literal["string", "integer", "double", "timestamp"]
1354
- nullable: bool = True
1355
-
1356
- def to_dict(self) -> Dict:
1357
- return {"name": self.name, "type": self.data_type, "nullable": self.nullable}
1358
-
1359
-
1360
- class WatsonxMetricThreshold(BaseModel):
1361
- """
1362
- Defines the metric threshold for IBM watsonx.governance.
1363
-
1364
- Attributes:
1365
- threshold_type (str): The threshold type. Can be either `lower_limit` or `upper_limit`.
1366
- default_value (float): The metric threshold value.
1367
-
1368
- Example:
1369
- ```python
1370
- from beekeeper.monitors.watsonx import WatsonxMetricThreshold
1371
-
1372
- WatsonxMetricThreshold(threshold_type="lower_limit", default_value=0.8)
1373
- ```
1374
- """
1375
-
1376
- threshold_type: Literal["lower_limit", "upper_limit"]
1377
- default_value: float = None
1378
-
1379
- def to_dict(self) -> Dict:
1380
- return {"type": self.threshold_type, "default": self.default_value}
1381
-
1382
-
1383
- class WatsonxMetric(BaseModel):
1384
- """
1385
- Defines the IBM watsonx.governance global monitor metric.
1386
-
1387
- Attributes:
1388
- name (str): The name of the metric.
1389
- applies_to (List[str]): A list of task types that the metric applies to. Currently supports:
1390
- "summarization", "generation", "question_answering", "extraction", and "retrieval_augmented_generation".
1391
- thresholds (List[WatsonxMetricThreshold]): A list of metric thresholds associated with the metric.
1392
-
1393
- Example:
1394
- ```python
1395
- from beekeeper.monitors.watsonx import (
1396
- WatsonxMetric,
1397
- WatsonxMetricThreshold,
1398
- )
1399
-
1400
- WatsonxMetric(
1401
- name="context_quality",
1402
- applies_to=["retrieval_augmented_generation", "summarization"],
1403
- thresholds=[
1404
- WatsonxMetricThreshold(threshold_type="lower_limit", default_value=0.75)
1405
- ],
1406
- )
1407
- ```
1408
- """
1409
-
1410
- name: str
1411
- applies_to: List[
1412
- Literal[
1413
- "summarization",
1414
- "generation",
1415
- "question_answering",
1416
- "extraction",
1417
- "retrieval_augmented_generation",
1418
- ]
1419
- ]
1420
- thresholds: Optional[List[WatsonxMetricThreshold]] = None
1421
-
1422
- def to_dict(self) -> Dict:
1423
- from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
1424
- ApplicabilitySelection,
1425
- MetricThreshold,
1426
- )
1427
-
1428
- monitor_metric = {
1429
- "name": self.name,
1430
- "applies_to": ApplicabilitySelection(problem_type=self.applies_to),
1431
- }
1432
-
1433
- if self.thresholds is not None:
1434
- monitor_metric["thresholds"] = [
1435
- MetricThreshold(**threshold.to_dict()) for threshold in self.thresholds
1436
- ]
1437
-
1438
- return monitor_metric
1439
-
1440
-
1441
- # ===== Metric Classes =====
1442
- class WatsonxCustomMetric:
1443
- """
1444
- Provides functionality to set up a custom metric to measure your model's performance with IBM watsonx.governance.
1445
-
1446
- Attributes:
1447
- api_key (str): The API key for IBM watsonx.governance.
1448
- region (str, optional): The region where IBM watsonx.governance is hosted when using IBM Cloud.
1449
- Defaults to `us-south`.
1450
- cpd_creds (CloudPakforDataCredentials, optional): IBM Cloud Pak for Data environment credentials.
1451
-
1452
- Example:
1453
- ```python
1454
- from beekeeper.monitors.watsonx import (
1455
- WatsonxCustomMetric,
1456
- CloudPakforDataCredentials,
1457
- )
1458
-
1459
- # watsonx.governance (IBM Cloud)
1460
- wxgov_client = WatsonxCustomMetric(api_key="API_KEY")
1461
-
1462
- # watsonx.governance (CP4D)
1463
- cpd_creds = CloudPakforDataCredentials(
1464
- url="CPD_URL",
1465
- username="USERNAME",
1466
- password="PASSWORD",
1467
- version="5.0",
1468
- instance_id="openshift",
1469
- )
1470
-
1471
- wxgov_client = WatsonxCustomMetric(cpd_creds=cpd_creds)
1472
- ```
1473
- """
1474
-
1475
- def __init__(
1476
- self,
1477
- api_key: str = None,
1478
- region: Literal["us-south", "eu-de", "au-syd"] = "us-south",
1479
- cpd_creds: CloudPakforDataCredentials | Dict = None,
1480
- ) -> None:
1481
- from ibm_cloud_sdk_core.authenticators import IAMAuthenticator # type: ignore
1482
- from ibm_watson_openscale import APIClient as WosAPIClient # type: ignore
1483
-
1484
- self.region = region
1485
- self._api_key = api_key
1486
- self._wos_client = None
1487
-
1488
- if cpd_creds:
1489
- self._wos_cpd_creds = _filter_dict(
1490
- cpd_creds.to_dict(),
1491
- ["username", "password", "api_key", "disable_ssl_verification"],
1492
- ["url"],
1493
- )
1494
-
1495
- if not self._wos_client:
1496
- try:
1497
- if hasattr(self, "_wos_cpd_creds") and self._wos_cpd_creds:
1498
- from ibm_cloud_sdk_core.authenticators import (
1499
- CloudPakForDataAuthenticator, # type: ignore
1500
- )
1501
-
1502
- authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
1503
-
1504
- self._wos_client = WosAPIClient(
1505
- authenticator=authenticator,
1506
- service_url=self._wos_cpd_creds["url"],
1507
- )
1508
-
1509
- else:
1510
- from ibm_cloud_sdk_core.authenticators import (
1511
- IAMAuthenticator, # type: ignore
1512
- )
1513
-
1514
- authenticator = IAMAuthenticator(apikey=self._api_key)
1515
- self._wos_client = WosAPIClient(
1516
- authenticator=authenticator,
1517
- service_url=REGIONS_URL[self.region]["wos"],
1518
- )
1519
-
1520
- except Exception as e:
1521
- logging.error(
1522
- f"Error connecting to IBM watsonx.governance (openscale): {e}",
1523
- )
1524
- raise
1525
-
1526
- def _add_integrated_system(
1527
- self,
1528
- credentials: IntegratedSystemCredentials,
1529
- name: str,
1530
- endpoint: str,
1531
- ) -> str:
1532
- custom_metrics_integrated_system = self._wos_client.integrated_systems.add(
1533
- name=name,
1534
- description="Integrated system created by Beekeeper.",
1535
- type="custom_metrics_provider",
1536
- credentials=credentials.to_dict(),
1537
- connection={"display_name": name, "endpoint": endpoint},
1538
- ).result
1539
-
1540
- return custom_metrics_integrated_system.metadata.id
1541
-
1542
- def _add_monitor_definitions(
1543
- self,
1544
- name: str,
1545
- metrics: List[WatsonxMetric],
1546
- schedule: bool,
1547
- ):
1548
- from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
1549
- ApplicabilitySelection,
1550
- MonitorInstanceSchedule,
1551
- MonitorMetricRequest,
1552
- MonitorRuntime,
1553
- ScheduleStartTime,
1554
- )
1555
-
1556
- _metrics = [MonitorMetricRequest(**metric.to_dict()) for metric in metrics]
1557
- _monitor_runtime = None
1558
- _monitor_schedule = None
1559
-
1560
- if schedule:
1561
- _monitor_runtime = MonitorRuntime(type="custom_metrics_provider")
1562
- _monitor_schedule = MonitorInstanceSchedule(
1563
- repeat_interval=1,
1564
- repeat_unit="hour",
1565
- start_time=ScheduleStartTime(
1566
- type="relative",
1567
- delay_unit="minute",
1568
- delay=30,
1569
- ),
1570
- )
1571
-
1572
- custom_monitor_details = self._wos_client.monitor_definitions.add(
1573
- name=name,
1574
- metrics=_metrics,
1575
- tags=[],
1576
- schedule=_monitor_schedule,
1577
- applies_to=ApplicabilitySelection(input_data_type=["unstructured_text"]),
1578
- monitor_runtime=_monitor_runtime,
1579
- background_mode=False,
1580
- ).result
1581
-
1582
- return custom_monitor_details.metadata.id
1583
-
1584
- def _get_monitor_instance(self, subscription_id: str, monitor_definition_id: str):
1585
- monitor_instances = self._wos_client.monitor_instances.list(
1586
- monitor_definition_id=monitor_definition_id,
1587
- target_target_id=subscription_id,
1588
- ).result.monitor_instances
1589
-
1590
- if len(monitor_instances) == 1:
1591
- return monitor_instances[0]
1592
- else:
1593
- return None
1594
-
1595
- def _update_monitor_instance(
1596
- self,
1597
- integrated_system_id: str,
1598
- custom_monitor_id: str,
1599
- ):
1600
- payload = [
1601
- {
1602
- "op": "replace",
1603
- "path": "/parameters",
1604
- "value": {
1605
- "custom_metrics_provider_id": integrated_system_id,
1606
- "custom_metrics_wait_time": 60,
1607
- "enable_custom_metric_runs": True,
1608
- },
1609
- },
1610
- ]
1611
-
1612
- return self._wos_client.monitor_instances.update(
1613
- custom_monitor_id,
1614
- payload,
1615
- update_metadata_only=True,
1616
- ).result
1617
-
1618
- def _get_patch_request_field(
1619
- self,
1620
- field_path: str,
1621
- field_value: Any,
1622
- op_name: str = "replace",
1623
- ) -> Dict:
1624
- return {"op": op_name, "path": field_path, "value": field_value}
1625
-
1626
- def _get_dataset_id(
1627
- self,
1628
- subscription_id: str,
1629
- data_set_type: Literal["feedback", "payload_logging"],
1630
- ) -> str:
1631
- data_sets = self._wos_client.data_sets.list(
1632
- target_target_id=subscription_id,
1633
- type=data_set_type,
1634
- ).result.data_sets
1635
- data_set_id = None
1636
- if len(data_sets) > 0:
1637
- data_set_id = data_sets[0].metadata.id
1638
- return data_set_id
1639
-
1640
- def _get_dataset_data(self, data_set_id: str):
1641
- json_data = self._wos_client.data_sets.get_list_of_records(
1642
- data_set_id=data_set_id,
1643
- format="list",
1644
- ).result
1645
-
1646
- if not json_data.get("records"):
1647
- return None
1648
-
1649
- return json_data["records"][0]
1650
-
1651
- def _get_existing_data_mart(self):
1652
- data_marts = self._wos_client.data_marts.list().result.data_marts
1653
- if len(data_marts) == 0:
1654
- raise Exception(
1655
- "No data marts found. Please ensure at least one data mart is available.",
1656
- )
1657
-
1658
- return data_marts[0].metadata.id
1659
-
1660
- # ===== Global Custom Metrics =====
1661
- def add_metric_definition(
1662
- self,
1663
- name: str,
1664
- metrics: List[WatsonxMetric],
1665
- integrated_system_url: str,
1666
- integrated_system_credentials: IntegratedSystemCredentials,
1667
- schedule: bool = False,
1668
- ):
1669
- """
1670
- Creates a custom monitor definition for IBM watsonx.governance.
1671
-
1672
- This must be done before using custom metrics.
1673
-
1674
- Args:
1675
- name (str): The name of the custom metric group.
1676
- metrics (List[WatsonxMetric]): A list of metrics to be measured.
1677
- schedule (bool, optional): Enable or disable the scheduler. Defaults to `False`.
1678
- integrated_system_url (str): The URL of the external metric provider.
1679
- integrated_system_credentials (IntegratedSystemCredentials): The credentials for the integrated system.
1680
-
1681
- Example:
1682
- ```python
1683
- from beekeeper.monitors.watsonx import (
1684
- WatsonxMetric,
1685
- IntegratedSystemCredentials,
1686
- WatsonxMetricThreshold,
1687
- )
1688
-
1689
- wxgov_client.add_metric_definition(
1690
- name="Custom Metric - Custom LLM Quality",
1691
- metrics=[
1692
- WatsonxMetric(
1693
- name="context_quality",
1694
- applies_to=[
1695
- "retrieval_augmented_generation",
1696
- "summarization",
1697
- ],
1698
- thresholds=[
1699
- WatsonxMetricThreshold(
1700
- threshold_type="lower_limit", default_value=0.75
1701
- )
1702
- ],
1703
- )
1704
- ],
1705
- integrated_system_url="IS_URL", # URL to the endpoint computing the metric
1706
- integrated_system_credentials=IntegratedSystemCredentials(
1707
- auth_type="basic", username="USERNAME", password="PASSWORD"
1708
- ),
1709
- )
1710
- ```
1711
- """
1712
- integrated_system_id = self._add_integrated_system(
1713
- integrated_system_credentials,
1714
- name,
1715
- integrated_system_url,
1716
- )
1717
-
1718
- external_monitor_id = suppress_output(
1719
- self._add_monitor_definitions,
1720
- name,
1721
- metrics,
1722
- schedule,
1723
- )
1724
-
1725
- # Associate the external monitor with the integrated system
1726
- payload = [
1727
- {
1728
- "op": "add",
1729
- "path": "/parameters",
1730
- "value": {"monitor_definition_ids": [external_monitor_id]},
1731
- },
1732
- ]
1733
-
1734
- self._wos_client.integrated_systems.update(integrated_system_id, payload)
1735
-
1736
- return {
1737
- "integrated_system_id": integrated_system_id,
1738
- "monitor_definition_id": external_monitor_id,
1739
- }
1740
-
1741
- @deprecated(
1742
- reason="'add_observer_instance()' is deprecated and will be removed in a future version. Use 'add_monitor_instance()' from 'beekeeper-monitors-watsonx' instead.",
1743
- version="1.0.5",
1744
- action="always",
1745
- )
1746
- def add_observer_instance(
1747
- self,
1748
- integrated_system_id: str,
1749
- monitor_definition_id: str,
1750
- subscription_id: str,
1751
- ):
1752
- return self.add_monitor_instance(
1753
- integrated_system_id=integrated_system_id,
1754
- monitor_definition_id=monitor_definition_id,
1755
- subscription_id=subscription_id,
1756
- )
1757
-
1758
- def add_monitor_instance(
1759
- self,
1760
- integrated_system_id: str,
1761
- monitor_definition_id: str,
1762
- subscription_id: str,
1763
- ):
1764
- """
1765
- Enables a custom monitor for the specified subscription and monitor definition.
1766
-
1767
- Args:
1768
- integrated_system_id (str): The ID of the integrated system.
1769
- monitor_definition_id (str): The ID of the custom metric monitor instance.
1770
- subscription_id (str): The ID of the subscription to associate the monitor with.
1771
-
1772
- Example:
1773
- ```python
1774
- wxgov_client.add_monitor_instance(
1775
- integrated_system_id="019667ca-5687-7838-8d29-4ff70c2b36b0",
1776
- monitor_definition_id="custom_llm_quality",
1777
- subscription_id="0195e95d-03a4-7000-b954-b607db10fe9e",
1778
- )
1779
- ```
1780
- """
1781
- from ibm_watson_openscale.base_classes.watson_open_scale_v2 import Target
1782
-
1783
- data_marts = self._wos_client.data_marts.list().result.data_marts
1784
- if len(data_marts) == 0:
1785
- raise Exception(
1786
- "No data marts found. Please ensure at least one data mart is available.",
1787
- )
1788
-
1789
- data_mart_id = data_marts[0].metadata.id
1790
- existing_monitor_instance = self._get_monitor_instance(
1791
- subscription_id,
1792
- monitor_definition_id,
1793
- )
1794
-
1795
- if existing_monitor_instance is None:
1796
- target = Target(target_type="subscription", target_id=subscription_id)
1797
-
1798
- parameters = {
1799
- "custom_metrics_provider_id": integrated_system_id,
1800
- "custom_metrics_wait_time": 60,
1801
- "enable_custom_metric_runs": True,
1802
- }
1803
-
1804
- monitor_instance_details = suppress_output(
1805
- self._wos_client.monitor_instances.create,
1806
- data_mart_id=data_mart_id,
1807
- background_mode=False,
1808
- monitor_definition_id=monitor_definition_id,
1809
- target=target,
1810
- parameters=parameters,
1811
- ).result
1812
- else:
1813
- existing_instance_id = existing_monitor_instance.metadata.id
1814
- monitor_instance_details = self._update_monitor_instance(
1815
- integrated_system_id,
1816
- existing_instance_id,
1817
- )
1818
-
1819
- return monitor_instance_details
1820
-
1821
- def publish_metrics(
1822
- self,
1823
- monitor_instance_id: str,
1824
- run_id: str,
1825
- request_records: Dict[str, Union[float, int]],
1826
- ):
1827
- """
1828
- Publishes computed custom metrics for a specific global monitor instance.
1829
-
1830
- Args:
1831
- monitor_instance_id (str): The unique ID of the monitor instance.
1832
- run_id (str): The ID of the monitor run that generated the metrics.
1833
- request_records (Dict[str | float | int]): Dict containing the metrics to be published.
1834
-
1835
- Example:
1836
- ```python
1837
- wxgov_client.publish_metrics(
1838
- monitor_instance_id="01966801-f9ee-7248-a706-41de00a8a998",
1839
- run_id="RUN_ID",
1840
- request_records={"context_quality": 0.914, "sensitivity": 0.85},
1841
- )
1842
- ```
1843
- """
1844
- from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
1845
- MonitorMeasurementRequest,
1846
- Runs,
1847
- )
1848
-
1849
- measurement_request = MonitorMeasurementRequest(
1850
- timestamp=datetime.datetime.now(datetime.timezone.utc).strftime(
1851
- "%Y-%m-%dT%H:%M:%S.%fZ",
1852
- ),
1853
- run_id=run_id,
1854
- metrics=[request_records],
1855
- )
1856
-
1857
- self._wos_client.monitor_instances.add_measurements(
1858
- monitor_instance_id=monitor_instance_id,
1859
- monitor_measurement_request=[measurement_request],
1860
- ).result
1861
-
1862
- run = Runs(watson_open_scale=self._wos_client)
1863
- patch_payload = []
1864
- patch_payload.append(self._get_patch_request_field("/status/state", "finished"))
1865
- patch_payload.append(
1866
- self._get_patch_request_field(
1867
- "/status/completed_at",
1868
- datetime.datetime.now(datetime.timezone.utc).strftime(
1869
- "%Y-%m-%dT%H:%M:%S.%fZ",
1870
- ),
1871
- ),
1872
- )
1873
-
1874
- return run.update(
1875
- monitor_instance_id=monitor_instance_id,
1876
- monitoring_run_id=run_id,
1877
- json_patch_operation=patch_payload,
1878
- ).result
1879
-
1880
- # ===== Local Custom Metrics =====
1881
- def add_local_metric_definition(
1882
- self,
1883
- name: str,
1884
- metrics: List[WatsonxLocalMetric],
1885
- subscription_id: str,
1886
- ) -> str:
1887
- """
1888
- Creates a custom metric definition to compute metrics at the local (transaction) level for IBM watsonx.governance.
1889
-
1890
- Args:
1891
- name (str): The name of the custom transaction metric group.
1892
- metrics (List[WatsonxLocalMetric]): A list of metrics to be monitored at the local (transaction) level.
1893
- subscription_id (str): The IBM watsonx.governance subscription ID associated with the metric definition.
1894
-
1895
- Example:
1896
- ```python
1897
- from beekeeper.monitors.watsonx import WatsonxLocalMetric
1898
-
1899
- wxgov_client.add_local_metric_definition(
1900
- name="Custom LLM Local Metric",
1901
- subscription_id="019674ca-0c38-745f-8e9b-58546e95174e",
1902
- metrics=[
1903
- WatsonxLocalMetric(name="context_quality", data_type="double")
1904
- ],
1905
- )
1906
- ```
1907
- """
1908
- from ibm_watson_openscale.base_classes.watson_open_scale_v2 import (
1909
- LocationTableName,
1910
- SparkStruct,
1911
- SparkStructFieldPrimitive,
1912
- Target,
1913
- )
1914
-
1915
- target = Target(target_id=subscription_id, target_type="subscription")
1916
- data_mart_id = self._get_existing_data_mart()
1917
- metrics = [SparkStructFieldPrimitive(**metric.to_dict()) for metric in metrics]
1918
-
1919
- schema_fields = [
1920
- SparkStructFieldPrimitive(
1921
- name="scoring_id",
1922
- type="string",
1923
- nullable=False,
1924
- ),
1925
- SparkStructFieldPrimitive(
1926
- name="run_id",
1927
- type="string",
1928
- nullable=True,
1929
- ),
1930
- SparkStructFieldPrimitive(
1931
- name="computed_on",
1932
- type="string",
1933
- nullable=False,
1934
- ),
1935
- ]
1936
-
1937
- schema_fields.extend(metrics)
1938
-
1939
- data_schema = SparkStruct(type="struct", fields=schema_fields)
1940
-
1941
- return self._wos_client.data_sets.add(
1942
- target=target,
1943
- name=name,
1944
- type="custom",
1945
- data_schema=data_schema,
1946
- data_mart_id=data_mart_id,
1947
- location=LocationTableName(
1948
- table_name=name.lower().replace(" ", "_") + "_" + str(uuid.uuid4())[:8],
1949
- ),
1950
- background_mode=False,
1951
- ).result.metadata.id
1952
-
1953
- def publish_local_metrics(
1954
- self,
1955
- metric_instance_id: str,
1956
- request_records: List[Dict],
1957
- ):
1958
- """
1959
- Publishes computed custom metrics for a specific transaction record.
1960
-
1961
- Args:
1962
- metric_instance_id (str): The unique ID of the custom transaction metric.
1963
- request_records (List[Dict]): A list of dictionaries containing the records to be stored.
1964
-
1965
- Example:
1966
- ```python
1967
- wxgov_client.publish_local_metrics(
1968
- metric_instance_id="0196ad39-1b75-7e77-bddb-cc5393d575c2",
1969
- request_records=[
1970
- {
1971
- "scoring_id": "304a9270-44a1-4c4d-bfd4-f756541011f8",
1972
- "run_id": "RUN_ID",
1973
- "computed_on": "payload",
1974
- "context_quality": 0.786,
1975
- }
1976
- ],
1977
- )
1978
- ```
1979
- """
1980
- return self._wos_client.data_sets.store_records(
1981
- data_set_id=metric_instance_id,
1982
- request_body=request_records,
1983
- ).result
1984
-
1985
- def list_local_metrics(
1986
- self,
1987
- metric_instance_id: str,
1988
- ):
1989
- """
1990
- Lists records from a custom local metric definition.
1991
-
1992
- Args:
1993
- metric_instance_id (str): The unique ID of the custom transaction metric.
1994
-
1995
- Example:
1996
- ```python
1997
- wxgov_client.list_local_metrics(
1998
- metric_instance_id="0196ad47-c505-73c0-9d7b-91c082b697e3"
1999
- )
2000
- ```
2001
- """
2002
- return self._get_dataset_data(metric_instance_id)