teradataml 20.0.0.4__py3-none-any.whl → 20.0.0.6__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 (131) hide show
  1. teradataml/LICENSE-3RD-PARTY.pdf +0 -0
  2. teradataml/README.md +182 -13
  3. teradataml/__init__.py +2 -1
  4. teradataml/_version.py +2 -2
  5. teradataml/analytics/analytic_function_executor.py +8 -13
  6. teradataml/analytics/json_parser/analytic_functions_argument.py +4 -0
  7. teradataml/analytics/sqle/__init__.py +16 -1
  8. teradataml/analytics/utils.py +60 -1
  9. teradataml/automl/__init__.py +290 -106
  10. teradataml/automl/autodataprep/__init__.py +471 -0
  11. teradataml/automl/data_preparation.py +29 -10
  12. teradataml/automl/data_transformation.py +11 -0
  13. teradataml/automl/feature_engineering.py +64 -4
  14. teradataml/automl/feature_exploration.py +639 -25
  15. teradataml/automl/model_training.py +1 -1
  16. teradataml/clients/auth_client.py +12 -8
  17. teradataml/clients/keycloak_client.py +165 -0
  18. teradataml/common/constants.py +71 -26
  19. teradataml/common/exceptions.py +32 -0
  20. teradataml/common/messagecodes.py +28 -0
  21. teradataml/common/messages.py +13 -4
  22. teradataml/common/sqlbundle.py +3 -2
  23. teradataml/common/utils.py +345 -45
  24. teradataml/context/context.py +259 -93
  25. teradataml/data/apriori_example.json +22 -0
  26. teradataml/data/docs/sqle/docs_17_20/Apriori.py +138 -0
  27. teradataml/data/docs/sqle/docs_17_20/NERExtractor.py +121 -0
  28. teradataml/data/docs/sqle/docs_17_20/NGramSplitter.py +3 -3
  29. teradataml/data/docs/sqle/docs_17_20/SMOTE.py +212 -0
  30. teradataml/data/docs/sqle/docs_17_20/TextMorph.py +119 -0
  31. teradataml/data/docs/sqle/docs_17_20/TextParser.py +54 -3
  32. teradataml/data/docs/uaf/docs_17_20/ACF.py +1 -1
  33. teradataml/data/docs/uaf/docs_17_20/ArimaEstimate.py +2 -2
  34. teradataml/data/docs/uaf/docs_17_20/ArimaXEstimate.py +2 -2
  35. teradataml/data/docs/uaf/docs_17_20/DFFT.py +1 -1
  36. teradataml/data/docs/uaf/docs_17_20/DFFT2.py +1 -1
  37. teradataml/data/docs/uaf/docs_17_20/DFFT2Conv.py +1 -1
  38. teradataml/data/docs/uaf/docs_17_20/DFFTConv.py +1 -1
  39. teradataml/data/docs/uaf/docs_17_20/FilterFactory1d.py +4 -4
  40. teradataml/data/docs/uaf/docs_17_20/GenseriesSinusoids.py +2 -2
  41. teradataml/data/docs/uaf/docs_17_20/GoldfeldQuandt.py +2 -2
  42. teradataml/data/docs/uaf/docs_17_20/HoltWintersForecaster.py +6 -6
  43. teradataml/data/docs/uaf/docs_17_20/LineSpec.py +1 -1
  44. teradataml/data/docs/uaf/docs_17_20/LinearRegr.py +1 -1
  45. teradataml/data/docs/uaf/docs_17_20/Matrix2Image.py +4 -4
  46. teradataml/data/docs/uaf/docs_17_20/MultivarRegr.py +1 -1
  47. teradataml/data/docs/uaf/docs_17_20/PACF.py +1 -1
  48. teradataml/data/docs/uaf/docs_17_20/PowerSpec.py +2 -2
  49. teradataml/data/docs/uaf/docs_17_20/PowerTransform.py +3 -3
  50. teradataml/data/docs/uaf/docs_17_20/Resample.py +5 -5
  51. teradataml/data/docs/uaf/docs_17_20/SAX.py +3 -3
  52. teradataml/data/docs/uaf/docs_17_20/SignifPeriodicities.py +1 -1
  53. teradataml/data/docs/uaf/docs_17_20/SimpleExp.py +1 -1
  54. teradataml/data/docs/uaf/docs_17_20/Smoothma.py +3 -3
  55. teradataml/data/docs/uaf/docs_17_20/UNDIFF.py +1 -1
  56. teradataml/data/jsons/byom/onnxembeddings.json +1 -0
  57. teradataml/data/jsons/sqle/17.20/NGramSplitter.json +6 -6
  58. teradataml/data/jsons/sqle/17.20/TD_Apriori.json +181 -0
  59. teradataml/data/jsons/sqle/17.20/TD_NERExtractor.json +145 -0
  60. teradataml/data/jsons/sqle/17.20/TD_SMOTE.json +267 -0
  61. teradataml/data/jsons/sqle/17.20/TD_TextMorph.json +134 -0
  62. teradataml/data/jsons/sqle/17.20/TD_TextParser.json +114 -9
  63. teradataml/data/jsons/sqle/20.00/AI_AnalyzeSentiment.json +328 -0
  64. teradataml/data/jsons/sqle/20.00/AI_AskLLM.json +420 -0
  65. teradataml/data/jsons/sqle/20.00/AI_DetectLanguage.json +343 -0
  66. teradataml/data/jsons/sqle/20.00/AI_ExtractKeyPhrases.json +328 -0
  67. teradataml/data/jsons/sqle/20.00/AI_MaskPII.json +328 -0
  68. teradataml/data/jsons/sqle/20.00/AI_RecognizeEntities.json +328 -0
  69. teradataml/data/jsons/sqle/20.00/AI_RecognizePIIEntities.json +328 -0
  70. teradataml/data/jsons/sqle/20.00/AI_TextClassifier.json +359 -0
  71. teradataml/data/jsons/sqle/20.00/AI_TextEmbeddings.json +360 -0
  72. teradataml/data/jsons/sqle/20.00/AI_TextSummarize.json +343 -0
  73. teradataml/data/jsons/sqle/20.00/AI_TextTranslate.json +343 -0
  74. teradataml/data/jsons/sqle/20.00/TD_SMOTE.json +2 -2
  75. teradataml/data/jsons/sqle/20.00/TD_VectorDistance.json +1 -1
  76. teradataml/data/ner_dict.csv +8 -0
  77. teradataml/data/ner_input_eng.csv +7 -0
  78. teradataml/data/ner_rule.csv +5 -0
  79. teradataml/data/pattern_matching_data.csv +11 -0
  80. teradataml/data/pos_input.csv +40 -0
  81. teradataml/data/sdk/modelops/modelops_spec.json +101737 -0
  82. teradataml/data/tdnerextractor_example.json +14 -0
  83. teradataml/data/teradataml_example.json +21 -1
  84. teradataml/data/textmorph_example.json +5 -0
  85. teradataml/data/to_num_data.csv +4 -0
  86. teradataml/data/tochar_data.csv +5 -0
  87. teradataml/data/trans_dense.csv +16 -0
  88. teradataml/data/trans_sparse.csv +55 -0
  89. teradataml/data/url_data.csv +10 -9
  90. teradataml/dataframe/copy_to.py +38 -27
  91. teradataml/dataframe/data_transfer.py +61 -45
  92. teradataml/dataframe/dataframe.py +1110 -132
  93. teradataml/dataframe/dataframe_utils.py +73 -27
  94. teradataml/dataframe/functions.py +1070 -9
  95. teradataml/dataframe/sql.py +750 -959
  96. teradataml/dbutils/dbutils.py +33 -13
  97. teradataml/dbutils/filemgr.py +14 -10
  98. teradataml/hyperparameter_tuner/utils.py +4 -2
  99. teradataml/lib/aed_0_1.dll +0 -0
  100. teradataml/opensource/_base.py +12 -157
  101. teradataml/options/configure.py +24 -9
  102. teradataml/scriptmgmt/UserEnv.py +317 -39
  103. teradataml/scriptmgmt/lls_utils.py +456 -135
  104. teradataml/sdk/README.md +79 -0
  105. teradataml/sdk/__init__.py +4 -0
  106. teradataml/sdk/_auth_modes.py +422 -0
  107. teradataml/sdk/_func_params.py +487 -0
  108. teradataml/sdk/_json_parser.py +453 -0
  109. teradataml/sdk/_openapi_spec_constants.py +249 -0
  110. teradataml/sdk/_utils.py +236 -0
  111. teradataml/sdk/api_client.py +897 -0
  112. teradataml/sdk/constants.py +62 -0
  113. teradataml/sdk/modelops/__init__.py +98 -0
  114. teradataml/sdk/modelops/_client.py +406 -0
  115. teradataml/sdk/modelops/_constants.py +304 -0
  116. teradataml/sdk/modelops/models.py +2308 -0
  117. teradataml/sdk/spinner.py +107 -0
  118. teradataml/store/__init__.py +1 -1
  119. teradataml/table_operators/Apply.py +16 -1
  120. teradataml/table_operators/Script.py +20 -1
  121. teradataml/table_operators/query_generator.py +4 -21
  122. teradataml/table_operators/table_operator_util.py +58 -9
  123. teradataml/utils/dtypes.py +4 -2
  124. teradataml/utils/internal_buffer.py +22 -2
  125. teradataml/utils/utils.py +0 -1
  126. teradataml/utils/validators.py +318 -58
  127. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/METADATA +188 -14
  128. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/RECORD +131 -84
  129. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/WHEEL +0 -0
  130. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/top_level.txt +0 -0
  131. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/zip-safe +0 -0
