teradataml 20.0.0.3__py3-none-any.whl → 20.0.0.5__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 (151) hide show
  1. teradataml/LICENSE-3RD-PARTY.pdf +0 -0
  2. teradataml/README.md +193 -1
  3. teradataml/__init__.py +2 -1
  4. teradataml/_version.py +2 -2
  5. teradataml/analytics/analytic_function_executor.py +25 -18
  6. teradataml/analytics/byom/__init__.py +1 -1
  7. teradataml/analytics/json_parser/analytic_functions_argument.py +4 -0
  8. teradataml/analytics/sqle/__init__.py +20 -2
  9. teradataml/analytics/utils.py +15 -1
  10. teradataml/analytics/valib.py +18 -4
  11. teradataml/automl/__init__.py +341 -112
  12. teradataml/automl/autodataprep/__init__.py +471 -0
  13. teradataml/automl/data_preparation.py +84 -42
  14. teradataml/automl/data_transformation.py +69 -33
  15. teradataml/automl/feature_engineering.py +76 -9
  16. teradataml/automl/feature_exploration.py +639 -25
  17. teradataml/automl/model_training.py +35 -14
  18. teradataml/clients/auth_client.py +2 -2
  19. teradataml/common/__init__.py +1 -2
  20. teradataml/common/constants.py +122 -63
  21. teradataml/common/messagecodes.py +14 -3
  22. teradataml/common/messages.py +8 -4
  23. teradataml/common/sqlbundle.py +40 -10
  24. teradataml/common/utils.py +366 -74
  25. teradataml/common/warnings.py +11 -0
  26. teradataml/context/context.py +348 -86
  27. teradataml/data/amazon_reviews_25.csv +26 -0
  28. teradataml/data/apriori_example.json +22 -0
  29. teradataml/data/byom_example.json +11 -0
  30. teradataml/data/docs/byom/docs/DataRobotPredict.py +2 -2
  31. teradataml/data/docs/byom/docs/DataikuPredict.py +40 -1
  32. teradataml/data/docs/byom/docs/H2OPredict.py +2 -2
  33. teradataml/data/docs/byom/docs/ONNXEmbeddings.py +242 -0
  34. teradataml/data/docs/byom/docs/ONNXPredict.py +2 -2
  35. teradataml/data/docs/byom/docs/PMMLPredict.py +2 -2
  36. teradataml/data/docs/sqle/docs_17_20/Apriori.py +138 -0
  37. teradataml/data/docs/sqle/docs_17_20/NERExtractor.py +121 -0
  38. teradataml/data/docs/sqle/docs_17_20/NGramSplitter.py +3 -3
  39. teradataml/data/docs/sqle/docs_17_20/SMOTE.py +212 -0
  40. teradataml/data/docs/sqle/docs_17_20/Shap.py +28 -6
  41. teradataml/data/docs/sqle/docs_17_20/TextMorph.py +119 -0
  42. teradataml/data/docs/sqle/docs_17_20/TextParser.py +54 -3
  43. teradataml/data/docs/uaf/docs_17_20/ACF.py +1 -1
  44. teradataml/data/docs/uaf/docs_17_20/ArimaEstimate.py +2 -2
  45. teradataml/data/docs/uaf/docs_17_20/ArimaXEstimate.py +2 -2
  46. teradataml/data/docs/uaf/docs_17_20/DFFT.py +1 -1
  47. teradataml/data/docs/uaf/docs_17_20/DFFT2.py +1 -1
  48. teradataml/data/docs/uaf/docs_17_20/DFFT2Conv.py +1 -1
  49. teradataml/data/docs/uaf/docs_17_20/DFFTConv.py +1 -1
  50. teradataml/data/docs/uaf/docs_17_20/DWT2D.py +4 -1
  51. teradataml/data/docs/uaf/docs_17_20/FilterFactory1d.py +4 -4
  52. teradataml/data/docs/uaf/docs_17_20/GenseriesSinusoids.py +2 -2
  53. teradataml/data/docs/uaf/docs_17_20/GoldfeldQuandt.py +2 -2
  54. teradataml/data/docs/uaf/docs_17_20/HoltWintersForecaster.py +6 -6
  55. teradataml/data/docs/uaf/docs_17_20/LineSpec.py +1 -1
  56. teradataml/data/docs/uaf/docs_17_20/LinearRegr.py +1 -1
  57. teradataml/data/docs/uaf/docs_17_20/Matrix2Image.py +4 -4
  58. teradataml/data/docs/uaf/docs_17_20/MultivarRegr.py +1 -1
  59. teradataml/data/docs/uaf/docs_17_20/PACF.py +1 -1
  60. teradataml/data/docs/uaf/docs_17_20/PowerSpec.py +2 -2
  61. teradataml/data/docs/uaf/docs_17_20/PowerTransform.py +3 -3
  62. teradataml/data/docs/uaf/docs_17_20/Resample.py +5 -5
  63. teradataml/data/docs/uaf/docs_17_20/SAX.py +3 -3
  64. teradataml/data/docs/uaf/docs_17_20/SignifPeriodicities.py +1 -1
  65. teradataml/data/docs/uaf/docs_17_20/SimpleExp.py +1 -1
  66. teradataml/data/docs/uaf/docs_17_20/Smoothma.py +3 -3
  67. teradataml/data/docs/uaf/docs_17_20/UNDIFF.py +1 -1
  68. teradataml/data/hnsw_alter_data.csv +5 -0
  69. teradataml/data/hnsw_data.csv +10 -0
  70. teradataml/data/jsons/byom/h2opredict.json +1 -1
  71. teradataml/data/jsons/byom/onnxembeddings.json +266 -0
  72. teradataml/data/jsons/sqle/17.20/NGramSplitter.json +6 -6
  73. teradataml/data/jsons/sqle/17.20/TD_Apriori.json +181 -0
  74. teradataml/data/jsons/sqle/17.20/TD_NERExtractor.json +145 -0
  75. teradataml/data/jsons/sqle/17.20/TD_SMOTE.json +267 -0
  76. teradataml/data/jsons/sqle/17.20/TD_Shap.json +0 -1
  77. teradataml/data/jsons/sqle/17.20/TD_TextMorph.json +134 -0
  78. teradataml/data/jsons/sqle/17.20/TD_TextParser.json +114 -9
  79. teradataml/data/jsons/sqle/20.00/AI_AnalyzeSentiment.json +328 -0
  80. teradataml/data/jsons/sqle/20.00/AI_AskLLM.json +420 -0
  81. teradataml/data/jsons/sqle/20.00/AI_DetectLanguage.json +343 -0
  82. teradataml/data/jsons/sqle/20.00/AI_ExtractKeyPhrases.json +328 -0
  83. teradataml/data/jsons/sqle/20.00/AI_MaskPII.json +328 -0
  84. teradataml/data/jsons/sqle/20.00/AI_RecognizeEntities.json +328 -0
  85. teradataml/data/jsons/sqle/20.00/AI_RecognizePIIEntities.json +328 -0
  86. teradataml/data/jsons/sqle/20.00/AI_TextClassifier.json +359 -0
  87. teradataml/data/jsons/sqle/20.00/AI_TextEmbeddings.json +360 -0
  88. teradataml/data/jsons/sqle/20.00/AI_TextSummarize.json +343 -0
  89. teradataml/data/jsons/sqle/20.00/AI_TextTranslate.json +343 -0
  90. teradataml/data/jsons/sqle/20.00/TD_HNSW.json +296 -0
  91. teradataml/data/jsons/sqle/20.00/TD_HNSWPredict.json +206 -0
  92. teradataml/data/jsons/sqle/20.00/TD_HNSWSummary.json +32 -0
  93. teradataml/data/jsons/sqle/20.00/TD_KMeans.json +2 -2
  94. teradataml/data/jsons/sqle/20.00/TD_SMOTE.json +3 -3
  95. teradataml/data/jsons/sqle/20.00/TD_VectorDistance.json +6 -6
  96. teradataml/data/ner_dict.csv +8 -0
  97. teradataml/data/ner_input_eng.csv +7 -0
  98. teradataml/data/ner_rule.csv +5 -0
  99. teradataml/data/pos_input.csv +40 -0
  100. teradataml/data/tdnerextractor_example.json +14 -0
  101. teradataml/data/teradataml_example.json +21 -0
  102. teradataml/data/textmorph_example.json +5 -0
  103. teradataml/data/to_num_data.csv +4 -0
  104. teradataml/data/tochar_data.csv +5 -0
  105. teradataml/data/trans_dense.csv +16 -0
  106. teradataml/data/trans_sparse.csv +55 -0
  107. teradataml/data/vectordistance_example.json +1 -1
  108. teradataml/dataframe/copy_to.py +45 -29
  109. teradataml/dataframe/data_transfer.py +72 -46
  110. teradataml/dataframe/dataframe.py +642 -166
  111. teradataml/dataframe/dataframe_utils.py +167 -22
  112. teradataml/dataframe/functions.py +135 -20
  113. teradataml/dataframe/setop.py +11 -6
  114. teradataml/dataframe/sql.py +330 -78
  115. teradataml/dbutils/dbutils.py +556 -140
  116. teradataml/dbutils/filemgr.py +14 -10
  117. teradataml/hyperparameter_tuner/optimizer.py +12 -1
  118. teradataml/lib/aed_0_1.dll +0 -0
  119. teradataml/opensource/{sklearn/_sklearn_wrapper.py → _base.py} +168 -1013
  120. teradataml/opensource/_class.py +141 -17
  121. teradataml/opensource/{constants.py → _constants.py} +7 -3
  122. teradataml/opensource/_lightgbm.py +52 -53
  123. teradataml/opensource/_sklearn.py +1008 -0
  124. teradataml/opensource/_wrapper_utils.py +5 -5
  125. teradataml/options/__init__.py +47 -15
  126. teradataml/options/configure.py +103 -26
  127. teradataml/options/display.py +13 -2
  128. teradataml/plot/axis.py +47 -8
  129. teradataml/plot/figure.py +33 -0
  130. teradataml/plot/plot.py +63 -13
  131. teradataml/scriptmgmt/UserEnv.py +307 -40
  132. teradataml/scriptmgmt/lls_utils.py +428 -145
  133. teradataml/store/__init__.py +2 -3
  134. teradataml/store/feature_store/feature_store.py +102 -7
  135. teradataml/table_operators/Apply.py +48 -19
  136. teradataml/table_operators/Script.py +23 -2
  137. teradataml/table_operators/TableOperator.py +3 -1
  138. teradataml/table_operators/table_operator_util.py +58 -9
  139. teradataml/utils/dtypes.py +49 -1
  140. teradataml/utils/internal_buffer.py +38 -0
  141. teradataml/utils/validators.py +377 -62
  142. {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/METADATA +200 -4
  143. {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/RECORD +146 -112
  144. teradataml/data/SQL_Fundamentals.pdf +0 -0
  145. teradataml/libaed_0_1.dylib +0 -0
  146. teradataml/libaed_0_1.so +0 -0
  147. teradataml/opensource/sklearn/__init__.py +0 -0
  148. teradataml/store/vector_store/__init__.py +0 -1586
  149. {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/WHEEL +0 -0
  150. {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/top_level.txt +0 -0
  151. {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/zip-safe +0 -0
@@ -10,36 +10,40 @@ 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
27
  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
28
+ from teradataml.common.constants import HTTPRequest, AsyncStatusColumns, AuthMechs
29
+ from teradataml.clients.auth_client import _AuthWorkflow
30
+ from teradataml.clients.pkce_client import _DAWorkflow
31
+ from teradataml.common.constants import (AsyncOpStatus, AsyncStatusColumns,
32
+ HTTPRequest)
27
33
  from teradataml.common.exceptions import TeradataMlException
28
- from teradataml.common.messages import Messages
29
34
  from teradataml.common.messagecodes import MessageCodes
35
+ from teradataml.common.messages import Messages
30
36
  from teradataml.common.utils import UtilFuncs
31
- from teradataml.clients.pkce_client import _DAWorkflow
32
- from teradataml.clients.auth_client import _AuthWorkflow
37
+ from teradataml.context.context import _get_user, get_connection
38
+ from teradataml.scriptmgmt.UserEnv import (UserEnv, _AuthToken,
39
+ _get_auth_token, _get_ues_url,
40
+ _process_ues_response, _get_ccp_url)
41
+ from teradataml.telemetry_utils.queryband import collect_queryband
33
42
  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
43
  from teradataml.utils.utils import _async_run_id_info
42
- from teradataml.telemetry_utils.queryband import collect_queryband
44
+ from teradataml.utils.validators import _Validators
45
+
46
+
43
47
 
44
48
  @collect_queryband(queryband="LstBsEnv")
45
49
  def list_base_envs():
@@ -74,6 +78,11 @@ def list_base_envs():
74
78
  5 r_4.0.2 R 4.0.2
75
79
  >>>
76
80
  """
81
+ # Check if the cache data is available and is not stale.
82
+ # If available, return the data.
83
+ if _InternalBuffer.get('list_base_envs') is not None:
84
+ return _InternalBuffer.get('list_base_envs')
85
+
77
86
  try:
78
87
  response = UtilFuncs._http_request(_get_ues_url("base_environments"), headers=_get_auth_token())
79
88
 
@@ -86,7 +95,8 @@ def list_base_envs():
86
95
  return
87
96
 
88
97
  # Create a pandas DataFrame from data.
89
- return pd.DataFrame.from_records(data)
98
+ _InternalBuffer.add(list_base_envs=pd.DataFrame.from_records(data))
99
+ return _InternalBuffer.get('list_base_envs')
90
100
 
91
101
  except (TeradataMlException, RuntimeError):
92
102
  raise
@@ -191,7 +201,7 @@ def list_user_envs(env_name=None, **kwargs):
191
201
  ... 'python_3.9',
192
202
  ... 'Sales team environment.',
193
203
  ... conda_env=True)
194
- Conda environment creation initiated
204
+ Conda environment creation initiated.
195
205
  User environment 'Sales_cond_env' created.
196
206
 
197
207
  # Example 1: List all available user environments.
@@ -297,7 +307,7 @@ def list_user_envs(env_name=None, **kwargs):
297
307
 
298
308
  try:
299
309
  response = UtilFuncs._http_request(_get_ues_url(), headers=_get_auth_token())
300
- # Below condition is special case handeling when remove_all_envs() used by user, remove_all_envs()
310
+ # Below condition is special case handling when remove_all_envs() used by user, remove_all_envs()
301
311
  # removes all the envs which result in a status_code 404 and due to which warnings provided in
302
312
  # list_user_envs() not appears.
303
313
  if response.status_code == 404 and "No user environments found." in response.text:
@@ -333,7 +343,7 @@ def list_user_envs(env_name=None, **kwargs):
333
343
  # Return the DataFrame if not empty.
334
344
  if len(pandas_df) > 0:
335
345
  return pandas_df
336
-
346
+
337
347
  print("No user environment(s) found.")
338
348
  except (TeradataMlException, RuntimeError):
339
349
  raise
@@ -417,21 +427,20 @@ def __create_envs(template):
417
427
  # Install files if requested any.
418
428
  if files:
419
429
  print("Installing files in environment '{}'...".format(env_name))
420
- try:
421
- if isinstance(files, str):
422
- files = [files]
430
+ if isinstance(files, str):
431
+ files = [files]
423
432
 
424
- for file in files:
433
+ for file in files:
434
+ try:
425
435
  if os.path.isfile(file):
426
436
  env_handle.install_file(file)
427
437
  elif os.path.isdir(file):
428
- __install_files(env_handle, file)
429
- print("File installation in environment '{}' - Completed.".format(env_name))
430
- except Exception as file_installation_failure:
431
- print("Failed to process file installation request for environment: '{}'".format(env_name))
432
- print(str(file_installation_failure))
433
- errored = errored or True
434
- pass
438
+ errored = __install_files(env_handle, file)
439
+ except Exception as file_installation_failure:
440
+ print("Failed to install file '{}' in environment '{}'.".format(file, env_name))
441
+ print(str(file_installation_failure))
442
+ errored = True
443
+ pass
435
444
 
436
445
  # Install libraries if requested any.
437
446
  if libs or libs_file_path:
@@ -446,8 +455,8 @@ def __create_envs(template):
446
455
  except Exception as lib_installation_failure:
447
456
  error_code = MessageCodes.FUNC_EXECUTION_FAILED
448
457
  error_msg = Messages.get_message(error_code,
449
- "'install_lib' request for enviornment: '{}'".format(env_name),
450
- '\n'+str(lib_installation_failure))
458
+ "'install_lib' request for enviornment: '{}'".format(env_name),
459
+ '\n' + str(lib_installation_failure))
451
460
  print(error_msg)
452
461
  errored = errored or True
453
462
  pass
@@ -472,6 +481,10 @@ def __get_default_base_env():
472
481
  Function returns the latest python environment available with
473
482
  Open Analytics Framework.
474
483
  """
484
+ # Check if the default base environment is already available.
485
+ if _InternalBuffer.get('default_base_env') is not None:
486
+ return _InternalBuffer.get('default_base_env')
487
+
475
488
  try:
476
489
  base_envs = list_base_envs()
477
490
  python_versions = base_envs[base_envs.language == 'Python']['version']
@@ -481,7 +494,9 @@ def __get_default_base_env():
481
494
  latest_version_tuple = max(version_tuples)
482
495
  # Convert the latest version tuple back to a string
483
496
  latest_version = '.'.join(map(str, latest_version_tuple))
484
- return base_envs[base_envs.version == latest_version]['base_name'].to_list()[0]
497
+ # Get the base environment name for the latest version
498
+ _InternalBuffer.add(default_base_env=base_envs[base_envs.version == latest_version]['base_name'].to_list()[0])
499
+ return _InternalBuffer.get('default_base_env')
485
500
  except Exception as base_env_err:
486
501
  raise Exception("Failed to obtain default base environment.", str(base_env_err.exception))
487
502
 
@@ -491,9 +506,20 @@ def __install_files(env, directory):
491
506
  Function to install files under given directory and
492
507
  all the subdirectories recursively.
493
508
  """
509
+ errored = False
494
510
  for (dir_path, dir_names, file_names) in os.walk(directory):
511
+ # install the files under all the directories.
512
+ # If any problem with any file installation, skip the error
513
+ # and proceed to install other files.
495
514
  for file_name in file_names:
496
- env.install_file(os.path.join(dir_path, file_name))
515
+ try:
516
+ env.install_file(os.path.join(dir_path, file_name))
517
+ except Exception as file_installation_failure:
518
+ print("Failed to install file '{}' in environment '{}'.".format(file_name, env.env_name))
519
+ print(str(file_installation_failure))
520
+ errored = True
521
+
522
+ return errored
497
523
 
498
524
 
499
525
  @collect_queryband(queryband="CrtEnv")
@@ -725,9 +751,18 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
725
751
  >>> fraud_detection_env = create_env('Fraud_detection_conda',
726
752
  ... 'python_3.8',
727
753
  ... 'Fraud detection through time matching',
728
- conda_env=True)
729
- Conda environment creation initiated
730
- User environment 'Fraud_detection_conda' created.
754
+ ... conda_env=True)
755
+ Conda environment creation initiated.
756
+ User environment 'Fraud_detection_conda' created.
757
+
758
+ # Example 5: Create a Conda R 4.2 environment with given name and
759
+ # description in the Vantage.
760
+ >>> conda_r_env = create_env('conda_r_env',
761
+ ... 'r_4.2',
762
+ ... 'Conda R environment',
763
+ ... conda_env=True)
764
+ Conda environment creation initiated.
765
+ User environment 'conda_r_env' created.
731
766
  """
732
767
 
733
768
  # Either env_name or template can be used.
@@ -751,9 +786,27 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
751
786
  # Get the latest python base env in OpenAF, if base_env is not provided,
752
787
  # Or if base_env is provided and not in the list of base envs.
753
788
  # Note: By default python base env is obtained.
754
- if not base_env or \
755
- (base_env and base_env.lower() not in list_base_envs()['base_name'].str.lower().to_list()):
756
- base_env = __get_default_base_env()
789
+ if configure.ues_url is not None and \
790
+ get_connection() is not None:
791
+ # Check if base_env is provided or not in the list of base envs.
792
+
793
+ # Check if user requested for conda environment but do not specify the base_env.
794
+ # In such case, set base_env to the default python base environment.
795
+ if conda_env:
796
+ if base_env is None:
797
+ base_env = __get_default_base_env()
798
+ # Not a conda environment.
799
+ else:
800
+ # Check if base_env provided or not. If provided, check if it is available in
801
+ # the list of base envs. If not available, set base_env to the default python base env.
802
+ if not base_env or \
803
+ base_env.lower() not in list_base_envs()['base_name'].str.lower().to_list():
804
+ # Print warning message if base_env provided is not available.
805
+ if base_env:
806
+ print(f"Note: The specified base environment '{base_env}' is unavailable. " \
807
+ "Using the default base environment as specified in the documentation.")
808
+ # Set base_env to the default
809
+ base_env = __get_default_base_env()
757
810
  if not desc:
758
811
  desc = "This env '{}' is created with base env '{}'.".format(env_name, base_env)
759
812
  try:
@@ -764,21 +817,25 @@ def create_env(env_name=None, base_env=None, desc=None, template=None, conda_env
764
817
  response = UtilFuncs._http_request(
765
818
  _get_ues_url(conda_env=conda_env), HTTPRequest.POST, headers=_get_auth_token(), json=data)
766
819
 
767
- # UES reponse.
768
- resp = _process_ues_response(api_name="create_env", response=response)
820
+ # Validate UES response.
821
+ _process_ues_response(api_name="create_env", response=response)
769
822
 
770
823
  msg = "User environment '{}' created."
771
824
 
772
825
  if conda_env:
773
- print("Conda environment creation initiated")
826
+ print("Conda environment creation initiated.")
774
827
  # Get claim_id.
775
828
  claim_id = response.json().get("claim_id", "")
776
- # Poll the claim_id status.
829
+
830
+ # Since create_env() for conda environment is internally
831
+ # asynchronous but exposed as synchronous API, keep polling
832
+ # the status of underlying asynchronous operation until
833
+ # it is either successful or errored.
777
834
  __poll_claim_id_status(claim_id, "create_env")
778
835
  print(msg.format(env_name))
779
836
 
780
837
  # Return an instance of class UserEnv.
781
- return UserEnv(env_name, base_env, desc)
838
+ return UserEnv(env_name, base_env, desc, conda_env)
782
839
 
783
840
  except (TeradataMlException, RuntimeError):
784
841
  raise
@@ -815,7 +872,7 @@ def _async_run_status_open_af(claim_id):
815
872
  __get_claim_id_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
816
873
  """
817
874
  # Get the claim id status.
818
- resp_data = __get_status(claim_id)
875
+ resp_data = _get_status(claim_id)
819
876
 
820
877
  desc = _async_run_id_info.get(claim_id, {}).get("description", "Unknown")
821
878
  get_details = lambda data: {AsyncStatusColumns.ADDITIONAL_DETAILS.value:
@@ -831,7 +888,7 @@ def _async_run_status_open_af(claim_id):
831
888
  return [get_details(sub_step) for sub_step in resp_data]
832
889
 
833
890
 
834
- def __get_status(claim_id):
891
+ def _get_status(claim_id):
835
892
  """
836
893
  DESCRIPTION:
837
894
  Internal function to get the status of a claim_id using
@@ -851,7 +908,7 @@ def __get_status(claim_id):
851
908
  None
852
909
 
853
910
  EXAMPLES:
854
- __get_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
911
+ _get_status('278381bf-e3b3-47ff-9ba5-c3b5d9007363')
855
912
  """
856
913
  # Get the claim id status
857
914
  response = UtilFuncs._http_request(_get_ues_url(env_type="fm",
@@ -990,6 +1047,9 @@ def __manage_envs(env_name=None, api_name="remove_env", **kwargs):
990
1047
 
991
1048
  try:
992
1049
  # Get the ues url for corresponding API.
1050
+ # While deleting environment, endpoint UES URL for deleting
1051
+ # normal and conda environment is same, unlike creating
1052
+ # normal and conda environment.
993
1053
  ues_url = _get_ues_url(env_name=env_name, api_name=api_name) if api_name == "remove_env" \
994
1054
  else _get_ues_url(remove_all_envs=True, api_name=api_name)
995
1055
 
@@ -1008,7 +1068,7 @@ def __manage_envs(env_name=None, api_name="remove_env", **kwargs):
1008
1068
  if api_name == "remove_env":
1009
1069
  msg = "{2}list_user_envs(). If environment is not removed, " \
1010
1070
  "check the status of asynchronous call using" \
1011
- " async_run_status('{1}') or get_env('{0}').status('{1}')".\
1071
+ " async_run_status('{1}') or get_env('{0}').status('{1}')". \
1012
1072
  format(env_name, claim_id, msg)
1013
1073
  else:
1014
1074
  msg = "{0}async_run_status('{1}')".format(msg, claim_id)
@@ -1053,30 +1113,37 @@ def __poll_claim_id_status(claim_id, api_name="remove_env"):
1053
1113
  Default Value: remove_env
1054
1114
  Types: str
1055
1115
 
1056
-
1057
-
1058
1116
  RETURNS:
1059
1117
  None.
1060
1118
 
1061
1119
  RAISES:
1062
- None.
1120
+ TeradataMlException
1063
1121
 
1064
1122
  EXAMPLES:
1065
1123
  __poll_claim_id_status('cf7245f0-e962-4451-addf-efa7e123998d')
1066
1124
  """
1125
+ err_details = None
1067
1126
  while True:
1068
1127
  sleep(2)
1069
1128
 
1070
1129
  # Poll the claim id to get the status.
1071
- resp_data = __get_status(claim_id)
1130
+ resp_data = _get_status(claim_id)
1072
1131
 
1073
1132
  # Breaking condition -
1074
1133
  # For create_env and remove_env: Check for the 'Finished' stage in the list of resp.
1075
1134
  # For remove_all_envs: above cond. and No user envs condition should break it .
1076
1135
  for data in resp_data:
1077
- if ("Finished" in data["stage"]) or \
1078
- (api_name in ["create_env", "remove_all_envs"] and "Errored" in data["stage"]):
1136
+ if AsyncOpStatus.FINISHED.value in data["stage"]:
1079
1137
  return
1138
+ elif AsyncOpStatus.ERRED.value in data["stage"]:
1139
+ err_details = data["details"]
1140
+ break
1141
+ if err_details:
1142
+ break
1143
+
1144
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1145
+ api_name, err_details),
1146
+ MessageCodes.FUNC_EXECUTION_FAILED)
1080
1147
 
1081
1148
 
1082
1149
  @collect_queryband(queryband="GtEnv")
@@ -1151,7 +1218,9 @@ def get_env(env_name):
1151
1218
  # Return an instance of class UserEnv.
1152
1219
  return UserEnv(userenv_row.env_name.values[0],
1153
1220
  userenv_row.base_env_name.values[0],
1154
- userenv_row.env_description.values[0])
1221
+ userenv_row.env_description.values[0],
1222
+ userenv_row.conda.values[0]
1223
+ )
1155
1224
  except (TeradataMlException, RuntimeError) as tdemsg:
1156
1225
  # TeradataMlException and RuntimeError are raised by list_user_envs.
1157
1226
  # list_user_envs should be replaced with get_env in the error
@@ -1406,7 +1475,7 @@ def _remove_all_envs(env_type, **kwargs):
1406
1475
  if env_type.capitalize() == "Py":
1407
1476
  env_type = ["Python", "python"]
1408
1477
  else:
1409
- env_type = ["R"]
1478
+ env_type = ["R", "r"]
1410
1479
  env_type_message = "R"
1411
1480
  asynchronous = kwargs.get("asynchronous", False)
1412
1481
 
@@ -1445,7 +1514,7 @@ def _remove_all_envs(env_type, **kwargs):
1445
1514
  if len(failed_envs) > 0:
1446
1515
  emsg = ""
1447
1516
  for env, tdemsg in failed_envs.items():
1448
- emsg += "\nUser environment '{0}' failed to remove. Reason: {1}"\
1517
+ emsg += "\nUser environment '{0}' failed to remove. Reason: {1}" \
1449
1518
  .format(env, tdemsg.args[0])
1450
1519
  msg_code = MessageCodes.FUNC_EXECUTION_FAILED
1451
1520
  error_msg = Messages.get_message(msg_code, "remove_all_envs()", emsg)
@@ -1558,30 +1627,94 @@ def get_user_env():
1558
1627
  return configure._default_user_env
1559
1628
 
1560
1629
 
1561
- @collect_queryband(queryband="StAthTkn")
1562
- @argument_deprecation("20.00.00.04", "ues_url", False, "base_url")
1563
- def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None, **kwargs):
1630
+ def _validate_jwt_token(base_url, token_data):
1564
1631
  """
1565
1632
  DESCRIPTION:
1566
- Function to set the Authentication token to connect to User Environment Service
1567
- in VantageCloud Lake.
1568
- Note:
1569
- User must have a privilege to login with a NULL password to use set_auth_token().
1570
- Please refer to GRANT LOGON section in Teradata Documentation for more details.
1571
- If ues_url and client_id are specified then authentication is through OAuth.
1572
- If ues_url, pat_token, pem_file are specified then authentication is through PAT.
1573
- Refresh token still works but only for OAuth authentication.
1633
+ Function to validate the authentication token generated using PAT and PEM file.
1574
1634
 
1575
1635
  PARAMETERS:
1576
-
1577
- ues_url:
1636
+ base_url:
1578
1637
  Required Argument.
1579
- Specifies the URL for User Environment Service in VantageCloud Lake.
1638
+ Specifies the endpoint URL for a given environment on VantageCloud Lake.
1580
1639
  Types: str
1581
1640
 
1641
+ token_data:
1642
+ Required Argument.
1643
+ Specifies the JWT token to be authenticated.
1644
+
1645
+ RETURNS:
1646
+ Boolan flag representing validation status.
1647
+ * True: Indicates that token is valid.
1648
+ * None: Indicates that token is not validated.
1649
+
1650
+ RAISES:
1651
+ TeradataMlException
1652
+
1653
+ EXAMPLES:
1654
+ Example 1: Validate JWT token.
1655
+ >>> _validate_jwt_token(base_url, token_data)
1656
+
1657
+ """
1658
+ # Extract environment id from base_url.
1659
+ try:
1660
+ url_parser = urlparse(base_url)
1661
+ env_id = url_parser.path.split("accounts/")[1].split("/")[0]
1662
+ if not env_id:
1663
+ raise
1664
+ except Exception:
1665
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1666
+ "set_auth_token",
1667
+ "Use valid value for 'base_url'"),
1668
+ MessageCodes.FUNC_EXECUTION_FAILED)
1669
+
1670
+ valid_token = None
1671
+ try:
1672
+ response = UtilFuncs._http_request(url="{}/{}/{}/{}".format(_get_ccp_url(base_url),
1673
+ "api", "accounts", env_id),
1674
+ method_type=HTTPRequest.GET,
1675
+ headers={"Authorization": "Bearer {}".format(token_data)})
1676
+ if 200 <= response.status_code < 300: # Authorized access.
1677
+ valid_token = True
1678
+ elif 400 <= response.status_code < 500: # Unauthorized access.
1679
+ valid_token = False
1680
+ except:
1681
+ pass
1682
+
1683
+ if valid_token is False:
1684
+ raise TeradataMlException(Messages.get_message(MessageCodes.FUNC_EXECUTION_FAILED,
1685
+ "set_auth_token",
1686
+ "Use valid values for input arguments ['base_url',"
1687
+ " 'pat_token', 'pem_file']."),
1688
+ MessageCodes.FUNC_EXECUTION_FAILED)
1689
+ return valid_token
1690
+
1691
+
1692
+ @collect_queryband(queryband="StAthTkn")
1693
+ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None, **kwargs):
1694
+ """
1695
+ DESCRIPTION:
1696
+ Function to set the authentication token required to access services running on
1697
+ Teradata Vantage.
1698
+ Notes:
1699
+ * User must have a privilege to login with a NULL password to use set_auth_token().
1700
+ Refer to GRANT LOGON section in Teradata Documentation for more details.
1701
+ * When "auth_mech" is not specified, arguments are used in the following combination
1702
+ to derive authentication mechanism.
1703
+ * If "base_url" and "client_id" are specified then token generation is done through OAuth.
1704
+ * If "base_url", "pat_token", "pem_file" are specified then token generation is done using PAT.
1705
+ * If "base_url", "username" and "password" are specified then authentication is done via
1706
+ Basic authentication mechanism using user credentials.
1707
+ * If "base_url" and "auth_token" are specified then readily available token is used.
1708
+ * If only "base_url" is specified then token generation is done through OAuth.
1709
+ * Refresh token works only for OAuth authentication.
1710
+ * Use the argument "kid" only when key used during the pem file generation is different
1711
+ from pem file name. For example, if you use the key as 'key1' while generating pem file
1712
+ and the name of the pem file is `key1(1).pem`, then pass value 'key1' to the argument "kid".
1713
+
1714
+ PARAMETERS:
1582
1715
  base_url:
1583
1716
  Required Argument.
1584
- Specifies the CCP endpoint URL.
1717
+ Specifies the endpoint URL for a given environment on Teradata Vantage system.
1585
1718
  Types: str
1586
1719
 
1587
1720
  client_id:
@@ -1598,33 +1731,68 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1598
1731
  pem_file:
1599
1732
  Required, if PAT authentication is to be used, optional otherwise.
1600
1733
  Specifies the path to private key file which is generated from VantageCloud Lake Console.
1734
+ Note:
1735
+ Teradata recommends not to change the name of the file generated from VantageCloud Lake
1736
+ Console. If the name of the file is changed, then authentication token generated from
1737
+ this function will not work.
1601
1738
  Types: str
1602
1739
 
1603
1740
  **kwargs:
1604
1741
  username:
1742
+ Optional Argument.
1605
1743
  Specifies the user for which authentication is to be requested.
1606
1744
  If not specified, then user associated with current connection is used.
1607
- Note:
1608
- 1. Use this option only if name of the database username has lower case letters.
1609
- 2. This option is used only for PAT and not for OAuth.
1745
+ Notes:
1746
+ * Use this option only if name of the database username has lowercase letters.
1747
+ * This option is used only for PAT and not for OAuth.
1610
1748
  Types: str
1611
1749
 
1612
1750
  expiration_time:
1613
- Specifies the expiration time of the token in seconds. After expiry time JWT token expires and
1614
- UserEnv methods does not work, user should regenerate the token.
1751
+ Optional Argument.
1752
+ Specifies the expiration time of the token in seconds. After expiry time, JWT
1753
+ token expires and UserEnv methods does not work, user should regenerate the token.
1615
1754
  Note:
1616
- This option is used only for PAT and not for OAuth.
1755
+ * This option is used only for PAT and not for OAuth.
1617
1756
  Default Value: 31536000
1618
1757
  Types: int
1619
1758
 
1620
1759
  auth_token:
1621
- Optional Parameter.
1622
- Specifies the authentication token to connect to VantageCloud Lake.
1760
+ Optional Argument.
1761
+ Specifies the authentication token required to access services running
1762
+ on Teradata Vantage.
1623
1763
  Notes:
1624
- * if "auth_token" is set through this function, then this function
1625
- should always be used only after create_context.
1626
- * use this option only if user has got JWT token and wants to set the same
1627
- instead of generating it again from this function.
1764
+ * If "auth_token" is set through this function, then this function
1765
+ should always be used only after create_context().
1766
+ * Use this option only if user has got JWT token and wants to set
1767
+ the same instead of generating it again from this function.
1768
+
1769
+ Types: str
1770
+
1771
+ kid:
1772
+ Optional Argument.
1773
+ Specifies the name of the key which is used while generating 'pem_file'.
1774
+ Types: str
1775
+
1776
+ password:
1777
+ Optional Argument.
1778
+ Specifies the password for database user to be used for Basic authentication.
1779
+ Types: str
1780
+
1781
+ auth_mech:
1782
+ Optional Argument.
1783
+ Specifies the mechanism to be used for generating authentication token.
1784
+ Note:
1785
+ * When "auth_mech" is provided, other arguments are used in the following
1786
+ combination as per value of "auth_mech":
1787
+ * OAuth: Token generation is done through OAuth by using client id
1788
+ which can be sepcified by user in "client_id" argument or
1789
+ can be derived internally from "base_url".
1790
+ * PAT : Token generation is done using "pat_token" and "pem_file".
1791
+ * BASIC: Authentication is done via Basic authentication mechanism
1792
+ using user credentials passed in "username" and "password"
1793
+ arguments.
1794
+ * JWT : Readily available token in "auth_token" argument is used.
1795
+ Permitted Values: "OAuth", "PAT", "BASIC", "JWT".
1628
1796
  Types: str
1629
1797
 
1630
1798
  RETURNS:
@@ -1638,10 +1806,14 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1638
1806
  # Example 1: Set the Authentication token using default client_id.
1639
1807
  >>> import getpass
1640
1808
  >>> set_auth_token(base_url=getpass.getpass("ues_url : "))
1809
+ Authentication token is generated and set for the session.
1810
+ True
1641
1811
 
1642
1812
  # Example 2: Set the Authentication token by specifying the client_id.
1643
1813
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1644
1814
  ... client_id=getpass.getpass("client_id : "))
1815
+ Authentication token is generated and set for the session.
1816
+ True
1645
1817
 
1646
1818
  # Example 3: Set the Authentication token by specifying the "pem_file" and "pat_token"
1647
1819
  # without specifying "username".
@@ -1649,6 +1821,7 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1649
1821
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1650
1822
  ... pat_token=getpass.getpass("pat_token : "),
1651
1823
  ... pem_file=getpass.getpass("pem_file : "))
1824
+ Authentication token is generated, authenticated and set for the session.
1652
1825
  True
1653
1826
 
1654
1827
  # Example 4: Set the Authentication token by specifying the "pem_file" and "pat_token"
@@ -1656,85 +1829,175 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1656
1829
  >>> import getpass
1657
1830
  >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1658
1831
  ... pat_token=getpass.getpass("pat_token : "),
1659
- ... pem_file=getpass.getpass("pem_file : "))
1660
- ... username = "alice")
1832
+ ... pem_file=getpass.getpass("pem_file : "),
1833
+ ... username=getpass.getpass("username : "))
1834
+ Authentication token is generated, authenticated and set for the session.
1661
1835
  True
1836
+
1837
+ # Example 5: Set the Authentication token by specifying the "pem_file" and "pat_token"
1838
+ # and "kid".
1839
+ >>> import getpass
1840
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1841
+ ... pat_token=getpass.getpass("pat_token : "),
1842
+ ... pem_file=getpass.getpass("pem_file : ")
1843
+ ... kid="key1")
1844
+ Authentication token is generated, authenticated and set for the session.
1845
+ True
1846
+
1847
+ # Example 6: Set the authentication token via Basic Authentication mechanism by
1848
+ # specifying the "base_url", "username" and "password".
1849
+ >>> import getpass
1850
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1851
+ ... username=getpass.getpass("username : "),
1852
+ ... password=getpass.getpass("password : "))
1853
+ Authentication token is generated and set for the session.
1854
+ True
1855
+
1856
+ # Example 7: Set the authentication token for by specifying "base_url" and
1857
+ # "auth_mech" as "OAuth".
1858
+ >>> import getpass
1859
+ >>> set_auth_token(base_url=getpass.getpass("base_url : "),
1860
+ ... auth_mech="OAuth")
1861
+ Authentication token is generated and set for the session.
1862
+ True
1863
+
1662
1864
  """
