teradataml 20.0.0.6__py3-none-any.whl → 20.0.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.

Potentially problematic release.


This version of teradataml might be problematic. Click here for more details.

Files changed (96) hide show
  1. teradataml/README.md +210 -0
  2. teradataml/__init__.py +1 -1
  3. teradataml/_version.py +1 -1
  4. teradataml/analytics/analytic_function_executor.py +162 -76
  5. teradataml/analytics/byom/__init__.py +1 -1
  6. teradataml/analytics/json_parser/__init__.py +2 -0
  7. teradataml/analytics/json_parser/analytic_functions_argument.py +95 -2
  8. teradataml/analytics/json_parser/metadata.py +22 -4
  9. teradataml/analytics/sqle/DecisionTreePredict.py +3 -2
  10. teradataml/analytics/sqle/NaiveBayesPredict.py +3 -2
  11. teradataml/analytics/sqle/__init__.py +3 -0
  12. teradataml/analytics/utils.py +4 -1
  13. teradataml/automl/__init__.py +2369 -464
  14. teradataml/automl/autodataprep/__init__.py +15 -0
  15. teradataml/automl/custom_json_utils.py +184 -112
  16. teradataml/automl/data_preparation.py +113 -58
  17. teradataml/automl/data_transformation.py +154 -53
  18. teradataml/automl/feature_engineering.py +113 -53
  19. teradataml/automl/feature_exploration.py +548 -25
  20. teradataml/automl/model_evaluation.py +260 -32
  21. teradataml/automl/model_training.py +399 -206
  22. teradataml/clients/auth_client.py +2 -2
  23. teradataml/common/aed_utils.py +11 -2
  24. teradataml/common/bulk_exposed_utils.py +4 -2
  25. teradataml/common/constants.py +62 -2
  26. teradataml/common/garbagecollector.py +50 -21
  27. teradataml/common/messagecodes.py +47 -2
  28. teradataml/common/messages.py +19 -1
  29. teradataml/common/sqlbundle.py +23 -6
  30. teradataml/common/utils.py +116 -10
  31. teradataml/context/aed_context.py +16 -10
  32. teradataml/data/Employee.csv +5 -0
  33. teradataml/data/Employee_Address.csv +4 -0
  34. teradataml/data/Employee_roles.csv +5 -0
  35. teradataml/data/JulesBelvezeDummyData.csv +100 -0
  36. teradataml/data/byom_example.json +5 -0
  37. teradataml/data/creditcard_data.csv +284618 -0
  38. teradataml/data/docs/byom/docs/ONNXSeq2Seq.py +255 -0
  39. teradataml/data/docs/sqle/docs_17_10/NGramSplitter.py +1 -1
  40. teradataml/data/docs/sqle/docs_17_20/NGramSplitter.py +1 -1
  41. teradataml/data/docs/sqle/docs_17_20/TextParser.py +1 -1
  42. teradataml/data/jsons/byom/ONNXSeq2Seq.json +287 -0
  43. teradataml/data/jsons/sqle/20.00/AI_AnalyzeSentiment.json +3 -7
  44. teradataml/data/jsons/sqle/20.00/AI_AskLLM.json +3 -7
  45. teradataml/data/jsons/sqle/20.00/AI_DetectLanguage.json +3 -7
  46. teradataml/data/jsons/sqle/20.00/AI_ExtractKeyPhrases.json +3 -7
  47. teradataml/data/jsons/sqle/20.00/AI_MaskPII.json +3 -7
  48. teradataml/data/jsons/sqle/20.00/AI_RecognizeEntities.json +3 -7
  49. teradataml/data/jsons/sqle/20.00/AI_RecognizePIIEntities.json +3 -7
  50. teradataml/data/jsons/sqle/20.00/AI_TextClassifier.json +3 -7
  51. teradataml/data/jsons/sqle/20.00/AI_TextEmbeddings.json +3 -7
  52. teradataml/data/jsons/sqle/20.00/AI_TextSummarize.json +3 -7
  53. teradataml/data/jsons/sqle/20.00/AI_TextTranslate.json +3 -7
  54. teradataml/data/jsons/sqle/20.00/TD_API_AzureML.json +151 -0
  55. teradataml/data/jsons/sqle/20.00/TD_API_Sagemaker.json +182 -0
  56. teradataml/data/jsons/sqle/20.00/TD_API_VertexAI.json +183 -0
  57. teradataml/data/load_example_data.py +29 -11
  58. teradataml/data/payment_fraud_dataset.csv +10001 -0
  59. teradataml/data/teradataml_example.json +67 -0
  60. teradataml/dataframe/copy_to.py +714 -54
  61. teradataml/dataframe/dataframe.py +1153 -33
  62. teradataml/dataframe/dataframe_utils.py +8 -3
  63. teradataml/dataframe/functions.py +168 -1
  64. teradataml/dataframe/setop.py +4 -1
  65. teradataml/dataframe/sql.py +141 -9
  66. teradataml/dbutils/dbutils.py +470 -35
  67. teradataml/dbutils/filemgr.py +1 -1
  68. teradataml/hyperparameter_tuner/optimizer.py +456 -142
  69. teradataml/lib/aed_0_1.dll +0 -0
  70. teradataml/lib/libaed_0_1.dylib +0 -0
  71. teradataml/lib/libaed_0_1.so +0 -0
  72. teradataml/lib/libaed_0_1_aarch64.so +0 -0
  73. teradataml/scriptmgmt/UserEnv.py +234 -34
  74. teradataml/scriptmgmt/lls_utils.py +43 -17
  75. teradataml/sdk/_json_parser.py +1 -1
  76. teradataml/sdk/api_client.py +9 -6
  77. teradataml/sdk/modelops/_client.py +3 -0
  78. teradataml/series/series.py +12 -7
  79. teradataml/store/feature_store/constants.py +601 -234
  80. teradataml/store/feature_store/feature_store.py +2886 -616
  81. teradataml/store/feature_store/mind_map.py +639 -0
  82. teradataml/store/feature_store/models.py +5831 -214
  83. teradataml/store/feature_store/utils.py +390 -0
  84. teradataml/table_operators/table_operator_util.py +1 -1
  85. teradataml/table_operators/templates/dataframe_register.template +6 -2
  86. teradataml/table_operators/templates/dataframe_udf.template +6 -2
  87. teradataml/utils/docstring.py +527 -0
  88. teradataml/utils/dtypes.py +93 -0
  89. teradataml/utils/internal_buffer.py +2 -2
  90. teradataml/utils/utils.py +41 -2
  91. teradataml/utils/validators.py +694 -17
  92. {teradataml-20.0.0.6.dist-info → teradataml-20.0.0.7.dist-info}/METADATA +213 -2
  93. {teradataml-20.0.0.6.dist-info → teradataml-20.0.0.7.dist-info}/RECORD +96 -81
  94. {teradataml-20.0.0.6.dist-info → teradataml-20.0.0.7.dist-info}/WHEEL +0 -0
  95. {teradataml-20.0.0.6.dist-info → teradataml-20.0.0.7.dist-info}/top_level.txt +0 -0
  96. {teradataml-20.0.0.6.dist-info → teradataml-20.0.0.7.dist-info}/zip-safe +0 -0
