teradataml 20.0.0.4__py3-none-any.whl → 20.0.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (131) hide show
  1. teradataml/LICENSE-3RD-PARTY.pdf +0 -0
  2. teradataml/README.md +182 -13
  3. teradataml/__init__.py +2 -1
  4. teradataml/_version.py +2 -2
  5. teradataml/analytics/analytic_function_executor.py +8 -13
  6. teradataml/analytics/json_parser/analytic_functions_argument.py +4 -0
  7. teradataml/analytics/sqle/__init__.py +16 -1
  8. teradataml/analytics/utils.py +60 -1
  9. teradataml/automl/__init__.py +290 -106
  10. teradataml/automl/autodataprep/__init__.py +471 -0
  11. teradataml/automl/data_preparation.py +29 -10
  12. teradataml/automl/data_transformation.py +11 -0
  13. teradataml/automl/feature_engineering.py +64 -4
  14. teradataml/automl/feature_exploration.py +639 -25
  15. teradataml/automl/model_training.py +1 -1
  16. teradataml/clients/auth_client.py +12 -8
  17. teradataml/clients/keycloak_client.py +165 -0
  18. teradataml/common/constants.py +71 -26
  19. teradataml/common/exceptions.py +32 -0
  20. teradataml/common/messagecodes.py +28 -0
  21. teradataml/common/messages.py +13 -4
  22. teradataml/common/sqlbundle.py +3 -2
  23. teradataml/common/utils.py +345 -45
  24. teradataml/context/context.py +259 -93
  25. teradataml/data/apriori_example.json +22 -0
  26. teradataml/data/docs/sqle/docs_17_20/Apriori.py +138 -0
  27. teradataml/data/docs/sqle/docs_17_20/NERExtractor.py +121 -0
  28. teradataml/data/docs/sqle/docs_17_20/NGramSplitter.py +3 -3
  29. teradataml/data/docs/sqle/docs_17_20/SMOTE.py +212 -0
  30. teradataml/data/docs/sqle/docs_17_20/TextMorph.py +119 -0
  31. teradataml/data/docs/sqle/docs_17_20/TextParser.py +54 -3
  32. teradataml/data/docs/uaf/docs_17_20/ACF.py +1 -1
  33. teradataml/data/docs/uaf/docs_17_20/ArimaEstimate.py +2 -2
  34. teradataml/data/docs/uaf/docs_17_20/ArimaXEstimate.py +2 -2
  35. teradataml/data/docs/uaf/docs_17_20/DFFT.py +1 -1
  36. teradataml/data/docs/uaf/docs_17_20/DFFT2.py +1 -1
  37. teradataml/data/docs/uaf/docs_17_20/DFFT2Conv.py +1 -1
  38. teradataml/data/docs/uaf/docs_17_20/DFFTConv.py +1 -1
  39. teradataml/data/docs/uaf/docs_17_20/FilterFactory1d.py +4 -4
  40. teradataml/data/docs/uaf/docs_17_20/GenseriesSinusoids.py +2 -2
  41. teradataml/data/docs/uaf/docs_17_20/GoldfeldQuandt.py +2 -2
  42. teradataml/data/docs/uaf/docs_17_20/HoltWintersForecaster.py +6 -6
  43. teradataml/data/docs/uaf/docs_17_20/LineSpec.py +1 -1
  44. teradataml/data/docs/uaf/docs_17_20/LinearRegr.py +1 -1
  45. teradataml/data/docs/uaf/docs_17_20/Matrix2Image.py +4 -4
  46. teradataml/data/docs/uaf/docs_17_20/MultivarRegr.py +1 -1
  47. teradataml/data/docs/uaf/docs_17_20/PACF.py +1 -1
  48. teradataml/data/docs/uaf/docs_17_20/PowerSpec.py +2 -2
  49. teradataml/data/docs/uaf/docs_17_20/PowerTransform.py +3 -3
  50. teradataml/data/docs/uaf/docs_17_20/Resample.py +5 -5
  51. teradataml/data/docs/uaf/docs_17_20/SAX.py +3 -3
  52. teradataml/data/docs/uaf/docs_17_20/SignifPeriodicities.py +1 -1
  53. teradataml/data/docs/uaf/docs_17_20/SimpleExp.py +1 -1
  54. teradataml/data/docs/uaf/docs_17_20/Smoothma.py +3 -3
  55. teradataml/data/docs/uaf/docs_17_20/UNDIFF.py +1 -1
  56. teradataml/data/jsons/byom/onnxembeddings.json +1 -0
  57. teradataml/data/jsons/sqle/17.20/NGramSplitter.json +6 -6
  58. teradataml/data/jsons/sqle/17.20/TD_Apriori.json +181 -0
  59. teradataml/data/jsons/sqle/17.20/TD_NERExtractor.json +145 -0
  60. teradataml/data/jsons/sqle/17.20/TD_SMOTE.json +267 -0
  61. teradataml/data/jsons/sqle/17.20/TD_TextMorph.json +134 -0
  62. teradataml/data/jsons/sqle/17.20/TD_TextParser.json +114 -9
  63. teradataml/data/jsons/sqle/20.00/AI_AnalyzeSentiment.json +328 -0
  64. teradataml/data/jsons/sqle/20.00/AI_AskLLM.json +420 -0
  65. teradataml/data/jsons/sqle/20.00/AI_DetectLanguage.json +343 -0
  66. teradataml/data/jsons/sqle/20.00/AI_ExtractKeyPhrases.json +328 -0
  67. teradataml/data/jsons/sqle/20.00/AI_MaskPII.json +328 -0
  68. teradataml/data/jsons/sqle/20.00/AI_RecognizeEntities.json +328 -0
  69. teradataml/data/jsons/sqle/20.00/AI_RecognizePIIEntities.json +328 -0
  70. teradataml/data/jsons/sqle/20.00/AI_TextClassifier.json +359 -0
  71. teradataml/data/jsons/sqle/20.00/AI_TextEmbeddings.json +360 -0
  72. teradataml/data/jsons/sqle/20.00/AI_TextSummarize.json +343 -0
  73. teradataml/data/jsons/sqle/20.00/AI_TextTranslate.json +343 -0
  74. teradataml/data/jsons/sqle/20.00/TD_SMOTE.json +2 -2
  75. teradataml/data/jsons/sqle/20.00/TD_VectorDistance.json +1 -1
  76. teradataml/data/ner_dict.csv +8 -0
  77. teradataml/data/ner_input_eng.csv +7 -0
  78. teradataml/data/ner_rule.csv +5 -0
  79. teradataml/data/pattern_matching_data.csv +11 -0
  80. teradataml/data/pos_input.csv +40 -0
  81. teradataml/data/sdk/modelops/modelops_spec.json +101737 -0
  82. teradataml/data/tdnerextractor_example.json +14 -0
  83. teradataml/data/teradataml_example.json +21 -1
  84. teradataml/data/textmorph_example.json +5 -0
  85. teradataml/data/to_num_data.csv +4 -0
  86. teradataml/data/tochar_data.csv +5 -0
  87. teradataml/data/trans_dense.csv +16 -0
  88. teradataml/data/trans_sparse.csv +55 -0
  89. teradataml/data/url_data.csv +10 -9
  90. teradataml/dataframe/copy_to.py +38 -27
  91. teradataml/dataframe/data_transfer.py +61 -45
  92. teradataml/dataframe/dataframe.py +1110 -132
  93. teradataml/dataframe/dataframe_utils.py +73 -27
  94. teradataml/dataframe/functions.py +1070 -9
  95. teradataml/dataframe/sql.py +750 -959
  96. teradataml/dbutils/dbutils.py +33 -13
  97. teradataml/dbutils/filemgr.py +14 -10
  98. teradataml/hyperparameter_tuner/utils.py +4 -2
  99. teradataml/lib/aed_0_1.dll +0 -0
  100. teradataml/opensource/_base.py +12 -157
  101. teradataml/options/configure.py +24 -9
  102. teradataml/scriptmgmt/UserEnv.py +317 -39
  103. teradataml/scriptmgmt/lls_utils.py +456 -135
  104. teradataml/sdk/README.md +79 -0
  105. teradataml/sdk/__init__.py +4 -0
  106. teradataml/sdk/_auth_modes.py +422 -0
  107. teradataml/sdk/_func_params.py +487 -0
  108. teradataml/sdk/_json_parser.py +453 -0
  109. teradataml/sdk/_openapi_spec_constants.py +249 -0
  110. teradataml/sdk/_utils.py +236 -0
  111. teradataml/sdk/api_client.py +897 -0
  112. teradataml/sdk/constants.py +62 -0
  113. teradataml/sdk/modelops/__init__.py +98 -0
  114. teradataml/sdk/modelops/_client.py +406 -0
  115. teradataml/sdk/modelops/_constants.py +304 -0
  116. teradataml/sdk/modelops/models.py +2308 -0
  117. teradataml/sdk/spinner.py +107 -0
  118. teradataml/store/__init__.py +1 -1
  119. teradataml/table_operators/Apply.py +16 -1
  120. teradataml/table_operators/Script.py +20 -1
  121. teradataml/table_operators/query_generator.py +4 -21
  122. teradataml/table_operators/table_operator_util.py +58 -9
  123. teradataml/utils/dtypes.py +4 -2
  124. teradataml/utils/internal_buffer.py +22 -2
  125. teradataml/utils/utils.py +0 -1
  126. teradataml/utils/validators.py +318 -58
  127. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/METADATA +188 -14
  128. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/RECORD +131 -84
  129. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/WHEEL +0 -0
  130. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/top_level.txt +0 -0
  131. {teradataml-20.0.0.4.dist-info → teradataml-20.0.0.6.dist-info}/zip-safe +0 -0