1865
+
1663
1866
  # Deriving global connection using get_connection().
1664
- con = get_connection()
1665
- if con is None:
1666
- raise TeradataMlException(Messages.get_message(MessageCodes.INVALID_CONTEXT_CONNECTION),
1867
+ if get_connection() is None:
1868
+ raise TeradataMlException(Messages.get_message(MessageCodes.INVALID_CONTEXT_CONNECTION),
1667
1869
  MessageCodes.INVALID_CONTEXT_CONNECTION)
1668
1870
 
1669
- # Getting the ues_url.
1670
- ues_url = kwargs.get("ues_url", None)
1871
+ # Remove keys from _InternalBuffer which are interrelated to base_url and authentication token.
1872
+ _InternalBuffer.remove_keys(['list_base_envs', 'default_base_env',
1873
+ 'vs_session_id', 'vs_header'])
1671
1874
 
1875
+ # ---------------------------------ARGUMENT VALIDATION------------------------------------------------------
1876
+ # STEP 1: Validate arguments for allowed types.
1877
+ # ----------------------------------------------------------------------------------------------------------
1672
1878
  __arg_info_matrix = []
1673
1879
  __arg_info_matrix.append(["base_url", base_url, True, (str), True])
1674
- __arg_info_matrix.append(["ues_url", ues_url, True, (str), True])
1675
1880
  __arg_info_matrix.append(["client_id", client_id, True, (str), True])
1676
1881
  __arg_info_matrix.append(["pat_token", pat_token, True, (str), True])
1677
1882
  __arg_info_matrix.append(["pem_file", pem_file, True, (str), True])
1678
1883
 
1679
- username = kwargs.get("username", None)
1884
+ # Get keyword arguments.
1885
+ ues_url = kwargs.get("ues_url", None)
1886
+ __arg_info_matrix.append(["ues_url", ues_url, True, (str), True])
1887
+
1888
+ username = kwargs.get("username", _get_user())
1680
1889
  __arg_info_matrix.append((["username", username, True, (str), True]))
1681
1890
 
1891
+ password = kwargs.get("password", None)
1892
+ __arg_info_matrix.append(["password", password, True, (str), True])
1893
+
1682
1894
  auth_token = kwargs.get("auth_token")
1683
1895
  __arg_info_matrix.append((["auth_token", auth_token, True, (str), True]))
1684
1896
 
1685
1897
  expiration_time = kwargs.get("expiration_time", 31536000)
1686
1898
  __arg_info_matrix.append((["expiration_time", expiration_time, True, (int), True]))
1687
1899
 
1900
+ kid = kwargs.get("kid")
1901
+ __arg_info_matrix.append((["kid", kid, True, (str), True]))
1902
+
1903
+ auth_mech = kwargs.get("auth_mech", None)
1904
+ __arg_info_matrix.append((["auth_mech", auth_mech, True, (str), True, [mech.value for mech in AuthMechs]]))
1905
+
1688
1906
  # Validate arguments.
1689
1907
  _Validators._validate_function_arguments(__arg_info_matrix)
1690
1908
 
1909
+ # ---------------------------------BASE_URL PROCESSING------------------------------------------------------
1910
+ # STEP 2: Process base_url/ues_url and set applicable config options.
1911
+ # ----------------------------------------------------------------------------------------------------------
1912
+
1691
1913
  # base_url should not end with 'open-analytics' or 'data-insights'
1692
1914
  if base_url:
1693
1915
  if base_url.endswith('open-analytics') or base_url.endswith('data-insights'):
1694
1916
  message = Messages.get_message(MessageCodes.ARG_NONE,
1695
- "base_url", "ending with 'data-insights' or 'open-analytics", None)
1917
+ "base_url", "ending with 'data-insights' or 'open-analytics", "")
1696
1918
  raise TeradataMlException(message, MessageCodes.ARG_NONE)