@@ -10,36 +10,38 @@ teradataml load library service wrappers.
10
10
  All teradataml wrappers to provide interface to load library service stored procedures
11
11
  from Open Analytics Framework.
12
12
  """
13
+ import base64
13
14
  import concurrent.futures
14
15
  import functools
15
16
  import json
16
17
  import operator
17
18
  import os
19
+ import warnings
20
+ from json.decoder import JSONDecodeError
21
+ from time import sleep, time
22
+ from urllib.parse import urlparse
18
23
 
19
24
  import pandas as pd
20
- import requests
21
25
 
22
- from json.decoder import JSONDecodeError
23
26
  from teradataml import configure
24
- from teradataml.context.context import _get_user, get_connection
25
- from teradataml.common.constants import HTTPRequest, AsyncStatusColumns
26
- from teradataml.common.deprecations import argument_deprecation
27
+ from teradataml.clients.auth_client import _AuthWorkflow
28
+ from teradataml.clients.keycloak_client import _KeycloakManager
29
+ from teradataml.clients.pkce_client import _DAWorkflow
30
+ from teradataml.common.constants import (AsyncOpStatus, AsyncStatusColumns,
31
+ AuthMechs, HTTPRequest, TDServices)
27
32
  from teradataml.common.exceptions import TeradataMlException
28
- from teradataml.common.messages import Messages
29
33
  from teradataml.common.messagecodes import MessageCodes
34
+ from teradataml.common.messages import Messages
30
35
  from teradataml.common.utils import UtilFuncs
31
- from teradataml.clients.pkce_client import _DAWorkflow
32
- from teradataml.clients.auth_client import _AuthWorkflow
36
+ from teradataml.context.context import _get_user, get_connection
37
+ from teradataml.scriptmgmt.UserEnv import (UserEnv, _AuthToken,
38
+ _get_auth_token, _get_ccp_url,
39
+ _get_ues_url, _process_ues_response)
40
+ from teradataml.telemetry_utils.queryband import collect_queryband
33
41
  from teradataml.utils.internal_buffer import _InternalBuffer
34
- from teradataml.scriptmgmt.UserEnv import UserEnv, _get_auth_token, \
35
- _process_ues_response, _get_ues_url, _AuthToken
36
- from teradataml.utils.validators import _Validators
37
- from time import time, sleep
38
- import warnings
39
- import webbrowser
40
- from urllib.parse import parse_qs, urlparse
41
42
  from teradataml.utils.utils import _async_run_id_info
42
- from teradataml.telemetry_utils.queryband import collect_queryband
43
+ from teradataml.utils.validators import _Validators
44
+
43
45
 
44
46
  @collect_queryband(queryband="LstBsEnv")
45
47
  def list_base_envs():
@@ -197,7 +199,7 @@ def list_user_envs(env_name=None, **kwargs):
197
199
  ... 'python_3.9',
198
200
  ... 'Sales team environment.',
199
201
  ... conda_env=True)
200
- Conda environment creation initiated
202
+ Conda environment creation initiated.
201
203
  User environment 'Sales_cond_env' created.
202
204
 
203
205
  # Example 1: List all available user environments.
@@ -303,7 +305,7 @@ def list_user_envs(env_name=None, **kwargs):
303
305
 
304
306
  try:
305
307
  response = UtilFuncs._http_request(_get_ues_url(), headers=_get_auth_token())
306
- # Below condition is special case handeling when remove_all_envs() used by user, remove_all_envs()
308
+ # Below condition is special case handling when remove_all_envs() used by user, remove_all_envs()
307
309
  # removes all the envs which result in a status_code 404 and due to which warnings provided in
308
310
  # list_user_envs() not appears.
309
311
  if response.status_code == 404 and "No user environments found." in response.text:
@@ -339,7 +341,7 @@ def list_user_envs(env_name=None, **kwargs):
339
341
  # Return the DataFrame if not empty.
340
342
  if len(pandas_df) > 0:
341
343
  return pandas_df
342
-
344
+
343
345
  print("No user environment(s) found.")
344
346
  except (TeradataMlException, RuntimeError):
345
347
  raise
@@ -451,8 +453,8 @@ def __create_envs(template):
451
453
  except Exception as lib_installation_failure:
452
454
  error_code = MessageCodes.FUNC_EXECUTION_FAILED
453
455
  error_msg = Messages.get_message(error_code,
454
- "'install_lib' request for enviornment: '{}'".format(env_name),
455
- '\n'+str(lib_installation_failure))
456
+ "'install_lib' request for enviornment: '{}'".format(env_name),
457
+ '\n' + str(lib_installation_failure))
456
458
  print(error_msg)
457
459
  errored = errored or True
458
460
  pass
@@ -747,9 +749,18 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
747
749
  >>> fraud_detection_env = create_env('Fraud_detection_conda',
748
750
  ... 'python_3.8',
749
751
  ... 'Fraud detection through time matching',
750
- conda_env=True)
751
- Conda environment creation initiated
752
- User environment 'Fraud_detection_conda' created.
752
+ ... conda_env=True)
753
+ Conda environment creation initiated.
754
+ User environment 'Fraud_detection_conda' created.
755
+
756
+ # Example 5: Create a Conda R 4.2 environment with given name and
757
+ # description in the Vantage.
758
+ >>> conda_r_env = create_env('conda_r_env',
759
+ ... 'r_4.2',
760
+ ... 'Conda R environment',
761
+ ... conda_env=True)
762
+ Conda environment creation initiated.
763
+ User environment 'conda_r_env' created.
753
764
  """