Binary file
Binary file
Binary file
Binary file
@@ -26,7 +26,7 @@ import pandas as pd
26
26
  from teradataml import configure
27
27
  from teradataml.clients.pkce_client import _DAWorkflow
28
28
  from teradataml.common.constants import (AsyncOpStatus, CloudProvider,
29
- HTTPRequest)
29
+ HTTPRequest, AsyncOpStatusOAFColumns)
30
30
  from teradataml.common.exceptions import TeradataMlException
31
31
  from teradataml.common.messagecodes import MessageCodes
32
32
  from teradataml.common.messages import Messages
@@ -120,6 +120,7 @@ def _get_ues_url(env_type="users", **kwargs):
120
120
 
121
121
  ues_url = "{0}/{1}/{2}".format(ues_url, _get_user(), env_type)
122
122
  env_name, files, libs = kwargs.get("env_name"), kwargs.get("files", False), kwargs.get("libs", False)
123
+ models = kwargs.get("models", False)
123
124
 
124
125
  if env_name is not None:
125
126
  ues_url = "{0}/{1}".format(ues_url, env_name)
@@ -131,6 +132,8 @@ def _get_ues_url(env_type="users", **kwargs):
131
132
  ues_url = "{0}/{1}".format(ues_url, file_name)
132
133
  elif libs:
133
134
  ues_url = "{0}/{1}".format(ues_url, "libraries")
135
+ elif models:
136
+ ues_url = "{0}/{1}".format(ues_url, "models")
134
137
  return ues_url
135
138
 
136
139
 
@@ -3661,7 +3664,7 @@ class UserEnv:
3661
3664
  record.update(claim_id_details)
3662
3665
  return [record]
3663
3666
 
