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.

Files changed (53) hide show
  1. truefoundry/common/utils.py +73 -1
  2. truefoundry/deploy/__init__.py +5 -0
  3. truefoundry/deploy/cli/cli.py +2 -0
  4. truefoundry/deploy/cli/commands/__init__.py +1 -0
  5. truefoundry/deploy/cli/commands/deploy_init_command.py +22 -0
  6. truefoundry/deploy/lib/dao/application.py +2 -1
  7. truefoundry/deploy/v2/lib/patched_models.py +8 -0
  8. truefoundry/ml/__init__.py +15 -12
  9. truefoundry/ml/artifact/truefoundry_artifact_repo.py +8 -3
  10. truefoundry/ml/autogen/client/__init__.py +11 -0
  11. truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +161 -0
  12. truefoundry/ml/autogen/client/models/__init__.py +11 -0
  13. truefoundry/ml/autogen/client/models/artifact_version_manifest.py +2 -2
  14. truefoundry/ml/autogen/client/models/export_deployment_files_request_dto.py +82 -0
  15. truefoundry/ml/autogen/client/models/infer_method_name.py +34 -0
  16. truefoundry/ml/autogen/client/models/model_server.py +34 -0
  17. truefoundry/ml/autogen/client/models/model_version_environment.py +97 -0
  18. truefoundry/ml/autogen/client/models/model_version_manifest.py +14 -3
  19. truefoundry/ml/autogen/client/models/serialization_format.py +35 -0
  20. truefoundry/ml/autogen/client/models/sklearn_framework.py +31 -2
  21. truefoundry/ml/autogen/client/models/transformers_framework.py +2 -2
  22. truefoundry/ml/autogen/client/models/xg_boost_framework.py +20 -2
  23. truefoundry/ml/autogen/client_README.md +6 -0
  24. truefoundry/ml/autogen/entities/artifacts.py +65 -6
  25. truefoundry/ml/cli/commands/model_init.py +97 -0
  26. truefoundry/ml/cli/utils.py +34 -0
  27. truefoundry/ml/log_types/artifacts/model.py +48 -24
  28. truefoundry/ml/log_types/artifacts/utils.py +37 -1
  29. truefoundry/ml/mlfoundry_api.py +77 -79
  30. truefoundry/ml/mlfoundry_run.py +3 -31
  31. truefoundry/ml/model_framework.py +257 -3
  32. truefoundry/ml/validation_utils.py +2 -0
  33. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/METADATA +2 -6
  34. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/RECORD +36 -45
  35. truefoundry/deploy/function_service/__init__.py +0 -3
  36. truefoundry/deploy/function_service/__main__.py +0 -27
  37. truefoundry/deploy/function_service/app.py +0 -92
  38. truefoundry/deploy/function_service/build.py +0 -45
  39. truefoundry/deploy/function_service/remote/__init__.py +0 -6
  40. truefoundry/deploy/function_service/remote/context.py +0 -3
  41. truefoundry/deploy/function_service/remote/method.py +0 -67
  42. truefoundry/deploy/function_service/remote/remote.py +0 -144
  43. truefoundry/deploy/function_service/route.py +0 -137
  44. truefoundry/deploy/function_service/service.py +0 -113
  45. truefoundry/deploy/function_service/utils.py +0 -53
  46. truefoundry/langchain/__init__.py +0 -12
  47. truefoundry/langchain/deprecated.py +0 -302
  48. truefoundry/langchain/truefoundry_chat.py +0 -130
  49. truefoundry/langchain/truefoundry_embeddings.py +0 -171
  50. truefoundry/langchain/truefoundry_llm.py +0 -106
  51. truefoundry/langchain/utils.py +0 -44
  52. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1rc1.dist-info}/WHEEL +0 -0
  53. {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, Sequence, Tuple, Union
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 ModelFrameworkType, _ModelFramework
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
- if self._model_version.manifest.framework:
146
- self._framework = copy.deepcopy(
147
- self._model_version.manifest.framework.actual_instance
148
- )
149
- else:
150
- self._framework = None
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(_framework.dict()) if _framework else None,
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/"
@@ -1,7 +1,8 @@
1
1
  import os
2
2
  import time
3
3
  import uuid
4
- from pathlib import Path
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}")
@@ -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}")