1697
1919
 
1698
1920
  # Set the vector_store_base_url. This should only be done if base_url is set.
1699
1921
  # In case ues_url is set, vector_store_base_url should not be set.
1700
1922
  configure._vector_store_base_url = f'{base_url}/data-insights'
1701
1923
 
1924
+ if ues_url:
1925
+ # If incorrectly formatted UES service URL is passed, set it to None
1926
+ # and let further validation raise error.
1927
+ if not (ues_url.endswith('open-analytics') or ues_url.endswith('user-environment-service/api/v1/')):
1928
+ ues_url = None
1929
+
1702
1930
  # If ues_url is provided, then use it as base_url.
1703
- base_url = kwargs.get("ues_url", base_url)
1931
+ base_url = ues_url if ues_url else base_url
1932
+
1933
+ if not (base_url or ues_url):
1934
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["base_url"]),
1935
+ MessageCodes.MISSING_ARGS)
1704
1936
 
1705
1937
  # Set the OpenAF url.
1706
- # If ues_url is present use that otherwise generate it from base_url.
1938
+ # If ues_url is present, then use that otherwise generate it from base_url.
1707
1939
  configure.ues_url = ues_url if ues_url else f'{base_url}/open-analytics'
1708
1940
 
1709
- # If user pass Auth token, set it.
1710
- if auth_token:
1711
- _InternalBuffer.add(auth_token=_AuthToken(token=auth_token))
1712
- return True
1713
-
1714
- if client_id and any([pat_token, pem_file]):
1715
- message = Messages.get_message(MessageCodes.EITHER_THIS_OR_THAT_ARGUMENT,
1716
- "client_id", "pat_token' and 'pem_file")
1717
- raise TeradataMlException(message, MessageCodes.EITHER_THIS_OR_THAT_ARGUMENT)
1718
-
1719
- if client_id is None:
1720
- if (pat_token and pem_file is None) or (pem_file and pat_token is None):
1721
- message = Messages.get_message(MessageCodes.MUST_PASS_ARGUMENT,
1722
- "pat_token", "pem_file")
1723
- raise TeradataMlException(message, MessageCodes.MUST_PASS_ARGUMENT)
1724
-
1725
- # Check if pem file exists.
1726
- if pem_file is not None:
1727
- _Validators._validate_file_exists(pem_file)
1728
-
1729
- # Extract the base URL.
1941
+ # Extract the base URL and org id.
1730
1942
  url_parser = urlparse(base_url)