3664
- def __get_claim_status(self, claim_id, timeout, action):
3667
+ def __get_claim_status(self, claim_id, timeout, action, **kwargs):
3665
3668
  """
3666
3669
  DESCRIPTION:
3667
3670
  Function to get the status of asynchronus process using the claim_id.
@@ -3687,12 +3690,13 @@ class UserEnv:
3687
3690
  Specifies the action for asynchronous process.
3688
3691
  Types: str
3689
3692
 
3690
- suppress_output:
3691
- Required Argument.
3692
- Specifies whether to print the output message or not.
3693
- When set to True, then the output message is not printed.
3694
- Default Value: False
3695
- Types: bool
3693
+ kwargs:
3694
+ suppress_output:
3695
+ Optional Argument.
3696
+ Specifies whether to print the output message or not.
3697
+ When set to True, then the output message is not printed.
3698
+ Default Value: False
3699
+ Types: bool
3696
3700
 
3697
3701
  RETURNS:
3698
3702
  Pandas DataFrame OR claim id.
@@ -3707,22 +3711,23 @@ class UserEnv:
3707
3711
  # If user specifies 'timeout', poll only for 'timeout' seconds. Otherwise,
3708
3712
  # poll status API indefinitely.
3709
3713
  timeout = UtilFuncs._get_positive_infinity() if timeout is None else timeout
3710
-
3714
+ suppress_output = kwargs.get("suppress_output", False)
3711
3715
  start_time = time.time()
3712
3716
  while time.time() - start_time <= timeout:
3713
3717
  time.sleep(3)
3714
- records = self.__is_async_operation_completed(claim_id)
3718
+ records = self.__is_async_operation_completed(claim_id, suppress_output=suppress_output)
3715
3719
  if records:
3716
3720
  return pd.DataFrame.from_records(records, columns=self.__status_columns)
3717
3721
 
3718
3722
  # Unable to get the response with in 'timeout' seconds. Print a message and
3719
3723
  # return claim id.
3720
- print("Request to {} initiated successfully in the remote user environment '{}' "
3721
- "but Timed out status check. Check the status using status() with the "
3722
- "claim id '{}'.".format(action, self.env_name, claim_id))
3724
+ if not suppress_output:
3725
+ print("Request to {} initiated successfully in the remote user environment '{}' "
3726
+ "but Timed out status check. Check the status using status() with the "
3727
+ "claim id '{}'.".format(action, self.env_name, claim_id))
3723
3728
  return claim_id
3724
3729
 
3725
- def __is_async_operation_completed(self, claim_id):
3730
+ def __is_async_operation_completed(self, claim_id, **kwargs):
3726
3731
  """
3727
3732
  DESCRIPTION:
3728
3733
  Function to check whether asynchronous process to install/update/uninstall libraries/file
@@ -3735,6 +3740,14 @@ class UserEnv:
3735
3740
  started by the UserEnv management methods.
3736
3741
  Types: str
3737
3742
 
3743
+ kwargs:
3744
+ suppress_output:
3745
+ Optional Argument.
3746
+ Specifies whether to print the output message or not.
3747
+ When set to True, then the output message is not printed.
3748
+ Default Value: False
3749
+ Types: bool
3750
+
3738
3751
  RETURNS:
3739
3752
  list OR bool.
3740
3753
 
@@ -3745,6 +3758,7 @@ class UserEnv:
3745
3758
  # Create a remote user environment.
3746
3759
  >>> env.__is_async_operation_completed('123-456')
3747
3760
  """
3761
+ suppress_output = kwargs.get("suppress_output", False)
3748
3762
  records = self.__get_claim_id_status(claim_id)
3749
3763
 
3750
3764
  # For library installation/uninstallation/updation, if the background process in
@@ -3753,12 +3767,17 @@ class UserEnv:
3753
3767
  action = self.__claim_ids.get(claim_id, {}).get("action")
3754
3768
  if action in ["install_file", "install_model"]:
3755
3769
  for record in records:
3756
- if record["Stage"] in [AsyncOpStatus.FILE_INSTALLED.value, AsyncOpStatus.ERRED.value]:
3757
- if record["Stage"] == AsyncOpStatus.FILE_INSTALLED.value:
3758
- print("Request for {} is {}.".format(action, "completed successfully"))
3770
+ if record["Stage"] in [AsyncOpStatus.FILE_INSTALLED.value,
3771
+ AsyncOpStatus.ERRED.value,
3772
+ AsyncOpStatus.MODEL_INSTALLED.value]:
3773
+ if record["Stage"] in [AsyncOpStatus.FILE_INSTALLED.value,
3774
+ AsyncOpStatus.MODEL_INSTALLED.value]:
3775
+ if not suppress_output:
3776
+ print("Request for {} is {}.".format(action, "completed successfully"))
3759
3777
  elif record["Stage"] == AsyncOpStatus.ERRED.value:
3760
- print("Request for {} is {}.".format(action, AsyncOpStatus.ERRED.value))
3761
- print("Check the status using status() with the claim id '{}'".format(claim_id))
3778
+ if not suppress_output:
3779
+ print("Request for {} is {}.".format(action, AsyncOpStatus.ERRED.value))
3780
+ print("Check the status using status() with the claim id '{}'".format(claim_id))
3762
3781
  return records
3763
3782
  return False
3764
3783
 
@@ -3766,24 +3785,51 @@ class UserEnv:
3766
3785
  return records if len(records) == 2 else False
3767
3786
 
3768
3787
  @collect_queryband(queryband="InstlMdl")
3769
- def install_model(self, model_path, **kwargs):
3788
+ def install_model(self, model_path=None, model_name=None, model_type=None, api_key=None, **kwargs):
3770
3789
  """