754
765
 
755
766
  # Either env_name or template can be used.
@@ -774,7 +785,7 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
774
785
  # Or if base_env is provided and not in the list of base envs.
775
786
  # Note: By default python base env is obtained.
776
787
  if configure.ues_url is not None and \
777
- get_connection() is not None:
788
+ get_connection() is not None:
778
789
  # Check if base_env is provided or not in the list of base envs.
779
790
 
780
791
  # Check if user requested for conda environment but do not specify the base_env.
@@ -787,11 +798,11 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
787
798
  # Check if base_env provided or not. If provided, check if it is available in
788
799
  # the list of base envs. If not available, set base_env to the default python base env.
789
800
  if not base_env or \
790
- base_env.lower() not in list_base_envs()['base_name'].str.lower().to_list():
801
+ base_env.lower() not in list_base_envs()['base_name'].str.lower().to_list():
791
802
  # Print warning message if base_env provided is not available.
792
803
  if base_env:
793
- print(f"Note: The specified base environment '{base_env}' is unavailable. "\
794
- "Using the default base environment as specified in the documentation.")
804
+ print(f"Note: The specified base environment '{base_env}' is unavailable. " \
805
+ "Using the default base environment as specified in the documentation.")
795
806
  # Set base_env to the default
796
807
  base_env = __get_default_base_env()
797
808
  if not desc:
@@ -804,21 +815,25 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
804
815
  response = UtilFuncs._http_request(
805
816
  _get_ues_url(conda_env=conda_env), HTTPRequest.POST, headers=_get_auth_token(), json=data)
806
817
 
807
- # UES reponse.
808
- resp = _process_ues_response(api_name="create_env", response=response)
818
+ # Validate UES response.
819
+ _process_ues_response(api_name="create_env", response=response)
809
820
 
810
821
  msg = "User environment '{}' created."
811
822
 
812
823
  if conda_env:
813
- print("Conda environment creation initiated")
824
+ print("Conda environment creation initiated.")
814
825
  # Get claim_id.
815
826
  claim_id = response.json().get("claim_id", "")
816
- # Poll the claim_id status.
827
+
828
+ # Since create_env() for conda environment is internally
829
+ # asynchronous but exposed as synchronous API, keep polling
830
+ # the status of underlying asynchronous operation until
831
+ # it is either successful or errored.
817
832
  __poll_claim_id_status(claim_id, "create_env")
818
833
  print(msg.format(env_name))
819
834
 
820
835
  # Return an instance of class UserEnv.
821
- return UserEnv(env_name, base_env, desc)
836
+ return UserEnv(env_name, base_env, desc, conda_env)
822
837
 
823
838
  except (TeradataMlException, RuntimeError):
824
839
  raise
@@ -855,7 +870,7 @@ def _async_run_status_open_af(claim_id):
855
870
  __get_claim_id_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
856
871
  """
857
872
  # Get the claim id status.
858
- resp_data = __get_status(claim_id)
873
+ resp_data = _get_status(claim_id)
859
874
 
860
875
  desc = _async_run_id_info.get(claim_id, {}).get("description", "Unknown")
861
876
  get_details = lambda data: {AsyncStatusColumns.ADDITIONAL_DETAILS.value:
@@ -871,7 +886,7 @@ def _async_run_status_open_af(claim_id):
871
886
  return [get_details(sub_step) for sub_step in resp_data]
872
887
 
873
888
 
874
- def __get_status(claim_id):
889
+ def _get_status(claim_id):
875
890
  """
876
891
  DESCRIPTION:
877
892
  Internal function to get the status of a claim_id using
@@ -891,7 +906,7 @@ def __get_status(claim_id):
891
906
  None
892
907
 
893
908
  EXAMPLES:
894
- __get_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
909
+ _get_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
895
910
  """
896
911
  # Get the claim id status
897
912
  response = UtilFuncs._http_request(_get_ues_url(env_type="fm",
@@ -1030,6 +1045,9 @@ def __manage_envs(env_name=None, api_name="remove_env", **kwargs):
1030
1045
 
1031
1046
  try:
1032
1047
  # Get the ues url for corresponding API.
1048
+ # While deleting environment, endpoint UES URL for deleting
1049
+ # normal and conda environment is same, unlike creating
1050
+ # normal and conda environment.
1033
1051
  ues_url = _get_ues_url(env_name=env_name, api_name=api_name) if api_name == "remove_env" \
1034
1052
  else _get_ues_url(remove_all_envs=True, api_name=api_name)
1035
1053
 
@@ -1048,7 +1066,7 @@ def __manage_envs(env_name=None, api_name="remove_env", **kwargs):
1048
1066
  if api_name == "remove_env":
1049
1067
  msg = "{2}list_user_envs(). If environment is not removed, " \
1050
1068
  "check the status of asynchronous call using" \
1051
- " async_run_status('{1}') or get_env('{0}').status('{1}')".\
1069
+ " async_run_status('{1}') or get_env('{0}').status('{1}')". \
1052
1070
  format(env_name, claim_id, msg)
1053
1071
  else:
1054
1072
  msg = "{0}async_run_status('{1}')".format(msg, claim_id)
@@ -1093,30 +1111,37 @@ def __poll_claim_id_status(claim_id, api_name="remove_env"):
1093
1111
  Default Value: remove_env
1094
1112
  Types: str
1095
1113
 
1096
-
1097
-
1098
1114
  RETURNS:
1099
1115
  None.
1100
1116
 
1101
1117
  RAISES:
1102
- None.
1118
+ TeradataMlException
1103
1119
 
1104
1120
  EXAMPLES:
1105
1121
  __poll_claim_id_status('cf7245f0-e962-4451-addf-efa7e123998d')
1106
1122
  """
1123
+ err_details = None
1107
1124
  while True:
1108
1125
  sleep(2)
1109
1126
 
1110
1127
  # Poll the claim id to get the status.
1111
- resp_data = __get_status(claim_id)
1128
+ resp_data = _get_status(claim_id)
1112
1129
 
1113
1130
  # Breaking condition -
1114
1131
  # For create_env and remove_env: Check for the 'Finished' stage in the list of resp.
1115
1132
  # For remove_all_envs: above cond. and No user envs condition should break it .
1116
1133
  for data in resp_data:
1117
- if ("Finished" in data["stage"]) or \
1118
- (api_name in ["create_env", "remove_all_envs"] and "Errored" in data["stage"]):
1134
+ if AsyncOpStatus.FINISHED.value in data["stage"]:
1119
1135
  return
1136
+ elif AsyncOpStatus.ERRED.value in data["stage"]:
1137
+ err_details = data["details"]
1138
+ break
1139
+ if err_details:
1140
+ break
1141
+
1142
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1143
+ api_name, err_details),
1144
+ MessageCodes.FUNC_EXECUTION_FAILED)
1120
1145
 
1121
1146
 
1122
1147
  @collect_queryband(queryband="GtEnv")
@@ -1191,7 +1216,9 @@ def get_env(env_name):
1191
1216
  # Return an instance of class UserEnv.
1192
1217
  return UserEnv(userenv_row.env_name.values[0],
1193
1218
  userenv_row.base_env_name.values[0],
1194
- userenv_row.env_description.values[0])
1219
+ userenv_row.env_description.values[0],
1220
+ userenv_row.conda.values[0]
1221
+ )
1195
1222
  except (TeradataMlException, RuntimeError) as tdemsg:
1196
1223
  # TeradataMlException and RuntimeError are raised by list_user_envs.
1197
1224
  # list_user_envs should be replaced with get_env in the error
@@ -1446,7 +1473,7 @@ def _remove_all_envs(env_type, **kwargs):
1446
1473
  if env_type.capitalize() == "Py":
1447
1474
  env_type = ["Python", "python"]
1448
1475
  else:
1449
- env_type = ["R"]
1476
+ env_type = ["R", "r"]
1450
1477
  env_type_message = "R"
1451
1478
  asynchronous = kwargs.get("asynchronous", False)
1452
1479
 
@@ -1485,7 +1512,7 @@ def _remove_all_envs(env_type, **kwargs):
1485
1512
  if len(failed_envs) > 0:
1486
1513
  emsg = ""
1487
1514
  for env, tdemsg in failed_envs.items():
1488
- emsg += "\nUser environment '{0}' failed to remove. Reason: {1}"\
1515
+ emsg += "\nUser environment '{0}' failed to remove. Reason: {1}" \
1489
1516
  .format(env, tdemsg.args[0])
1490
1517
  msg_code = MessageCodes.FUNC_EXECUTION_FAILED
1491
1518
  error_msg = Messages.get_message(msg_code, "remove_all_envs()", emsg)
@@ -1598,23 +1625,94 @@ def get_user_env():
1598
1625
  return configure._default_user_env
1599
1626
 
1600
1627
 
1628
+ def _validate_jwt_token(base_url, token_data):
1629
+ """
1630
+ DESCRIPTION:
1631
+ Function to validate the authentication token generated using PAT and PEM file.
1632
+
1633
+ PARAMETERS:
1634
+ base_url:
1635
+ Required Argument.
1636
+ Specifies the endpoint URL for a given environment on VantageCloud Lake.
1637
+ Types: str
1638
+
1639
+ token_data:
1640
+ Required Argument.
1641
+ Specifies the JWT token to be authenticated.
1642
+
1643
+ RETURNS:
1644
+ Boolan flag representing validation status.
1645
+ * True: Indicates that token is valid.
1646
+ * None: Indicates that token is not validated.
1647
+
1648
+ RAISES:
1649
+ TeradataMlException
1650
+
1651
+ EXAMPLES:
1652
+ Example 1: Validate JWT token.
1653
+ >>> _validate_jwt_token(base_url, token_data)
1654
+
1655
+ """
1656
+ # Extract environment id from base_url.
1657
+ try:
1658
+ url_parser = urlparse(base_url)
1659
+ env_id = url_parser.path.split("accounts/")[1].split("/")[0]
1660
+ if not env_id:
1661
+ raise
1662
+ except Exception:
1663
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1664
+ "set_auth_token",
1665
+ "Use valid value for 'base_url'"),
1666
+ MessageCodes.FUNC_EXECUTION_FAILED)
1667
+
1668
+ valid_token = None
1669
+ try:
1670
+ response = UtilFuncs._http_request(url="{}/{}/{}/{}".format(_get_ccp_url(base_url),
1671
+ "api", "accounts", env_id),
1672
+ method_type=HTTPRequest.GET,
1673
+ headers={"Authorization": "Bearer {}".format(token_data)})
1674
+ if 200 <= response.status_code < 300: # Authorized access.
1675
+ valid_token = True
1676
+ elif 400 <= response.status_code < 500: # Unauthorized access.
1677
+ valid_token = False
1678
+ except:
1679
+ pass
1680
+
1681
+ if valid_token is False:
1682
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1683
+ "set_auth_token",
1684
+ "Use valid values for input arguments ['base_url',"
1685
+ " 'pat_token', 'pem_file']."),
1686
+ MessageCodes.FUNC_EXECUTION_FAILED)
1687
+ return valid_token
1688
+
1689
+
1601
1690
  @collect_queryband(queryband="StAthTkn")
