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
@@ -13,32 +13,33 @@ A teradataml context functions provide interface to Teradata Vantage. Provides f
13
13
  context which can be used by other analytical functions to get the Teradata Vantage connection.
14
14
 
15
15
  """
16
+ import atexit
16
17
  import ipaddress
18
+ import os
19
+ import socket
20
+ import sys
21
+ import threading
22
+ import warnings
17
23
  from pathlib import Path
24
+
25
+ from dotenv import dotenv_values
18
26
  from sqlalchemy import create_engine
19
- from teradataml.telemetry_utils.queryband import collect_queryband
20
- from teradataml.common.deprecations import argument_deprecation
27
+ from sqlalchemy.engine.base import Engine
28
+ from sqlalchemy.engine.url import URL
29
+
30
+ from teradataml.common.constants import Query, SQLConstants, TeradataConstants
21
31
  from teradataml.common.exceptions import TeradataMlException
22
- from teradataml.common.warnings import TeradataMlRuntimeWarning
23
- from teradataml.common.messages import Messages
32
+ from teradataml.common.garbagecollector import GarbageCollector
24
33
  from teradataml.common.messagecodes import MessageCodes
34
+ from teradataml.common.messages import Messages
25
35
  from teradataml.common.sqlbundle import SQLBundle
26
- from teradataml.common.constants import SQLConstants
27
- from teradataml.common.garbagecollector import GarbageCollector
36
+ from teradataml.common.warnings import TeradataMlRuntimeWarning
28
37
  from teradataml.context.aed_context import AEDContext
29
- from teradataml.common.constants import TeradataConstants, Query
30
38
  from teradataml.options.configure import configure
39
+ from teradataml.telemetry_utils.queryband import collect_queryband
40
+ from teradataml.utils.internal_buffer import _InternalBuffer
31
41
  from teradataml.utils.utils import execute_sql
32
42
  from teradataml.utils.validators import _Validators
33
- from teradataml.utils.internal_buffer import _InternalBuffer
34
- from sqlalchemy.engine.base import Engine
35
- from sqlalchemy.engine.url import URL
36
- import os
37
- import warnings
38
- import atexit
39
- import socket
40
- import threading
41
- import urllib.parse
42
43
 
43
44
  # Store a global Teradata Vantage Connection.
44
45
  # Right now user can only provide a single Vantage connection at any point of time.
@@ -47,6 +48,8 @@ td_sqlalchemy_engine = None
47
48
  temporary_database_name = None
48
49
  user_specified_connection = False
49
50
  python_packages_installed = False
51
+ python_version_vantage = None
52
+ python_version_local = None
50
53
  td_user = None
51
54
 
52
55
  function_alias_mappings = {}
@@ -133,7 +136,7 @@ def __cleanup_garbage_collection():
133
136
  GarbageCollector._cleanup_garbage_collector()
134
137
 
135
138
 
136
- def _get_other_connection_parameters(logmech = None, logdata = None, database = None, **kwargs):
139
+ def _get_other_connection_parameters(logmech=None, logdata=None, database=None, **kwargs):
137
140
  """
138
141
  DESCRIPTION:
139
142
  Internal function to return the connection parameters.