3771
3790
  DESCRIPTION:
3772
- Function installs a model from client machine to the remote
3773
- user environment created in Vantage Languages Ecosystem. If
3774
- model with same name already exists in the remote user
3775
- environment, error is thrown.
3791
+ Function installs a model into the remote user environment created
3792
+ in Vantage Languages Ecosystem. Model can be installed from a zip file
3793
+ containing all the files related to the model or from a model registry
3794
+ like Hugging Face. If model with same name already exists in the remote
3795
+ user environment, error is thrown.
3776
3796
  Note:
3777
- Maximum size of the model should be less than or equal to 5GB.
3797
+ Maximum size of the model should be less than or equal to 5GB when
3798
+ installing using zip.
3778
3799
 
3779
3800
  PARAMETERS:
3780
3801
  model_path:
3781
- Required Argument.
3802
+ Optional Argument.
3782
3803
  Specifies absolute or relative path of the zip file containing
3783
3804
  model (including file name) to be installed in the remote user
3784
3805
  environment.
3806
+ Notes:
3807
+ * Model file should be in zip format.
3808
+ * Arguments "model_path" and "model_name" are mutually exclusive.
3809
+ Types: str
3810
+
3811
+ model_name:
3812
+ Optional Argument.
3813
+ Specifies the name/identifier of the model in the registry (e.g. "google-t5/t5-small"
3814
+ from Hugging Face registry).
3785
3815
  Note:
3786
- Model file should be in zip format.
3816
+ * Arguments "model_name" and "model_path" are mutually exclusive.
3817
+ Types: str
3818
+
3819
+ model_type:
3820
+ Optional Argument.
3821
+ Specifies the name of model registry like Hugging Face.
3822
+ Note:
3823
+ * Applicable when model is installed from a model registry.
3824
+ Default Value: "HF" (Hugging Face registry)
3825
+ Permitted Values: "HF"
3826
+ Types: str
3827
+
3828
+ api_key:
3829
+ Optional Argument.
3830
+ Specifies the API key for accessing the private models in registry.
3831
+ Note:
3832
+ Applicable only when model is installed from a model registry.
3787
3833
  Types: str
3788
3834
 
3789
3835
  **kwargs:
@@ -3860,13 +3906,148 @@ class UserEnv:
3860
3906
  >>> env.models
3861
3907
  Model Size Timestamp
3862
3908
  0 large_model 6144 2023-10-30T13:34:03Z