1602
1691
  def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None, **kwargs):
1603
1692
  """
1604
1693
  DESCRIPTION:
1605
- Function to set the Authentication token to connect to User Environment Service
1606
- in VantageCloud Lake.
1607
- Note:
1608
- User must have a privilege to login with a NULL password to use set_auth_token().
1609
- Please refer to GRANT LOGON section in Teradata Documentation for more details.
1610
- If base_url and client_id are specified then authentication is through OAuth.
1611
- If base_url, pat_token, pem_file are specified then authentication is through PAT.
1612
- Refresh token still works but only for OAuth authentication.
1694
+ Function to set the authentication token required to access services running on
1695
+ Teradata Vantage.
1696
+ Notes:
1697
+ * User must have a privilege to login with a NULL password to use set_auth_token().
1698
+ Refer to GRANT LOGON section in Teradata Documentation for more details.
1699
+ * When "auth_mech" is not specified, arguments are used in the following combination
1700
+ to derive authentication mechanism.
1701
+ * If "base_url" and "client_id" are specified then token generation is done through OAuth.
1702
+ * If "base_url", "pat_token", "pem_file" are specified then token generation is done using PAT.
1703
+ * If "base_url", "username" and "password" are specified then authentication is done via
1704
+ Basic authentication mechanism using user credentials.
1705
+ * If "base_url" and "auth_token" are specified then readily available token is used.
1706
+ * If only "base_url" is specified then token generation is done through OAuth.
1707
+ * Refresh token works only for OAuth authentication.
1708
+ * Use the argument "kid" only when key used during the pem file generation is different
1709
+ from pem file name. For example, if you use the key as 'key1' while generating pem file
1710
+ and the name of the pem file is `key1(1).pem`, then pass value 'key1' to the argument "kid".
1613
1711
 
1614
1712
  PARAMETERS:
1615
1713
  base_url:
1616
1714
  Required Argument.
1617
- Specifies the CCP endpoint URL.
1715
+ Specifies the endpoint URL for a given environment on Teradata Vantage system.
1618
1716
  Types: str
1619
1717
 
1620
1718
  client_id:
@@ -1631,35 +1729,99 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1631
1729
  pem_file:
1632
1730
  Required, if PAT authentication is to be used, optional otherwise.
1633
1731
  Specifies the path to private key file which is generated from VantageCloud Lake Console.
1732
+ Note:
1733
+ Teradata recommends not to change the name of the file generated from VantageCloud Lake
1734
+ Console. If the name of the file is changed, then authentication token generated from
1735
+ this function will not work.
1634
1736
  Types: str
1635
1737
 
1636
1738
  **kwargs:
1637
1739
  username:
1740
+ Optional Argument.
1638
1741
  Specifies the user for which authentication is to be requested.
1639
1742
  If not specified, then user associated with current connection is used.
1640
- Note:
1641
- 1. Use this option only if name of the database username has lower case letters.
1642
- 2. This option is used only for PAT and not for OAuth.
1743
+ Notes:
1744
+ * Use this option only if name of the database username has lowercase letters.
1745
+ * This option is used only for PAT and not for OAuth.
1643
1746
  Types: str
1644
1747
 
1645
1748
  expiration_time:
1646
- Specifies the expiration time of the token in seconds. After expiry time JWT token expires and
1647
- UserEnv methods does not work, user should regenerate the token.
1749
+ Optional Argument.
1750
+ Specifies the expiration time of the token in seconds. After expiry time, JWT
1751
+ token expires and UserEnv methods does not work, user should regenerate the token.
1648
1752
  Note:
1649
- This option is used only for PAT and not for OAuth.
1753
+ * This option is used only for PAT and not for OAuth.
1650
1754
  Default Value: 31536000
1651
1755
  Types: int
1652
1756
 
1653
1757
  auth_token:
1654
- Optional Parameter.
1655
- Specifies the authentication token to connect to VantageCloud Lake.
1758
+ Optional Argument.
1759
+ Specifies the authentication token required to access services running
1760
+ on Teradata Vantage.
1656
1761
  Notes:
1657
- * if "auth_token" is set through this function, then this function
1658
- should always be used only after create_context.
1659
- * use this option only if user has got JWT token and wants to set the same
1660
- instead of generating it again from this function.
1762
+ * If "auth_token" is set through this function, then this function
1763
+ should always be used only after create_context().
1764
+ * Use this option only if user has got JWT token and wants to set
1765
+ the same instead of generating it again from this function.
1766
+
1767
+ Types: str
1768
+
1769
+ kid:
1770
+ Optional Argument.
1771
+ Specifies the name of the key which is used while generating 'pem_file'.
1772
+ Types: str
1773
+
1774
+ password:
1775
+ Optional Argument.
1776
+ Specifies the password for database user to be used for Basic authentication.
1777
+ Types: str
1778
+
1779
+ auth_url:
1780
+ Optional Argument.
1781
+ Specifies the endpoint URL for a keycloak server.
1661
1782
  Types: str
1662
1783
 
1784
+ rest_client:
1785
+ Optional Argument.
1786
+ Specifies the service for which keycloak token is to be generated.
1787
+ Permitted values: "VECTORSTORE"
1788
+ Default value: "VECTORSTORE"
1789
+ Types: str
1790
+
1791
+ auth_mech:
1792
+ Optional Argument.
1793
+ Specifies the mechanism to be used for generating authentication token.
1794
+ Note:
1795
+ * When "auth_mech" is provided, other arguments are used in the following
1796
+ combination as per value of "auth_mech":
1797
+ * OAuth: Token generation is done through OAuth by using client id
1798
+ which can be sepcified by user in "client_id" argument or
1799
+ can be derived internally from "base_url".
1800
+ * PAT: Token generation is done using "pat_token" and "pem_file".
1801
+ * BASIC: Authentication is done via Basic authentication mechanism
1802
+ using user credentials passed in "username" and "password"
1803
+ arguments.
1804
+ * JWT: Readily available token in "auth_token" argument is used.
1805
+ * KEYCLOAK: Token generation is done using keycloak.
1806
+ Permitted Values: "OAuth", "PAT", "BASIC", "JWT", "KEYCLOAK".
1807
+ Types: str
1808
+
1809
+ validate_jwt:
1810
+ Optional Argument.
1811
+ Specifies whether to validate generated JWT token or not.
1812
+ Note:
1813
+ * Applicable only when "auth_mech" is "PAT".
1814
+ Default value: True
1815
+ Types: boolean
1816
+
1817
+ valid_from:
1818
+ Optional Argument.
1819
+ Specifies epoch seconds representing time from which JWT token will be valid.
1820
+ Note:
1821
+ * Applicable only when "auth_mech" is "PAT".
1822
+ Default value: None
1823
+ Types: int
1824
+
1663
1825
  RETURNS:
1664
1826
  True, if the operation is successful.
1665
1827
 
@@ -1671,10 +1833,14 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1671
1833
  # Example 1: Set the Authentication token using default client_id.
1672
1834
  >>> import getpass
1673
1835
  >>> set_auth_token(base_url=getpass.getpass("ues_url : "))
1836
+ Authentication token is generated and set for the session.
1837
+ True
1674
1838
 
1675
1839
  # Example 2: Set the Authentication token by specifying the client_id.
1676
1840
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1677
1841
  ... client_id=getpass.getpass("client_id : "))
1842
+ Authentication token is generated and set for the session.
1843
+ True
1678
1844
 
1679
1845
  # Example 3: Set the Authentication token by specifying the "pem_file" and "pat_token"
1680
1846
  # without specifying "username".
@@ -1682,6 +1848,7 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1682
1848
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1683
1849
  ... pat_token=getpass.getpass("pat_token : "),
1684
1850
  ... pem_file=getpass.getpass("pem_file : "))
1851
+ Authentication token is generated, authenticated and set for the session.
1685
1852
  True
1686
1853
 
1687
1854
  # Example 4: Set the Authentication token by specifying the "pem_file" and "pat_token"
@@ -1689,85 +1856,201 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1689
1856
  >>> import getpass
1690
1857
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1691
1858
  ... pat_token=getpass.getpass("pat_token : "),
1692
- ... pem_file=getpass.getpass("pem_file : "))
1693
- ... username = "alice")
1859
+ ... pem_file=getpass.getpass("pem_file : "),
1860
+ ... username=getpass.getpass("username : "))
1861
+ Authentication token is generated, authenticated and set for the session.
1862
+ True
1863
+
1864
+ # Example 5: Set the Authentication token by specifying the "pem_file" and "pat_token"
1865
+ # and "kid".
1866
+ >>> import getpass
1867
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1868
+ ... pat_token=getpass.getpass("pat_token : "),
1869
+ ... pem_file=getpass.getpass("pem_file : ")
1870
+ ... kid="key1")
1871
+ Authentication token is generated, authenticated and set for the session.
1872
+ True
1873
+
1874
+ # Example 6: Set the authentication token via Basic Authentication mechanism by
1875
+ # specifying the "base_url", "username" and "password".
1876
+ >>> import getpass
1877
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1878
+ ... username=getpass.getpass("username : "),
1879
+ ... password=getpass.getpass("password : "))
1880
+ Authentication token is generated and set for the session.
1881
+ True
1882
+
1883
+ # Example 7: Set the authentication token for by specifying "base_url" and
1884
+ # "auth_mech" as "OAuth".
1885
+ >>> import getpass
1886
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1887
+ ... auth_mech="OAuth")
1888
+ Authentication token is generated and set for the session.
1889
+ True
1890
+
1891
+ # Example 8: Set the authentication token for by specifying "base_url", "auth_url"
1892
+ # "password" and "rest_client" and generating keycloak token internally.
1893
+ >>> import getpass
1894
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1895
+ ... auth_url=getpass.getpass("auth_url : "),
1896
+ ... password=getpass.getpass("password : "),
1897
+ ... rest_client=getpass.getpass("rest_client : "))
1898
+ Authentication token is generated and set for the session.
1694
1899
  True
1900
+
1695
1901
  """
