truefoundry 0.4.0rc2__py3-none-any.whl → 0.4.0rc4__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 +59 -43
- 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/python_deploy_codegen.py +2 -2
- truefoundry/deploy/v2/lib/deploy.py +3 -3
- truefoundry/ml/__init__.py +0 -2
- 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/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 +1 -1
- truefoundry/ml/log_types/artifacts/model.py +7 -8
- truefoundry/ml/log_types/image/image.py +7 -8
- truefoundry/ml/log_types/image/image_normalizer.py +7 -6
- truefoundry/ml/mlfoundry_api.py +5 -17
- truefoundry/ml/mlfoundry_run.py +0 -5
- 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.0rc2.dist-info → truefoundry-0.4.0rc4.dist-info}/METADATA +2 -2
- {truefoundry-0.4.0rc2.dist-info → truefoundry-0.4.0rc4.dist-info}/RECORD +78 -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.0rc2.dist-info → truefoundry-0.4.0rc4.dist-info}/WHEEL +0 -0
- {truefoundry-0.4.0rc2.dist-info → truefoundry-0.4.0rc4.dist-info}/entry_points.txt +0 -0
|
@@ -1,38 +1,41 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import functools
|
|
4
3
|
import json
|
|
5
4
|
import os
|
|
6
5
|
import time
|
|
7
6
|
from datetime import datetime, timezone
|
|
8
7
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
|
9
|
-
from urllib.parse import urljoin
|
|
8
|
+
from urllib.parse import urljoin
|
|
10
9
|
|
|
11
10
|
import requests
|
|
12
11
|
import socketio
|
|
13
12
|
from dateutil.tz import tzlocal
|
|
14
|
-
from packaging import version
|
|
15
13
|
from rich.status import Status
|
|
16
14
|
from tqdm import tqdm
|
|
17
15
|
from tqdm.utils import CallbackIOWrapper
|
|
18
16
|
|
|
17
|
+
from truefoundry.common.constants import VERSION_PREFIX
|
|
18
|
+
from truefoundry.common.request_utils import request_handling
|
|
19
|
+
from truefoundry.common.servicefoundry_client import (
|
|
20
|
+
ServiceFoundryServiceClient as BaseServiceFoundryServiceClient,
|
|
21
|
+
)
|
|
22
|
+
from truefoundry.common.servicefoundry_client import (
|
|
23
|
+
check_min_cli_version,
|
|
24
|
+
session_with_retries,
|
|
25
|
+
)
|
|
26
|
+
from truefoundry.deploy.auto_gen import models as auto_gen_models
|
|
19
27
|
from truefoundry.deploy.io.output_callback import OutputCallBack
|
|
20
28
|
from truefoundry.deploy.lib.auth.servicefoundry_session import ServiceFoundrySession
|
|
21
|
-
from truefoundry.deploy.lib.clients.utils import request_handling
|
|
22
|
-
from truefoundry.deploy.lib.const import API_SERVER_RELATIVE_PATH, VERSION_PREFIX
|
|
23
29
|
from truefoundry.deploy.lib.model.entity import (
|
|
24
30
|
Application,
|
|
25
31
|
CreateDockerRepositoryResponse,
|
|
26
32
|
Deployment,
|
|
27
33
|
DockerRegistryCredentials,
|
|
28
34
|
JobRun,
|
|
29
|
-
PythonSDKConfig,
|
|
30
|
-
TenantInfo,
|
|
31
35
|
TriggerJobResult,
|
|
32
36
|
Workspace,
|
|
33
37
|
WorkspaceResources,
|
|
34
38
|
)
|
|
35
|
-
from truefoundry.deploy.lib.util import timed_lru_cache
|
|
36
39
|
from truefoundry.deploy.lib.win32 import allow_interrupt
|
|
37
40
|
from truefoundry.deploy.v2.lib.models import (
|
|
38
41
|
AppDeploymentStatusResponse,
|
|
@@ -42,7 +45,6 @@ from truefoundry.deploy.v2.lib.models import (
|
|
|
42
45
|
)
|
|
43
46
|
from truefoundry.logger import logger
|
|
44
47
|
from truefoundry.pydantic_v1 import parse_obj_as
|
|
45
|
-
from truefoundry.version import __version__
|
|
46
48
|
|
|
47
49
|
DEPLOYMENT_LOGS_SUBSCRIBE_MESSAGE = "DEPLOYMENT_LOGS"
|
|
48
50
|
BUILD_LOGS_SUBSCRIBE_MESSAGE = "BUILD_LOGS"
|
|
@@ -73,46 +75,7 @@ def _upload_packaged_code(metadata, package_file):
|
|
|
73
75
|
raise RuntimeError(f"Failed to upload code {http_response.content}")
|
|
74
76
|
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
@functools.wraps(fn)
|
|
78
|
-
def inner(*args, **kwargs):
|
|
79
|
-
if __version__ != "0.0.0":
|
|
80
|
-
client: "ServiceFoundryServiceClient" = args[0]
|
|
81
|
-
# "0.0.0" indicates dev version
|
|
82
|
-
# noinspection PyProtectedMember
|
|
83
|
-
min_cli_version_required = client._min_cli_version_required
|
|
84
|
-
if version.parse(__version__) < version.parse(min_cli_version_required):
|
|
85
|
-
raise Exception(
|
|
86
|
-
"You are using an outdated version of `truefoundry`.\n"
|
|
87
|
-
f"Run `pip install truefoundry>={min_cli_version_required}` to install the supported version.",
|
|
88
|
-
)
|
|
89
|
-
else:
|
|
90
|
-
logger.debug("Ignoring minimum cli version check")
|
|
91
|
-
|
|
92
|
-
return fn(*args, **kwargs)
|
|
93
|
-
|
|
94
|
-
return inner
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@timed_lru_cache(seconds=30 * 60)
|
|
98
|
-
def _cached_get_tenant_info(api_server_url: str) -> TenantInfo:
|
|
99
|
-
res = requests.get(
|
|
100
|
-
url=f"{api_server_url}/v1/tenant-id",
|
|
101
|
-
params={"hostName": urlparse(api_server_url).netloc},
|
|
102
|
-
)
|
|
103
|
-
res = request_handling(res)
|
|
104
|
-
return TenantInfo.parse_obj(res)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@timed_lru_cache(seconds=30 * 60)
|
|
108
|
-
def _cached_get_python_sdk_config(api_server_url: str) -> PythonSDKConfig:
|
|
109
|
-
url = f"{api_server_url}/v1/min-cli-version"
|
|
110
|
-
res = requests.get(url)
|
|
111
|
-
res = request_handling(res)
|
|
112
|
-
return PythonSDKConfig.parse_obj(res)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class ServiceFoundryServiceClient:
|
|
78
|
+
class ServiceFoundryServiceClient(BaseServiceFoundryServiceClient):
|
|
116
79
|
def __init__(self, init_session: bool = True, base_url: Optional[str] = None):
|
|
117
80
|
self._session: Optional[ServiceFoundrySession] = None
|
|
118
81
|
if init_session:
|
|
@@ -122,27 +85,7 @@ class ServiceFoundryServiceClient:
|
|
|
122
85
|
base_url = self._session.base_url
|
|
123
86
|
elif not base_url:
|
|
124
87
|
raise Exception("Neither session, not base_url provided")
|
|
125
|
-
|
|
126
|
-
self._base_url = base_url.strip("/")
|
|
127
|
-
self._api_server_url = f"{self._base_url}/{API_SERVER_RELATIVE_PATH}"
|
|
128
|
-
|
|
129
|
-
@property
|
|
130
|
-
def base_url(self) -> str:
|
|
131
|
-
return self._base_url
|
|
132
|
-
|
|
133
|
-
@property
|
|
134
|
-
def tenant_info(self) -> TenantInfo:
|
|
135
|
-
return _cached_get_tenant_info(self._api_server_url)
|
|
136
|
-
|
|
137
|
-
@property
|
|
138
|
-
def python_sdk_config(self) -> PythonSDKConfig:
|
|
139
|
-
return _cached_get_python_sdk_config(self._api_server_url)
|
|
140
|
-
|
|
141
|
-
@functools.cached_property
|
|
142
|
-
def _min_cli_version_required(self) -> str:
|
|
143
|
-
return _cached_get_python_sdk_config(
|
|
144
|
-
self._api_server_url
|
|
145
|
-
).truefoundry_cli_min_version
|
|
88
|
+
super().__init__(base_url=base_url)
|
|
146
89
|
|
|
147
90
|
def _get_header(self):
|
|
148
91
|
if not self._session:
|
|
@@ -152,14 +95,16 @@ class ServiceFoundryServiceClient:
|
|
|
152
95
|
@check_min_cli_version
|
|
153
96
|
def get_id_from_fqn(self, fqn_type: str, fqn: str):
|
|
154
97
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/fqn/{fqn_type}"
|
|
155
|
-
|
|
156
|
-
|
|
98
|
+
response = session_with_retries().get(
|
|
99
|
+
url, headers=self._get_header(), params={"fqn": fqn}
|
|
100
|
+
)
|
|
101
|
+
return request_handling(response)
|
|
157
102
|
|
|
158
103
|
@check_min_cli_version
|
|
159
104
|
def list_workspace(self):
|
|
160
105
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workspace"
|
|
161
|
-
|
|
162
|
-
return request_handling(
|
|
106
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
107
|
+
return request_handling(response)
|
|
163
108
|
|
|
164
109
|
@check_min_cli_version
|
|
165
110
|
def list_workspaces(
|
|
@@ -176,8 +121,10 @@ class ServiceFoundryServiceClient:
|
|
|
176
121
|
params["workspaceName"] = workspace_name
|
|
177
122
|
if workspace_fqn:
|
|
178
123
|
params["workspaceFqn"] = workspace_fqn
|
|
179
|
-
|
|
180
|
-
|
|
124
|
+
response = session_with_retries().get(
|
|
125
|
+
url, params=params, headers=self._get_header()
|
|
126
|
+
)
|
|
127
|
+
response = request_handling(response)
|
|
181
128
|
return parse_obj_as(List[Workspace], response)
|
|
182
129
|
|
|
183
130
|
@check_min_cli_version
|
|
@@ -188,7 +135,7 @@ class ServiceFoundryServiceClient:
|
|
|
188
135
|
resources: WorkspaceResources,
|
|
189
136
|
) -> Workspace:
|
|
190
137
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workspace"
|
|
191
|
-
|
|
138
|
+
response = session_with_retries().post(
|
|
192
139
|
url,
|
|
193
140
|
json={
|
|
194
141
|
"manifest": {
|
|
@@ -199,8 +146,8 @@ class ServiceFoundryServiceClient:
|
|
|
199
146
|
},
|
|
200
147
|
headers=self._get_header(),
|
|
201
148
|
)
|
|
202
|
-
|
|
203
|
-
return Workspace.parse_obj(
|
|
149
|
+
response_data = request_handling(response)
|
|
150
|
+
return Workspace.parse_obj(response_data)
|
|
204
151
|
|
|
205
152
|
@check_min_cli_version
|
|
206
153
|
def remove_workspace(self, workspace_id, force=False) -> Workspace:
|
|
@@ -208,35 +155,37 @@ class ServiceFoundryServiceClient:
|
|
|
208
155
|
force = json.dumps(
|
|
209
156
|
force
|
|
210
157
|
) # this dumb conversion is required because `params` just casts as str
|
|
211
|
-
|
|
212
|
-
|
|
158
|
+
response = session_with_retries().delete(
|
|
159
|
+
url, headers=self._get_header(), params={"force": force}
|
|
160
|
+
)
|
|
161
|
+
response = request_handling(response)
|
|
213
162
|
return Workspace.parse_obj(response["workspace"])
|
|
214
163
|
|
|
215
164
|
@check_min_cli_version
|
|
216
165
|
def get_workspace_by_name(self, workspace_name, cluster_id):
|
|
217
166
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workspace"
|
|
218
|
-
|
|
167
|
+
response = session_with_retries().get(
|
|
219
168
|
url,
|
|
220
169
|
headers=self._get_header(),
|
|
221
170
|
params={"name": workspace_name, "clusterId": cluster_id},
|
|
222
171
|
)
|
|
223
|
-
return request_handling(
|
|
172
|
+
return request_handling(response)
|
|
224
173
|
|
|
225
174
|
@check_min_cli_version
|
|
226
175
|
def get_workspace(self, workspace_id):
|
|
227
176
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workspace/{workspace_id}"
|
|
228
|
-
|
|
229
|
-
return request_handling(
|
|
177
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
178
|
+
return request_handling(response)
|
|
230
179
|
|
|
231
180
|
@check_min_cli_version
|
|
232
181
|
def get_workspace_by_fqn(self, workspace_fqn: str) -> List[Workspace]:
|
|
233
182
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workspace"
|
|
234
|
-
|
|
183
|
+
response = session_with_retries().get(
|
|
235
184
|
url,
|
|
236
185
|
headers=self._get_header(),
|
|
237
186
|
params={"fqn": workspace_fqn},
|
|
238
187
|
)
|
|
239
|
-
response = request_handling(
|
|
188
|
+
response = request_handling(response)
|
|
240
189
|
return parse_obj_as(List[Workspace], response)
|
|
241
190
|
|
|
242
191
|
@check_min_cli_version
|
|
@@ -245,25 +194,27 @@ class ServiceFoundryServiceClient:
|
|
|
245
194
|
params = {}
|
|
246
195
|
if workspace_id:
|
|
247
196
|
params["workspaceId"] = workspace_id
|
|
248
|
-
|
|
249
|
-
|
|
197
|
+
response = session_with_retries().get(
|
|
198
|
+
url=url, params=params, headers=self._get_header()
|
|
199
|
+
)
|
|
200
|
+
return request_handling(response)
|
|
250
201
|
|
|
251
202
|
@check_min_cli_version
|
|
252
203
|
def list_cluster(self):
|
|
253
204
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/cluster"
|
|
254
|
-
|
|
255
|
-
return request_handling(
|
|
205
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
206
|
+
return request_handling(response)
|
|
256
207
|
|
|
257
208
|
@check_min_cli_version
|
|
258
209
|
def get_cluster(self, cluster_id):
|
|
259
210
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/cluster/{cluster_id}"
|
|
260
|
-
|
|
261
|
-
return request_handling(
|
|
211
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
212
|
+
return request_handling(response)
|
|
262
213
|
|
|
263
214
|
@check_min_cli_version
|
|
264
215
|
def get_presigned_url(self, space_name, service_name, env):
|
|
265
216
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/deployment/code-upload-url"
|
|
266
|
-
|
|
217
|
+
response = session_with_retries().post(
|
|
267
218
|
url,
|
|
268
219
|
json={
|
|
269
220
|
"workspaceFqn": space_name,
|
|
@@ -272,7 +223,7 @@ class ServiceFoundryServiceClient:
|
|
|
272
223
|
},
|
|
273
224
|
headers=self._get_header(),
|
|
274
225
|
)
|
|
275
|
-
return request_handling(
|
|
226
|
+
return request_handling(response)
|
|
276
227
|
|
|
277
228
|
@check_min_cli_version
|
|
278
229
|
def upload_code_package(
|
|
@@ -287,7 +238,7 @@ class ServiceFoundryServiceClient:
|
|
|
287
238
|
|
|
288
239
|
@check_min_cli_version
|
|
289
240
|
def deploy_application(
|
|
290
|
-
self, workspace_id: str, application:
|
|
241
|
+
self, workspace_id: str, application: auto_gen_models.Workflow
|
|
291
242
|
) -> Deployment:
|
|
292
243
|
data = {
|
|
293
244
|
"workspaceId": workspace_id,
|
|
@@ -296,7 +247,9 @@ class ServiceFoundryServiceClient:
|
|
|
296
247
|
}
|
|
297
248
|
logger.debug(json.dumps(data))
|
|
298
249
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/deployment"
|
|
299
|
-
deploy_response =
|
|
250
|
+
deploy_response = session_with_retries().post(
|
|
251
|
+
url, json=data, headers=self._get_header()
|
|
252
|
+
)
|
|
300
253
|
response = request_handling(deploy_response)
|
|
301
254
|
return Deployment.parse_obj(response["deployment"])
|
|
302
255
|
|
|
@@ -358,27 +311,27 @@ class ServiceFoundryServiceClient:
|
|
|
358
311
|
@check_min_cli_version
|
|
359
312
|
def get_deployment(self, application_id: str, deployment_id: str) -> Deployment:
|
|
360
313
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/app/{application_id}/deployments/{deployment_id}"
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return Deployment.parse_obj(
|
|
314
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
315
|
+
response_data = request_handling(response)
|
|
316
|
+
return Deployment.parse_obj(response_data)
|
|
364
317
|
|
|
365
318
|
@check_min_cli_version
|
|
366
319
|
def get_deployment_statuses(
|
|
367
320
|
self, application_id: str, deployment_id: str
|
|
368
321
|
) -> List[AppDeploymentStatusResponse]:
|
|
369
322
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/app/{application_id}/deployments/{deployment_id}/statuses"
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return parse_obj_as(List[AppDeploymentStatusResponse],
|
|
323
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
324
|
+
response_data = request_handling(response)
|
|
325
|
+
return parse_obj_as(List[AppDeploymentStatusResponse], response_data)
|
|
373
326
|
|
|
374
327
|
@check_min_cli_version
|
|
375
328
|
def get_deployment_build_response(
|
|
376
329
|
self, application_id: str, deployment_id: str
|
|
377
330
|
) -> List[BuildResponse]:
|
|
378
331
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/app/{application_id}/deployments/{deployment_id}/builds"
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
return parse_obj_as(List[BuildResponse],
|
|
332
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
333
|
+
response_data = request_handling(response)
|
|
334
|
+
return parse_obj_as(List[BuildResponse], response_data)
|
|
382
335
|
|
|
383
336
|
def _get_deployment_logs(
|
|
384
337
|
self,
|
|
@@ -407,9 +360,11 @@ class ServiceFoundryServiceClient:
|
|
|
407
360
|
data["jobRunName"] = job_run_name
|
|
408
361
|
|
|
409
362
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/logs/{workspace_id}"
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
363
|
+
response = session_with_retries().get(
|
|
364
|
+
url=url, params=data, headers=self._get_header()
|
|
365
|
+
)
|
|
366
|
+
response_data = request_handling(response)
|
|
367
|
+
return list(response_data["logs"])
|
|
413
368
|
|
|
414
369
|
@check_min_cli_version
|
|
415
370
|
def tail_build_logs(
|
|
@@ -545,8 +500,8 @@ class ServiceFoundryServiceClient:
|
|
|
545
500
|
) -> None:
|
|
546
501
|
callback = callback or OutputCallBack()
|
|
547
502
|
url = build_response.getLogsUrl
|
|
548
|
-
|
|
549
|
-
logs_list = request_handling(
|
|
503
|
+
response = session_with_retries().get(url=url, headers=self._get_header())
|
|
504
|
+
logs_list = request_handling(response)
|
|
550
505
|
for log in logs_list["logs"]:
|
|
551
506
|
# TODO: Have to establish a log line format that includes timestamp, level, message
|
|
552
507
|
callback.print_line(self._get_log_print_line(log))
|
|
@@ -554,36 +509,36 @@ class ServiceFoundryServiceClient:
|
|
|
554
509
|
@check_min_cli_version
|
|
555
510
|
def get_deployment_info_by_fqn(self, deployment_fqn: str) -> DeploymentFqnResponse:
|
|
556
511
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/fqn/deployment"
|
|
557
|
-
|
|
512
|
+
response = session_with_retries().get(
|
|
558
513
|
url, headers=self._get_header(), params={"fqn": deployment_fqn}
|
|
559
514
|
)
|
|
560
|
-
|
|
561
|
-
return DeploymentFqnResponse.parse_obj(
|
|
515
|
+
response_data = request_handling(response)
|
|
516
|
+
return DeploymentFqnResponse.parse_obj(response_data)
|
|
562
517
|
|
|
563
518
|
@check_min_cli_version
|
|
564
519
|
def get_application_info_by_fqn(
|
|
565
520
|
self, application_fqn: str
|
|
566
521
|
) -> ApplicationFqnResponse:
|
|
567
522
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/fqn/app"
|
|
568
|
-
|
|
523
|
+
response = session_with_retries().get(
|
|
569
524
|
url, headers=self._get_header(), params={"fqn": application_fqn}
|
|
570
525
|
)
|
|
571
|
-
|
|
572
|
-
return ApplicationFqnResponse.parse_obj(
|
|
526
|
+
response_data = request_handling(response)
|
|
527
|
+
return ApplicationFqnResponse.parse_obj(response_data)
|
|
573
528
|
|
|
574
529
|
@check_min_cli_version
|
|
575
530
|
def remove_application(self, application_id: str):
|
|
576
531
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/app/{application_id}"
|
|
577
|
-
|
|
578
|
-
response = request_handling(
|
|
532
|
+
response = session_with_retries().delete(url, headers=self._get_header())
|
|
533
|
+
response = request_handling(response)
|
|
579
534
|
# TODO: Add pydantic here.
|
|
580
535
|
return response
|
|
581
536
|
|
|
582
537
|
@check_min_cli_version
|
|
583
538
|
def get_application_info(self, application_id: str) -> Application:
|
|
584
539
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/app/{application_id}"
|
|
585
|
-
|
|
586
|
-
response = request_handling(
|
|
540
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
541
|
+
response = request_handling(response)
|
|
587
542
|
return Application.parse_obj(response)
|
|
588
543
|
|
|
589
544
|
def list_job_runs(
|
|
@@ -601,9 +556,11 @@ class ServiceFoundryServiceClient:
|
|
|
601
556
|
params["offset"] = offset
|
|
602
557
|
if search_prefix:
|
|
603
558
|
params["searchPrefix"] = search_prefix
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
559
|
+
response = session_with_retries().get(
|
|
560
|
+
url, headers=self._get_header(), params=params
|
|
561
|
+
)
|
|
562
|
+
response_data = request_handling(response)
|
|
563
|
+
return parse_obj_as(List[JobRun], response_data["data"])
|
|
607
564
|
|
|
608
565
|
def get_job_run(
|
|
609
566
|
self,
|
|
@@ -611,9 +568,9 @@ class ServiceFoundryServiceClient:
|
|
|
611
568
|
job_run_name: str,
|
|
612
569
|
):
|
|
613
570
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/jobs/{application_id}/runs/{job_run_name}"
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
return parse_obj_as(JobRun,
|
|
571
|
+
response = session_with_retries().get(url, headers=self._get_header())
|
|
572
|
+
response_data = request_handling(response)
|
|
573
|
+
return parse_obj_as(JobRun, response_data)
|
|
617
574
|
|
|
618
575
|
def trigger_job(
|
|
619
576
|
self,
|
|
@@ -630,14 +587,18 @@ class ServiceFoundryServiceClient:
|
|
|
630
587
|
body["input"]["command"] = command
|
|
631
588
|
if params:
|
|
632
589
|
body["input"]["params"] = params
|
|
633
|
-
|
|
634
|
-
|
|
590
|
+
response = session_with_retries().post(
|
|
591
|
+
url, json=body, headers=self._get_header()
|
|
592
|
+
)
|
|
593
|
+
response = request_handling(response)
|
|
635
594
|
return TriggerJobResult.parse_obj(response)
|
|
636
595
|
|
|
637
596
|
def trigger_workflow(self, application_id: str, inputs: Dict[str, Any]):
|
|
638
597
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/workflow/{application_id}/executions"
|
|
639
|
-
|
|
640
|
-
|
|
598
|
+
response = session_with_retries().post(
|
|
599
|
+
url, json=inputs, headers=self._get_header()
|
|
600
|
+
)
|
|
601
|
+
response = request_handling(response)
|
|
641
602
|
return response
|
|
642
603
|
|
|
643
604
|
@check_min_cli_version
|
|
@@ -645,7 +606,7 @@ class ServiceFoundryServiceClient:
|
|
|
645
606
|
self, docker_registry_fqn: str, cluster_id: str
|
|
646
607
|
) -> DockerRegistryCredentials:
|
|
647
608
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/docker-registry/creds"
|
|
648
|
-
|
|
609
|
+
response = session_with_retries().get(
|
|
649
610
|
url,
|
|
650
611
|
headers=self._get_header(),
|
|
651
612
|
params={
|
|
@@ -653,7 +614,7 @@ class ServiceFoundryServiceClient:
|
|
|
653
614
|
"clusterId": cluster_id,
|
|
654
615
|
},
|
|
655
616
|
)
|
|
656
|
-
response = request_handling(
|
|
617
|
+
response = request_handling(response)
|
|
657
618
|
return DockerRegistryCredentials.parse_obj(response)
|
|
658
619
|
|
|
659
620
|
@check_min_cli_version
|
|
@@ -661,7 +622,7 @@ class ServiceFoundryServiceClient:
|
|
|
661
622
|
self, docker_registry_fqn: str, workspace_fqn: str, application_name: str
|
|
662
623
|
) -> CreateDockerRepositoryResponse:
|
|
663
624
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/docker-registry/create-repo"
|
|
664
|
-
|
|
625
|
+
response = session_with_retries().post(
|
|
665
626
|
url,
|
|
666
627
|
headers=self._get_header(),
|
|
667
628
|
data={
|
|
@@ -670,7 +631,7 @@ class ServiceFoundryServiceClient:
|
|
|
670
631
|
"applicationName": application_name,
|
|
671
632
|
},
|
|
672
633
|
)
|
|
673
|
-
response = request_handling(
|
|
634
|
+
response = request_handling(response)
|
|
674
635
|
return CreateDockerRepositoryResponse.parse_obj(response)
|
|
675
636
|
|
|
676
637
|
@check_min_cli_version
|
|
@@ -688,8 +649,10 @@ class ServiceFoundryServiceClient:
|
|
|
688
649
|
params["workspaceId"] = workspace_id
|
|
689
650
|
if application_name:
|
|
690
651
|
params["applicationName"] = application_name
|
|
691
|
-
|
|
692
|
-
|
|
652
|
+
response = session_with_retries().get(
|
|
653
|
+
url, params=params, headers=self._get_header()
|
|
654
|
+
)
|
|
655
|
+
response = request_handling(response)
|
|
693
656
|
return parse_obj_as(List[Application], response)
|
|
694
657
|
|
|
695
658
|
@check_min_cli_version
|
|
@@ -707,31 +670,38 @@ class ServiceFoundryServiceClient:
|
|
|
707
670
|
params["version"] = deployment_version
|
|
708
671
|
if deployment_id:
|
|
709
672
|
params["deploymentId"] = deployment_id
|
|
710
|
-
|
|
711
|
-
|
|
673
|
+
response = session_with_retries().get(
|
|
674
|
+
url, params=params, headers=self._get_header()
|
|
675
|
+
)
|
|
676
|
+
response = request_handling(response)
|
|
712
677
|
return parse_obj_as(List[Deployment], response)
|
|
713
678
|
|
|
714
679
|
@check_min_cli_version
|
|
715
|
-
def apply(self, manifest: Dict[str, Any])
|
|
680
|
+
def apply(self, manifest: Dict[str, Any]):
|
|
716
681
|
url = f"{self._api_server_url}/{VERSION_PREFIX}/apply"
|
|
717
682
|
body = {"manifest": manifest}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
683
|
+
response = session_with_retries().put(
|
|
684
|
+
url, headers=self._get_header(), json=body
|
|
685
|
+
)
|
|
686
|
+
response_data = request_handling(response)
|
|
687
|
+
return response_data
|
|
721
688
|
|
|
722
689
|
def terminate_job_run(
|
|
723
690
|
self,
|
|
724
691
|
deployment_id: str,
|
|
725
692
|
job_run_name: str,
|
|
726
|
-
callback=None,
|
|
727
693
|
):
|
|
728
|
-
|
|
729
|
-
url = f"{self._api_server_url}/{VERSION_PREFIX}/jobs/terminate?deploymentId={deployment_id}&jobRunName={job_run_name}"
|
|
694
|
+
url = f"{self._api_server_url}/{VERSION_PREFIX}/jobs/terminate"
|
|
730
695
|
body = {
|
|
731
696
|
"deploymentId": deployment_id,
|
|
732
697
|
"jobRunName": job_run_name,
|
|
733
698
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
699
|
+
response = session_with_retries().post(
|
|
700
|
+
url,
|
|
701
|
+
# TODO (chiragjn): Check if this is supposed to be params or json
|
|
702
|
+
params=body,
|
|
703
|
+
json=body,
|
|
704
|
+
headers=self._get_header(),
|
|
705
|
+
)
|
|
706
|
+
response_data = request_handling(response)
|
|
707
|
+
return response_data
|
truefoundry/deploy/lib/const.py
CHANGED
|
@@ -1,43 +1,9 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
1
|
from truefoundry.deploy.io.rich_output_callback import RichOutputCallBack
|
|
4
2
|
|
|
5
|
-
DEFAULT_BASE_URL = "https://app.truefoundry.com"
|
|
6
|
-
API_SERVER_RELATIVE_PATH = "api/svc"
|
|
7
|
-
DEFAULT_API_SERVER = f"{DEFAULT_BASE_URL.rstrip('/')}/{API_SERVER_RELATIVE_PATH}"
|
|
8
|
-
DEFAULT_AUTH_UI = DEFAULT_BASE_URL
|
|
9
|
-
DEFAULT_AUTH_SERVER = (
|
|
10
|
-
"https://auth-server.tfy-ctl-euwe1-production.production.truefoundry.com"
|
|
11
|
-
)
|
|
12
|
-
DEFAULT_TENANT_NAME = "truefoundry"
|
|
13
|
-
DEFAULT_PROFILE_NAME = "default"
|
|
14
|
-
HOST_ENV_NAME = "TFY_HOST"
|
|
15
|
-
API_KEY_ENV_NAME = "TFY_API_KEY"
|
|
16
|
-
|
|
17
|
-
_SFY_CONFIG_DIR = Path.home() / ".truefoundry"
|
|
18
|
-
SFY_CONFIG_DIR = str(_SFY_CONFIG_DIR) # as a directory
|
|
19
|
-
CREDENTIAL_FILEPATH = _SFY_CONFIG_DIR / "credentials.json"
|
|
20
|
-
|
|
21
|
-
OLD_SFY_PROFILES_FILEPATH = _SFY_CONFIG_DIR / "profiles.json" # as a directory
|
|
22
|
-
OLD_SFY_SESSIONS_FILEPATH = _SFY_CONFIG_DIR / "sessions.json" # as a directory
|
|
23
|
-
OLD_SESSION_FILEPATH = str(
|
|
24
|
-
Path.home() / ".truefoundry"
|
|
25
|
-
) # as a filepath, to be removed in future versions
|
|
26
|
-
|
|
27
|
-
# Polling during login redirect
|
|
28
|
-
MAX_POLLING_RETRY = 100
|
|
29
|
-
POLLING_SLEEP_TIME_IN_SEC = 4
|
|
30
|
-
|
|
31
|
-
# Refresh access token cutoff
|
|
32
|
-
REFRESH_ACCESS_TOKEN_IN_SEC = 10 * 60
|
|
33
|
-
|
|
34
3
|
ENTITY_JSON_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
|
|
35
4
|
RICH_OUTPUT_CALLBACK = RichOutputCallBack()
|
|
36
5
|
|
|
37
|
-
VERSION_PREFIX = "v1"
|
|
38
|
-
|
|
39
6
|
SFY_DEBUG_ENV_KEY = "SFY_DEBUG"
|
|
40
|
-
SFY_INTERNAL_ENV_KEY = "SFY_INTERNAL"
|
|
41
|
-
|
|
42
7
|
TFY_DEBUG_ENV_KEY = "TFY_DEBUG"
|
|
8
|
+
SFY_INTERNAL_ENV_KEY = "SFY_INTERNAL"
|
|
43
9
|
TFY_INTERNAL_ENV_KEY = "TFY_INTERNAL"
|
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class BadRequestException(Exception):
|
|
5
|
-
def __init__(self, status_code: int, message: Optional[str] = None):
|
|
6
|
-
super().__init__()
|
|
7
|
-
self.status_code = status_code
|
|
8
|
-
self.message = message
|
|
9
|
-
self.status_code = status_code
|
|
10
|
-
|
|
11
|
-
def __str__(self):
|
|
12
|
-
return self.message
|
|
13
|
-
|
|
14
|
-
|
|
15
4
|
class ConfigurationException(Exception):
|
|
16
5
|
def __init__(self, message: Optional[str] = None):
|
|
17
6
|
super().__init__()
|