3909
+
3910
+ # Example 3: Install the model from default registry 'Hugging Face'
3911
+ # in the 'testenv' environment synchronously.
3912
+ >>> env.install_model(model_name="google-bert/bert-base-uncased")
3913
+ Request for install_model is completed successfully.
3914
+ Model 'google-bert/bert-base-uncased' installed successfully in the remote user environment 'testenv'.
3915
+
3916
+ # Verify the model installation.
3917
+ >>> env.models
3918
+ Model Size Timestamp
3919
+ 0 models--google-bert--bert-base-uncased 6144 2025-07-30T03:58:01Z
3920
+
3921
+ # Example 4: Install the model from default registry 'Hugging Face'
3922
+ # in the 'testenv' environment asynchronously.
3923
+ >>> claim_id = env.install_model(model_name="Helsinki-NLP/opus-mt-en-fr", asynchronous=True)
3924
+ Model installation is initiated. Check the status using <UserEnv_obj>.status() with the claim id 'ac284706-0b72-4b83-8add-3cff632747f4'.
3925
+
3926
+ # Check status using claim-id.
3927
+ >>> env.status(claim_id)
3928
+ Claim Id File/Libs/Model Method Name Stage Timestamp Additional Details
3929
+ 0 ac284706-0b72-4b83-8add-3cff632747f4 Helsinki-NLP/opus-mt-en-fr install_model Started 2025-07-30T03:58:09Z Begin downloading model named Helsinki-NLP/opu...
3930
+ 1 ac284706-0b72-4b83-8add-3cff632747f4 Helsinki-NLP/opus-mt-en-fr install_model ModelInstalled 2025-07-30T03:58:28Z Model installed successfully
3931
+
3932
+ # Verify the model installation.
3933
+ >>> env.models
3934
+ Model Size Timestamp
3935
+ 0 models--Helsinki-NLP--opus-mt-en-fr 6144 2025-07-30T03:58:27Z
3936
+ 1 models--google-bert--bert-base-uncased 6144 2025-07-30T03:58:01Z
3863
3937
  """
3864
- # Install model in User environment.
3865
- kwargs["is_model"] = True
3866
- if not "is_llm" in kwargs:
3867
- kwargs["is_llm"] = True
3868
- records = self.install_file(model_path, **kwargs)
3869
- return records
3938
+ # Get default values for optional keyword arguments.
3939
+ suppress_output = kwargs.get("suppress_output", False)
3940
+ asynchronous = kwargs.get("asynchronous", False)
3941
+ timeout = kwargs.get("timeout", None)
3942
+
3943
+ # Get default value for optional positional argument.
3944
+ model_type = model_type if model_type is not None else "HF"
3945
+
3946
+ # Argument validation.
3947
+ __arg_info_matrix = []
3948
+ __arg_info_matrix.append(["model_path", model_path, True, (str), True])
3949
+ __arg_info_matrix.append(["model_name", model_name, True, (str), True])
3950
+ __arg_info_matrix.append(["model_type", model_type, True, (str), True, ["HF"]])
3951
+ __arg_info_matrix.append(["api_key", api_key, True, (str), True])
3952
+ __arg_info_matrix.append(["suppress_output", suppress_output, True, (bool)])
3953
+ __arg_info_matrix.append(["asynchronous", asynchronous, True, (bool)])
3954
+ __arg_info_matrix.append(["timeout", timeout, True, (int, float)])
3955
+
3956
+ _Validators._validate_function_arguments(__arg_info_matrix)
3957
+
3958
+ # Validate mutually exclusive arguments.
3959
+ _Validators._validate_mutually_exclusive_argument_groups({"model_name": model_name},
3960
+ {"model_path": model_path},
3961
+ all_falsy_check=True)
3962
+
3963
+ # Install model from zip file.
3964
+ if model_path:
3965
+ kwargs["is_model"] = True
3966
+ if not "is_llm" in kwargs:
3967
+ kwargs["is_llm"] = True
3968
+ records = self.install_file(model_path, **kwargs)
3969
+ return records
3970
+
3971
+ # Install models from registry.
3972
+ api_name = "install_model"
3973
+ try:
3974
+ # Prepare the payload
3975
+ payload = {
3976
+ "model_name": model_name,
3977
+ "model_type": model_type
3978
+ }
3979
+
3980
+ if api_key is not None:
3981
+ payload["api_key"] = api_key
3982
+
3983
+ # Make the REST call to install model from registry
3984
+ resource_url = _get_ues_url(env_name=self.env_name, api_name=api_name, models=True)
3985
+ response = UtilFuncs._http_request(resource_url,
3986
+ HTTPRequest.POST,
3987
+ headers=_get_auth_token(),
3988
+ json=payload)
3989
+
3990
+ data = _process_ues_response(api_name, response).json()
3991
+
3992
+ # Get claim-id model install async operation from response.
3993
+ claim_id = data["claim_id"]
3994
+
3995
+ # Store the claim id locally to display the model name in status API.
3996
+ self.__claim_ids[claim_id] = {"action": api_name, "value": model_name}
3997
+ installation_status = "is initiated"
3998
+
3999
+ # In case of synchronous mode, keep polling the status
4000
+ # of underlying asynchronous operation until it is either
4001
+ # successful or errored or timed out.
4002
+ if not asynchronous:
4003
+ installation_status = self.__get_claim_status(claim_id=claim_id,
4004
+ timeout=timeout,
4005
+ action=api_name,
4006
+ suppress_output=True)
4007
+ self.__models_changed = True
4008
+ # If model installation is complete(either success or fail),
4009
+ # pandas DF will be returned.
4010
+ if isinstance(installation_status, pd.DataFrame):
4011
+ # Model installation successful.
4012
+ if AsyncOpStatus.MODEL_INSTALLED.value in installation_status[AsyncOpStatusOAFColumns.STAGE.value].to_list():
4013
+ # Update the models changed flag
4014
+ self.__models_changed = True
4015
+ if not suppress_output:
4016
+ print("Model '{}' installed successfully in the remote user environment '{}'.".format(
4017
+ model_name, self.env_name))
4018
+ return True
4019
+ # Model installation erred out.
4020
+ if AsyncOpStatus.ERRED.value in installation_status[AsyncOpStatusOAFColumns.STAGE.value].to_list():
4021
+ err = ""
4022
+ for record in installation_status.to_dict("records"):
4023
+ if record["Stage"] == AsyncOpStatus.ERRED.value:
4024
+ err = record[AsyncOpStatusOAFColumns.ADDITIONAL_DETAILS.value]
4025
+ msg_code = MessageCodes.FUNC_EXECUTION_FAILED
4026
+ error_msg = Messages.get_message(msg_code, api_name, "Check the details using <UserEnv_obj>.status() with the claim id '{}'".format(claim_id) + "\nAdditional details: {}".format(err))
4027
+ raise TeradataMlException(error_msg, msg_code)
4028
+
4029
+ # Underlying asynchronous operation timed out, claim_id is returned.
4030
+ else:
4031
+ if not suppress_output:
4032
+ print("Request to install_model initiated successfully in the remote user environment '{}' "
4033
+ "but it is timed out. Check the status using <UserEnv_obj>.status() with the "
4034
+ "claim id '{}'.".format(self.env_name, claim_id))
4035
+ return claim_id
4036
+
4037
+ if not suppress_output:
4038
+ # Print a message to user console.
4039
+ print("Model installation {}. Check the status"
4040
+ " using <UserEnv_obj>.status() with the claim id '{}'.".format(installation_status, claim_id))
4041
+ self.__models_changed = True
4042
+ return claim_id
4043
+
4044
+ except (TeradataMlException, RuntimeError):
4045
+ raise
4046
+ except Exception as emsg:
4047
+ msg_code = MessageCodes.FUNC_EXECUTION_FAILED
4048
+ error_msg = Messages.get_message(msg_code, api_name, str(emsg))
4049
+ raise TeradataMlException(error_msg, msg_code)
4050
+
3870
4051
 
3871
4052
  @collect_queryband(queryband="UninstlMdl")
3872
4053
  def uninstall_model(self, model_name, **kwargs):
@@ -3905,7 +4086,7 @@ class UserEnv:
3905
4086
  # API. Let's assume that all models files are zipped under 'large_model.zip'
3906
4087
  >>> model = 'large_model.zip'
3907
4088
 
3908
- # Install the model in the 'test_env' environment.
4089
+ # Install the model in the 'test_env' environment using local zip file.
3909
4090
  >>> env.install_model(model_path = model)
3910
4091
  Request for install_model is completed successfully.
3911
4092
  Claim Id File/Libs/Model Method Name Stage Timestamp Additional Details
@@ -3918,9 +4099,28 @@ class UserEnv:
3918
4099
  Model Size Timestamp
3919
4100
  0 large_model 6144 2023-11-09T09:22:30Z
3920
4101
 
4102
+ # Install model from Hugging Face registry.
4103
+ >>> env.install_model(model_name="google-bert/bert-base-uncased")
4104
+ Request for install_model is completed successfully.
4105
+ Model 'google-bert/bert-base-uncased' installed successfully in the remote user environment 'test_env'.
4106
+ # List models.
4107
+ >>> env.models
4108
+ Model Size Timestamp
4109
+ 0 large_model 6144 2023-11-09T09:22:30Z
4110
+ 1 models--google-bert--bert-base-uncased 6144 2025-07-30T03:58:01Z
4111
+
3921
4112
  # Example 1: Uninstall model from remote user environment.
3922
4113
  >>> env.uninstall_model('large_model')
3923
4114
  Model 'large_model' uninstalled successfully from the remote user environment 'test_env'.
4115
+ True
4116
+
4117
+ # Verify the uninstallation of model.
4118
+ Model Size Timestamp
4119
+ 0 models--google-bert--bert-base-uncased 6144 2025-07-30T03:58:01Z
4120
+
4121
+ # Example 2: Uninstall Hugging Face model from remote user environment.
4122
+ >>> env.uninstall_model('models--google-bert--bert-base-uncased')
4123
+ Model 'models--google-bert--bert-base-uncased' uninstalled successfully from the remote user environment 'test_env'.
3924
4124
  True
3925
4125
 
3926
4126
  # Verify the uninstallation of model.
@@ -267,7 +267,7 @@ def list_user_envs(env_name=None, **kwargs):
267
267
 
268
268
  # Example 8: List all user environments where python 3 environment release version has
269
269
  # odd number. For e.g. python_3.7.x.
270
- >>> list_user_envs(base_env="\.\d*[13579]\.")
270
+ >>> list_user_envs(base_env="\\.\\d*[13579]\\.")
271
271
  env_name env_description base_env_name language
272
272
  1 Customer_Trends Analyse customer trends r_4.1.3 R
273
273
  2 Fraud_Detection Fraud detection through time matching python_3.7.13 Python
@@ -474,29 +474,51 @@ def __create_envs(template):
474
474
  return last_successful_env
475
475
 
476
476
 
477
- def __get_default_base_env():
477
+ def __get_default_base_env(lang="python"):
478
478
  """