@@ -194,16 +197,26 @@ def _get_other_connection_parameters(logmech = None, logdata = None, database =
194
197
 
195
198
  return result
196
199
 
197
- @argument_deprecation("future", ["url_encode"], False, None)
200
+
198
201
  @collect_queryband(queryband='CrtCxt')
199
- def create_context(host = None, username = None, password = None, tdsqlengine = None, temp_database_name = None,
200
- logmech = None, logdata = None, database = None, url_encode = True, **kwargs):
202
+ def create_context(host=None, username=None, password=None, tdsqlengine=None, temp_database_name=None,
203
+ logmech=None, logdata=None, database=None, **kwargs):
201
204
  """
202
205
  DESCRIPTION:
203
206
  Creates a connection to the Teradata Vantage using the teradatasql + teradatasqlalchemy DBAPI and dialect
204
- combination. Users can pass all required parameters (host, username, password) for establishing a connection to
205
- Vantage, or pass a sqlalchemy engine to the tdsqlengine parameter to override the default DBAPI and dialect
206
207
  combination.
208
+ Users can create a connection by passing the connection parameters using any one of the following methods:
209
+ 1. Pass all required parameters (host, username, password) directly to the function.
210
+ 2. Set the connection parameters in a configuration file (.cfg or .env) and
211
+ pass the configuration file.
212
+ 3. Set the connection parameters in environment variables and create_context() reads from
213
+ environment variables.
214
+
215
+ Alternatively, users can pass a SQLAlchemy engine object to the `tdsqlengine` parameter to override the default DBAPI
216
+ and dialect combination.
217
+
218
+ Function also enables user to set the authentication token which is required to access services running
219
+ on Teradata Vantage.
207
220
 
208
221
  Note:
209
222
  1. teradataml requires that the user has certain permissions on the user's default database or the initial
@@ -241,6 +254,39 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
241
254
  | | default database. |
242
255
  +------------------------------------------------------+---------------------------------------------+
243
256
 
257
+ 3. The function prioritizes parameters in the following order:
258
+ 1. Explicitly passed arguments (host, username, password).
259
+ 2. Environment variables (TD_HOST, TD_USERNAME, TD_PASSWORD, etc.).
260
+ Note:
261
+ * The environment variables should start with 'TD_' and all must be in upper case.
262
+ Example:
263
+ os.environ['TD_HOST'] = 'tdhost'
264
+ os.environ['TD_USERNAME'] = 'tduser'
265
+ os.environ['TD_PASSWORD'] = 'tdpassword'
266
+ 3. A configuration file if provided (such as a .env file).
267
+
268
+ 4. Points to note when user sets authentication token with create_context():
269
+ * The username provided in create_context() is not case-sensitive. For example,
270
+ if a user is created with the username xyz, create_context() still establishes
271
+ a connection if user passes the username as XyZ. However, authentication token
272
+ generation requires the username to be in the same case as when it was created.
273
+ Therefore, Teradata recommends to pass the username with the same case as when
274
+ it was created.
275
+ * User must have a privilege to login with a NULL password to use set_auth_token().
276
+ Refer to GRANT LOGON section in Teradata Documentation for more details.
277
+ * When "auth_mech" is not specified, arguments are used in the following combination
278
+ to derive authentication mechanism.
279
+ * If "base_url" and "client_id" are specified then token generation is done through OAuth.
280
+ * If "base_url", "pat_token", "pem_file" are specified then token generation is done using PAT.
281
+ * If "base_url" and "auth_token" are specified then value provided for "auth_token" is used.
282
+ * If only "base_url" is specified then token generation is done through OAuth.
283
+ * If Basic authentication mechanism is to be used then user must specify argument
284
+ "auth_mech" as "BASIC" along with "username" and "password".
285
+ * Refresh token works only for OAuth authentication.
286
+ * Use the argument "kid" only when key used during the pem file generation is different
287
+ from pem file name. For example, if you use the key as 'key1' while generating pem file
288
+ and the name of the pem file is `key1(1).pem`, then pass value 'key1' to the argument "kid".
289
+
244
290
  PARAMETERS:
245
291
  host:
246
292
  Optional Argument.
@@ -254,39 +300,15 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
254
300
 
255
301
  password:
256
302
  Optional Argument.
257
- Specifies the password required for the username.
303
+ Specifies the password required for the "username".
258
304
  Types: str
259
305
  Note:
260
306
  * Encrypted passwords can also be passed to this argument, using Stored Password Protection feature.
261
307
  Examples section below demonstrates passing encrypted password to 'create_context'.
262
308
  More details on Stored Password Protection and how to generate key and encrypted password file
263
309
  can be found at https://pypi.org/project/teradatasql/#StoredPasswordProtection
264
- * Special characters that may be used in the password are encoded by default, except '~'.
265
- The encoding is done using urllib.parse library and can be
266
- disabled by setting "url_encode" = False.
267
- For example, if the password is: "kx%jj5/g", then this password is encoded as below:
268
- "kx%25jj5%2Fg"
269
- where,
270
- %25 represents the '%' character and
271
- %2F represents the '/' character
272
- The details of how the special characters are replaced can be found in the below link:
273
- "https://docs.microfocus.com/OMi/10.62/Content/OMi/ExtGuide/ExtApps/URL_encoding.htm".
274
- Note:
275
- When password contains a space:
276
- * "url_encode" must be set to False.
277
- * In addition to space, other special characters in this password should be manually encoded,
278
- following the link: https://docs.microfocus.com/OMi/10.62/Content/OMi/ExtGuide/ExtApps/URL_encoding.htm
279
- Refer Example 16 in examples section for a detailed demonstration.
280
-
281
- When password contains unreserved characters like tilde("~"), dot("."), underscore("_"), hyphen("-"):
282
- * Character is not URL encoded by default.
283
- * If unreserved character in passed needs to be encoded then,
284
- it must be encoded manually and encoded password must be passed, along with "url_encode" set to False.
285
- * The unreserved characters differ from one Python version to another Python version.
286
- For example, The encoding standards for Python version 3.7 found in the below link:
287
- "https://docs.python.org/3/library/urllib.parse.html#url-quoting".
288
-
289
-
310
+ * Special characters used in the password are encoded by default.
311
+
290
312
  tdsqlengine:
291
313
  Optional Argument.
292
314
  Specifies Teradata Vantage sqlalchemy engine object that should be used to establish a Teradata Vantage
@@ -324,12 +346,90 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
324
346
  Types: str
325
347
 
326
348
  kwargs:
327
- Specifies the keyword-value pairs of connection parameters that are passed to Teradata SQL Driver for
328
- Python. Please refer to https://github.com/Teradata/python-driver#ConnectionParameters to get information
329
- on connection parameters of the driver.
330
- Note: When the type of a connection parameter is integer or boolean (eg: log, lob_support etc,.), pass
331
- integer or boolean value, instead of quoted integer or quoted boolean as suggested in the
332
- documentation. Please check the examples for usage.
349
+ Specifies optional keyword arguments accepted by create_context().
350
+ Below are the supported keyword arguments:
351
+
352
+ Connection parameters for Teradata SQL Driver:
353
+ Specifies the keyword-value pairs of connection parameters that are passed to Teradata SQL Driver for
354
+ Python. Please refer to https://github.com/Teradata/python-driver#ConnectionParameters to get information
355
+ on connection parameters of the driver.
356
+ Note:
357
+ * When type of a connection parameter is integer or boolean (eg: log, lob_support etc,.), pass
358
+ integer or boolean value, instead of quoted integer or quoted boolean as suggested in the
359
+ documentation. Please check the examples for usage.
360
+ * "sql_timeout" represents "request_timeout" connection parameter.
361
+
362
+ config_file:
363
+ Specifies the name of the configuration file to read the connection parameters.
364
+ Notes:
365
+ * If user does not specify full path of file, then file look up is done at current working directory.
366
+ * The content of the file must be in '.env' format.
367
+ * Use parameters of create_context() as key in the configuration file.
368
+ Example:
369
+ host=tdhost
370
+ username=tduser
371
+ password=tdpassword
372
+ temp_database_name=tdtemp_database_name
373
+ logmech=tdlogmech
374
+ logdata=tdlogdata
375
+ database=tddatabase
376
+ * For more information please refer examples section.
377
+ Default Value : td_properties.cfg
378
+ Types: str
379
+
380
+ base_url:
381
+ Specifies the endpoint URL for a given environment on Teradata Vantage.
382
+ Types: str
383
+
384
+ client_id:
385
+ Specifies the id of the application that requests the access token from
386
+ VantageCloud Lake.
387
+ Types: str
388
+
389
+ pat_token:
390
+ Specifies the PAT token generated from VantageCloud Lake Console.
391
+ Types: str
392
+
393
+ pem_file:
394
+ Specifies the path to private key file which is generated from VantageCloud Lake Console.
395
+ Types: str
396
+
397
+ auth_token:
398
+ Specifies the authentication token required to access services running
399
+ on Teradata Vantage.
400
+
401
+ expiration_time:
402
+ Specifies the expiration time of the token in seconds. After expiry time JWT token expires and
403
+ UserEnv methods does not work, user should regenerate the token.
404
+ Note:
405
+ This option is used only for PAT and not for OAuth.
406
+ Default Value: 31536000
407
+ Types: int
408
+
409
+ kid:
410
+ Specifies the name of the key which is used while generating 'pem_file'.
411
+ Note:
412
+ * Use the argument "kid" only when key used during the pem file generation is different
413
+ from pem file name. For example, if you use the key as 'key1' while generating pem file
414
+ and the name of the pem file is `key1(1).pem`, then pass value 'key1' to the argument "kid".
415
+ Types: str
416
+
417
+ auth_mech:
418
+ Specifies the mechanism to be used for generating authentication token.
419
+ Notes:
420
+ * User must use this argument if Basic authentication is to be used.
421
+ * When "auth_mech" is provided, other arguments are used in the following
422
+ combination as per value of "auth_mech":
423
+ * OAuth: Token generation is done through OAuth by using client id
424
+ which can be sepcified by user in "client_id" argument or
425
+ can be derived internally from "base_url".
426
+ * PAT : Token generation is done using "pat_token" and "pem_file".
427
+ * BASIC: Authentication is done via Basic authentication mechanism
428
+ using user credentials passed in "username" and "password"
429
+ arguments.
430
+ * JWT : Readily available token in "auth_token" argument is used.
431
+ Permitted Values: "OAuth", "PAT", "BASIC", "JWT".
432
+ Types: str
333
433
 
334
434
  RETURNS:
335
435
  A Teradata sqlalchemy engine object.
@@ -341,7 +441,7 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
341
441
  >>> from teradataml.context.context import *
342
442
 
343
443
  # Example 1: Create context using hostname, username and password
344
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword')
444
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword')
345
445
 
346
446
  # Example 2: Create context using already created sqlalchemy engine
347
447
  >>> from sqlalchemy import create_engine
@@ -349,56 +449,141 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
349
449
  >>> td_context = create_context(tdsqlengine = sqlalchemy_engine)
350
450
 
351
451
  # Example 3: Creating context for Vantage with default logmech 'TD2'
352
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', logmech='TD2')
452
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', logmech = 'TD2')
353
453
 
354
454
  # Example 4: Creating context for Vantage with logmech as 'TDNEGO'
355
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', logmech='TDNEGO')
455
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', logmech = 'TDNEGO')
356
456
 
357
457
  # Example 5: Creating context for Vantage with logmech as 'LDAP'
358
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', logmech='LDAP')
458
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', logmech = 'LDAP')
359
459
 
360
460
  # Example 6: Creating context for Vantage with logmech as 'KRB5'
361
- >>> td_context = create_context(host = 'tdhost', logmech='KRB5')
461
+ >>> td_context = create_context(host = 'tdhost', logmech = 'KRB5')
362
462
 
363
463
  # Example 7: Creating context for Vantage with logmech as 'JWT'
364
- >>> td_context = create_context(host = 'tdhost', logmech='JWT', logdata='token=eyJpc...h8dA')
464
+ >>> td_context = create_context(host = 'tdhost', logmech = 'JWT', logdata = 'token=eyJpc...h8dA')
365
465
 
366
466
  # Example 8: Create context using encrypted password and key passed to 'password' parameter.
367
- # The password should be specified in the format mentioned below:
368
- # ENCRYPTED_PASSWORD(file:<PasswordEncryptionKeyFileName>, file:<EncryptedPasswordFileName>)
369
- # The PasswordEncryptionKeyFileName specifies the name of a file that contains the password encryption key
370
- # and associated information.
371
- # The EncryptedPasswordFileName specifies the name of a file that contains the encrypted password and
372
- # associated information.
373
- # Each filename must be preceded by the 'file:' prefix. The PasswordEncryptionKeyFileName must be separated
374
- # from the EncryptedPasswordFileName by a single comma.
467
+ # The password should be specified in the format mentioned below:
468
+ # ENCRYPTED_PASSWORD(file:<PasswordEncryptionKeyFileName>, file:<EncryptedPasswordFileName>)
469
+ # The PasswordEncryptionKeyFileName specifies the name of a file that contains the password encryption key
470
+ # and associated information.
471
+ # The EncryptedPasswordFileName specifies the name of a file that contains the encrypted password and
472
+ # associated information.
473
+ # Each filename must be preceded by the 'file:' prefix. The PasswordEncryptionKeyFileName must be separated
474
+ # from the EncryptedPasswordFileName by a single comma.
375
475
  >>> encrypted_password = "ENCRYPTED_PASSWORD(file:PassKey.properties, file:EncPass.properties)"
376
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = encrypted_password)
476
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = encrypted_password)
377
477
 
378
478
  # Example 9: Create context using encrypted password in LDAP logon mechanism.
379
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = encrypted_password,
380
- logmech='LDAP')
479
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = encrypted_password,
480
+ ... logmech = 'LDAP')
381
481
 
382
482
  # Example 10: Create context using hostname, username, password and database parameters, and connect to a
383
483
  # different initial database by setting the database parameter.
384
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', database =
385
- 'database_name')
484
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', database =
485
+ ... 'database_name')
386
486
 
387
487
  # Example 11: Create context using already created sqlalchemy engine, and connect to a different initial
388
488
  # database by setting the database parameter.
389
489
  >>> from sqlalchemy import create_engine
390
490
  >>> sqlalchemy_engine = create_engine('teradatasql://'+ tduser +':' + tdpassword + '@'+tdhost +
391
- '/?DATABASE=database_name')
491
+ ... '/?DATABASE=database_name')
392
492
  >>> td_context = create_context(tdsqlengine = sqlalchemy_engine)
393
493
 
394
494
  # Example 12: Create context for Vantage with logmech as 'LDAP', and connect to a different initial
395
495
  # database by setting the database parameter.
396
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', logmech='LDAP',
397
- database = 'database_name')
496
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', logmech = 'LDAP',
497
+ ... database = 'database_name')
398
498
 
399
499
  # Example 13: Create context using 'tera' mode with log value set to 8 and lob_support disabled.
400
- >>> td_context = create_context(host = 'tdhost', username='tduser', password = 'tdpassword', tmode = 'tera',
401
- log = 8, lob_support = False)
500
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', tmode = 'tera',
501
+ ... log = 8, lob_support = False)
502
+
503
+ # Example 14: Create context from config file with name 'td_properties.cfg'
504
+ # available under current working directory.
505
+ # td_properties.cfg content:
506
+ # host=tdhost
507
+ # username=tduser
508
+ # password=tdpassword
509
+ # temp_database_name=tdtemp_database_name
510
+ # logmech=tdlogmech
511
+ # logdata=tdlogdata
512
+ # database=tddatabase
513
+ >>> td_context = create_context()
514
+
515
+ # Example 15: Create context using the file specified in user's home directory
516
+ # with name user_td_properties.cfg.
517
+ # user_td_properties.cfg content:
518
+ # host=tdhost
519
+ # username=tduser
520
+ # password=tdpassword
521
+ # temp_database_name=tdtemp_database_name
522
+ # logmech=tdlogmech
523
+ # logdata=tdlogdata
524
+ # database=tddatabase
525
+ >>> td_context = create_context(config_file = "user_td_properties.cfg")
526
+
527
+ # Example 16: Create context using environment variables.
528
+ # Set these using os.environ and then run the example:
529
+ # os.environ['TD_HOST'] = 'tdhost'
530
+ # os.environ['TD_USERNAME'] = 'tduser'
531
+ # os.environ['TD_PASSWORD'] = 'tdpassword'
532
+ # os.environ['TD_TEMP_DATABASE_NAME'] = 'tdtemp_database_name'
533
+ # os.environ['TD_LOGMECH'] = 'tdlogmech'
534
+ # os.environ['TD_LOGDATA'] = 'tdlogdata'
535
+ # os.environ['TD_DATABASE'] = 'tddatabase'
536
+ >>> td_context = create_context()
537
+
538
+ # Example 17: Create a context by providing username and password. Along with it,
539
+ # set authentication token by providing the pem file and pat token.
540
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword',
541
+ ... base_url = 'base_url', pat_token = 'pat_token', pem_file = 'pem_file')
542
+
543
+ # Example 18: Create a context by providing username and password. Along with it,
544
+ # generate authentication token by providing the client id.
545
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword',
546
+ ... base_url = 'base_url', client_id = 'client_id')
547
+
548
+ # Example 19: Create context and set authentication token by providing all the details in a config file.
549
+ # td_properties.cfg content:
550
+ # host=tdhost
551
+ # username=tduser
552
+ # password=tdpassword
553
+ # base_url=base_url
554
+ # pat_token=pat_token
555
+ # pem_file=pem_file
556
+ >>> td_context = create_context()
557
+
558
+ # Example 20: Create context and set authentication token by providing all the details in environment variables.
559
+ # Set these using os.environ and then run the example:
560
+ # os.environ['TD_HOST'] = 'tdhost'
561
+ # os.environ['TD_USERNAME'] = 'tduser'
562
+ # os.environ['TD_PASSWORD'] = 'tdpassword'
563
+ # os.environ['TD_BASE_URL'] = 'base_url'
564
+ # os.environ['TD_PAT_TOKEN'] = 'pat_token'
565
+ # os.environ['TD_PEM_FILE'] = 'pem_file'
566
+ >>> td_context = create_context()
567
+
568
+ # Example 21: Create context with sql_timeout set to 3.
569
+ >>> td_context = create_context(host = 'tdhost', username = 'tduser', password = 'tdpassword', sql_timeout = 3)
570
+
571
+ # Example 22: Create context and set authentication token via Basic authentication mechanism
572
+ # using username and password.
573
+ >>> import getpass
574
+ >>> create_context(host="host",
575
+ ... username=getpass.getpass("username : "),
576
+ ... password=getpass.getpass("password : "),
577
+ ... base_url=getpass.getpass("base_url : "),
578
+ ... auth_mech="BASIC")
579
+
580
+ # Example 23: Create context and set authentication token by providing auth_mech argument.
581
+ >>> import getpass
582
+ >>> create_context(host="vcl_host",
583
+ ... username=getpass.getpass("username : "),
584
+ ... password=getpass.getpass("password : "),
585
+ ... base_url=getpass.getpass("base_url : "),
586
+ ... auth_mech="OAuth")
402
587
 
403
588
  """
404
589
  global td_connection
@@ -406,7 +591,16 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
406
591
  global temporary_database_name
407
592
  global user_specified_connection
408
593
  global python_packages_installed
594
+ global python_version_vantage
595
+ global python_version_local
409
596
  global td_user
597
+
598
+ # Check if the user has provided the connection parameters or tdsqlengine.
599
+ # If not, check if the user has provided the connection parameters in the environment variables.
600
+ # If not, check if the user has provided the connection parameters in the config file.
601
+ if not (host or tdsqlengine) and host != "":
602
+ return _load_context_from_env_config(kwargs.pop('config_file', 'td_properties.cfg'))
603
+
410
604
  awu_matrix = []
411
605
  awu_matrix.append(["host", host, True, (str), True])
412
606
  awu_matrix.append(["username", username, True, (str), True])
@@ -415,13 +609,23 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
415
609
  awu_matrix.append(["logmech", logmech, True, (str), True])
416
610
  awu_matrix.append(["logdata", logdata, True, (str), True])
417
611
  awu_matrix.append(["database", database, True, (str), True])
612
+ # set_auth_token parameters
613
+ _set_auth_token_params = {}
614
+ auth_mech = kwargs.get('auth_mech', None)
615
+ for param in ['base_url', 'pat_token', 'pem_file', 'client_id', 'auth_token', 'expiration_time', 'kid', 'auth_mech']:
616
+ if kwargs.get(param):
617
+ _set_auth_token_params[param] = kwargs.pop(param)
618
+
619
+ # Set the "sql_timeout" parameter to "request_timeout" which is consumed by teradatasql.
620
+ if kwargs.get('sql_timeout'):
621
+ awu_matrix.append(["sql_timeout", kwargs.get('sql_timeout'), True, (int), True])
622
+ kwargs['request_timeout'] = kwargs.pop('sql_timeout')
418
623
 
419
624
  awu = _Validators()
420
625
  awu._validate_function_arguments(awu_matrix)
421
626
 
422
627
  # Clearing the internal buffer.
423
628
  _InternalBuffer.clean()
424
-
425
629
  if logmech == "JWT" and not logdata:
426
630
  raise TeradataMlException(Messages.get_message(MessageCodes.DEPENDENT_ARG_MISSING,
427
631
  'logdata',
@@ -456,7 +660,6 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
456
660
  host_value = '{}:@{}'.format(username, host)
457
661
  else:
458
662
  host_value = '{}:{}@{}'.format(username, password, host)
459
-
460
663
  url_object = URL.create(
461
664
  "teradatasql",
462
665
  username=username,
@@ -470,7 +673,7 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
470
673
  td_connection = td_sqlalchemy_engine.connect()
471
674
  td_user = username.upper()
472
675
 
473
- # Masking senstive information - password, logmech and logdata.
676
+ # Masking sensitive information - password, logmech and logdata.
474
677
  if password:
475
678
  try:
476
679
  # Below statement raises an AttributeError with SQLAlchemy
@@ -497,6 +700,8 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
497
700
  _load_function_aliases()
498
701
 
499
702
  python_packages_installed = False
703
+ python_version_vantage = None
704
+ python_version_local = sys.version.split(" ")[0].strip()
500
705
 
501
706
  # Assign the tempdatabase name to global
502
707
  if temp_database_name is None:
@@ -520,7 +725,19 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
520
725
  # Process Analytic functions.
521
726
  from teradataml.analytics import _process_analytic_functions
522
727
  _process_analytic_functions()
523
-
728
+
729
+ if _set_auth_token_params.get('base_url'):
730
+ from teradataml.scriptmgmt.lls_utils import set_auth_token
731
+ try:
732
+ if auth_mech and auth_mech.lower() == 'basic' and password:
733
+ _set_auth_token_params['password'] = password
734
+ set_auth_token(**_set_auth_token_params)
735
+ except Exception as err:
736
+ print("Connection to Vantage established successfully.")
737
+ mssg = f"Failed to set authentication token. Rerun \"set_auth_token()\" again to set the authentication token." \
738
+ f" Reason for failure: {err.args[0]}"
739
+ warnings.warn(mssg, stacklevel=2)
740
+
524
741
  # Add global lock to internal buffer
525
742
  _InternalBuffer.add(global_lock=threading.Lock())
526
743
 
@@ -528,6 +745,36 @@ def create_context(host = None, username = None, password = None, tdsqlengine =
528
745
  return td_sqlalchemy_engine
529
746
 
530
747
 
748
+ def _load_context_from_env_config(config_file=None):
749
+ """
750
+ DESCRIPTION:
751
+ Reads the connection parameters from the configuration file or environment variables.
752
+
753
+ PARAMETERS:
754
+ config_file:
755
+ Optional Argument.
756
+ Specifies the name of the configuration file to read the connection parameters.
757
+ Types: str
758
+
759
+ RETURNS:
760
+ A Teradata sqlalchemy engine object.
761
+
762
+ RAISES:
763
+ TeradataMlException
764
+ """
765
+ host = os.environ.get('TD_HOST')
766
+ if host:
767
+ connection_params_from_env = {key[3:].lower(): value for key, value in os.environ.items()
768
+ if key.startswith('TD_')}
769
+ return create_context(**connection_params_from_env)
770
+ elif config_file is not None:
771
+ connection_params_from_file = dotenv_values(config_file)
772
+ if connection_params_from_file.get('host'):
773
+ return create_context(**connection_params_from_file)
774
+ raise TeradataMlException(Messages.get_message(MessageCodes.CONNECTION_PARAMS),
775
+ MessageCodes.MISSING_ARGS)
776
+
777
+
531
778
  def _mask_logmech_logdata():
532
779
  """
533
780
  Masks sensitive connection information LOGMECH, LOGDATA exposed by sqlalchemy engine object
@@ -625,6 +872,8 @@ def set_context(tdsqlengine, temp_database_name=None):
625
872
  global temporary_database_name
626
873
  global user_specified_connection
627
874
  global python_packages_installed
875
+ global python_version_local
876
+ global python_version_vantage
628
877
  if td_connection is not None:
629
878
  # Clearing the internal buffer.
630
879
  _InternalBuffer.clean()
@@ -654,10 +903,12 @@ def set_context(tdsqlengine, temp_database_name=None):
654
903
  _load_function_aliases()
655
904
 
656
905
  python_packages_installed = False
906
+ python_version_vantage = None
907
+ python_version_local = sys.version.split(" ")[0].strip()
657
908
 
658
909
  # Initialise Dag
659
910
  __initalise_dag()
660
-
911
+
661
912
  # Add global lock to internal buffer
662
913
  _InternalBuffer.add(global_lock=threading.Lock())
663
914
 
@@ -687,11 +938,16 @@ def remove_context():
687
938
  global td_sqlalchemy_engine
688
939
  global user_specified_connection
689
940
  global python_packages_installed
941
+ global python_version_vantage
942
+ global python_version_local
690
943
  global td_user
691
944
 
692
945
  # Initiate the garbage collection
693
946
  __cleanup_garbage_collection()
694
947
 
948
+ # Clearing the internal buffer.
949
+ _InternalBuffer.clean()
950
+
695
951
  # Check if connection is established or not.
696
952
  if user_specified_connection is not True:
697
953
  try:
@@ -706,10 +962,13 @@ def remove_context():
706
962
  td_connection = None
707
963
  td_sqlalchemy_engine = None
708
964
  python_packages_installed = False
965
+ python_version_local = None
966
+ python_version_vantage = None
709
967
  td_user = None
710
968
  configure._current_database_name = None
711
969
  configure._database_username = None
712
970
  configure.database_version = None
971
+ configure.indb_install_location = ''
713
972
 
714
973
  # Closing Dag
715
974
  __close_dag()
@@ -993,6 +1252,7 @@ def _get_user():
993
1252
  td_user = _get_database_username()
994
1253
  return td_user
995
1254
 
1255
+
996
1256
  def _get_host():
997
1257
  """
998
1258
  DESCRIPTION:
@@ -1015,6 +1275,7 @@ def _get_host():
1015
1275
  else:
1016
1276
  return td_sqlalchemy_engine.url.host
1017
1277
 
1278
+
1018
1279
  def _get_host_ip():
1019
1280
  """
1020
1281
  DESCRIPTION:
@@ -1035,7 +1296,7 @@ def _get_host_ip():
1035
1296
  # Return None if connection is not established.
1036
1297
  if td_connection is None:
1037
1298
  return None
1038
-
1299
+
1039
1300
  host = _get_host()
1040
1301
  try:
1041
1302
  # Validate if host_ip is a valid IP address (IPv4 or IPv6)
@@ -1046,7 +1307,7 @@ def _get_host_ip():
1046
1307
  dns_host_ip = _InternalBuffer.get('dns_host_ip')
1047
1308
  if dns_host_ip:
1048
1309
  return dns_host_ip
1049
-
1310
+
1050
1311
  # If DNS host ip not found, resolve the host name to get the IP address.
1051
1312
  # If there is issue in resolving the host name, it will proceed with DNS host as it is.
1052
1313
  try:
@@ -1061,6 +1322,7 @@ def _get_host_ip():
1061
1322
  host_ip = host
1062
1323
  return host_ip
1063
1324
 
1325
+
1064
1326
  class ContextUtilFuncs():
1065
1327
  @staticmethod
1066
1328
  def _check_alias_config_file_exists(vantage_version, alias_config_file):