1731
1943
  parsed_base_url = "{}://{}".format(url_parser.scheme, url_parser.netloc)
1732
- netloc = url_parser.netloc.split('.')[0]
1733
-
1734
- # Check if the authentication is PAT based or OAuth.
1735
- if all(arg is None for arg in [pat_token, pem_file]):
1944
+ org_id = url_parser.netloc.split('.')[0]
1945
+
1946
+ # ---------------------------------TOKEN GENERATION------------------------------------------------------
1947
+ # STEP 3: Based on auth_mech, generate authentication token data and store in _InternalBuffer.
1948
+ # Note: auth_mech can be user-provided or can be derived from valid combination of supporting parameters.
1949
+ # --------------------------------------------------------------------------------------------------------
1950
+ if auth_mech:
1951
+ auth_mech = auth_mech.lower()
1952
+ if auth_mech == 'oauth':
1953
+ pat_token = pem_file = password = auth_token = None
1954
+ elif auth_mech == 'jwt':
1955
+ pat_token = pem_file = password = client_id = None
1956
+ elif auth_mech == 'basic':
1957
+ pat_token = pem_file = auth_token = client_id = None
1958
+ elif auth_mech == 'pat':
1959
+ password = client_id = auth_token = None
1960
+
1961
+ # Validate arguments for mutual exclusiveness.
1962
+ all_groups_none = \
1963
+ _Validators._validate_mutually_exclusive_argument_groups({"client_id": client_id},
1964
+ {"auth_token": auth_token},
1965
+ {"pat_token": pat_token,
1966
+ "pem_file": pem_file},
1967
+ {"password": password},
1968
+ return_all_falsy_status=True)
1969
+
1970
+ # Determine authentication mechanism from availability of supportive arguments.
1971
+ if auth_mech is None:
1972
+ if auth_token:
1973
+ auth_mech = 'jwt'
1974
+ elif any([pat_token, pem_file]):
1975
+ auth_mech = 'pat'
1976
+ elif password:
1977
+ # Authentication is done via Basic authentication mechanism
1978
+ # by passing 'basic' field in header.
1979
+ auth_mech = 'basic'
1980
+ # When all supporting arguments are None, default mechanism is OAuth.
1981
+ elif client_id or all_groups_none:
1982
+ auth_mech = 'oauth'
1983
+
1984
+ token_validated = False
1985
+ # Generate and use authentication data as per authentication mechanism.
1986
+ if auth_mech == 'jwt':
1987
+ if not auth_token:
1988
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["auth_token"]),
1989
+ MessageCodes.MISSING_ARGS)
1990
+ # Validate JWT token if base_url points to CCP environment.
1991
+ # TODO: Uncomment when mechanism to validate JWT for AI-On-prem system is available.
1992
+ # if not ues_url:
1993
+ # token_validated = _validate_jwt_token(base_url, auth_token)
1994
+
1995
+ _InternalBuffer.add(auth_token=_AuthToken(token=auth_token,
1996
+ auth_type='bearer'))
1997
+ elif auth_mech == 'oauth':
1998
+ # TODO: Finalize need to set this flag to False in other scenarios.
1736
1999
  configure._oauth = True