1902
+
1696
1903
  # Deriving global connection using get_connection().
1697
- con = get_connection()
1698
- if con is None:
1699
- raise TeradataMlException(Messages.get_message(MessageCodes.INVALID_CONTEXT_CONNECTION),
1904
+ if get_connection() is None:
1905
+ raise TeradataMlException(Messages.get_message(MessageCodes.INVALID_CONTEXT_CONNECTION),
1700
1906
  MessageCodes.INVALID_CONTEXT_CONNECTION)
1701
1907
 
1702
- # Getting the ues_url.
1703
- ues_url = kwargs.get("ues_url", None)
1908
+ # Remove keys from _InternalBuffer which are interrelated to base_url and authentication token.
1909
+ _InternalBuffer.remove_keys(['list_base_envs', 'default_base_env',
1910
+ 'vs_session_id', 'vs_header'])
1704
1911
 
1912
+ # ---------------------------------ARGUMENT VALIDATION------------------------------------------------------
1913
+ # STEP 1: Validate arguments for allowed types.
1914
+ # ----------------------------------------------------------------------------------------------------------
1705
1915
  __arg_info_matrix = []
1706
1916
  __arg_info_matrix.append(["base_url", base_url, True, (str), True])
1707
- __arg_info_matrix.append(["ues_url", ues_url, True, (str), True])
1708
1917
  __arg_info_matrix.append(["client_id", client_id, True, (str), True])
1709
1918
  __arg_info_matrix.append(["pat_token", pat_token, True, (str), True])
1710
1919
  __arg_info_matrix.append(["pem_file", pem_file, True, (str), True])
1711
1920
 
1712
- username = kwargs.get("username", None)
1713
- __arg_info_matrix.append((["username", username, True, (str), True]))
1921
+ # Get keyword arguments.
1922
+ ues_url = kwargs.get("ues_url", None)
1923
+ __arg_info_matrix.append(["ues_url", ues_url, True, (str), True])
1924
+
1925
+ username = kwargs.get("username", _get_user())
1926
+ __arg_info_matrix.append(["username", username, True, (str), True])
1927
+
1928
+ password = kwargs.get("password", None)
1929
+ __arg_info_matrix.append(["password", password, True, (str), True])
1714
1930
 
1715
1931
  auth_token = kwargs.get("auth_token")
1716
- __arg_info_matrix.append((["auth_token", auth_token, True, (str), True]))
1932
+ __arg_info_matrix.append(["auth_token", auth_token, True, (str), True])
1717
1933
 
1718
- expiration_time = kwargs.get("expiration_time", 31536000)
1719
- __arg_info_matrix.append((["expiration_time", expiration_time, True, (int), True]))
1934
+ expiration_time = kwargs.get("expiration_time", 31536000) # 31536000 seconds meaning 365 days.
1935
+ __arg_info_matrix.append(["expiration_time", expiration_time, True, (int), True])
1936
+
1937
+ kid = kwargs.get("kid")
1938
+ __arg_info_matrix.append(["kid", kid, True, (str), True])
1939
+
1940
+ auth_url = kwargs.get("auth_url", None)
1941
+ __arg_info_matrix.append(["auth_url", auth_url, True, (str), True])
1942
+
1943
+ rest_client = kwargs.get("rest_client", "VECTORSTORE")
1944
+ __arg_info_matrix.append(["rest_client", rest_client, True, (str), True, [svc.name for svc in TDServices]])
1945
+
1946
+ auth_mech = kwargs.get("auth_mech", None)
1947
+ __arg_info_matrix.append(["auth_mech", auth_mech, True, (str), True, [mech.name for mech in AuthMechs]])
1948
+
1949
+ validate_jwt = kwargs.get("validate_jwt", True)
1950
+ __arg_info_matrix.append(["validate_jwt", validate_jwt, True, (bool)])
1951
+
1952
+ valid_from = kwargs.get("valid_from", None)
1953
+ __arg_info_matrix.append(["valid_from", valid_from, True, int])
1720
1954
 
1721
1955
  # Validate arguments.
1722
1956
  _Validators._validate_function_arguments(__arg_info_matrix)
1723
1957
 
1958
+ # ---------------------------------BASE_URL PROCESSING------------------------------------------------------
1959
+ # STEP 2: Process base_url/ues_url and set applicable config options.
1960
+ # ----------------------------------------------------------------------------------------------------------
1961
+
1724
1962
  # base_url should not end with 'open-analytics' or 'data-insights'
1725
1963
  if base_url:
1726
1964
  if base_url.endswith('open-analytics') or base_url.endswith('data-insights'):
1727
1965
  message = Messages.get_message(MessageCodes.ARG_NONE,
1728
- "base_url", "ending with 'data-insights' or 'open-analytics", None)
1966
+ "base_url", "ending with 'data-insights' or 'open-analytics", "")
1729
1967
  raise TeradataMlException(message, MessageCodes.ARG_NONE)
