truefoundry 0.5.0rc6__py3-none-any.whl → 0.5.1rc1__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 +73 -1
- truefoundry/deploy/__init__.py +5 -0
- truefoundry/deploy/cli/cli.py +2 -0
- truefoundry/deploy/cli/commands/__init__.py +1 -0
- truefoundry/deploy/cli/commands/deploy_init_command.py +22 -0
- truefoundry/deploy/lib/dao/application.py +2 -1
- truefoundry/deploy/v2/lib/patched_models.py +8 -0
- truefoundry/ml/__init__.py +15 -12
- truefoundry/ml/artifact/truefoundry_artifact_repo.py +8 -3
- truefoundry/ml/autogen/client/__init__.py +11 -0
- truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +161 -0
- truefoundry/ml/autogen/client/models/__init__.py +11 -0
- truefoundry/ml/autogen/client/models/artifact_version_manifest.py +2 -2
- truefoundry/ml/autogen/client/models/export_deployment_files_request_dto.py +82 -0
- truefoundry/ml/autogen/client/models/infer_method_name.py +34 -0
- truefoundry/ml/autogen/client/models/model_server.py +34 -0
- truefoundry/ml/autogen/client/models/model_version_environment.py +97 -0
- truefoundry/ml/autogen/client/models/model_version_manifest.py +14 -3
- truefoundry/ml/autogen/client/models/serialization_format.py +35 -0
- truefoundry/ml/autogen/client/models/sklearn_framework.py +31 -2
- truefoundry/ml/autogen/client/models/transformers_framework.py +2 -2
- truefoundry/ml/autogen/client/models/xg_boost_framework.py +20 -2
- truefoundry/ml/autogen/client_README.md +6 -0
- truefoundry/ml/autogen/entities/artifacts.py +65 -6
- truefoundry/ml/cli/commands/model_init.py +97 -0
- truefoundry/ml/cli/utils.py +34 -0
- truefoundry/ml/log_types/artifacts/model.py +48 -24
- truefoundry/ml/log_types/artifacts/utils.py +37 -1
- truefoundry/ml/mlfoundry_api.py +77 -79
- truefoundry/ml/mlfoundry_run.py +3 -31
- truefoundry/ml/model_framework.py +257 -3
- truefoundry/ml/validation_utils.py +2 -0
- {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/METADATA +2 -6
- {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/RECORD +36 -45
- truefoundry/deploy/function_service/__init__.py +0 -3
- truefoundry/deploy/function_service/__main__.py +0 -27
- truefoundry/deploy/function_service/app.py +0 -92
- truefoundry/deploy/function_service/build.py +0 -45
- truefoundry/deploy/function_service/remote/__init__.py +0 -6
- truefoundry/deploy/function_service/remote/context.py +0 -3
- truefoundry/deploy/function_service/remote/method.py +0 -67
- truefoundry/deploy/function_service/remote/remote.py +0 -144
- truefoundry/deploy/function_service/route.py +0 -137
- truefoundry/deploy/function_service/service.py +0 -113
- truefoundry/deploy/function_service/utils.py +0 -53
- truefoundry/langchain/__init__.py +0 -12
- truefoundry/langchain/deprecated.py +0 -302
- truefoundry/langchain/truefoundry_chat.py +0 -130
- truefoundry/langchain/truefoundry_embeddings.py +0 -171
- truefoundry/langchain/truefoundry_llm.py +0 -106
- truefoundry/langchain/utils.py +0 -44
- {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/WHEEL +0 -0
- {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/entry_points.txt +0 -0
|
@@ -8,7 +8,7 @@ import typing
|
|
|
8
8
|
import uuid
|
|
9
9
|
import warnings
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
12
12
|
|
|
13
13
|
from truefoundry.ml.artifact.truefoundry_artifact_repo import (
|
|
14
14
|
ArtifactIdentifier,
|
|
@@ -25,6 +25,7 @@ from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
|
25
25
|
MlfoundryArtifactsApi,
|
|
26
26
|
ModelDto,
|
|
27
27
|
ModelVersionDto,
|
|
28
|
+
ModelVersionEnvironment,
|
|
28
29
|
ModelVersionManifest,
|
|
29
30
|
NotifyArtifactVersionFailureDto,
|
|
30
31
|
TrueFoundryArtifactSource,
|
|
@@ -43,7 +44,12 @@ from truefoundry.ml.log_types.artifacts.utils import (
|
|
|
43
44
|
_validate_description,
|
|
44
45
|
calculate_total_size,
|
|
45
46
|
)
|
|
46
|
-
from truefoundry.ml.model_framework import
|
|
47
|
+
from truefoundry.ml.model_framework import (
|
|
48
|
+
ModelFrameworkType,
|
|
49
|
+
_ModelFramework,
|
|
50
|
+
auto_update_environment_details,
|
|
51
|
+
auto_update_model_framework_details,
|
|
52
|
+
)
|
|
47
53
|
from truefoundry.ml.session import _get_api_client
|
|
48
54
|
from truefoundry.pydantic_v1 import BaseModel, Extra
|
|
49
55
|
|
|
@@ -97,6 +103,7 @@ class ModelVersion:
|
|
|
97
103
|
self._description: str = ""
|
|
98
104
|
self._metadata: Dict[str, Any] = {}
|
|
99
105
|
self._model_schema: Optional[Dict[str, Any]] = None
|
|
106
|
+
self._environment: Optional[ModelVersionEnvironment] = None
|
|
100
107
|
self._framework: Optional[ModelFrameworkType] = None
|
|
101
108
|
self._set_mutable_attrs()
|
|
102
109
|
|
|
@@ -142,19 +149,20 @@ class ModelVersion:
|
|
|
142
149
|
self._model_schema = copy.deepcopy(
|
|
143
150
|
self._model_version.manifest.model_schema
|
|
144
151
|
)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
self._environment = copy.deepcopy(self._model_version.manifest.environment)
|
|
153
|
+
self._framework = (
|
|
154
|
+
copy.deepcopy(self._model_version.manifest.framework.actual_instance)
|
|
155
|
+
if self._model_version.manifest.framework
|
|
156
|
+
else None
|
|
157
|
+
)
|
|
151
158
|
else:
|
|
152
159
|
self._description = self._model_version.description or ""
|
|
153
160
|
self._metadata = copy.deepcopy(self._model_version.artifact_metadata)
|
|
161
|
+
self._model_schema = None
|
|
162
|
+
self._environment = None
|
|
154
163
|
self._framework = _ModelFramework.to_model_framework_type(
|
|
155
164
|
self._model_version.model_framework
|
|
156
165
|
)
|
|
157
|
-
self._model_schema = None
|
|
158
166
|
|
|
159
167
|
def _refetch_model_version(self, reset_mutable_attrs: bool = True):
|
|
160
168
|
_model_version = self._mlfoundry_artifacts_api.get_model_version_get(
|
|
@@ -241,6 +249,23 @@ class ModelVersion:
|
|
|
241
249
|
return
|
|
242
250
|
self._model_schema = copy.deepcopy(value)
|
|
243
251
|
|
|
252
|
+
@property
|
|
253
|
+
def environment(self) -> Optional[ModelVersionEnvironment]:
|
|
254
|
+
"""Get the environment details for the model"""
|
|
255
|
+
return self._environment
|
|
256
|
+
|
|
257
|
+
@environment.setter
|
|
258
|
+
def environment(self, value: Optional[Dict[str, Any]]):
|
|
259
|
+
"""set the environment details for the model"""
|
|
260
|
+
if not self._model_version.manifest:
|
|
261
|
+
warnings.warn(
|
|
262
|
+
message="This model version was created using an older serialization format. Environment will not be updated",
|
|
263
|
+
category=DeprecationWarning,
|
|
264
|
+
stacklevel=2,
|
|
265
|
+
)
|
|
266
|
+
return
|
|
267
|
+
self._environment = copy.deepcopy(value)
|
|
268
|
+
|
|
244
269
|
@property
|
|
245
270
|
def framework(self) -> Optional["ModelFrameworkType"]:
|
|
246
271
|
"""Get the framework of the model"""
|
|
@@ -439,6 +464,7 @@ class ModelVersion:
|
|
|
439
464
|
self._model_version.manifest.description = self.description
|
|
440
465
|
self._model_version.manifest.metadata = self.metadata
|
|
441
466
|
self._model_version.manifest.model_schema = self.model_schema
|
|
467
|
+
self._model_version.manifest.environment = self.environment
|
|
442
468
|
self._model_version.manifest.framework = (
|
|
443
469
|
Framework.from_dict(self.framework.dict()) if self.framework else None
|
|
444
470
|
)
|
|
@@ -466,12 +492,12 @@ def _log_model_version( # noqa: C901
|
|
|
466
492
|
model_file_or_folder: Union[str, BlobStorageDirectory],
|
|
467
493
|
mlfoundry_artifacts_api: Optional[MlfoundryArtifactsApi] = None,
|
|
468
494
|
ml_repo_id: Optional[str] = None,
|
|
469
|
-
additional_files: Sequence[Tuple[Union[str, Path], Optional[str]]] = (),
|
|
470
495
|
description: Optional[str] = None,
|
|
471
496
|
metadata: Optional[Dict[str, Any]] = None,
|
|
472
497
|
step: Optional[int] = 0,
|
|
473
498
|
progress: Optional[bool] = None,
|
|
474
499
|
framework: Optional[Union[str, ModelFramework, "ModelFrameworkType"]] = None,
|
|
500
|
+
environment: Optional[ModelVersionEnvironment] = None,
|
|
475
501
|
model_schema: Optional[Dict[str, Any]] = None,
|
|
476
502
|
) -> ModelVersion:
|
|
477
503
|
if (run and mlfoundry_artifacts_api) or (not run and not mlfoundry_artifacts_api):
|
|
@@ -496,7 +522,6 @@ def _log_model_version( # noqa: C901
|
|
|
496
522
|
step = step or 0
|
|
497
523
|
total_size = None
|
|
498
524
|
metadata = metadata or {}
|
|
499
|
-
additional_files = additional_files or {}
|
|
500
525
|
|
|
501
526
|
_validate_description(description)
|
|
502
527
|
_validate_artifact_metadata(metadata)
|
|
@@ -514,17 +539,6 @@ def _log_model_version( # noqa: C901
|
|
|
514
539
|
ignore_model_dir_dest_conflict=True,
|
|
515
540
|
)
|
|
516
541
|
|
|
517
|
-
# verify additional files and paths, copy additional files
|
|
518
|
-
if additional_files:
|
|
519
|
-
logger.info("Adding `additional_files` to model version contents")
|
|
520
|
-
temp_dest_to_src_map = _copy_additional_files(
|
|
521
|
-
root_dir=temp_dir.name,
|
|
522
|
-
files_dir="",
|
|
523
|
-
model_dir=None,
|
|
524
|
-
additional_files=additional_files,
|
|
525
|
-
ignore_model_dir_dest_conflict=False,
|
|
526
|
-
existing_dest_to_src_map=temp_dest_to_src_map,
|
|
527
|
-
)
|
|
528
542
|
except Exception as e:
|
|
529
543
|
temp_dir.cleanup()
|
|
530
544
|
raise MlFoundryException("Failed to log model") from e
|
|
@@ -578,13 +592,23 @@ def _log_model_version( # noqa: C901
|
|
|
578
592
|
else:
|
|
579
593
|
raise MlFoundryException("Invalid model_file_or_folder provided")
|
|
580
594
|
|
|
581
|
-
_framework = _ModelFramework.to_model_framework_type(framework)
|
|
582
595
|
_source_cls = typing.get_type_hints(ModelVersionManifest)["source"]
|
|
596
|
+
|
|
597
|
+
# Auto fetch the framework & environment details if not provided
|
|
598
|
+
framework = _ModelFramework.to_model_framework_type(framework)
|
|
599
|
+
if framework and isinstance(model_file_or_folder, str):
|
|
600
|
+
auto_update_model_framework_details(
|
|
601
|
+
framework=framework, model_file_or_folder=model_file_or_folder
|
|
602
|
+
)
|
|
603
|
+
environment = environment or ModelVersionEnvironment()
|
|
604
|
+
auto_update_environment_details(environment=environment, framework=framework)
|
|
605
|
+
|
|
583
606
|
model_manifest = ModelVersionManifest(
|
|
584
607
|
description=description,
|
|
585
608
|
metadata=metadata,
|
|
586
609
|
source=_source_cls.from_dict(source.dict()),
|
|
587
|
-
framework=Framework.from_dict(
|
|
610
|
+
framework=Framework.from_dict(framework.dict()) if framework else None,
|
|
611
|
+
environment=environment,
|
|
588
612
|
step=step,
|
|
589
613
|
model_schema=model_schema,
|
|
590
614
|
)
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
4
|
import posixpath
|
|
5
|
-
from pathlib import Path
|
|
5
|
+
from pathlib import Path, PureWindowsPath
|
|
6
6
|
from typing import Any, Dict, Optional, Sequence, Tuple, Union
|
|
7
7
|
|
|
8
8
|
from truefoundry.ml.exceptions import MlFoundryException
|
|
@@ -11,6 +11,13 @@ from truefoundry.ml.log_types.artifacts.constants import DESCRIPTION_MAX_LENGTH
|
|
|
11
11
|
logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
def to_unix_path(path):
|
|
15
|
+
path = os.path.normpath(path)
|
|
16
|
+
if os.path.sep == "\\":
|
|
17
|
+
path = PureWindowsPath(path).as_posix()
|
|
18
|
+
return path
|
|
19
|
+
|
|
20
|
+
|
|
14
21
|
def _copy_tree(
|
|
15
22
|
root_dir: str, src_path: str, dest_path: str, dest_to_src: Dict[str, str]
|
|
16
23
|
):
|
|
@@ -42,6 +49,35 @@ def is_destination_path_dirlike(dest_path) -> bool:
|
|
|
42
49
|
return False
|
|
43
50
|
|
|
44
51
|
|
|
52
|
+
def get_single_file_path_if_only_one_in_directory(path: str) -> Optional[str]:
|
|
53
|
+
"""
|
|
54
|
+
Get the filename from a path, or return a filename from a directory if a single file exists.
|
|
55
|
+
Args:
|
|
56
|
+
path: The file or folder path.
|
|
57
|
+
Returns:
|
|
58
|
+
Optional[str]: The filename or None if no files are found or multiple files are found.
|
|
59
|
+
"""
|
|
60
|
+
# If it's already a file, return it as-is
|
|
61
|
+
if os.path.isfile(path):
|
|
62
|
+
return path
|
|
63
|
+
|
|
64
|
+
# If it's a directory, check if it contains a single file
|
|
65
|
+
if is_destination_path_dirlike(path):
|
|
66
|
+
all_files = []
|
|
67
|
+
for root, _, files in os.walk(path):
|
|
68
|
+
# Collect all files found in any subdirectory
|
|
69
|
+
all_files.extend(os.path.join(root, f) for f in files)
|
|
70
|
+
# If more than one file is found, stop early
|
|
71
|
+
if len(all_files) > 1:
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
# If only one file is found, return it
|
|
75
|
+
if len(all_files) == 1:
|
|
76
|
+
return all_files[0]
|
|
77
|
+
|
|
78
|
+
return None # No file found or Multiple files found
|
|
79
|
+
|
|
80
|
+
|
|
45
81
|
def _copy_additional_files(
|
|
46
82
|
root_dir: str,
|
|
47
83
|
files_dir: str, # relative to root dir e.g. "files/"
|
truefoundry/ml/mlfoundry_api.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import time
|
|
3
3
|
import uuid
|
|
4
|
-
|
|
4
|
+
import zipfile
|
|
5
|
+
from io import BytesIO
|
|
5
6
|
from typing import (
|
|
6
7
|
TYPE_CHECKING,
|
|
7
8
|
Any,
|
|
@@ -15,10 +16,9 @@ from typing import (
|
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
import coolname
|
|
18
|
-
import pandas as pd
|
|
19
19
|
|
|
20
|
-
from truefoundry.common.utils import relogin_error_message
|
|
21
|
-
from truefoundry.ml import constants
|
|
20
|
+
from truefoundry.common.utils import ContextualDirectoryManager, relogin_error_message
|
|
21
|
+
from truefoundry.ml import ModelVersionEnvironment, constants
|
|
22
22
|
from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
23
23
|
ArtifactDto,
|
|
24
24
|
ArtifactType,
|
|
@@ -27,12 +27,14 @@ from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
|
27
27
|
CreateRunRequestDto,
|
|
28
28
|
DatasetDto,
|
|
29
29
|
ExperimentsApi,
|
|
30
|
+
ExportDeploymentFilesRequestDto,
|
|
30
31
|
ListArtifactsRequestDto,
|
|
31
32
|
ListArtifactVersionsRequestDto,
|
|
32
33
|
ListDatasetsRequestDto,
|
|
33
34
|
ListModelVersionsRequestDto,
|
|
34
35
|
MlfoundryArtifactsApi,
|
|
35
36
|
ModelDto,
|
|
37
|
+
ModelServer,
|
|
36
38
|
RunsApi,
|
|
37
39
|
RunTagDto,
|
|
38
40
|
SearchRunsRequestDto,
|
|
@@ -75,7 +77,7 @@ if TYPE_CHECKING:
|
|
|
75
77
|
from truefoundry.ml import ModelFrameworkType
|
|
76
78
|
|
|
77
79
|
_SEARCH_MAX_RESULTS_DEFAULT = 1000
|
|
78
|
-
|
|
80
|
+
_ML_FOUNDRY_API_REQUEST_TIMEOUT = 10
|
|
79
81
|
_INTERNAL_ENV_VARS = [
|
|
80
82
|
"TFY_INTERNAL_APPLICATION_ID",
|
|
81
83
|
"TFY_INTERNAL_JOB_RUN_NAME",
|
|
@@ -476,43 +478,6 @@ class MlFoundry:
|
|
|
476
478
|
)
|
|
477
479
|
return mlfoundry_run
|
|
478
480
|
|
|
479
|
-
def get_all_runs(
|
|
480
|
-
self,
|
|
481
|
-
ml_repo: str,
|
|
482
|
-
) -> pd.DataFrame:
|
|
483
|
-
"""Returns all the run name and id present under a ML Repo.
|
|
484
|
-
|
|
485
|
-
The user must have `READ` access to the ML Repo.
|
|
486
|
-
|
|
487
|
-
Args:
|
|
488
|
-
ml_repo (str): Name of the ML Repo.
|
|
489
|
-
Returns:
|
|
490
|
-
pd.DataFrame: dataframe with two columns- run_id and run_name
|
|
491
|
-
|
|
492
|
-
Examples:
|
|
493
|
-
|
|
494
|
-
### get all the runs from a ml_repo
|
|
495
|
-
```python
|
|
496
|
-
from truefoundry.ml import get_client
|
|
497
|
-
|
|
498
|
-
client = get_client()
|
|
499
|
-
|
|
500
|
-
run = client.get_all_runs(ml_repo='my-repo')
|
|
501
|
-
```
|
|
502
|
-
"""
|
|
503
|
-
runs = []
|
|
504
|
-
for run in self.search_runs(ml_repo=ml_repo):
|
|
505
|
-
runs.append((run.run_id, run.run_name))
|
|
506
|
-
|
|
507
|
-
if len(runs) == 0:
|
|
508
|
-
return pd.DataFrame(
|
|
509
|
-
columns=[constants.RUN_ID_COL_NAME, constants.RUN_NAME_COL_NAME]
|
|
510
|
-
)
|
|
511
|
-
|
|
512
|
-
return pd.DataFrame(
|
|
513
|
-
runs, columns=[constants.RUN_ID_COL_NAME, constants.RUN_NAME_COL_NAME]
|
|
514
|
-
)
|
|
515
|
-
|
|
516
481
|
def search_runs(
|
|
517
482
|
self,
|
|
518
483
|
ml_repo: str,
|
|
@@ -658,6 +623,74 @@ class MlFoundry:
|
|
|
658
623
|
"""
|
|
659
624
|
return self._tracking_uri
|
|
660
625
|
|
|
626
|
+
def _initialize_model_server(
|
|
627
|
+
self,
|
|
628
|
+
name: str,
|
|
629
|
+
model_version_fqn: str,
|
|
630
|
+
workspace_fqn: str,
|
|
631
|
+
model_server: ModelServer,
|
|
632
|
+
output_dir: Optional[str] = None,
|
|
633
|
+
) -> str:
|
|
634
|
+
"""
|
|
635
|
+
Initialize the model server for deployment.
|
|
636
|
+
|
|
637
|
+
Args:
|
|
638
|
+
name (str): Name of the application.
|
|
639
|
+
model_version_fqn (str): Fully Qualified Name of the model version.
|
|
640
|
+
workspace_fqn (str): Fully Qualified Name of the workspace.
|
|
641
|
+
model_server (ModelServer): Server type for deployment (e.g., TRITON).
|
|
642
|
+
output_dir (Optional[str]): Directory where the model files will be extracted.
|
|
643
|
+
Defaults to the current working directory.
|
|
644
|
+
|
|
645
|
+
Returns:
|
|
646
|
+
str: Path to the directory where the model files are extracted.
|
|
647
|
+
|
|
648
|
+
Raises:
|
|
649
|
+
MlFoundryException: If an error occurs during API calls, directory creation, or file extraction.
|
|
650
|
+
"""
|
|
651
|
+
|
|
652
|
+
# Using get_with_http_info to get the response object and extract the raw data
|
|
653
|
+
try:
|
|
654
|
+
export_deployment_files_request_dto = ExportDeploymentFilesRequestDto(
|
|
655
|
+
model_version_fqn=model_version_fqn,
|
|
656
|
+
workspace_fqn=workspace_fqn,
|
|
657
|
+
service_name=name,
|
|
658
|
+
model_server=model_server,
|
|
659
|
+
)
|
|
660
|
+
response = self._mlfoundry_artifacts_api.export_deployment_files_by_fqn_post_with_http_info(
|
|
661
|
+
export_deployment_files_request_dto=export_deployment_files_request_dto,
|
|
662
|
+
_preload_content=False,
|
|
663
|
+
_request_timeout=_ML_FOUNDRY_API_REQUEST_TIMEOUT,
|
|
664
|
+
)
|
|
665
|
+
except ApiException as e:
|
|
666
|
+
err_msg = (
|
|
667
|
+
f"Failed to fetch deployment files for name={name}, "
|
|
668
|
+
f"model_version_fqn={model_version_fqn}, workspace_fqn={workspace_fqn}. "
|
|
669
|
+
f"Error: {e}"
|
|
670
|
+
)
|
|
671
|
+
raise MlFoundryException(err_msg) from e
|
|
672
|
+
|
|
673
|
+
output_dir = os.path.abspath(output_dir or os.getcwd())
|
|
674
|
+
codegen_dir = os.path.join(output_dir, name)
|
|
675
|
+
if codegen_dir == output_dir:
|
|
676
|
+
raise ValueError("Name cannot be empty, please provide a valid name")
|
|
677
|
+
|
|
678
|
+
try:
|
|
679
|
+
with ContextualDirectoryManager(dir_path=codegen_dir) as dir_path:
|
|
680
|
+
with zipfile.ZipFile(BytesIO(response.raw_data), mode="r") as zip_file:
|
|
681
|
+
zip_file.extractall(dir_path)
|
|
682
|
+
except FileExistsError as e:
|
|
683
|
+
err_msg = (
|
|
684
|
+
f"Deployment directory {codegen_dir!r} already exists. "
|
|
685
|
+
"Please choose a different deployment name or delete the existing directory."
|
|
686
|
+
)
|
|
687
|
+
raise MlFoundryException(err_msg) from e
|
|
688
|
+
except zipfile.BadZipFile as e:
|
|
689
|
+
raise MlFoundryException(
|
|
690
|
+
f"Failed to extract model files. Error: {e}"
|
|
691
|
+
) from e
|
|
692
|
+
return codegen_dir
|
|
693
|
+
|
|
661
694
|
def get_model_version(
|
|
662
695
|
self,
|
|
663
696
|
ml_repo: str,
|
|
@@ -1227,11 +1260,11 @@ class MlFoundry:
|
|
|
1227
1260
|
ml_repo: str,
|
|
1228
1261
|
name: str,
|
|
1229
1262
|
model_file_or_folder: Union[str, BlobStorageDirectory],
|
|
1230
|
-
additional_files: Sequence[Tuple[Union[str, Path], Optional[str]]] = (),
|
|
1231
1263
|
description: Optional[str] = None,
|
|
1232
1264
|
metadata: Optional[Dict[str, Any]] = None,
|
|
1233
1265
|
progress: Optional[bool] = None,
|
|
1234
1266
|
framework: Optional[Union[str, ModelFramework, "ModelFrameworkType"]] = None,
|
|
1267
|
+
environment: Optional[ModelVersionEnvironment] = None,
|
|
1235
1268
|
model_schema: Optional[Dict[str, Any]] = None,
|
|
1236
1269
|
) -> ModelVersion:
|
|
1237
1270
|
"""
|
|
@@ -1262,41 +1295,6 @@ class MlFoundry:
|
|
|
1262
1295
|
Can also be `None` if the framework is not known or not supported.
|
|
1263
1296
|
**Deprecated**: Prefer `ModelFrameworkType` over `enums.ModelFramework`.
|
|
1264
1297
|
|
|
1265
|
-
additional_files (Sequence[Tuple[Union[str, Path], Optional[str]]], optional): A list of pairs
|
|
1266
|
-
of (source path, destination path) to add additional files and folders
|
|
1267
|
-
to the model version contents. The first member of the pair should be a file or directory path
|
|
1268
|
-
and the second member should be the path inside the model versions contents to upload to.
|
|
1269
|
-
The model version contents are arranged like follows
|
|
1270
|
-
.
|
|
1271
|
-
└── model/
|
|
1272
|
-
└── # model files are serialized here
|
|
1273
|
-
└── # any additional files and folders can be added here.
|
|
1274
|
-
|
|
1275
|
-
You can also add additional files to model/ subdirectory by specifying the destination path as model/
|
|
1276
|
-
|
|
1277
|
-
```python
|
|
1278
|
-
from truefoundry.ml import TensorFlowFramework
|
|
1279
|
-
|
|
1280
|
-
run.log_model(
|
|
1281
|
-
name="xyz",
|
|
1282
|
-
model_file_or_folder="clf.joblib",
|
|
1283
|
-
framework=TensorFlowFramework(),
|
|
1284
|
-
additional_files=[("foo.txt", "foo/bar/foo.txt"), ("tokenizer/", "foo/tokenizer/")]
|
|
1285
|
-
)
|
|
1286
|
-
```
|
|
1287
|
-
|
|
1288
|
-
would result in
|
|
1289
|
-
|
|
1290
|
-
```
|
|
1291
|
-
.
|
|
1292
|
-
├── model/
|
|
1293
|
-
│ └── clf.joblib # if `model_file_or_folder` is a folder, contents will be added here
|
|
1294
|
-
└── foo/
|
|
1295
|
-
├── bar/
|
|
1296
|
-
│ └── foo.txt
|
|
1297
|
-
└── tokenizer/
|
|
1298
|
-
└── # contents of tokenizer/ directory will be uploaded here
|
|
1299
|
-
```
|
|
1300
1298
|
description (Optional[str], optional): arbitrary text upto 1024 characters to store as description.
|
|
1301
1299
|
This field can be updated at any time after logging. Defaults to `None`
|
|
1302
1300
|
metadata (Optional[Dict[str, Any]], optional): arbitrary json serializable dictionary to store metadata.
|
|
@@ -1386,12 +1384,12 @@ class MlFoundry:
|
|
|
1386
1384
|
ml_repo_id=ml_repo_id,
|
|
1387
1385
|
name=name,
|
|
1388
1386
|
model_file_or_folder=model_file_or_folder,
|
|
1389
|
-
additional_files=additional_files,
|
|
1390
1387
|
description=description,
|
|
1391
1388
|
metadata=metadata,
|
|
1392
1389
|
step=None,
|
|
1393
1390
|
progress=progress,
|
|
1394
1391
|
framework=framework,
|
|
1392
|
+
environment=environment,
|
|
1395
1393
|
model_schema=model_schema,
|
|
1396
1394
|
)
|
|
1397
1395
|
logger.info(f"Logged model successfully with fqn {model_version.fqn!r}")
|
truefoundry/ml/mlfoundry_run.py
CHANGED
|
@@ -3,7 +3,6 @@ import os
|
|
|
3
3
|
import platform
|
|
4
4
|
import re
|
|
5
5
|
import time
|
|
6
|
-
from pathlib import Path
|
|
7
6
|
from typing import (
|
|
8
7
|
TYPE_CHECKING,
|
|
9
8
|
Any,
|
|
@@ -12,7 +11,6 @@ from typing import (
|
|
|
12
11
|
Iterator,
|
|
13
12
|
List,
|
|
14
13
|
Optional,
|
|
15
|
-
Sequence,
|
|
16
14
|
Tuple,
|
|
17
15
|
Union,
|
|
18
16
|
)
|
|
@@ -20,7 +18,7 @@ from urllib.parse import urljoin, urlsplit
|
|
|
20
18
|
|
|
21
19
|
from truefoundry import version
|
|
22
20
|
from truefoundry.common.utils import relogin_error_message
|
|
23
|
-
from truefoundry.ml import constants
|
|
21
|
+
from truefoundry.ml import ModelVersionEnvironment, constants
|
|
24
22
|
from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
25
23
|
ArtifactType,
|
|
26
24
|
DeleteRunRequest,
|
|
@@ -930,12 +928,12 @@ class MlFoundryRun:
|
|
|
930
928
|
*,
|
|
931
929
|
name: str,
|
|
932
930
|
model_file_or_folder: Union[str, BlobStorageDirectory],
|
|
933
|
-
additional_files: Sequence[Tuple[Union[str, Path], Optional[str]]] = (),
|
|
934
931
|
description: Optional[str] = None,
|
|
935
932
|
metadata: Optional[Dict[str, Any]] = None,
|
|
936
933
|
step: int = 0,
|
|
937
934
|
progress: Optional[bool] = None,
|
|
938
935
|
framework: Optional[Union[str, ModelFramework, "ModelFrameworkType"]] = None,
|
|
936
|
+
environment: Optional[ModelVersionEnvironment] = None,
|
|
939
937
|
model_schema: Optional[Dict[str, Any]] = None,
|
|
940
938
|
) -> ModelVersion:
|
|
941
939
|
# TODO (chiragjn): Document mapping of framework to list of valid model save kwargs
|
|
@@ -964,33 +962,7 @@ class MlFoundryRun:
|
|
|
964
962
|
Supported frameworks can be found in `truefoundry.ml.enums.ModelFramework`.
|
|
965
963
|
Can also be `None` if the framework is not known or not supported.
|
|
966
964
|
**Deprecated**: Prefer `ModelFrameworkType` over `enums.ModelFramework`.
|
|
967
|
-
additional_files (Sequence[Tuple[Union[str, Path], Optional[str]]], optional): A list of pairs
|
|
968
|
-
of (source path, destination path) to add additional files and folders
|
|
969
|
-
to the model version contents. The first member of the pair should be a file or directory path
|
|
970
|
-
and the second member should be the path inside the model versions contents to upload to.
|
|
971
|
-
The model version contents are arranged like follows
|
|
972
|
-
.
|
|
973
|
-
└── model/
|
|
974
|
-
└── # model files are serialized here
|
|
975
|
-
└── # any additional files and folders can be added here.
|
|
976
|
-
|
|
977
|
-
You can also add additional files to model/ subdirectory by specifying the destination path as model/
|
|
978
965
|
|
|
979
|
-
```
|
|
980
|
-
E.g. >>> run.log_model(
|
|
981
|
-
... name="xyz", model_file_or_folder="clf.joblib", framework="sklearn",
|
|
982
|
-
... additional_files=[("foo.txt", "foo/bar/foo.txt"), ("tokenizer/", "foo/tokenizer/")]
|
|
983
|
-
... )
|
|
984
|
-
would result in
|
|
985
|
-
.
|
|
986
|
-
├── model/
|
|
987
|
-
│ └── clf.joblib # if `model_file_or_folder` is a folder, contents will be added here
|
|
988
|
-
└── foo/
|
|
989
|
-
├── bar/
|
|
990
|
-
│ └── foo.txt
|
|
991
|
-
└── tokenizer/
|
|
992
|
-
└── # contents of tokenizer/ directory will be uploaded here
|
|
993
|
-
```
|
|
994
966
|
description (Optional[str], optional): arbitrary text upto 1024 characters to store as description.
|
|
995
967
|
This field can be updated at any time after logging. Defaults to `None`
|
|
996
968
|
metadata (Optional[Dict[str, Any]], optional): arbitrary json serializable dictionary to store metadata.
|
|
@@ -1083,12 +1055,12 @@ class MlFoundryRun:
|
|
|
1083
1055
|
run=self,
|
|
1084
1056
|
name=name,
|
|
1085
1057
|
model_file_or_folder=model_file_or_folder,
|
|
1086
|
-
additional_files=additional_files,
|
|
1087
1058
|
description=description,
|
|
1088
1059
|
metadata=metadata,
|
|
1089
1060
|
step=step,
|
|
1090
1061
|
progress=progress,
|
|
1091
1062
|
framework=framework,
|
|
1063
|
+
environment=environment,
|
|
1092
1064
|
model_schema=model_schema,
|
|
1093
1065
|
)
|
|
1094
1066
|
logger.info(f"Logged model successfully with fqn {model_version.fqn!r}")
|