1737
- client_id = "{}-oaf-device".format(netloc) if client_id is None else client_id
2000
+ client_id = "{}-oaf-device".format(org_id) if client_id is None else client_id
1738
2001
  da_wf = _DAWorkflow(parsed_base_url, client_id)
1739
2002
  token_data = da_wf._get_token_data()
1740
2003
 
@@ -1744,30 +2007,50 @@ def set_auth_token(base_url=None, client_id=None, pat_token=None, pem_file=None,
1744
2007
  configure._auth_token_expiry_time = time() + token_data["expires_in"] - 15
1745
2008
 
1746
2009
  # Store the jwt token in internal class attribute.
1747
- _InternalBuffer.add(auth_token=_AuthToken(token=token_data["access_token"]))
1748
-
1749
- else:
1750
- configure._oauth = False
1751
-
1752
- if username is None:
1753
- # If username is not specified then the database username associated with the current context will be
1754
- # considered.
1755
- username = _get_user()
1756
-
1757
- org_id = netloc
2010
+ _InternalBuffer.add(auth_token=_AuthToken(token=token_data["access_token"],
2011
+ auth_type='bearer'))
2012
+ elif auth_mech == 'pat':
2013
+ if any([pat_token, pem_file]):
2014
+ _Validators._validate_mutually_inclusive_n_arguments(pat_token=pat_token,
2015
+ pem_file=pem_file)
2016
+ else:
2017
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["pat_token", "pem_file"]),
2018
+ MessageCodes.MISSING_ARGS)
2019
+
2020
+ # Check if pem file exists.
2021
+ if pem_file is not None:
2022
+ _Validators._validate_file_exists(pem_file)
2023
+
2024
+ # Generate JWT token.
2025
+ auth_wf = _AuthWorkflow({"base_url": parsed_base_url,
2026
+ "org_id": org_id,
2027
+ "pat_token": pat_token,
2028
+ "pem_file": pem_file,
2029
+ "username": username,
2030
+ "expiration_time": expiration_time,
2031
+ "kid": kid})
2032
+ token_data = auth_wf._proxy_jwt()
1758
2033
 