1730
1968
 
1731
1969
  # Set the vector_store_base_url. This should only be done if base_url is set.
1732
1970
  # In case ues_url is set, vector_store_base_url should not be set.
1733
1971
  configure._vector_store_base_url = f'{base_url}/data-insights'
1734
1972
 
1973
+ if ues_url:
1974
+ # If incorrectly formatted UES service URL is passed, set it to None
1975
+ # and let further validation raise error.
1976
+ if not (ues_url.endswith('open-analytics') or ues_url.endswith('user-environment-service/api/v1/')):
1977
+ ues_url = None
1978
+
1735
1979
  # If ues_url is provided, then use it as base_url.
1736
- base_url = kwargs.get("ues_url", base_url)
1980
+ base_url = ues_url if ues_url else base_url
1981
+
1982
+ if not (base_url or ues_url):
1983
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["base_url"]),
1984
+ MessageCodes.MISSING_ARGS)
1737
1985
 
1738
1986
  # Set the OpenAF url.
1739
- # If ues_url is present use that otherwise generate it from base_url.
1987
+ # If ues_url is present, then use that otherwise generate it from base_url.
1740
1988
  configure.ues_url = ues_url if ues_url else f'{base_url}/open-analytics'
1741
1989
 
1742
- # If user pass Auth token, set it.
1743
- if auth_token:
1744
- _InternalBuffer.add(auth_token=_AuthToken(token=auth_token))
1745
- return True
1746
-
1747
- if client_id and any([pat_token, pem_file]):
1748
- message = Messages.get_message(MessageCodes.EITHER_THIS_OR_THAT_ARGUMENT,
1749
- "client_id", "pat_token' and 'pem_file")
1750
- raise TeradataMlException(message, MessageCodes.EITHER_THIS_OR_THAT_ARGUMENT)
1751
-
1752
- if client_id is None:
1753
- if (pat_token and pem_file is None) or (pem_file and pat_token is None):
1754
- message = Messages.get_message(MessageCodes.MUST_PASS_ARGUMENT,
1755
- "pat_token", "pem_file")
1756
- raise TeradataMlException(message, MessageCodes.MUST_PASS_ARGUMENT)
1757
-
1758
- # Check if pem file exists.
1759
- if pem_file is not None:
1760
- _Validators._validate_file_exists(pem_file)
1761
-
1762
- # Extract the base URL.
1990
+ # Extract the base URL and org id.
1763
1991
  url_parser = urlparse(base_url)
1764
1992
  parsed_base_url = "{}://{}".format(url_parser.scheme, url_parser.netloc)
1765
- netloc = url_parser.netloc.split('.')[0]
1766
-
1767
- # Check if the authentication is PAT based or OAuth.
1768
- if all(arg is None for arg in [pat_token, pem_file]):
1993
+ org_id = url_parser.netloc.split('.')[0]
1994
+
1995
+ # ---------------------------------TOKEN GENERATION------------------------------------------------------
1996
+ # STEP 3: Based on auth_mech, generate authentication token data and store in _InternalBuffer.
1997
+ # Note: auth_mech can be user-provided or can be derived from valid combination of supporting parameters.
1998
+ # --------------------------------------------------------------------------------------------------------
1999
+ if auth_mech:
2000
+ auth_mech = auth_mech.lower()
2001
+ if auth_mech == 'oauth':
2002
+ pat_token = pem_file = password = auth_token = auth_url = None
2003
+ elif auth_mech == 'jwt':
2004
+ pat_token = pem_file = password = client_id = auth_url = None
2005
+ elif auth_mech == 'basic':
2006
+ pat_token = pem_file = auth_token = client_id = auth_url = None
2007
+ elif auth_mech == 'pat':
2008
+ password = client_id = auth_token = auth_url = None
2009
+ elif auth_mech == 'keycloak':
2010
+ pat_token = pem_file = auth_token = client_id = None
2011
+
2012
+ # Validate arguments for mutual exclusiveness.
2013
+ all_groups_none = \
2014
+ _Validators._validate_mutually_exclusive_argument_groups({"client_id": client_id},
2015
+ {"auth_token": auth_token},
2016
+ {"pat_token": pat_token,
2017
+ "pem_file": pem_file},
2018
+ {"password": password} if not auth_url else
2019
+ {"password": password, "auth_url": auth_url},
2020
+ return_all_falsy_status=True)
2021
+
2022
+ # Determine authentication mechanism from availability of supportive arguments.
2023
+ if auth_mech is None:
2024
+ if auth_token:
2025
+ auth_mech = 'jwt'
2026
+ elif any([pat_token, pem_file]):
2027
+ auth_mech = 'pat'
2028
+ elif auth_url:
2029
+ auth_mech = 'keycloak'
2030
+ elif password:
2031
+ # Authentication is done via Basic authentication mechanism
2032
+ # by passing 'basic' field in header.
2033
+ auth_mech = 'basic'
2034
+ # When all supporting arguments are None, default mechanism is OAuth.
2035
+ elif client_id or all_groups_none:
2036
+ auth_mech = 'oauth'
2037
+
2038
+ token_validated = False
2039
+ # Generate and use authentication data as per authentication mechanism.
2040
+ if auth_mech == 'jwt':
2041
+ if not auth_token:
2042
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["auth_token"]),
2043
+ MessageCodes.MISSING_ARGS)
2044
+ # Validate JWT token if base_url points to CCP environment.
2045
+ # TODO: Uncomment when mechanism to validate JWT for AI-On-prem system is available.
2046
+ # if not ues_url:
2047
+ # token_validated = _validate_jwt_token(base_url, auth_token)
2048
+
2049
+ _InternalBuffer.add(auth_token=_AuthToken(token=auth_token,
2050
+ auth_type='bearer'))
2051
+ elif auth_mech == 'oauth':
1769
2052
  configure._oauth = True
