truefoundry 0.4.0rc1__py3-none-any.whl → 0.4.0rc3__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 truefoundry might be problematic. Click here for more details.
- truefoundry/__init__.py +2 -0
- truefoundry/autodeploy/agents/developer.py +1 -1
- truefoundry/autodeploy/agents/project_identifier.py +2 -2
- truefoundry/autodeploy/agents/tester.py +1 -1
- truefoundry/autodeploy/cli.py +1 -1
- truefoundry/autodeploy/tools/list_files.py +1 -1
- truefoundry/{deploy/lib/auth → common}/auth_service_client.py +50 -40
- truefoundry/common/constants.py +12 -0
- truefoundry/{deploy/lib/auth → common}/credential_file_manager.py +7 -7
- truefoundry/{deploy/lib/auth → common}/credential_provider.py +9 -12
- truefoundry/{ml/services → common}/entities.py +57 -41
- truefoundry/common/exceptions.py +12 -0
- truefoundry/common/request_utils.py +36 -8
- truefoundry/common/servicefoundry_client.py +91 -0
- truefoundry/common/utils.py +56 -0
- truefoundry/deploy/auto_gen/models.py +4 -6
- truefoundry/deploy/cli/cli.py +2 -0
- truefoundry/deploy/cli/commands/apply_command.py +1 -1
- truefoundry/deploy/cli/commands/build_command.py +1 -1
- truefoundry/deploy/cli/commands/deploy_command.py +1 -1
- truefoundry/deploy/cli/commands/login_command.py +2 -2
- truefoundry/deploy/cli/commands/patch_application_command.py +1 -1
- truefoundry/deploy/cli/commands/patch_command.py +1 -1
- truefoundry/deploy/cli/commands/terminate_comand.py +1 -1
- truefoundry/deploy/cli/util.py +1 -1
- truefoundry/deploy/function_service/remote/remote.py +1 -1
- truefoundry/deploy/lib/auth/servicefoundry_session.py +2 -2
- truefoundry/deploy/lib/clients/servicefoundry_client.py +120 -150
- truefoundry/deploy/lib/const.py +1 -35
- truefoundry/deploy/lib/exceptions.py +0 -11
- truefoundry/deploy/lib/model/entity.py +1 -112
- truefoundry/deploy/lib/session.py +13 -26
- truefoundry/deploy/lib/util.py +0 -37
- truefoundry/deploy/v2/lib/deploy.py +3 -3
- truefoundry/deploy/v2/lib/deployable_patched_models.py +1 -1
- truefoundry/ml/__init__.py +0 -9
- truefoundry/ml/artifact/truefoundry_artifact_repo.py +63 -22
- truefoundry/ml/autogen/client/__init__.py +0 -3
- truefoundry/ml/autogen/client/api/experiments_api.py +0 -165
- truefoundry/ml/autogen/client/models/__init__.py +0 -3
- truefoundry/ml/autogen/client/models/artifact_dto.py +6 -6
- truefoundry/ml/autogen/client/models/artifact_version_dto.py +8 -8
- truefoundry/ml/autogen/client/models/create_artifact_response_dto.py +2 -3
- truefoundry/ml/autogen/client/models/create_artifact_version_response_dto.py +2 -3
- truefoundry/ml/autogen/client/models/create_python_deployment_config_request_dto.py +2 -2
- truefoundry/ml/autogen/client/models/create_python_deployment_config_response_dto.py +2 -3
- truefoundry/ml/autogen/client/models/create_run_request_dto.py +5 -5
- truefoundry/ml/autogen/client/models/create_run_response_dto.py +2 -3
- truefoundry/ml/autogen/client/models/dataset_dto.py +10 -10
- truefoundry/ml/autogen/client/models/experiment_dto.py +18 -18
- truefoundry/ml/autogen/client/models/get_latest_run_log_response_dto.py +2 -3
- truefoundry/ml/autogen/client/models/get_tenant_id_response_dto.py +4 -5
- truefoundry/ml/autogen/client/models/model_dto.py +6 -6
- truefoundry/ml/autogen/client/models/model_version_dto.py +15 -8
- truefoundry/ml/autogen/client/models/run_info_dto.py +10 -10
- truefoundry/ml/autogen/client/models/update_run_response_dto.py +2 -3
- truefoundry/ml/autogen/client_README.md +0 -2
- truefoundry/ml/clients/entities.py +8 -0
- truefoundry/ml/{services/servicefoundry_service.py → clients/servicefoundry_client.py} +20 -10
- truefoundry/ml/{services → clients}/utils.py +2 -2
- truefoundry/ml/entities.py +62 -0
- truefoundry/ml/env_vars.py +1 -5
- truefoundry/ml/internal_namespace.py +8 -8
- truefoundry/ml/log_types/artifacts/artifact.py +7 -3
- truefoundry/ml/log_types/artifacts/dataset.py +5 -4
- truefoundry/ml/log_types/artifacts/model.py +8 -25
- truefoundry/ml/log_types/image/image.py +7 -8
- truefoundry/ml/log_types/image/image_normalizer.py +7 -6
- truefoundry/ml/mlfoundry_api.py +10 -55
- truefoundry/ml/mlfoundry_run.py +6 -41
- truefoundry/ml/run_utils.py +1 -10
- truefoundry/ml/session.py +14 -117
- truefoundry/pydantic_v1.py +1 -1
- truefoundry/workflow/__init__.py +16 -1
- {truefoundry-0.4.0rc1.dist-info → truefoundry-0.4.0rc3.dist-info}/METADATA +1 -1
- {truefoundry-0.4.0rc1.dist-info → truefoundry-0.4.0rc3.dist-info}/RECORD +79 -77
- truefoundry/deploy/lib/clients/utils.py +0 -41
- truefoundry/ml/autogen/client/models/backfill_default_storage_integration_id_request_dto.py +0 -67
- truefoundry/ml/login.py +0 -241
- truefoundry/ml/services/auth_service.py +0 -109
- /truefoundry/ml/{services → clients}/__init__.py +0 -0
- {truefoundry-0.4.0rc1.dist-info → truefoundry-0.4.0rc3.dist-info}/WHEEL +0 -0
- {truefoundry-0.4.0rc1.dist-info → truefoundry-0.4.0rc3.dist-info}/entry_points.txt +0 -0
truefoundry/ml/login.py
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import threading
|
|
3
|
-
from functools import lru_cache, wraps
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
import click
|
|
8
|
-
from filelock import FileLock, Timeout
|
|
9
|
-
|
|
10
|
-
from truefoundry.ml.env_vars import API_KEY_GLOBAL, TRACKING_HOST_GLOBAL
|
|
11
|
-
from truefoundry.ml.exceptions import MlFoundryException
|
|
12
|
-
from truefoundry.ml.logger import logger
|
|
13
|
-
from truefoundry.ml.run_utils import resolve_tracking_uri
|
|
14
|
-
from truefoundry.ml.services.auth_service import get_auth_service
|
|
15
|
-
from truefoundry.ml.services.entities import Token
|
|
16
|
-
from truefoundry.pydantic_v1 import BaseModel, Field, NonEmptyStr
|
|
17
|
-
|
|
18
|
-
CREDENTIALS_DIR = Path.home() / ".truefoundry"
|
|
19
|
-
CREDENTIALS_FILE = CREDENTIALS_DIR / "credentials.json"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
OLD_CREDENTIALS_DIR = Path.home() / ".mlfoundry"
|
|
23
|
-
OLD_CREDENTIALS_FILE = OLD_CREDENTIALS_DIR / "credentials.netrc"
|
|
24
|
-
|
|
25
|
-
if OLD_CREDENTIALS_FILE.exists():
|
|
26
|
-
logger.warning(
|
|
27
|
-
"%s file is deprecated. You can delete this file now.", OLD_CREDENTIALS_FILE
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class CredentialsFileContent(BaseModel):
|
|
32
|
-
access_token: NonEmptyStr = Field(repr=False)
|
|
33
|
-
refresh_token: Optional[NonEmptyStr] = Field(repr=False)
|
|
34
|
-
host: NonEmptyStr
|
|
35
|
-
|
|
36
|
-
class Config:
|
|
37
|
-
allow_mutation = False
|
|
38
|
-
|
|
39
|
-
def to_token(self) -> Token:
|
|
40
|
-
return Token(
|
|
41
|
-
access_token=self.access_token, # type: ignore[call-arg]
|
|
42
|
-
refresh_token=self.refresh_token,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def _ensure_lock_taken(method):
|
|
47
|
-
@wraps(method)
|
|
48
|
-
def lock_guard(self: "CredentialsFileManager", *method_args, **method_kwargs):
|
|
49
|
-
if not self.lock_taken():
|
|
50
|
-
raise Exception(
|
|
51
|
-
"Trying to write to credential file without using with block"
|
|
52
|
-
)
|
|
53
|
-
return method(self, *method_args, **method_kwargs)
|
|
54
|
-
|
|
55
|
-
return lock_guard
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
CRED_FILE_THREAD_LOCK = threading.RLock()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@lru_cache(maxsize=None)
|
|
62
|
-
def get_file_lock(lock_file_path: str) -> FileLock:
|
|
63
|
-
return FileLock(lock_file_path)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class CredentialsFileManager:
|
|
67
|
-
def __init__(
|
|
68
|
-
self,
|
|
69
|
-
credentials_file_path: Path = CREDENTIALS_FILE,
|
|
70
|
-
lock_timeout: float = 60.0,
|
|
71
|
-
):
|
|
72
|
-
credentials_file_path = credentials_file_path.absolute()
|
|
73
|
-
|
|
74
|
-
logger.debug("credential file path %r", credentials_file_path)
|
|
75
|
-
|
|
76
|
-
credentials_lock_file_path = f"{credentials_file_path}.lock"
|
|
77
|
-
|
|
78
|
-
logger.debug("credential lock file path %r", credentials_lock_file_path)
|
|
79
|
-
self._credentials_file_path = credentials_file_path
|
|
80
|
-
|
|
81
|
-
cred_file_dir = credentials_file_path.parent
|
|
82
|
-
cred_file_dir.mkdir(exist_ok=True, parents=True)
|
|
83
|
-
|
|
84
|
-
self._file_lock = get_file_lock(credentials_lock_file_path)
|
|
85
|
-
self._lock_timeout = lock_timeout
|
|
86
|
-
self._lock_owner: Optional[int] = None
|
|
87
|
-
|
|
88
|
-
def __enter__(self) -> "CredentialsFileManager":
|
|
89
|
-
# The lock objects are recursive locks, which means that once acquired,
|
|
90
|
-
# they will not block on successive lock requests:
|
|
91
|
-
lock_aquired = CRED_FILE_THREAD_LOCK.acquire(timeout=self._lock_timeout)
|
|
92
|
-
if not lock_aquired:
|
|
93
|
-
raise MlFoundryException(
|
|
94
|
-
"Could not aquire CRED_FILE_THREAD_LOCK"
|
|
95
|
-
f" in {self._lock_timeout} seconds"
|
|
96
|
-
)
|
|
97
|
-
try:
|
|
98
|
-
self._file_lock.acquire(timeout=self._lock_timeout)
|
|
99
|
-
except Timeout as ex:
|
|
100
|
-
raise MlFoundryException(
|
|
101
|
-
f"Failed to aquire lock on credential file within {self._lock_timeout} seconds.\n"
|
|
102
|
-
"Is any other process trying to login?"
|
|
103
|
-
) from ex
|
|
104
|
-
logger.debug("Acquired file and thread lock to access credential file")
|
|
105
|
-
self._lock_owner = threading.get_ident()
|
|
106
|
-
return self
|
|
107
|
-
|
|
108
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
109
|
-
self._file_lock.release()
|
|
110
|
-
CRED_FILE_THREAD_LOCK.release()
|
|
111
|
-
logger.debug("Released file and thread lock to access credential file")
|
|
112
|
-
self._lock_owner = None
|
|
113
|
-
|
|
114
|
-
def lock_taken(self) -> bool:
|
|
115
|
-
return self._lock_owner == threading.get_ident()
|
|
116
|
-
|
|
117
|
-
@_ensure_lock_taken
|
|
118
|
-
def read(self) -> CredentialsFileContent:
|
|
119
|
-
try:
|
|
120
|
-
return CredentialsFileContent.parse_file(self._credentials_file_path)
|
|
121
|
-
except Exception as ex:
|
|
122
|
-
raise MlFoundryException(
|
|
123
|
-
"Error while reading the credentials file "
|
|
124
|
-
f"{self._credentials_file_path}. Please login again "
|
|
125
|
-
"using `tfy login` command or `truefoundry.login()` function"
|
|
126
|
-
) from ex
|
|
127
|
-
|
|
128
|
-
@_ensure_lock_taken
|
|
129
|
-
def write(self, credentials_file_content: CredentialsFileContent):
|
|
130
|
-
if not isinstance(credentials_file_content, CredentialsFileContent):
|
|
131
|
-
raise MlFoundryException(
|
|
132
|
-
"Only object of type `CredentialsFileContent` is allowed. "
|
|
133
|
-
f"Got {type(credentials_file_content)}"
|
|
134
|
-
)
|
|
135
|
-
logger.debug("Updating the credential file content")
|
|
136
|
-
with open(self._credentials_file_path, "w", encoding="utf8") as file:
|
|
137
|
-
file.write(credentials_file_content.json())
|
|
138
|
-
|
|
139
|
-
@_ensure_lock_taken
|
|
140
|
-
def exists(self) -> bool:
|
|
141
|
-
return self._credentials_file_path.exists()
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def login(
|
|
145
|
-
tracking_uri: Optional[str] = None,
|
|
146
|
-
relogin: bool = False,
|
|
147
|
-
api_key: Optional[str] = None,
|
|
148
|
-
) -> bool:
|
|
149
|
-
"""Save API key in local file system for a given `tracking_uri`.
|
|
150
|
-
|
|
151
|
-
Args:
|
|
152
|
-
tracking_uri (Optional[str], optional): tracking_uri for the given API key
|
|
153
|
-
relogin (bool, optional): Overwrites the existing API key for the `tracking_uri` if
|
|
154
|
-
set to `True`. If set to `False` and an API key is already present for
|
|
155
|
-
the given `tracking_uri`, then the existing API key is kept untouched.
|
|
156
|
-
Default is `False`.
|
|
157
|
-
api_key (Optional[str], optional): The API key for the given `tracking_uri`.
|
|
158
|
-
If `api_key` is not passed, this function prompts for the API key.
|
|
159
|
-
|
|
160
|
-
Returns:
|
|
161
|
-
bool: Returns `True` if any credential was persisted.
|
|
162
|
-
"""
|
|
163
|
-
from truefoundry.ml.session import EnvCredentialProvider
|
|
164
|
-
|
|
165
|
-
if API_KEY_GLOBAL in os.environ and TRACKING_HOST_GLOBAL in os.environ:
|
|
166
|
-
logger.warning(
|
|
167
|
-
"Skipping login because environment variables %s and "
|
|
168
|
-
"%s are set and will be used when running truefoundry. "
|
|
169
|
-
"If you want to relogin then unset these environment keys.",
|
|
170
|
-
TRACKING_HOST_GLOBAL,
|
|
171
|
-
API_KEY_GLOBAL,
|
|
172
|
-
)
|
|
173
|
-
return False
|
|
174
|
-
|
|
175
|
-
if EnvCredentialProvider.can_provide():
|
|
176
|
-
logger.warning(
|
|
177
|
-
"TFY_API_KEY env var is already set. "
|
|
178
|
-
"When running mlfoundry, it will use the api key to authorize.\n"
|
|
179
|
-
"Login will just save the credentials on disk."
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
tracking_uri = resolve_tracking_uri(tracking_uri).strip("/")
|
|
183
|
-
auth_service = get_auth_service(tracking_uri=tracking_uri)
|
|
184
|
-
|
|
185
|
-
cred_file = CredentialsFileManager()
|
|
186
|
-
|
|
187
|
-
with cred_file:
|
|
188
|
-
if not relogin and cred_file.exists():
|
|
189
|
-
cred_file_content = cred_file.read()
|
|
190
|
-
if tracking_uri != cred_file_content.host:
|
|
191
|
-
if click.confirm(
|
|
192
|
-
f"Already logged in to {cred_file_content.host!r}\n"
|
|
193
|
-
f"Do you want to relogin to {tracking_uri!r}?"
|
|
194
|
-
):
|
|
195
|
-
return login(
|
|
196
|
-
tracking_uri=tracking_uri, relogin=True, api_key=api_key
|
|
197
|
-
)
|
|
198
|
-
user_info = cred_file_content.to_token().to_user_info()
|
|
199
|
-
user_name_display_info = user_info.email or user_info.user_type.value
|
|
200
|
-
print(
|
|
201
|
-
f"Already logged in to {cred_file_content.host!r} as "
|
|
202
|
-
f"{user_info.user_id!r} ({user_name_display_info!r})\n"
|
|
203
|
-
"Please use `tfy login --relogin` or `truefoundry.login(relogin=True)` "
|
|
204
|
-
"to force relogin"
|
|
205
|
-
)
|
|
206
|
-
return False
|
|
207
|
-
|
|
208
|
-
if api_key:
|
|
209
|
-
logger.debug("Logging in with api key")
|
|
210
|
-
token = Token(access_token=api_key, refresh_token=None) # type: ignore[call-arg]
|
|
211
|
-
cred_file_content = CredentialsFileContent(
|
|
212
|
-
access_token=token.access_token,
|
|
213
|
-
refresh_token=token.refresh_token,
|
|
214
|
-
host=tracking_uri,
|
|
215
|
-
)
|
|
216
|
-
cred_file.write(cred_file_content)
|
|
217
|
-
else:
|
|
218
|
-
device_code = auth_service.get_device_code()
|
|
219
|
-
url_to_go = device_code.get_user_clickable_url(tracking_uri=tracking_uri)
|
|
220
|
-
print(f"Opening:- {url_to_go}")
|
|
221
|
-
print(
|
|
222
|
-
"Please click on the above link if it is not "
|
|
223
|
-
"automatically opened in a browser window."
|
|
224
|
-
)
|
|
225
|
-
click.launch(url_to_go)
|
|
226
|
-
token = auth_service.get_token_from_device_code(
|
|
227
|
-
device_code=device_code.device_code, timeout=120
|
|
228
|
-
)
|
|
229
|
-
cred_file_content = CredentialsFileContent(
|
|
230
|
-
access_token=token.access_token,
|
|
231
|
-
refresh_token=token.refresh_token,
|
|
232
|
-
host=tracking_uri,
|
|
233
|
-
)
|
|
234
|
-
cred_file.write(cred_file_content)
|
|
235
|
-
|
|
236
|
-
user_info = token.to_user_info()
|
|
237
|
-
user_name_display_info = user_info.email or user_info.user_type.value
|
|
238
|
-
print(
|
|
239
|
-
f"Logged in to {cred_file_content.host!r} as {user_info.user_id!r} ({user_name_display_info})"
|
|
240
|
-
)
|
|
241
|
-
return True
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
from urllib.parse import urlparse
|
|
3
|
-
|
|
4
|
-
from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
5
|
-
ApiClient,
|
|
6
|
-
AuthApi,
|
|
7
|
-
Configuration,
|
|
8
|
-
)
|
|
9
|
-
from truefoundry.ml.exceptions import MlFoundryException
|
|
10
|
-
from truefoundry.ml.logger import logger
|
|
11
|
-
from truefoundry.ml.run_utils import append_path_to_rest_tracking_uri
|
|
12
|
-
from truefoundry.ml.services.entities import (
|
|
13
|
-
AuthServerInfo,
|
|
14
|
-
DeviceCode,
|
|
15
|
-
HostCreds,
|
|
16
|
-
Token,
|
|
17
|
-
)
|
|
18
|
-
from truefoundry.ml.services.utils import http_request, http_request_safe
|
|
19
|
-
|
|
20
|
-
# TODO: This will eventually go away, this is duplicate of AuthServiceClient
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class AuthService:
|
|
24
|
-
def __init__(self, url: str, tenant_name: str):
|
|
25
|
-
self._host_creds = HostCreds(host=url.rstrip("/"), token=None)
|
|
26
|
-
self._tenant_name = tenant_name
|
|
27
|
-
|
|
28
|
-
def refresh_token(self, token: Token) -> Token:
|
|
29
|
-
if not token.refresh_token:
|
|
30
|
-
# TODO: Add a way to propagate error messages without traceback to the output interface side
|
|
31
|
-
raise MlFoundryException(
|
|
32
|
-
"Unable to resume login session. Please log in again using `tfy login [--host HOST] --relogin`"
|
|
33
|
-
)
|
|
34
|
-
try:
|
|
35
|
-
response = http_request_safe(
|
|
36
|
-
method="post",
|
|
37
|
-
host_creds=self._host_creds,
|
|
38
|
-
endpoint="api/v1/oauth/token/refresh",
|
|
39
|
-
json={
|
|
40
|
-
"tenantName": token.tenant_name,
|
|
41
|
-
"refreshToken": token.refresh_token,
|
|
42
|
-
},
|
|
43
|
-
timeout=3,
|
|
44
|
-
)
|
|
45
|
-
except MlFoundryException as e:
|
|
46
|
-
if e.status_code and (400 <= e.status_code < 500):
|
|
47
|
-
raise MlFoundryException(
|
|
48
|
-
"Unable to resume login session. "
|
|
49
|
-
"Please log in again using `tfy login [--host HOST] --relogin`"
|
|
50
|
-
) from None
|
|
51
|
-
raise
|
|
52
|
-
return Token.parse_obj(response)
|
|
53
|
-
|
|
54
|
-
def get_device_code(self) -> DeviceCode:
|
|
55
|
-
response = http_request_safe(
|
|
56
|
-
method="post",
|
|
57
|
-
host_creds=self._host_creds,
|
|
58
|
-
endpoint="api/v1/oauth/device",
|
|
59
|
-
json={"tenantName": self._tenant_name},
|
|
60
|
-
timeout=3,
|
|
61
|
-
)
|
|
62
|
-
return DeviceCode.parse_obj(response)
|
|
63
|
-
|
|
64
|
-
def get_token_from_device_code(
|
|
65
|
-
self, device_code: str, timeout: float = 60
|
|
66
|
-
) -> Token:
|
|
67
|
-
start_time = time.monotonic()
|
|
68
|
-
while (time.monotonic() - start_time) <= timeout:
|
|
69
|
-
response = http_request(
|
|
70
|
-
method="post",
|
|
71
|
-
host_creds=self._host_creds,
|
|
72
|
-
endpoint="api/v1/oauth/device/token",
|
|
73
|
-
json={"tenantName": self._tenant_name, "deviceCode": device_code},
|
|
74
|
-
timeout=3,
|
|
75
|
-
)
|
|
76
|
-
if response.status_code == 202:
|
|
77
|
-
logger.debug("User has not authorized yet. Checking again.")
|
|
78
|
-
time.sleep(1.0)
|
|
79
|
-
continue
|
|
80
|
-
if response.status_code == 201:
|
|
81
|
-
response = response.json()
|
|
82
|
-
return Token.parse_obj(response)
|
|
83
|
-
raise MlFoundryException(
|
|
84
|
-
"Failed to get token using device code.\n"
|
|
85
|
-
f"Status Code: {response.status_code},\nResponse: {response.text}"
|
|
86
|
-
)
|
|
87
|
-
raise MlFoundryException(f"Did not get authorized within {timeout} seconds.")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def get_auth_service(tracking_uri: str) -> AuthService:
|
|
91
|
-
tracking_uri = append_path_to_rest_tracking_uri(tracking_uri)
|
|
92
|
-
parsed_tracking_uri = urlparse(tracking_uri)
|
|
93
|
-
host = parsed_tracking_uri.netloc
|
|
94
|
-
# Anonymous api
|
|
95
|
-
api_client = ApiClient(
|
|
96
|
-
configuration=Configuration(
|
|
97
|
-
host=tracking_uri.rstrip("/"),
|
|
98
|
-
access_token=None,
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
auth_api = AuthApi(api_client=api_client)
|
|
102
|
-
auth_server_info = auth_api.get_tenant_id_get(
|
|
103
|
-
host_name=host,
|
|
104
|
-
_request_timeout=3,
|
|
105
|
-
)
|
|
106
|
-
tenant_info = AuthServerInfo.parse_obj(auth_server_info.dict())
|
|
107
|
-
return AuthService(
|
|
108
|
-
url=tenant_info.auth_server_url, tenant_name=tenant_info.tenant_name
|
|
109
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|