@@ -0,0 +1,79 @@
1
+ ## How to create Software Development Kit (SDK) using OpenAPI spec
2
+
3
+ All SDKs should be in module `teradataml.sdk`. If a module name `<module_name>` is to be created with OpenAPI JSON file,
4
+ - The json file (say `openapi_spec.json`) should be placed in the directory `teradataml/data/sdk/<module_name>"` after creating required folders to maintain the folder structure.
5
+ - Create a folder `<module_name>` in `teradataml/sdk/` and place `__init__.py` file.
6
+ - Copy and paste the code from `teradataml/sdk/modelops/__init__.py` to newly created `__init__.py` file.
7
+ - Update the constants `SdkNames` and `SdkPackagePaths` in `teradataml/sdk/constants.py` to name the module and locate to appropriate location of OpenAPI JSON spec.
8
+ - Update the values to the constants `SdkNames` and `SdkPackagePaths` in `__init__.py`.
9
+ - Create `teradataml/sdk/<module_name>/_constants.py`.
10
+ - Copy and paste the code from `teradataml/sdk/modelops/_constants.py`. Keep empty dictionaries if no change in class names and function names is required. Fill in the dictionary similar to `teradataml/sdk/modelops/_constants.py` with intended class and function names.
11
+ - If customization is needed in client object, copy and paste the file `teradataml/sdk/modelops/_client.py` to `teradataml/sdk/<module_name>/_client.py` and update corresponding imports (for new client) in `teradataml/sdk/<module_name>/__init__.py`. Otherwise, user can use `BaseClient` from `teradataml/sdk/api_client.py`.
12
+ - Generate Pydantic models for OpenAPI schema using below commands which will create `teradataml/sdk/<module_name>/models.py`. Add unit test cases similar to `teradataml/tests/unit/sdk/test_modelops_schema.py` which import models and use helper class to bulk test the classes.
13
+ ```shell
14
+ pip install datamodel-code-generator==0.27.3
15
+ # Run below command from pyTeradata directory.
16
+ datamodel-codegen --input teradataml/data/sdk/<module_name>/openapi_spec.json --input-file-type openapi --output teradataml/sdk/<module_name>/models.py --output-model-type pydantic_v2.BaseModel --use-field-description --keep-model-order --target-python-version=3.8 --use-schema-description --field-constraints --allow-population-by-field-name --strict-types bool int float # From windows use datamodel-codegen.exe
17
+ ```
18
+ - If there are not schema in OpenAPI spec, create empty file `teradataml/sdk/<module_name>/models.py`.
19
+
20
+
21
+ ## What is created dynamically
22
+
23
+ When the user runs `from teradataml.sdk.<module_name> import *` or `from teradataml.sdk.<module_name> import AnyClass`, it creates classes and class methods dynamically.
24
+
25
+ How are these classes created?
26
+ - Tags from OpenAPI spec are converted to Camel case and used as classes.
27
+ - If any of the API endpoint methods does not have tags associated with them, such functions are kept in class name `DefaultApi`.
28
+
29
+ How are class methods created?
30
+ - All the API endpoint methods form each function of the class.
31
+ - The function names are taken from `OperationId` field of function in OpenAPI JSON spec. The value of `OperationId` is converted to Snake case along with replacing hyphens (`-`) with underscores (`_`). This new value is used as API function name for the user to call by passing parameters.
32
+
33
+
34
+ ## Example - Vantage ModelOps SDK
35
+
36
+ Couple of the tags in ModelOps OpenAPI spec is `Alert rules`, `Models`. These tags are converted to classes `AlertRules` and `Models` respectively.
37
+
38
+ The API end point `/api/models` contains `get` method with `operationId` as `getCollectionResource-model-get`. The framework creates `get_collection_resource_model_get(...)` function in `Models` class.
39
+
40
+ Similarly, the API end point `/api/models/{id}/alertRules` contains `get` method with `operationId` as `getAlertRules`. The framework creates `get_alert_rules(...)` functions in `AlertRules` class.
41
+
42
+ So, these API endpoints can be accessed through SDK as follows:
43
+ ```python
44
+ # Authenticate and connect to client.
45
+ from teradataml.sdk.modelops import ModelOpsClient
46
+ from teradataml.sdk import ClientCredentialsAuth # Three different authentication mechanisms are supported.
47
+ auth_obj = ClientCredentialsAuth(
48
+ auth_client_id="<client_id>",
49
+ auth_client_secret="<client_secret>",
50
+ auth_token_url="https://10.27.117.175/sso/realms/teradata/protocol/openid-connect/token"
51
+ )
52
+ client = ModelOpsCleint(
53
+ base_url="https://10.27.117.175/core",
54
+ auth=auth_obj,
55
+ ssl_verify=False
56
+ )
57
+
58
+ # Import required classes.
59
+ from teradataml.sdk.modelops import AlertRules, Models
60
+
61
+ # Some APIs are tied with Project ID which needs to be set to the client.
62
+ client.set_project_id("<uuid_project_id>")
63
+
64
+ # Create Models object and get all the models.
65
+ mod = Models(client=client)
66
+ models = mod.get_collection_resource_model_get()
67
+
68
+ # Get alert rules for any one of the model.
69
+ ar = AlertRules(client=client)
70
+ ar.get_alert_rules(id="<uuid_model_id>")
71
+ ```
72
+
73
+ ## Note:
74
+ - All the argument to the API functions are read as `**kwargs`. So, the user has to pass keyword arguments i.e., positional argument usage is not supported yet.
75
+ - The following validations are done for arguments which accepts basic data types:
76
+ - Missing required arguments.
77
+ - Invalid type passed to arguments.
78
+ - Invalid (non-permitted) value passed to arguments.
79
+ - Validations for dict type objects (like input for `requestBody`) are yet to be added.
@@ -0,0 +1,4 @@
1
+ from teradataml.sdk._auth_modes import (BearerAuth, ClientCredentialsAuth,
2
+ DeviceCodeAuth)
3
+ from teradataml.sdk.api_client import Client
4
+ from teradataml.sdk.constants import SdkPackagePaths
@@ -0,0 +1,422 @@
1
+ # ################################################################################################
2
+ #
3
+ # Copyright 2025 Teradata. All rights reserved.
4
+ # TERADATA CONFIDENTIAL AND TRADE SECRET
5
+ #
6
+ # Primary Owner: Adithya Avvaru (adithya.avvaru@teradata.com)
7
+ # Secondary Owner: Pankaj Purandare (pankajvinod.purandare@teradata.com)
8
+ #
9
+ # Version: 1.0
10
+ # SDK Version: 1.0
11
+ #
12
+ # This file contains different authentication modes and corresponding classes for the OpenAPI SDK.
13
+ #
14
+ # ################################################################################################
15
+
16
+ import json
17
+ import logging
18
+ import os
19
+ import re
20
+ import time
21
+ from abc import ABC, abstractmethod
22
+ from enum import Enum
23
+
24
+ import requests
25
+ from oauthlib.oauth2 import BackendApplicationClient
26
+ from requests.auth import HTTPBasicAuth
27
+ from requests_oauthlib import OAuth2Session
28
+
29
+ from teradataml.common.exceptions import TeradataMlException
30
+ from teradataml.common.messages import MessageCodes, Messages
31
+ from teradataml.utils.validators import _Validators
32
+
33
+ from .spinner import spin_it
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ class AuthMode(Enum):
39
+ DEVICE_CODE = "device_code"
40
+ CLIENT_CREDENTIALS = "client_credentials"
41
+ BEARER = "bearer"
42
+
43
+
44
+ class _BaseAuth(ABC):
45
+ AUTH_MODE = None
46
+
47
+ def __init__(self):
48
+
49
+ self.session = None
50
+ self._ssl_verify = None
51
+ self._base_url = None
52
+
53
+ @abstractmethod
54
+ def authenticate(self, **kwargs):
55
+ raise NotImplementedError("Subclasses must implement authenticate method")
56
+
57
+ def _set_session_tls(self):
58
+ self.session.verify = self._ssl_verify
59
+ if not self._ssl_verify:
60
+ import urllib3
61
+ from urllib3.exceptions import InsecureRequestWarning
62
+
63
+ logger.warning(
64
+ "Certificate validation disabled. Adding certificate verification is"
65
+ " strongly advised"
66
+ )
67
+ urllib3.disable_warnings(InsecureRequestWarning)
68
+
69
+
70
+ class ClientCredentialsAuth(_BaseAuth):
71
+ """
72
+ Class to handle authentication using client credentials.
73
+ """
74
+ AUTH_MODE = AuthMode.CLIENT_CREDENTIALS
75
+
76
+ def __init__(self, auth_token_url, auth_client_id, auth_client_secret):
77
+ """
78
+ DESCRIPTION:
79
+ Initializes the object to authenticate through client credentials authentication.
80
+
81
+ PARAMETERS:
82
+ auth_token_url:
83
+ Required Argument.
84
+ Specifies the token endpoint URL to fetch the access token.
85
+ Types: str
86
+
87
+ auth_client_id:
88
+ Required Argument.
89
+ Specifies the client ID for authentication.
90
+ Types: str
91
+
92
+ auth_client_secret:
93
+ Required Argument.
94
+ Specifies the client secret for authentication.
95
+ Types: str
96
+
97
+ RETURNS:
98
+ None
99
+
100
+ RAISES:
101
+ None
102
+
103
+ EXAMPLES:
104
+ >>> from teradataml.sdk import ClientCredentialsAuth
105
+ >>> auth = ClientCredentialsAuth(
106
+ auth_token_url="https://example.com/token",
107
+ auth_client_id="your_client_id",
108
+ auth_client_secret="your_client_secret"
109
+ )
110
+ """
111
+ arg_info_matrix = []
112
+ arg_info_matrix.append(["auth_token_url", auth_token_url, False, (str,), True])
113
+ arg_info_matrix.append(["auth_client_id", auth_client_id, False, (str,), True])
114
+ arg_info_matrix.append(["auth_client_secret", auth_client_secret, False, (str,), True])
115
+ _Validators._validate_missing_required_arguments(arg_info_matrix)
116
+ _Validators._validate_function_arguments(arg_info_matrix)
117
+
118
+ self._auth_client_id = auth_client_id
119
+ self._auth_client_secret = auth_client_secret
120
+ self._auth_token_url = auth_token_url
121
+
122
+ def authenticate(self):
123
+ """
124
+ DESCRIPTION:
125
+ Authenticates using client credentials and fetches the access token.
126
+
127
+ PARAMETERS:
128
+ None
129
+
130
+ RETURNS:
131
+ requests.Session: Authenticated session with the access token.
132
+
133
+ RAISES:
134
+ None
135
+
136
+ EXAMPLES:
137
+ >>> from teradataml.sdk import ClientCredentialsAuth
138
+ >>> auth = ClientCredentialsAuth(
139
+ auth_token_url="https://example.com/token",
140
+ auth_client_id="your_client_id",
141
+ auth_client_secret="your_client_secret"
142
+ )
143
+ >>> session = auth.authenticate()
144
+ """
145
+ self.session = OAuth2Session(client=BackendApplicationClient(client_id=self._auth_client_id))
146
+
147
+ self._set_session_tls()
148
+ self.session.fetch_token(
149
+ token_url=self._auth_token_url,
150
+ auth=HTTPBasicAuth(self._auth_client_id, self._auth_client_secret),
151
+ verify=self._ssl_verify,
152
+ )
153
+
154
+ return self.session
155
+
156
+
157
+ class DeviceCodeAuth(_BaseAuth):
158
+ """
159
+ Class to handle authentication using device code.
160
+ """
161
+ AUTH_MODE = AuthMode.DEVICE_CODE
162
+
163
+ def __init__(self, auth_token_url, auth_device_auth_url, auth_client_id, auth_client_secret=None):
164
+ """
165
+ DESCRIPTION:
166
+ Initializes the object to authenticate through device code authentication.
167
+
168
+ PARAMETERS:
169
+ auth_token_url:
170
+ Required Argument.
171
+ Specifies the token endpoint URL to fetch the access token.
172
+ Types: str
173
+
174
+ auth_device_auth_url:
175
+ Required Argument.
176
+ Specifies the device code endpoint URL to initiate device code flow.
177
+ Types: str
178
+
179
+ auth_client_id:
180
+ Required Argument.
181
+ Specifies the client ID for authentication.
182
+ Types: str
183
+
184
+ auth_client_secret:
185
+ Optional Argument.
186
+ Specifies the client secret for authentication.
187
+ Types: str or None
188
+
189
+ RETURNS:
190
+ None
191
+
192
+ RAISES:
193
+ None
194
+
195
+ EXAMPLES:
196
+ >>> from teradataml.sdk import DeviceCodeAuth
197
+ >>> auth = DeviceCodeAuth(
198
+ auth_token_url="https://example.com/token",
199
+ auth_device_auth_url="https://example.com/device_auth",
200
+ auth_client_id="your_client_id",
201
+ auth_client_secret="your_client_secret"
202
+ )
203
+ """
204
+ arg_info_matrix = []
205
+ arg_info_matrix.append(["auth_token_url", auth_token_url, False, (str,), True])
206
+ arg_info_matrix.append(["auth_device_auth_url", auth_device_auth_url, False, (str,), True])
207
+ arg_info_matrix.append(["auth_client_id", auth_client_id, False, (str,), True])
208
+ arg_info_matrix.append(["auth_client_secret", auth_client_secret, True, (str,), True])
209
+ _Validators._validate_missing_required_arguments(arg_info_matrix)
210
+ _Validators._validate_function_arguments(arg_info_matrix)
211
+
212
+ self._auth_client_id = auth_client_id
213
+ self._auth_client_secret = auth_client_secret
214
+ self._auth_token_url = auth_token_url
215
+ self._auth_device_auth_url = auth_device_auth_url
216
+
217
+ def authenticate(self, token_cache_file_path=None):
218
+ """
219
+ DESCRIPTION:
220
+ Authenticates using device code flow and fetches the access token.
221
+
222
+ PARAMETERS:
223
+ token_cache_file_path:
224
+ Optional Argument.
225
+ Specifies the file path to load and/or cache the token data.
226
+ Types: str
227
+
228
+ RETURNS:
229
+ requests.Session: Authenticated session with the access token.
230
+
231
+ RAISES:
232
+ None
233
+
234
+ EXAMPLES:
235
+ >>> from teradataml.sdk import DeviceCodeAuth
236
+ >>> auth = DeviceCodeAuth(
237
+ auth_token_url="https://example.com/token",
238
+ auth_device_auth_url="https://example.com/device_auth",
239
+ auth_client_id="your_client_id",
240
+ auth_client_secret="your_client_secret"
241
+ )
242
+ >>> session = auth.authenticate(token_cache_file_path="/path/to/token_cache.json")
243
+ """
244
+ arg_info_matrix = []
245
+ arg_info_matrix.append(["token_cache_file_path", token_cache_file_path, True, (str,), True])
246
+ _Validators._validate_missing_required_arguments(arg_info_matrix)
247
+ _Validators._validate_function_arguments(arg_info_matrix)
248
+
249
+ token = None
250
+ if token_cache_file_path and os.path.exists(token_cache_file_path):
251
+ logger.debug(
252
+ f"Loading cached token data from {token_cache_file_path}"
253
+ )
254
+ with open(token_cache_file_path, "r") as f:
255
+ token = json.load(f)
256
+
257
+ if not token:
258
+ self.session = requests.session()
259
+ self._set_session_tls()
260
+ token = self._get_device_code()
261
+
262
+ if "access_token" in token:
263
+ logger.debug(f"Access token acquired successfully: {token}")
264
+
265
+ self.__prepare_session_for_token()
266
+
267
+ # Create session.
268
+ _bearer = BearerAuth(auth_bearer=token["access_token"])
269
+ _bearer._ssl_verify = self._ssl_verify
270
+ _bearer._base_url = self._base_url
271
+ self.session = _bearer.authenticate()
272
+
273
+ elif "refresh_token" in token:
274
+ logger.debug(f"Refresh token acquired successfully: {token}")
275
+
276
+ self.__prepare_session_for_token()
277
+
278
+ # Refresh token for the session.
279
+ self.session.refresh_token(
280
+ token_url=self._auth_token_url,
281
+ refresh_token=token["refresh_token"],
282
+ auth=HTTPBasicAuth(self._auth_client_id, self._auth_client_secret),
283
+ verify=self._ssl_verify,
284
+ )
285
+
286
+ else:
287
+ raise TeradataMlException(Messages.get_message(MessageCodes.REST_DEVICE_CODE_NO_BOTH, token),
288
+ MessageCodes.REST_DEVICE_CODE_NO_BOTH)
289
+
290
+ with open(token_cache_file_path, "w") as f:
291
+ json.dump(token, f)
292
+
293
+ return self.session
294
+
295
+ def __prepare_session_for_token(self):
296
+ session = OAuth2Session(client_id=self._auth_client_id)
297
+
298
+ # don't chase certs/print warning for TLS if already done for _get_device_code
299
+ if hasattr(self, "session"):
300
+ session.verify = self.session.verify
301
+ self.session = session
302
+ else:
303
+ self.session = session
304
+ self._set_session_tls()
305
+
306
+ def _get_device_code(self):
307
+ device_code_response = self.session.post(
308
+ self._auth_device_auth_url,
309
+ data={"client_id": self._auth_client_id, "scope": "openid profile"},
310
+ )
311
+
312
+ if device_code_response.status_code != 200:
313
+ raise TeradataMlException(Messages.get_message(MessageCodes.REST_DEVICE_CODE_GEN_FAILED,
314
+ device_code_response.status_code),
315
+ MessageCodes.REST_DEVICE_CODE_GEN_FAILED)
316
+
317
+ device_code_data = device_code_response.json()
318
+ print(
319
+ "1. On your computer or mobile device navigate to: ",
320
+ device_code_data["verification_uri_complete"],
321
+ )
322
+ print("2. Enter the following code: ", device_code_data["user_code"])
323
+
324
+ def authorize():
325
+ authenticated = False
326
+ token_data = None
327
+
328
+ while not authenticated:
329
+ token_response = self.session.post(
330
+ self._auth_token_url,
331
+ data={
332
+ "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
333
+ "device_code": device_code_data["device_code"],
334
+ "client_id": self._auth_client_id,
335
+ },
336
+ )
337
+
338
+ token_data = token_response.json()
339
+ if token_response.status_code == 200:
340
+ authenticated = True
341
+
342
+ elif "error" in token_data:
343
+ if token_data["error"] in ("authorization_pending", "slow_down"):
344
+ time.sleep(device_code_data["interval"])
345
+ else:
346
+ raise TeradataMlException(Messages.get_message(MessageCodes.REST_DEVICE_CODE_AUTH_FAILED,
347
+ token_data["error_description"]),
348
+ MessageCodes.REST_DEVICE_CODE_AUTH_FAILED)
349
+
350
+ else:
351
+ raise TeradataMlException(Messages.get_message(MessageCodes.REST_DEVICE_CODE_AUTH_FAILED,
352
+ f"Bad response code: {token_response.status_code}"),
353
+ MessageCodes.REST_DEVICE_CODE_AUTH_FAILED)
354
+
355
+ return token_data
356
+
357
+ msg = "Waiting for device code to be authorized\n"
358
+ res = spin_it(authorize, msg, 3)
359
+ print(
360
+ "\033[32m\U0001f512 This device has been authorized successfully.\033[0m\n"
361
+ )
362
+ return res
363
+
364
+
365
+ class BearerAuth(_BaseAuth):
366
+ """
367
+ Class to handle authentication using bearer token.
368
+ """
369
+ AUTH_MODE = AuthMode.BEARER
370
+
371
+ def __init__(self, auth_bearer):
372
+ """
373
+ DESCRIPTION:
374
+ Initializes the object to authenticate through bearer token authentication.
375
+
376
+ PARAMETERS:
377
+ auth_bearer:
378
+ Required Argument.
379
+ Specifies the raw bearer token to be used for authentication.
380
+ Types: str
381
+
382
+ RETURNS:
383
+ None
384
+
385
+ RAISES:
386
+ None
387
+
388
+ EXAMPLES:
389
+ >>> from teradataml.sdk import BearerAuth
390
+ >>> auth = BearerAuth(auth_bearer="your_bearer_token")
391
+ """
392
+ arg_info_matrix = [["auth_bearer", auth_bearer, False, (str,), True]]
393
+ _Validators._validate_missing_required_arguments(arg_info_matrix)
394
+ _Validators._validate_function_arguments(arg_info_matrix)
395
+
396
+ self._auth_bearer = f"Bearer {auth_bearer}"
397
+
398
+ def authenticate(self):
399
+ """
400
+ DESCRIPTION:
401
+ Authenticates using the provided bearer token.
402
+
403
+ PARAMETERS:
404
+ None
405
+
406
+ RETURNS:
407
+ requests.Session: Authenticated session with the bearer token.
408
+
409
+ RAISES:
410
+ None
411
+
412
+ EXAMPLES:
413
+ >>> from teradataml.sdk import BearerAuth
414
+ >>> auth = BearerAuth(auth_bearer="your_bearer_token")
415
+ >>> session = auth.authenticate()
416
+ """
417
+ self.session = requests.session()
418
+ self.session.headers.update({"Authorization": self._auth_bearer})
419
+
420
+ self._set_session_tls()
421
+
422
+ return self.session