1770
- client_id = "{}-oaf-device".format(netloc) if client_id is None else client_id
2053
+ client_id = "{}-oaf-device".format(org_id) if client_id is None else client_id
1771
2054
  da_wf = _DAWorkflow(parsed_base_url, client_id)
1772
2055
  token_data = da_wf._get_token_data()
1773
2056
 
@@ -1777,34 +2060,72 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1777
2060
  configure._auth_token_expiry_time = time() + token_data["expires_in"] - 15
1778
2061
 
1779
2062
  # Store the jwt token in internal class attribute.
1780
- _InternalBuffer.add(auth_token=_AuthToken(token=token_data["access_token"]))
1781
-
1782
- else:
1783
- configure._oauth = False
1784
-
1785
- if username is None:
1786
- # If username is not specified then the database username associated with the current context will be
1787
- # considered.
1788
- username = _get_user()
1789
-
1790
- org_id = netloc
2063
+ _InternalBuffer.add(auth_token=_AuthToken(token=token_data["access_token"],
2064
+ auth_type='bearer'))
2065
+ elif auth_mech == 'pat':
2066
+ if any([pat_token, pem_file]):
2067
+ _Validators._validate_mutually_inclusive_n_arguments(pat_token=pat_token,
2068
+ pem_file=pem_file)
2069
+ else:
2070
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["pat_token", "pem_file"]),
2071
+ MessageCodes.MISSING_ARGS)
2072
+
2073
+ # Check if pem file exists.
2074
+ if pem_file is not None:
2075
+ _Validators._validate_file_exists(pem_file)
2076
+
2077
+ # Generate JWT token.
2078
+ auth_wf = _AuthWorkflow({"base_url": parsed_base_url,
2079
+ "org_id": org_id,
2080
+ "pat_token": pat_token,
2081
+ "pem_file": pem_file,
2082
+ "username": username,
2083
+ "expiration_time": expiration_time,
2084
+ "kid": kid,
2085
+ "valid_from": valid_from})
2086
+ token_data = auth_wf._proxy_jwt()
1791
2087
 
1792
- # Construct a dictionary to be passed to _AuthWorkflow().
1793
- state_dict = {}
1794
- state_dict["base_url"] = parsed_base_url
1795
- state_dict["org_id"] = org_id
1796
- state_dict["pat_token"] = pat_token
1797
- state_dict["pem_file"] = pem_file
1798
- state_dict["username"] = username
1799
- state_dict["expiration_time"] = expiration_time
2088
+ if validate_jwt:
2089
+ # Validate generated JWT token.
2090
+ token_validated = _validate_jwt_token(base_url, token_data)
1800
2091
 
1801
- auth_wf = _AuthWorkflow(state_dict)
1802
- token_data = auth_wf._proxy_jwt()
1803
2092
  # Store the jwt token in internal class attribute.
1804
- _InternalBuffer.add(auth_token=_AuthToken(token=token_data))
1805
- # If set_auth_token is triggered then it will be ccp_enabled = True.
1806
- # The function returns if we have just passed the auth_token, thus
1807
- # having ccp_enabled = False.
1808
- configure._ccp_enabled = True
2093
+ _InternalBuffer.add(auth_token=_AuthToken(token=token_data,
2094
+ auth_type='bearer'))
2095
+ elif auth_mech == 'basic':
2096
+ if not password:
2097
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["password"]),
2098
+ MessageCodes.MISSING_ARGS)
2099
+ credentials = f"{username}:{password}"
2100
+ # Encode the credentials string using Base64.
2101
+ encoded_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
2102
+ # Store the header data in internal class attribute.
2103
+ _InternalBuffer.add(auth_token=_AuthToken(token=encoded_credentials,
2104
+ auth_type='basic'))
2105
+ elif auth_mech == 'keycloak':
2106
+ _Validators._validate_missing_required_arguments([["password", password, False, (str), True],
2107
+ ["auth_url", auth_url, False, (str), True]
2108
+ ])
2109
+ token_generator = _KeycloakManager(auth_url=auth_url,
2110
+ client_id=TDServices[rest_client].value)
2111
+
2112
+ # Store manager object in _InternalBuffer in order to generate token after expiry time.
2113
+ _InternalBuffer.add(keycloak_manager=token_generator)
2114
+ try:
2115
+ token_data = token_generator.generate_token(username=username,
2116
+ password=password)
2117
+ except:
2118
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
2119
+ "set_auth_token",
2120
+ "Failed to generate keycloak token."),
2121
+ MessageCodes.FUNC_EXECUTION_FAILED)
2122
+
2123
+ _InternalBuffer.add(auth_token=_AuthToken(token=token_data,
2124
+ auth_type='keycloak'))
2125
+
2126
+ if token_validated:
2127
+ print("Authentication token is generated, authenticated and set for the session.")
2128
+ else:
2129
+ print("Authentication token is generated and set for the session.")
1809
2130
 
1810
2131
  return True