1759
- # Construct a dictionary to be passed to _AuthWorkflow().
1760
- state_dict = {}
1761
- state_dict["base_url"] = parsed_base_url
1762
- state_dict["org_id"] = org_id
1763
- state_dict["pat_token"] = pat_token
1764
- state_dict["pem_file"] = pem_file
1765
- state_dict["username"] = username
1766
- state_dict["expiration_time"] = expiration_time
2034
+ # Validate generated JWT token.
2035
+ token_validated = _validate_jwt_token(base_url, token_data)
1767
2036
 
1768
- auth_wf = _AuthWorkflow(state_dict)
1769
- token_data = auth_wf._proxy_jwt()
1770
2037
  # Store the jwt token in internal class attribute.
1771
- _InternalBuffer.add(auth_token=_AuthToken(token=token_data))
2038
+ _InternalBuffer.add(auth_token=_AuthToken(token=token_data,
2039
+ auth_type='bearer'))
2040
+ elif auth_mech == 'basic':
2041
+ if not password:
2042
+ raise TeradataMlException(Messages.get_message(MessageCodes.MISSING_ARGS, ["password"]),
2043
+ MessageCodes.MISSING_ARGS)
2044
+ credentials = f"{username}:{password}"
2045
+ # Encode the credentials string using Base64.
2046
+ encoded_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
2047
+ # Store the header data in internal class attribute.
2048
+ _InternalBuffer.add(auth_token=_AuthToken(token=encoded_credentials,
2049
+ auth_type='basic'))
2050
+
2051
+ if token_validated:
2052
+ print("Authentication token is generated, authenticated and set for the session.")
2053
+ else:
2054
+ print("Authentication token is generated and set for the session.")
1772
2055
 
1773
2056
  return True