479
- Function returns the latest python environment available with
480
- Open Analytics Framework.
479
+ DESCRIPTION:
480
+ Function returns the name of latest environment available with
481
+ Open Analytics Framework for given programming language.
482
+
483
+ PARAMETERS:
484
+ lang:
485
+ Optional Argument.
486
+ Specifies the language for which latest base env is to be retrieved.
487
+ Default value: "python"
488
+ Permitted values: "python", "r", "PYTHON", "R"
489
+ Types: str
490
+
491
+ RETURNS:
492
+ Base environment name.
493
+
494
+ RAISES:
495
+ None.
496
+
497
+ EXAMPLES:
498
+ # Get default R base environment.
499
+ >>> __get_default_base_env(lang="R")
481
500
  """
501
+ lang = lang.lower()
502
+ default_env_key = "default_base_env_{}".format(lang)
482
503
  # Check if the default base environment is already available.
483
- if _InternalBuffer.get('default_base_env') is not None:
484
- return _InternalBuffer.get('default_base_env')
504
+ if _InternalBuffer.get(default_env_key) is not None:
505
+ return _InternalBuffer.get(default_env_key)
485
506
 
486
507
  try:
487
508
  base_envs = list_base_envs()
488
- python_versions = base_envs[base_envs.language == 'Python']['version']
509
+ versions = base_envs[base_envs.language.str.lower() == lang]['version']
489
510
  # Convert version strings to tuples of integers for comparison
490
- version_tuples = [tuple(map(int, version.split('.'))) for version in python_versions]
511
+ version_tuples = [tuple(map(int, version.split('.'))) for version in versions]
491
512
  # Find the latest version tuple using max() function
492
513
  latest_version_tuple = max(version_tuples)
493
514
  # Convert the latest version tuple back to a string
494
515
  latest_version = '.'.join(map(str, latest_version_tuple))
495
- # Get the base environment name for the latest version
496
- _InternalBuffer.add(default_base_env=base_envs[base_envs.version == latest_version]['base_name'].to_list()[0])
497
- return _InternalBuffer.get('default_base_env')
516
+ # Get the base environment name for the latest version and add in internal buffer.
517
+ _InternalBuffer.add(**{default_env_key:
518
+ base_envs[base_envs.version == latest_version]['base_name'].to_list()[0]})
519
+ return _InternalBuffer.get(default_env_key)
498
520
  except Exception as base_env_err:
499
- raise Exception("Failed to obtain default base environment.", str(base_env_err.exception))
521
+ raise Exception("Failed to obtain default base environment.", str(base_env_err))
500
522
 
501
523
 
502
524
  def __install_files(env, directory):
@@ -799,12 +821,14 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
799
821
  # the list of base envs. If not available, set base_env to the default python base env.
800
822
  if not base_env or \
801
823
  base_env.lower() not in list_base_envs()['base_name'].str.lower().to_list():
824
+ lang = "python"
802
825
  # Print warning message if base_env provided is not available.
803
826
  if base_env:
804
827
  print(f"Note: The specified base environment '{base_env}' is unavailable. " \
805
828
  "Using the default base environment as specified in the documentation.")
829
+ lang = base_env.split('_')[0].lower() # Extract language for given base_env.
806
830
  # Set base_env to the default
807
- base_env = __get_default_base_env()
831
+ base_env = __get_default_base_env(lang=lang)
808
832
  if not desc:
809
833
  desc = "This env '{}' is created with base env '{}'.".format(env_name, base_env)
810
834
  try:
@@ -1505,7 +1529,7 @@ def _remove_all_envs(env_type, **kwargs):
1505
1529
  claim_id_list.append(future_result)
1506
1530
 
1507
1531
  except (TeradataMlException, RuntimeError, Exception) as emsg:
1508
- # Catching exceptions by remove_env if occured in any thread.
1532
+ # Catching exceptions by remove_env if occurred in any thread.
1509
1533
  failed_envs[env] = emsg
1510
1534
 
1511
1535
  # Negative case - Failed to remove env.
@@ -1819,7 +1843,7 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1819
1843
  Specifies epoch seconds representing time from which JWT token will be valid.
1820
1844
  Note:
1821
1845
  * Applicable only when "auth_mech" is "PAT".
1822
- Default value: None
1846
+ Default value: 0
1823
1847
  Types: int
1824
1848
 
1825
1849
  RETURNS:
@@ -1906,7 +1930,7 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1906
1930
  MessageCodes.INVALID_CONTEXT_CONNECTION)
1907
1931
 
1908
1932
  # Remove keys from _InternalBuffer which are interrelated to base_url and authentication token.
1909
- _InternalBuffer.remove_keys(['list_base_envs', 'default_base_env',
1933
+ _InternalBuffer.remove_keys(['list_base_envs', 'default_base_env_python', 'default_base_env_r',
1910
1934
  'vs_session_id', 'vs_header'])
1911
1935
 
1912
1936
  # ---------------------------------ARGUMENT VALIDATION------------------------------------------------------
@@ -1949,7 +1973,7 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1949
1973
  validate_jwt = kwargs.get("validate_jwt", True)
1950
1974
  __arg_info_matrix.append(["validate_jwt", validate_jwt, True, (bool)])
1951
1975
 
1952
- valid_from = kwargs.get("valid_from", None)
1976
+ valid_from = kwargs.get("valid_from", 0) # This sets iat to UTC beginning.
1953
1977
  __arg_info_matrix.append(["valid_from", valid_from, True, int])
1954
1978
 
1955
1979
  # Validate arguments.
@@ -1968,6 +1992,8 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1968
1992
 
1969
1993
  # Set the vector_store_base_url. This should only be done if base_url is set.
1970
1994
  # In case ues_url is set, vector_store_base_url should not be set.
1995
+ # Remove trailing forward slash from base_url if present.
1996
+ base_url = base_url[: -1] if base_url.endswith("/") else base_url
1971
1997
  configure._vector_store_base_url = f'{base_url}/data-insights'
1972
1998
 
1973
1999
  if ues_url:
@@ -198,7 +198,7 @@ class _SdkJsonParser:
198
198
  # Hence adding `projection` argument for those endpoints as well.
199
199
 
200
200
  if ("/search" in path and "projection" not in query_params_dict.keys()) or \
201
- (re.search(pattern="^/api/[a-zA-Z]+/\{id\}$", string=path) is not None and method == "get"):
201
+ (re.search(pattern=r"^/api/[a-zA-Z]+/\{id\}$", string=path) is not None and method == "get"):
202
202
  # TODO: Confirm with ModelOps team.
203
203
  # There is "projection" parameter in query params for some endpoints
204
204
  # but missing in some other endpoints.
@@ -40,7 +40,7 @@ os.system("") # enables ansi escape characters in terminal
40
40
 
41
41
 
42
42
  class Client(object):
43
- DEFAULT_CONFIG_DIR = os.path.join(GarbageCollector._get_temp_dir_name(), ".sdk")
43
+ DEFAULT_CONFIG_DIR = os.path.join(GarbageCollector._get_temp_dir_name(), "sdk")
44
44
  DEFAULT_TOKEN_CACHE_FILE_PATH = os.path.join(DEFAULT_CONFIG_DIR, ".token")
45
45
  DEFAULT_CONFIG_FILE_PATH = os.path.join(DEFAULT_CONFIG_DIR, "config.yaml")
46
46
  MAX_RETRIES = 3
@@ -198,7 +198,10 @@ class Client(object):
198
198
  """
