truefoundry 0.11.0__py3-none-any.whl → 0.11.2__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/common/utils.py +9 -3
- truefoundry/deploy/builder/builders/tfy_spark_buildpack/tfy_execute_notebook.py +32 -28
- truefoundry/ml/artifact/truefoundry_artifact_repo.py +15 -50
- truefoundry/ml/mlfoundry_api.py +21 -27
- {truefoundry-0.11.0.dist-info → truefoundry-0.11.2.dist-info}/METADATA +2 -2
- {truefoundry-0.11.0.dist-info → truefoundry-0.11.2.dist-info}/RECORD +8 -9
- truefoundry/ml/clients/servicefoundry_client.py +0 -65
- {truefoundry-0.11.0.dist-info → truefoundry-0.11.2.dist-info}/WHEEL +0 -0
- {truefoundry-0.11.0.dist-info → truefoundry-0.11.2.dist-info}/entry_points.txt +0 -0
truefoundry/common/utils.py
CHANGED
|
@@ -16,6 +16,7 @@ from truefoundry.common.constants import (
|
|
|
16
16
|
API_SERVER_RELATIVE_PATH,
|
|
17
17
|
ENV_VARS,
|
|
18
18
|
MLFOUNDRY_SERVER_RELATIVE_PATH,
|
|
19
|
+
TFY_API_KEY_ENV_KEY,
|
|
19
20
|
TFY_DEBUG_ENV_KEY,
|
|
20
21
|
TFY_HOST_ENV_KEY,
|
|
21
22
|
TFY_INTERNAL_ENV_KEY,
|
|
@@ -113,9 +114,14 @@ def validate_tfy_host(tfy_host: str) -> None:
|
|
|
113
114
|
def resolve_tfy_host(tfy_host: Optional[str] = None) -> str:
|
|
114
115
|
tfy_host = tfy_host or ENV_VARS.TFY_HOST
|
|
115
116
|
if not tfy_host:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
if ENV_VARS.TFY_API_KEY:
|
|
118
|
+
raise ValueError(
|
|
119
|
+
f"TFY_HOST` env must be set since `{TFY_API_KEY_ENV_KEY}` env is set. Either set `{TFY_HOST_ENV_KEY}` or unset `{TFY_API_KEY_ENV_KEY}` and login"
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
f"Either `host` should be provided using `--host <value>`, or `{TFY_HOST_ENV_KEY}` env must be set"
|
|
124
|
+
)
|
|
119
125
|
tfy_host = tfy_host.strip("/")
|
|
120
126
|
validate_tfy_host(tfy_host)
|
|
121
127
|
return tfy_host
|
|
@@ -45,16 +45,9 @@ def upload_file_to_s3(file_path, bucket_name, s3_key):
|
|
|
45
45
|
# Use s3proxy for pushing data to s3
|
|
46
46
|
# The JWT token is already available in the pod
|
|
47
47
|
aws_access_key_id = os.environ.get("SPARK_APPLICATION_EVENT_LOG_JWT_TOKEN")
|
|
48
|
-
aws_secret_access_key = "
|
|
48
|
+
aws_secret_access_key = os.environ.get("TFY_NOTEBOOK_OUTPUT_S3_SECRET_KEY")
|
|
49
49
|
s3_endpoint_url = os.environ.get("S3_PROXY_URL")
|
|
50
50
|
|
|
51
|
-
if not aws_access_key_id:
|
|
52
|
-
raise ValueError(
|
|
53
|
-
"SPARK_APPLICATION_EVENT_LOG_JWT_TOKEN environment variable is not set"
|
|
54
|
-
)
|
|
55
|
-
if not s3_endpoint_url:
|
|
56
|
-
raise ValueError("S3_PROXY_URL environment variable is not set")
|
|
57
|
-
|
|
58
51
|
# Needed for the issue https://github.com/gaul/s3proxy/issues/765
|
|
59
52
|
s3_config = Config(
|
|
60
53
|
request_checksum_calculation="when_required",
|
|
@@ -106,7 +99,22 @@ def execute_notebook(notebook_path, output_path="/tmp/output.ipynb", parameters=
|
|
|
106
99
|
stderr_file=sys.stderr,
|
|
107
100
|
)
|
|
108
101
|
print(f"Successfully executed notebook: {notebook_path}")
|
|
109
|
-
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def validate_env_vars():
|
|
105
|
+
keys = [
|
|
106
|
+
"TFY_NOTEBOOK_OUTPUT_S3_KEY",
|
|
107
|
+
"TFY_NOTEBOOK_OUTPUT_S3_BUCKET",
|
|
108
|
+
"SPARK_APPLICATION_EVENT_LOG_JWT_TOKEN",
|
|
109
|
+
"TFY_NOTEBOOK_OUTPUT_S3_SECRET_KEY",
|
|
110
|
+
]
|
|
111
|
+
unset_keys = [key for key in keys if not os.environ.get(key)]
|
|
112
|
+
if unset_keys:
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"Environment variables {unset_keys} are not set."
|
|
115
|
+
f"Contact you tenant-admin to configure storage bucket on the control plane "
|
|
116
|
+
f"to enable uploading spark notebook outputs."
|
|
117
|
+
)
|
|
110
118
|
|
|
111
119
|
|
|
112
120
|
if __name__ == "__main__":
|
|
@@ -116,35 +124,31 @@ if __name__ == "__main__":
|
|
|
116
124
|
parser.add_argument("notebook_path", help="Path to the notebook file to execute")
|
|
117
125
|
args = parser.parse_args()
|
|
118
126
|
|
|
127
|
+
# Since failure to upload is considered a job failure, fail the job even before it run if uploads cannot happen
|
|
128
|
+
validate_env_vars()
|
|
129
|
+
|
|
119
130
|
output_notebook_path = "/tmp/output.ipynb"
|
|
120
131
|
|
|
121
132
|
# This would be the same as the default bucket used by servicefoundry-server
|
|
122
133
|
s3_bucket = os.environ.get("TFY_NOTEBOOK_OUTPUT_S3_BUCKET")
|
|
123
|
-
# This would be something like sparkjob-events/<tenant-id
|
|
124
|
-
|
|
134
|
+
# This would be something like sparkjob-events/<tenant-id>/output-notebooks/<application-id>/<jobrun-name>/output.html
|
|
135
|
+
s3_key = os.environ.get("TFY_NOTEBOOK_OUTPUT_S3_KEY")
|
|
125
136
|
|
|
126
137
|
try:
|
|
127
|
-
|
|
128
|
-
args.notebook_path, output_path=output_notebook_path
|
|
129
|
-
)
|
|
138
|
+
execute_notebook(args.notebook_path, output_path=output_notebook_path)
|
|
130
139
|
|
|
131
140
|
# The following may also be modeled as an entrypoint
|
|
132
141
|
# https://papermill.readthedocs.io/en/latest/extending-entry-points.html
|
|
133
142
|
# Will take that up with next iteration where we save the executed notebook periodically
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
s3_html_key = f"{s3_key_prefix}/output.html"
|
|
144
|
-
upload_file_to_s3(
|
|
145
|
-
file_path=html_output_path, bucket_name=s3_bucket, s3_key=s3_html_key
|
|
146
|
-
)
|
|
147
|
-
print(f"Successfully uploaded HTML to s3://{s3_bucket}/{s3_html_key}")
|
|
143
|
+
print("Converting notebook to HTML and uploading to S3...")
|
|
144
|
+
html_output_path = "/tmp/output.html"
|
|
145
|
+
convert_notebook_to_html(
|
|
146
|
+
notebook_path=output_notebook_path, output_html_path=html_output_path
|
|
147
|
+
)
|
|
148
|
+
upload_file_to_s3(
|
|
149
|
+
file_path=html_output_path, bucket_name=s3_bucket, s3_key=s3_key
|
|
150
|
+
)
|
|
151
|
+
print(f"Successfully uploaded HTML to s3://{s3_bucket}/{s3_key}")
|
|
148
152
|
|
|
149
153
|
except Exception as e:
|
|
150
154
|
print(f"Error executing notebook {args.notebook_path}: {e}")
|
|
@@ -6,17 +6,7 @@ import uuid
|
|
|
6
6
|
from concurrent.futures import FIRST_EXCEPTION, Future, ThreadPoolExecutor, wait
|
|
7
7
|
from shutil import rmtree
|
|
8
8
|
from threading import Event
|
|
9
|
-
from typing import
|
|
10
|
-
Any,
|
|
11
|
-
Callable,
|
|
12
|
-
Dict,
|
|
13
|
-
Iterator,
|
|
14
|
-
List,
|
|
15
|
-
Optional,
|
|
16
|
-
Sequence,
|
|
17
|
-
Tuple,
|
|
18
|
-
Union,
|
|
19
|
-
)
|
|
9
|
+
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Tuple
|
|
20
10
|
from urllib.parse import unquote
|
|
21
11
|
from urllib.request import pathname2url
|
|
22
12
|
|
|
@@ -31,6 +21,7 @@ from rich.progress import (
|
|
|
31
21
|
)
|
|
32
22
|
from tqdm.utils import CallbackIOWrapper
|
|
33
23
|
from truefoundry_sdk import (
|
|
24
|
+
FileInfo,
|
|
34
25
|
MultiPartUploadResponse,
|
|
35
26
|
MultiPartUploadStorageProvider,
|
|
36
27
|
Operation,
|
|
@@ -52,11 +43,6 @@ from truefoundry.common.storage_provider_utils import (
|
|
|
52
43
|
)
|
|
53
44
|
from truefoundry.ml._autogen.client import ( # type: ignore[attr-defined]
|
|
54
45
|
ApiClient,
|
|
55
|
-
FileInfoDto,
|
|
56
|
-
ListFilesForArtifactVersionRequestDto,
|
|
57
|
-
ListFilesForArtifactVersionsResponseDto,
|
|
58
|
-
ListFilesForDatasetRequestDto,
|
|
59
|
-
ListFilesForDatasetResponseDto,
|
|
60
46
|
MlfoundryArtifactsApi,
|
|
61
47
|
RunArtifactsApi,
|
|
62
48
|
)
|
|
@@ -592,44 +578,23 @@ class MlFoundryArtifactsRepository:
|
|
|
592
578
|
progress=progress,
|
|
593
579
|
)
|
|
594
580
|
|
|
595
|
-
def _list_files(
|
|
596
|
-
self, artifact_identifier: ArtifactIdentifier, path, page_size, page_token
|
|
597
|
-
) -> Union[ListFilesForDatasetResponseDto, ListFilesForArtifactVersionsResponseDto]:
|
|
598
|
-
if artifact_identifier.dataset_fqn:
|
|
599
|
-
return self._mlfoundry_artifacts_api.list_files_for_dataset_post(
|
|
600
|
-
list_files_for_dataset_request_dto=ListFilesForDatasetRequestDto(
|
|
601
|
-
dataset_fqn=artifact_identifier.dataset_fqn,
|
|
602
|
-
path=path,
|
|
603
|
-
max_results=page_size,
|
|
604
|
-
page_token=page_token,
|
|
605
|
-
)
|
|
606
|
-
)
|
|
607
|
-
else:
|
|
608
|
-
return self._mlfoundry_artifacts_api.list_files_for_artifact_version_post(
|
|
609
|
-
list_files_for_artifact_version_request_dto=ListFilesForArtifactVersionRequestDto(
|
|
610
|
-
id=str(artifact_identifier.artifact_version_id),
|
|
611
|
-
path=path,
|
|
612
|
-
max_results=page_size,
|
|
613
|
-
page_token=page_token,
|
|
614
|
-
)
|
|
615
|
-
)
|
|
616
|
-
|
|
617
581
|
def list_artifacts(
|
|
618
582
|
self, path=None, page_size=_LIST_FILES_PAGE_SIZE, **kwargs
|
|
619
|
-
) -> Iterator[
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
started = True
|
|
624
|
-
page = self._list_files(
|
|
625
|
-
artifact_identifier=self.artifact_identifier,
|
|
583
|
+
) -> Iterator[FileInfo]:
|
|
584
|
+
if self.artifact_identifier.dataset_id:
|
|
585
|
+
for file_info in client.data_directories.list_files(
|
|
586
|
+
id=str(self.artifact_identifier.dataset_id),
|
|
626
587
|
path=path,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
588
|
+
limit=page_size,
|
|
589
|
+
):
|
|
590
|
+
yield file_info
|
|
591
|
+
else:
|
|
592
|
+
for file_info in client.artifact_versions.list_files(
|
|
593
|
+
id=str(self.artifact_identifier.artifact_version_id),
|
|
594
|
+
path=path,
|
|
595
|
+
limit=page_size,
|
|
596
|
+
):
|
|
631
597
|
yield file_info
|
|
632
|
-
page_token = page.next_page_token
|
|
633
598
|
|
|
634
599
|
def _is_directory(self, artifact_path):
|
|
635
600
|
# TODO: Ideally server should return a flag to indicate if it is a directory
|
truefoundry/ml/mlfoundry_api.py
CHANGED
|
@@ -46,7 +46,6 @@ from truefoundry.ml._autogen.client.exceptions import (
|
|
|
46
46
|
ApiException,
|
|
47
47
|
NotFoundException,
|
|
48
48
|
)
|
|
49
|
-
from truefoundry.ml.clients.servicefoundry_client import ServiceFoundryServiceClient
|
|
50
49
|
from truefoundry.ml.enums import ModelFramework, ViewType
|
|
51
50
|
from truefoundry.ml.exceptions import MlFoundryException
|
|
52
51
|
from truefoundry.ml.internal_namespace import NAMESPACE
|
|
@@ -139,7 +138,8 @@ class MlFoundry:
|
|
|
139
138
|
except (IndexError, NotFoundError):
|
|
140
139
|
err_msg = (
|
|
141
140
|
f"ML Repo Does Not Exist for name: {ml_repo}. You may either "
|
|
142
|
-
"create it from the dashboard or using
|
|
141
|
+
f"create it from the dashboard or using "
|
|
142
|
+
f"`client.create_ml_repo(ml_repo='{ml_repo}', storage_integration_fqn='<storage_integration_fqn>')`"
|
|
143
143
|
)
|
|
144
144
|
raise MlFoundryException(err_msg) from None
|
|
145
145
|
except ApiError as e:
|
|
@@ -191,7 +191,12 @@ class MlFoundry:
|
|
|
191
191
|
|
|
192
192
|
client = get_client()
|
|
193
193
|
|
|
194
|
-
client.create_ml_repo(
|
|
194
|
+
client.create_ml_repo(
|
|
195
|
+
ml_repo="my-repo",
|
|
196
|
+
# This controls which bucket is used.
|
|
197
|
+
# You can get this from Platform > Integrations > Copy FQN of any Blob Storage type integration.
|
|
198
|
+
storage_integration_fqn="..."
|
|
199
|
+
)
|
|
195
200
|
```
|
|
196
201
|
"""
|
|
197
202
|
_validate_ml_repo_name(ml_repo_name=name)
|
|
@@ -235,28 +240,11 @@ class MlFoundry:
|
|
|
235
240
|
raise MlFoundryException(err_msg) from e
|
|
236
241
|
return
|
|
237
242
|
|
|
238
|
-
|
|
239
|
-
tfy_host=self._api_client.tfy_host,
|
|
240
|
-
token=self._api_client.access_token,
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
assert existing_ml_repo.storage_integration_id is not None
|
|
244
|
-
try:
|
|
245
|
-
existing_storage_integration = (
|
|
246
|
-
servicefoundry_client.get_integration_from_id(
|
|
247
|
-
existing_ml_repo.storage_integration_id
|
|
248
|
-
)
|
|
249
|
-
)
|
|
250
|
-
except Exception as e:
|
|
251
|
-
raise MlFoundryException(
|
|
252
|
-
"Error in getting storage integration for ML Repo"
|
|
253
|
-
) from e
|
|
254
|
-
|
|
255
|
-
if existing_storage_integration["fqn"] != storage_integration_fqn:
|
|
243
|
+
if existing_ml_repo.manifest.storage_integration_fqn != storage_integration_fqn:
|
|
256
244
|
raise MlFoundryException(
|
|
257
245
|
f"ML Repo with same name already exists with storage integration:"
|
|
258
|
-
f"{
|
|
259
|
-
f"{storage_integration_fqn}"
|
|
246
|
+
f"{existing_ml_repo.manifest.storage_integration_fqn!r}. "
|
|
247
|
+
f"Cannot update the storage integration to: {storage_integration_fqn!r}"
|
|
260
248
|
)
|
|
261
249
|
|
|
262
250
|
def create_run(
|
|
@@ -562,7 +550,8 @@ class MlFoundry:
|
|
|
562
550
|
except (IndexError, NotFoundError):
|
|
563
551
|
raise MlFoundryException(
|
|
564
552
|
f"ML Repo with name {ml_repo} does not exist. "
|
|
565
|
-
"You may either create it from the dashboard or using
|
|
553
|
+
f"You may either create it from the dashboard or using "
|
|
554
|
+
f"`client.create_ml_repo(ml_repo='{ml_repo}', storage_integration_fqn='<storage_integration_fqn>')`"
|
|
566
555
|
) from None
|
|
567
556
|
except ApiError as e:
|
|
568
557
|
raise MlFoundryException(
|
|
@@ -1202,7 +1191,12 @@ class MlFoundry:
|
|
|
1202
1191
|
client = get_client()
|
|
1203
1192
|
ml_repo = "sample-repo"
|
|
1204
1193
|
|
|
1205
|
-
client.create_ml_repo(
|
|
1194
|
+
client.create_ml_repo(
|
|
1195
|
+
ml_repo=ml_repo,
|
|
1196
|
+
# This controls which bucket is used.
|
|
1197
|
+
# You can get this from Platform > Integrations > Copy FQN of any Blob Storage type integration.
|
|
1198
|
+
storage_integration_fqn="..."
|
|
1199
|
+
)
|
|
1206
1200
|
client.log_artifact(
|
|
1207
1201
|
ml_repo=ml_repo,
|
|
1208
1202
|
name="hello-world-file",
|
|
@@ -1301,8 +1295,8 @@ class MlFoundry:
|
|
|
1301
1295
|
client.create_ml_repo( # This is only required once
|
|
1302
1296
|
ml_repo="my-classification-project",
|
|
1303
1297
|
# This controls which bucket is used.
|
|
1304
|
-
# You can get this from Integrations > Blob Storage
|
|
1305
|
-
storage_integration_fqn=
|
|
1298
|
+
# You can get this from Platform > Integrations > Copy FQN of any Blob Storage type integration.
|
|
1299
|
+
storage_integration_fqn="..."
|
|
1306
1300
|
)
|
|
1307
1301
|
model_version = client.log_model(
|
|
1308
1302
|
ml_repo="my-classification-project",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: truefoundry
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.2
|
|
4
4
|
Summary: TrueFoundry CLI
|
|
5
5
|
Author-email: TrueFoundry Team <abhishek@truefoundry.com>
|
|
6
6
|
Requires-Python: <3.14,>=3.8.1
|
|
@@ -30,7 +30,7 @@ Requires-Dist: requirements-parser<0.12.0,>=0.11.0
|
|
|
30
30
|
Requires-Dist: rich-click<2.0.0,>=1.2.1
|
|
31
31
|
Requires-Dist: rich<14.0.0,>=13.7.1
|
|
32
32
|
Requires-Dist: tqdm<5.0.0,>=4.0.0
|
|
33
|
-
Requires-Dist: truefoundry-sdk<0.2.0,>=0.1.
|
|
33
|
+
Requires-Dist: truefoundry-sdk<0.2.0,>=0.1.7
|
|
34
34
|
Requires-Dist: typing-extensions>=4.0
|
|
35
35
|
Requires-Dist: urllib3<3,>=1.26.18
|
|
36
36
|
Requires-Dist: yq<4.0.0,>=3.1.0
|
|
@@ -50,7 +50,7 @@ truefoundry/common/servicefoundry_client.py,sha256=2fYhdVPSvLXz5C5tosOq86JD8WM3I
|
|
|
50
50
|
truefoundry/common/session.py,sha256=d9l3TEBpqVP4mr4mTGY1qVxc815skzMlNNdw14otg34,2923
|
|
51
51
|
truefoundry/common/storage_provider_utils.py,sha256=yURhMw8k0FLFvaviRHDiifhvc6GnuQwGMC9Qd2uM440,10934
|
|
52
52
|
truefoundry/common/types.py,sha256=BMJFCsR1lPJAw66IQBSvLyV4I6o_x5oj78gVsUa9si8,188
|
|
53
|
-
truefoundry/common/utils.py,sha256=
|
|
53
|
+
truefoundry/common/utils.py,sha256=P0FuAadoJGdpieUORLSN-PiFnkyoGO-K2cS4OPITBWg,6714
|
|
54
54
|
truefoundry/common/warnings.py,sha256=xDMhR_-ZGC40Ycaj6nlFb5MYPexn8WbKCHd4FlflTXQ,705
|
|
55
55
|
truefoundry/deploy/__init__.py,sha256=PVbGPU9S3-dTFn5LvLwaEnfsp2RrGT9iiM7_15kOV84,2837
|
|
56
56
|
truefoundry/deploy/python_deploy_codegen.py,sha256=k19_m5DGsUyjOUCSKwIVP8vDna2sq01tHABsUfoVpW4,8019
|
|
@@ -67,7 +67,7 @@ truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py,sha256=_fjq
|
|
|
67
67
|
truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=f4l3fH21E2b8W3-JotMKc0AdPcCxV7LRPxxYJa7z_UQ,9134
|
|
68
68
|
truefoundry/deploy/builder/builders/tfy_spark_buildpack/__init__.py,sha256=NEPlM6_vTVxp4ITa18B8DBbgYCn1q5d8be21lbgu5oY,2888
|
|
69
69
|
truefoundry/deploy/builder/builders/tfy_spark_buildpack/dockerfile_template.py,sha256=2zohUaW8Yw_QREHlpRW7Pooomt19HJh44fHjlsiDmwM,6064
|
|
70
|
-
truefoundry/deploy/builder/builders/tfy_spark_buildpack/tfy_execute_notebook.py,sha256=
|
|
70
|
+
truefoundry/deploy/builder/builders/tfy_spark_buildpack/tfy_execute_notebook.py,sha256=QvawKw30dcHROJ05XQU2KgwH3gtUmEGSkuLxiuPNJ2c,5899
|
|
71
71
|
truefoundry/deploy/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
72
72
|
truefoundry/deploy/cli/commands/__init__.py,sha256=qv818jxqSAygJ3h-6Ul8t-5VOgR_UrSgsVtNCl3e5G0,1408
|
|
73
73
|
truefoundry/deploy/cli/commands/apply_command.py,sha256=DmXmKVokkauyKIiJDtErTwbJ5_LvQeJbTQsG5BjyKpo,2427
|
|
@@ -127,7 +127,7 @@ truefoundry/ml/exceptions.py,sha256=QpDJSWmF7dIsByS0qOQbQZ_jytdNTzkHDDO3BxhTSo0,
|
|
|
127
127
|
truefoundry/ml/git_info.py,sha256=jvAVm9ilqivnGq8qJdUvYdd8Siv0PLtqurB-PXsS5ho,2023
|
|
128
128
|
truefoundry/ml/internal_namespace.py,sha256=QcqMHp6-C2im2H_02hlhi01EIcr1HhNaZprszs13EMU,1790
|
|
129
129
|
truefoundry/ml/logger.py,sha256=VT-BF3BnBYTWVq87O58F0c8uXMu94gYzsiFlGY3_7Ao,458
|
|
130
|
-
truefoundry/ml/mlfoundry_api.py,sha256=
|
|
130
|
+
truefoundry/ml/mlfoundry_api.py,sha256=EZvFs-HiUDV2H0tDrgRdeotplWTZm3T5Uw-0Zq3WuHo,60174
|
|
131
131
|
truefoundry/ml/mlfoundry_run.py,sha256=b0wm08OUAiO1UpzdDNBeJh-Gsm_O5kEdbY86Ugv-26Y,44181
|
|
132
132
|
truefoundry/ml/model_framework.py,sha256=nVbKTtKDRBdLzt7Wrg5_vJKZ-awHbISGvL73s-V9egU,18975
|
|
133
133
|
truefoundry/ml/prompt_utils.py,sha256=8FueyElVTXLnLtC3O6hKsW_snocArr_B8KG3Qv6eFIQ,2651
|
|
@@ -347,7 +347,7 @@ truefoundry/ml/_autogen/models/schema.py,sha256=a_bp42MMPUbwO3407m0UW2W8EOhnxZXf
|
|
|
347
347
|
truefoundry/ml/_autogen/models/signature.py,sha256=rBjpxUIsEeWM0sIyYG5uCJB18DKHR4k5yZw8TzuoP48,4987
|
|
348
348
|
truefoundry/ml/_autogen/models/utils.py,sha256=c7RtSLXhOLcP8rjuUtfnMdaKVTZvvbsmw98gPAkAFrs,24371
|
|
349
349
|
truefoundry/ml/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
350
|
-
truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=
|
|
350
|
+
truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=hbgLxSoihkLVuICzRueuh8iAIc-yruCW5TuMXYQ-aCU,35692
|
|
351
351
|
truefoundry/ml/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
352
352
|
truefoundry/ml/cli/cli.py,sha256=MwpY7z_NEeJE_XIP7XbZELjNeu2vpMmohttHCKDRk54,335
|
|
353
353
|
truefoundry/ml/cli/utils.py,sha256=j6_mZ4Spn114mz3P4QQ8jx0tmorXIuyQnHXVUSDvZi4,1035
|
|
@@ -355,7 +355,6 @@ truefoundry/ml/cli/commands/__init__.py,sha256=diDUiRUX4l6TtNLI4iF-ZblczkELM7FRV
|
|
|
355
355
|
truefoundry/ml/cli/commands/download.py,sha256=N9MhsEQ3U24v_OmnMZT8Q4SoAi38Sm7a21unrACOSDw,2573
|
|
356
356
|
truefoundry/ml/cli/commands/model_init.py,sha256=INyUAU6hiFClI8cZqX5hgnrtNbeKxlZxrjFrjzStU18,2664
|
|
357
357
|
truefoundry/ml/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
358
|
-
truefoundry/ml/clients/servicefoundry_client.py,sha256=GiB_SmETI2uo8E0Q43cEsOG6qYb80nB6gM7l3rL7zEs,2422
|
|
359
358
|
truefoundry/ml/log_types/__init__.py,sha256=g4u4D4Jaj0aBK5GtrLV88-qThKZR9pSZ17vFEkN-LmM,125
|
|
360
359
|
truefoundry/ml/log_types/plot.py,sha256=LDh4uy6z2P_a2oPM2lc85c0lt8utVvunohzeMawFjZw,7572
|
|
361
360
|
truefoundry/ml/log_types/pydantic_base.py,sha256=eBlw_AEyAz4iJKDP4zgJOCFWcldwQqpf7FADW1jzIQY,272
|
|
@@ -381,7 +380,7 @@ truefoundry/workflow/remote_filesystem/__init__.py,sha256=LQ95ViEjJ7Ts4JcCGOxMPs
|
|
|
381
380
|
truefoundry/workflow/remote_filesystem/logger.py,sha256=em2l7D6sw7xTLDP0kQSLpgfRRCLpN14Qw85TN7ujQcE,1022
|
|
382
381
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=xcT0wQmQlgzcj0nP3tJopyFSVWT1uv3nhiTIuwfXYeg,12342
|
|
383
382
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py,sha256=nSGPZu0Gyd_jz0KsEE-7w_BmnTD8CVF1S8cUJoxaCbc,13305
|
|
384
|
-
truefoundry-0.11.
|
|
385
|
-
truefoundry-0.11.
|
|
386
|
-
truefoundry-0.11.
|
|
387
|
-
truefoundry-0.11.
|
|
383
|
+
truefoundry-0.11.2.dist-info/METADATA,sha256=7n9RCZ9gGKy-q0nVRgja-FIyJEBcgo4eXtbrCPpfIFk,2505
|
|
384
|
+
truefoundry-0.11.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
385
|
+
truefoundry-0.11.2.dist-info/entry_points.txt,sha256=xVjn7RMN-MW2-9f7YU-bBdlZSvvrwzhpX1zmmRmsNPU,98
|
|
386
|
+
truefoundry-0.11.2.dist-info/RECORD,,
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
|
|
3
|
-
from truefoundry.common.constants import (
|
|
4
|
-
SERVICEFOUNDRY_CLIENT_MAX_RETRIES,
|
|
5
|
-
VERSION_PREFIX,
|
|
6
|
-
)
|
|
7
|
-
from truefoundry.common.exceptions import HttpRequestException
|
|
8
|
-
from truefoundry.common.request_utils import (
|
|
9
|
-
http_request,
|
|
10
|
-
request_handling,
|
|
11
|
-
requests_retry_session,
|
|
12
|
-
)
|
|
13
|
-
from truefoundry.common.servicefoundry_client import (
|
|
14
|
-
ServiceFoundryServiceClient as BaseServiceFoundryServiceClient,
|
|
15
|
-
)
|
|
16
|
-
from truefoundry.common.utils import get_user_agent
|
|
17
|
-
from truefoundry.ml.exceptions import MlFoundryException
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class ServiceFoundryServiceClient(BaseServiceFoundryServiceClient):
|
|
21
|
-
def __init__(self, tfy_host: str, token: str):
|
|
22
|
-
super().__init__(tfy_host=tfy_host)
|
|
23
|
-
self._token = token
|
|
24
|
-
|
|
25
|
-
@functools.cached_property
|
|
26
|
-
def _min_cli_version_required(self) -> str:
|
|
27
|
-
# TODO (chiragjn): read the mlfoundry min cli version from the config?
|
|
28
|
-
return self.python_sdk_config.truefoundry_cli_min_version
|
|
29
|
-
|
|
30
|
-
def get_integration_from_id(self, integration_id: str):
|
|
31
|
-
integration_id = integration_id or ""
|
|
32
|
-
session = requests_retry_session(retries=SERVICEFOUNDRY_CLIENT_MAX_RETRIES)
|
|
33
|
-
response = http_request(
|
|
34
|
-
method="get",
|
|
35
|
-
url=f"{self._api_server_url}/{VERSION_PREFIX}/provider-accounts/provider-integrations",
|
|
36
|
-
token=self._token,
|
|
37
|
-
timeout=3,
|
|
38
|
-
params={"id": integration_id, "type": "blob-storage"},
|
|
39
|
-
session=session,
|
|
40
|
-
headers={
|
|
41
|
-
"User-Agent": get_user_agent(),
|
|
42
|
-
},
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
try:
|
|
46
|
-
result = request_handling(response)
|
|
47
|
-
assert isinstance(result, dict)
|
|
48
|
-
except HttpRequestException as he:
|
|
49
|
-
raise MlFoundryException(
|
|
50
|
-
f"Failed to get storage integration from id: {integration_id}. Error: {he.message}",
|
|
51
|
-
status_code=he.status_code,
|
|
52
|
-
) from None
|
|
53
|
-
except Exception as e:
|
|
54
|
-
raise MlFoundryException(
|
|
55
|
-
f"Failed to get storage integration from id: {integration_id}. Error: {str(e)}"
|
|
56
|
-
) from None
|
|
57
|
-
|
|
58
|
-
data = result.get("data", result.get("providerAccounts"))
|
|
59
|
-
# TODO (chiragjn): Parse this using Pydantic
|
|
60
|
-
if data and len(data) > 0 and data[0]:
|
|
61
|
-
return data[0]
|
|
62
|
-
else:
|
|
63
|
-
raise MlFoundryException(
|
|
64
|
-
f"Invalid storage integration id: {integration_id}"
|
|
65
|
-
)
|
|
File without changes
|
|
File without changes
|