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.
- teradataml/LICENSE-3RD-PARTY.pdf +0 -0
- teradataml/README.md +193 -1
- teradataml/__init__.py +2 -1
- teradataml/_version.py +2 -2
- teradataml/analytics/analytic_function_executor.py +25 -18
- teradataml/analytics/byom/__init__.py +1 -1
- teradataml/analytics/json_parser/analytic_functions_argument.py +4 -0
- teradataml/analytics/sqle/__init__.py +20 -2
- teradataml/analytics/utils.py +15 -1
- teradataml/analytics/valib.py +18 -4
- teradataml/automl/__init__.py +341 -112
- teradataml/automl/autodataprep/__init__.py +471 -0
- teradataml/automl/data_preparation.py +84 -42
- teradataml/automl/data_transformation.py +69 -33
- teradataml/automl/feature_engineering.py +76 -9
- teradataml/automl/feature_exploration.py +639 -25
- teradataml/automl/model_training.py +35 -14
- teradataml/clients/auth_client.py +2 -2
- teradataml/common/__init__.py +1 -2
- teradataml/common/constants.py +122 -63
- teradataml/common/messagecodes.py +14 -3
- teradataml/common/messages.py +8 -4
- teradataml/common/sqlbundle.py +40 -10
- teradataml/common/utils.py +366 -74
- teradataml/common/warnings.py +11 -0
- teradataml/context/context.py +348 -86
- teradataml/data/amazon_reviews_25.csv +26 -0
- teradataml/data/apriori_example.json +22 -0
- teradataml/data/byom_example.json +11 -0
- teradataml/data/docs/byom/docs/DataRobotPredict.py +2 -2
- teradataml/data/docs/byom/docs/DataikuPredict.py +40 -1
- teradataml/data/docs/byom/docs/H2OPredict.py +2 -2
- teradataml/data/docs/byom/docs/ONNXEmbeddings.py +242 -0
- teradataml/data/docs/byom/docs/ONNXPredict.py +2 -2
- teradataml/data/docs/byom/docs/PMMLPredict.py +2 -2
- teradataml/data/docs/sqle/docs_17_20/Apriori.py +138 -0
- teradataml/data/docs/sqle/docs_17_20/NERExtractor.py +121 -0
- teradataml/data/docs/sqle/docs_17_20/NGramSplitter.py +3 -3
- teradataml/data/docs/sqle/docs_17_20/SMOTE.py +212 -0
- teradataml/data/docs/sqle/docs_17_20/Shap.py +28 -6
- teradataml/data/docs/sqle/docs_17_20/TextMorph.py +119 -0
- teradataml/data/docs/sqle/docs_17_20/TextParser.py +54 -3
- teradataml/data/docs/uaf/docs_17_20/ACF.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/ArimaEstimate.py +2 -2
- teradataml/data/docs/uaf/docs_17_20/ArimaXEstimate.py +2 -2
- teradataml/data/docs/uaf/docs_17_20/DFFT.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/DFFT2.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/DFFT2Conv.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/DFFTConv.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/DWT2D.py +4 -1
- teradataml/data/docs/uaf/docs_17_20/FilterFactory1d.py +4 -4
- teradataml/data/docs/uaf/docs_17_20/GenseriesSinusoids.py +2 -2
- teradataml/data/docs/uaf/docs_17_20/GoldfeldQuandt.py +2 -2
- teradataml/data/docs/uaf/docs_17_20/HoltWintersForecaster.py +6 -6
- teradataml/data/docs/uaf/docs_17_20/LineSpec.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/LinearRegr.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/Matrix2Image.py +4 -4
- teradataml/data/docs/uaf/docs_17_20/MultivarRegr.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/PACF.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/PowerSpec.py +2 -2
- teradataml/data/docs/uaf/docs_17_20/PowerTransform.py +3 -3
- teradataml/data/docs/uaf/docs_17_20/Resample.py +5 -5
- teradataml/data/docs/uaf/docs_17_20/SAX.py +3 -3
- teradataml/data/docs/uaf/docs_17_20/SignifPeriodicities.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/SimpleExp.py +1 -1
- teradataml/data/docs/uaf/docs_17_20/Smoothma.py +3 -3
- teradataml/data/docs/uaf/docs_17_20/UNDIFF.py +1 -1
- teradataml/data/hnsw_alter_data.csv +5 -0
- teradataml/data/hnsw_data.csv +10 -0
- teradataml/data/jsons/byom/h2opredict.json +1 -1
- teradataml/data/jsons/byom/onnxembeddings.json +266 -0
- teradataml/data/jsons/sqle/17.20/NGramSplitter.json +6 -6
- teradataml/data/jsons/sqle/17.20/TD_Apriori.json +181 -0
- teradataml/data/jsons/sqle/17.20/TD_NERExtractor.json +145 -0
- teradataml/data/jsons/sqle/17.20/TD_SMOTE.json +267 -0
- teradataml/data/jsons/sqle/17.20/TD_Shap.json +0 -1
- teradataml/data/jsons/sqle/17.20/TD_TextMorph.json +134 -0
- teradataml/data/jsons/sqle/17.20/TD_TextParser.json +114 -9
- teradataml/data/jsons/sqle/20.00/AI_AnalyzeSentiment.json +328 -0
- teradataml/data/jsons/sqle/20.00/AI_AskLLM.json +420 -0
- teradataml/data/jsons/sqle/20.00/AI_DetectLanguage.json +343 -0
- teradataml/data/jsons/sqle/20.00/AI_ExtractKeyPhrases.json +328 -0
- teradataml/data/jsons/sqle/20.00/AI_MaskPII.json +328 -0
- teradataml/data/jsons/sqle/20.00/AI_RecognizeEntities.json +328 -0
- teradataml/data/jsons/sqle/20.00/AI_RecognizePIIEntities.json +328 -0
- teradataml/data/jsons/sqle/20.00/AI_TextClassifier.json +359 -0
- teradataml/data/jsons/sqle/20.00/AI_TextEmbeddings.json +360 -0
- teradataml/data/jsons/sqle/20.00/AI_TextSummarize.json +343 -0
- teradataml/data/jsons/sqle/20.00/AI_TextTranslate.json +343 -0
- teradataml/data/jsons/sqle/20.00/TD_HNSW.json +296 -0
- teradataml/data/jsons/sqle/20.00/TD_HNSWPredict.json +206 -0
- teradataml/data/jsons/sqle/20.00/TD_HNSWSummary.json +32 -0
- teradataml/data/jsons/sqle/20.00/TD_KMeans.json +2 -2
- teradataml/data/jsons/sqle/20.00/TD_SMOTE.json +3 -3
- teradataml/data/jsons/sqle/20.00/TD_VectorDistance.json +6 -6
- teradataml/data/ner_dict.csv +8 -0
- teradataml/data/ner_input_eng.csv +7 -0
- teradataml/data/ner_rule.csv +5 -0
- teradataml/data/pos_input.csv +40 -0
- teradataml/data/tdnerextractor_example.json +14 -0
- teradataml/data/teradataml_example.json +21 -0
- teradataml/data/textmorph_example.json +5 -0
- teradataml/data/to_num_data.csv +4 -0
- teradataml/data/tochar_data.csv +5 -0
- teradataml/data/trans_dense.csv +16 -0
- teradataml/data/trans_sparse.csv +55 -0
- teradataml/data/vectordistance_example.json +1 -1
- teradataml/dataframe/copy_to.py +45 -29
- teradataml/dataframe/data_transfer.py +72 -46
- teradataml/dataframe/dataframe.py +642 -166
- teradataml/dataframe/dataframe_utils.py +167 -22
- teradataml/dataframe/functions.py +135 -20
- teradataml/dataframe/setop.py +11 -6
- teradataml/dataframe/sql.py +330 -78
- teradataml/dbutils/dbutils.py +556 -140
- teradataml/dbutils/filemgr.py +14 -10
- teradataml/hyperparameter_tuner/optimizer.py +12 -1
- teradataml/lib/aed_0_1.dll +0 -0
- teradataml/opensource/{sklearn/_sklearn_wrapper.py → _base.py} +168 -1013
- teradataml/opensource/_class.py +141 -17
- teradataml/opensource/{constants.py → _constants.py} +7 -3
- teradataml/opensource/_lightgbm.py +52 -53
- teradataml/opensource/_sklearn.py +1008 -0
- teradataml/opensource/_wrapper_utils.py +5 -5
- teradataml/options/__init__.py +47 -15
- teradataml/options/configure.py +103 -26
- teradataml/options/display.py +13 -2
- teradataml/plot/axis.py +47 -8
- teradataml/plot/figure.py +33 -0
- teradataml/plot/plot.py +63 -13
- teradataml/scriptmgmt/UserEnv.py +307 -40
- teradataml/scriptmgmt/lls_utils.py +428 -145
- teradataml/store/__init__.py +2 -3
- teradataml/store/feature_store/feature_store.py +102 -7
- teradataml/table_operators/Apply.py +48 -19
- teradataml/table_operators/Script.py +23 -2
- teradataml/table_operators/TableOperator.py +3 -1
- teradataml/table_operators/table_operator_util.py +58 -9
- teradataml/utils/dtypes.py +49 -1
- teradataml/utils/internal_buffer.py +38 -0
- teradataml/utils/validators.py +377 -62
- {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/METADATA +200 -4
- {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/RECORD +146 -112
- teradataml/data/SQL_Fundamentals.pdf +0 -0
- teradataml/libaed_0_1.dylib +0 -0
- teradataml/libaed_0_1.so +0 -0
- teradataml/opensource/sklearn/__init__.py +0 -0
- teradataml/store/vector_store/__init__.py +0 -1586
- {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/WHEEL +0 -0
- {teradataml-20.0.0.3.dist-info → teradataml-20.0.0.5.dist-info}/top_level.txt +0 -0
- {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.
|
|
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.
|
|
32
|
-
from teradataml.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
421
|
-
|
|
422
|
-
files = [files]
|
|
430
|
+
if isinstance(files, str):
|
|
431
|
+
files = [files]
|
|
423
432
|
|
|
424
|
-
|
|
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
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
729
|
-
|
|
730
|
-
|
|
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
|
|
755
|
-
|
|
756
|
-
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
|
|
768
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
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
|
-
|
|
1614
|
-
|
|
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
|
|
1622
|
-
Specifies the authentication token to
|
|
1760
|
+
Optional Argument.
|
|
1761
|
+
Specifies the authentication token required to access services running
|
|
1762
|
+
on Teradata Vantage.
|
|
1623
1763
|
Notes:
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
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
|
|
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
|
-
|
|
1665
|
-
|
|
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
|
-
#
|
|
1670
|
-
|
|
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
|
-
|
|
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",
|
|
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 =
|
|
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
|
-
#
|
|
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
|
-
|
|
1733
|
-
|
|
1734
|
-
#
|
|
1735
|
-
|
|
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(
|
|
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
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
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
|
-
#
|
|
1760
|
-
|
|
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
|