199
199
  self.logger = logging.getLogger(__name__)
200
200
 
201
- os.makedirs(self.DEFAULT_CONFIG_DIR, exist_ok=True)
201
+ # Use the class attributes of the actual instance's class (could be a child class)
202
+ # rather than Client's class attributes
203
+ cls = self.__class__
204
+ os.makedirs(cls.DEFAULT_CONFIG_DIR, exist_ok=True)
202
205
 
203
206
 
204
207
  arg_info_matrix = []
@@ -239,14 +242,14 @@ class Client(object):
239
242
 
240
243
  if self.auth_mode == DeviceCodeAuth.AUTH_MODE.value:
241
244
  try:
242
- self.session = auth.authenticate(token_cache_file_path=self.DEFAULT_TOKEN_CACHE_FILE_PATH)
245
+ self.session = auth.authenticate(token_cache_file_path=cls.DEFAULT_TOKEN_CACHE_FILE_PATH)
243
246
  except InvalidGrantError as ge:
244
247
  if ge.description in ["Token is not active", "Session not active"]:
245
248
  logging.warning(ge.description + "\nRetrying one more time\n")
246
249
 
247
250
  self.__remove_cached_token()
248
251
 
249
- self.session = auth.authenticate(token_cache_file_path=self.DEFAULT_TOKEN_CACHE_FILE_PATH)
252
+ self.session = auth.authenticate(token_cache_file_path=cls.DEFAULT_TOKEN_CACHE_FILE_PATH)
250
253
  else:
251
254
  raise ge
252
255
  except InvalidTokenError as ge:
@@ -294,8 +297,8 @@ class Client(object):
294
297
  yaml_file_path = None
295
298
  if self.__config_file is not None:
296
299
  yaml_file_path = self.__config_file
297
- elif os.path.isfile(self.DEFAULT_CONFIG_FILE_PATH):
298
- yaml_file_path = self.DEFAULT_CONFIG_FILE_PATH
300
+ elif os.path.isfile(self.__class__.DEFAULT_CONFIG_FILE_PATH):
301
+ yaml_file_path = self.__class__.DEFAULT_CONFIG_FILE_PATH
299
302
  if yaml_file_path:
300
303
  with open(yaml_file_path, "r") as handle:
301
304
  conf = yaml.safe_load(handle)
@@ -27,6 +27,9 @@ from ..constants import SdkNames
27
27
 
28
28
  class ModelOpsClient(Client):
29
29
  DEFAULT_CONFIG_DIR = os.path.join(GarbageCollector._get_temp_dir_name(), "sdk", "modelops")
30
+ DEFAULT_TOKEN_CACHE_FILE_PATH = os.path.join(DEFAULT_CONFIG_DIR, ".token")
31
+ DEFAULT_CONFIG_FILE_PATH = os.path.join(DEFAULT_CONFIG_DIR, "config.yaml")
32
+ MAX_RETRIES = 3
30
33
  SDK_NAME = SdkNames.MODELOPS.value
31
34
 
32
35
  def __init__(self, base_url=None, auth=None, ssl_verify=True, config_file=None, project_id=None):