truefoundry 0.5.0rc6__py3-none-any.whl → 0.5.1__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 (68) hide show
  1. truefoundry/common/auth_service_client.py +2 -2
  2. truefoundry/common/constants.py +9 -0
  3. truefoundry/common/utils.py +81 -1
  4. truefoundry/deploy/__init__.py +5 -0
  5. truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +4 -2
  6. truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +7 -5
  7. truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +87 -28
  8. truefoundry/deploy/builder/constants.py +8 -0
  9. truefoundry/deploy/builder/utils.py +9 -4
  10. truefoundry/deploy/cli/cli.py +2 -0
  11. truefoundry/deploy/cli/commands/__init__.py +1 -0
  12. truefoundry/deploy/cli/commands/deploy_init_command.py +22 -0
  13. truefoundry/deploy/lib/dao/application.py +2 -1
  14. truefoundry/deploy/v2/lib/patched_models.py +8 -0
  15. truefoundry/ml/__init__.py +25 -15
  16. truefoundry/ml/artifact/truefoundry_artifact_repo.py +8 -3
  17. truefoundry/ml/autogen/client/__init__.py +24 -0
  18. truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +325 -0
  19. truefoundry/ml/autogen/client/models/__init__.py +24 -0
  20. truefoundry/ml/autogen/client/models/artifact_version_manifest.py +2 -2
  21. truefoundry/ml/autogen/client/models/export_deployment_files_request_dto.py +82 -0
  22. truefoundry/ml/autogen/client/models/infer_method_name.py +34 -0
  23. truefoundry/ml/autogen/client/models/model_server.py +34 -0
  24. truefoundry/ml/autogen/client/models/model_version_environment.py +97 -0
  25. truefoundry/ml/autogen/client/models/model_version_manifest.py +13 -8
  26. truefoundry/ml/autogen/client/models/sklearn_framework.py +25 -2
  27. truefoundry/ml/autogen/client/models/sklearn_model_schema.py +82 -0
  28. truefoundry/ml/autogen/client/models/sklearn_serialization_format.py +35 -0
  29. truefoundry/ml/autogen/client/models/transformers_framework.py +2 -2
  30. truefoundry/ml/autogen/client/models/validate_external_storage_root_request_dto.py +71 -0
  31. truefoundry/ml/autogen/client/models/validate_external_storage_root_response_dto.py +69 -0
  32. truefoundry/ml/autogen/client/models/xg_boost_framework.py +28 -3
  33. truefoundry/ml/autogen/client/models/xg_boost_model_schema.py +88 -0
  34. truefoundry/ml/autogen/client/models/xg_boost_serialization_format.py +36 -0
  35. truefoundry/ml/autogen/client_README.md +12 -0
  36. truefoundry/ml/autogen/entities/artifacts.py +119 -26
  37. truefoundry/ml/autogen/models/signature.py +6 -3
  38. truefoundry/ml/autogen/models/utils.py +12 -7
  39. truefoundry/ml/cli/commands/model_init.py +97 -0
  40. truefoundry/ml/cli/utils.py +34 -0
  41. truefoundry/ml/log_types/artifacts/model.py +53 -38
  42. truefoundry/ml/log_types/artifacts/utils.py +38 -2
  43. truefoundry/ml/mlfoundry_api.py +77 -81
  44. truefoundry/ml/mlfoundry_run.py +3 -33
  45. truefoundry/ml/model_framework.py +372 -3
  46. truefoundry/ml/validation_utils.py +2 -0
  47. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1.dist-info}/METADATA +2 -6
  48. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1.dist-info}/RECORD +50 -55
  49. truefoundry/deploy/function_service/__init__.py +0 -3
  50. truefoundry/deploy/function_service/__main__.py +0 -27
  51. truefoundry/deploy/function_service/app.py +0 -92
  52. truefoundry/deploy/function_service/build.py +0 -45
  53. truefoundry/deploy/function_service/remote/__init__.py +0 -6
  54. truefoundry/deploy/function_service/remote/context.py +0 -3
  55. truefoundry/deploy/function_service/remote/method.py +0 -67
  56. truefoundry/deploy/function_service/remote/remote.py +0 -144
  57. truefoundry/deploy/function_service/route.py +0 -137
  58. truefoundry/deploy/function_service/service.py +0 -113
  59. truefoundry/deploy/function_service/utils.py +0 -53
  60. truefoundry/langchain/__init__.py +0 -12
  61. truefoundry/langchain/deprecated.py +0 -302
  62. truefoundry/langchain/truefoundry_chat.py +0 -130
  63. truefoundry/langchain/truefoundry_embeddings.py +0 -171
  64. truefoundry/langchain/truefoundry_llm.py +0 -106
  65. truefoundry/langchain/utils.py +0 -44
  66. truefoundry/ml/log_types/artifacts/model_extras.py +0 -48
  67. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1.dist-info}/WHEEL +0 -0
  68. {truefoundry-0.5.0rc6.dist-info → truefoundry-0.5.1.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,11 +25,13 @@ 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,
31
32
  UpdateModelVersionRequestDto,
32
33
  )
34
+ from truefoundry.ml.autogen.models import infer_signature as _infer_signature
33
35
  from truefoundry.ml.enums import ModelFramework
34
36
  from truefoundry.ml.exceptions import MlFoundryException
35
37
  from truefoundry.ml.log_types.artifacts.artifact import BlobStorageDirectory
@@ -43,11 +45,19 @@ from truefoundry.ml.log_types.artifacts.utils import (
43
45
  _validate_description,
44
46
  calculate_total_size,
45
47
  )
46
- from truefoundry.ml.model_framework import ModelFrameworkType, _ModelFramework
48
+ from truefoundry.ml.model_framework import (
49
+ ModelFrameworkType,
50
+ _ModelFramework,
51
+ auto_update_environment_details,
52
+ auto_update_model_framework_details,
53
+ )
47
54
  from truefoundry.ml.session import _get_api_client
48
55
  from truefoundry.pydantic_v1 import BaseModel, Extra
49
56
 
50
57
  if TYPE_CHECKING:
58
+ import numpy as np
59
+ import pandas as pd
60
+
51
61
  from truefoundry.ml.mlfoundry_run import MlFoundryRun
52
62
 
53
63
 
@@ -96,7 +106,7 @@ class ModelVersion:
96
106
  self._deleted = False
97
107
  self._description: str = ""
98
108
  self._metadata: Dict[str, Any] = {}
99
- self._model_schema: Optional[Dict[str, Any]] = None
109
+ self._environment: Optional[ModelVersionEnvironment] = None
100
110
  self._framework: Optional[ModelFrameworkType] = None
101
111
  self._set_mutable_attrs()
102
112
 
@@ -139,22 +149,19 @@ class ModelVersion:
139
149
  if self._model_version.manifest:
140
150
  self._description = self._model_version.manifest.description or ""
141
151
  self._metadata = copy.deepcopy(self._model_version.manifest.metadata)
142
- self._model_schema = copy.deepcopy(
143
- self._model_version.manifest.model_schema
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
144
157
  )
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
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._environment = None
154
162
  self._framework = _ModelFramework.to_model_framework_type(
155
163
  self._model_version.model_framework
156
164
  )
157
- self._model_schema = None
158
165
 
159
166
  def _refetch_model_version(self, reset_mutable_attrs: bool = True):
160
167
  _model_version = self._mlfoundry_artifacts_api.get_model_version_get(
@@ -225,21 +232,21 @@ class ModelVersion:
225
232
  self._metadata = copy.deepcopy(value)
226
233
 
227
234
  @property
228
- def model_schema(self) -> Optional[Dict[str, Any]]:
229
- """Get model_schema for the current model"""
230
- return self._model_schema
235
+ def environment(self) -> Optional[ModelVersionEnvironment]:
236
+ """Get the environment details for the model"""
237
+ return self._environment
231
238
 
232
- @model_schema.setter
233
- def model_schema(self, value: Optional[Dict[str, Any]]):
234
- """set the model_schema for current model"""
239
+ @environment.setter
240
+ def environment(self, value: Optional[Dict[str, Any]]):
241
+ """set the environment details for the model"""
235
242
  if not self._model_version.manifest:
236
243
  warnings.warn(
237
- message="This model version was created using an older serialization format. model_schema will not be updated",
244
+ message="This model version was created using an older serialization format. Environment will not be updated",
238
245
  category=DeprecationWarning,
239
246
  stacklevel=2,
240
247
  )
241
248
  return
242
- self._model_schema = copy.deepcopy(value)
249
+ self._environment = copy.deepcopy(value)
243
250
 
244
251
  @property
245
252
  def framework(self) -> Optional["ModelFrameworkType"]:
@@ -438,7 +445,7 @@ class ModelVersion:
438
445
  if self._model_version.manifest:
439
446
  self._model_version.manifest.description = self.description
440
447
  self._model_version.manifest.metadata = self.metadata
441
- self._model_version.manifest.model_schema = self.model_schema
448
+ self._model_version.manifest.environment = self.environment
442
449
  self._model_version.manifest.framework = (
443
450
  Framework.from_dict(self.framework.dict()) if self.framework else None
444
451
  )
@@ -466,13 +473,12 @@ def _log_model_version( # noqa: C901
466
473
  model_file_or_folder: Union[str, BlobStorageDirectory],
467
474
  mlfoundry_artifacts_api: Optional[MlfoundryArtifactsApi] = None,
468
475
  ml_repo_id: Optional[str] = None,
469
- additional_files: Sequence[Tuple[Union[str, Path], Optional[str]]] = (),
470
476
  description: Optional[str] = None,
471
477
  metadata: Optional[Dict[str, Any]] = None,
472
478
  step: Optional[int] = 0,
473
479
  progress: Optional[bool] = None,
474
480
  framework: Optional[Union[str, ModelFramework, "ModelFrameworkType"]] = None,
475
- model_schema: Optional[Dict[str, Any]] = None,
481
+ environment: Optional[ModelVersionEnvironment] = None,
476
482
  ) -> ModelVersion:
477
483
  if (run and mlfoundry_artifacts_api) or (not run and not mlfoundry_artifacts_api):
478
484
  raise MlFoundryException(
@@ -496,7 +502,6 @@ def _log_model_version( # noqa: C901
496
502
  step = step or 0
497
503
  total_size = None
498
504
  metadata = metadata or {}
499
- additional_files = additional_files or {}
500
505
 
501
506
  _validate_description(description)
502
507
  _validate_artifact_metadata(metadata)
@@ -514,17 +519,6 @@ def _log_model_version( # noqa: C901
514
519
  ignore_model_dir_dest_conflict=True,
515
520
  )
516
521
 
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
522
  except Exception as e:
529
523
  temp_dir.cleanup()
530
524
  raise MlFoundryException("Failed to log model") from e
@@ -578,15 +572,24 @@ def _log_model_version( # noqa: C901
578
572
  else:
579
573
  raise MlFoundryException("Invalid model_file_or_folder provided")
580
574
 
581
- _framework = _ModelFramework.to_model_framework_type(framework)
582
575
  _source_cls = typing.get_type_hints(ModelVersionManifest)["source"]
576
+
577
+ # Auto fetch the framework & environment details if not provided
578
+ framework = _ModelFramework.to_model_framework_type(framework)
579
+ if framework and isinstance(model_file_or_folder, str):
580
+ auto_update_model_framework_details(
581
+ framework=framework, model_file_or_folder=model_file_or_folder
582
+ )
583
+ environment = environment or ModelVersionEnvironment()
584
+ auto_update_environment_details(environment=environment, framework=framework)
585
+
583
586
  model_manifest = ModelVersionManifest(
584
587
  description=description,
585
588
  metadata=metadata,
586
589
  source=_source_cls.from_dict(source.dict()),
587
- framework=Framework.from_dict(_framework.dict()) if _framework else None,
590
+ framework=Framework.from_dict(framework.dict()) if framework else None,
591
+ environment=environment,
588
592
  step=step,
589
- model_schema=model_schema,
590
593
  )
591
594
  artifact_version_response = mlfoundry_artifacts_api.finalize_artifact_version_post(
592
595
  finalize_artifact_version_request_dto=FinalizeArtifactVersionRequestDto(
@@ -600,3 +603,15 @@ def _log_model_version( # noqa: C901
600
603
  )
601
604
  )
602
605
  return ModelVersion.from_fqn(fqn=artifact_version_response.artifact_version.fqn)
606
+
607
+
608
+ def infer_signature(
609
+ model_input: Any = None,
610
+ model_output: Optional[
611
+ Union["pd.DataFrame", "np.ndarray", Dict[str, "np.ndarray"]]
612
+ ] = None,
613
+ params: Optional[Dict[str, Any]] = None,
614
+ ):
615
+ return _infer_signature(
616
+ model_input=model_input, model_output=model_output, params=params
617
+ )
@@ -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/"
@@ -136,7 +172,7 @@ def _get_src_dest_pairs(
136
172
  dest_to_src_map: Dict[str, str],
137
173
  ) -> Sequence[Tuple[str, str]]:
138
174
  src_dest_pairs = [
139
- (src_path, os.path.relpath(dest_abs_path, root_dir))
175
+ (src_path, to_unix_path(os.path.relpath(dest_abs_path, root_dir)))
140
176
  for dest_abs_path, src_path in dest_to_src_map.items()
141
177
  ]
142
178
  return src_dest_pairs
@@ -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,12 +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,
1235
- model_schema: Optional[Dict[str, Any]] = None,
1267
+ environment: Optional[ModelVersionEnvironment] = None,
1236
1268
  ) -> ModelVersion:
1237
1269
  """
1238
1270
  Serialize and log a versioned model under the current ml_repo. Each logged model generates a new version
@@ -1262,41 +1294,6 @@ class MlFoundry:
1262
1294
  Can also be `None` if the framework is not known or not supported.
1263
1295
  **Deprecated**: Prefer `ModelFrameworkType` over `enums.ModelFramework`.
1264
1296
 
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
1297
  description (Optional[str], optional): arbitrary text upto 1024 characters to store as description.
1301
1298
  This field can be updated at any time after logging. Defaults to `None`
1302
1299
  metadata (Optional[Dict[str, Any]], optional): arbitrary json serializable dictionary to store metadata.
@@ -1386,13 +1383,12 @@ class MlFoundry:
1386
1383
  ml_repo_id=ml_repo_id,
1387
1384
  name=name,
1388
1385
  model_file_or_folder=model_file_or_folder,
1389
- additional_files=additional_files,
1390
1386
  description=description,
1391
1387
  metadata=metadata,
1392
1388
  step=None,
1393
1389
  progress=progress,
1394
1390
  framework=framework,
1395
- model_schema=model_schema,
1391
+ environment=environment,
1396
1392
  )
1397
1393
  logger.info(f"Logged model successfully with fqn {model_version.fqn!r}")
1398
1394
  return model_version
@@ -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,13 +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,
939
- model_schema: Optional[Dict[str, Any]] = None,
936
+ environment: Optional[ModelVersionEnvironment] = None,
940
937
  ) -> ModelVersion:
941
938
  # TODO (chiragjn): Document mapping of framework to list of valid model save kwargs
942
939
  # TODO (chiragjn): Add more examples
@@ -964,33 +961,7 @@ class MlFoundryRun:
964
961
  Supported frameworks can be found in `truefoundry.ml.enums.ModelFramework`.
965
962
  Can also be `None` if the framework is not known or not supported.
966
963
  **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
964
 
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
965
  description (Optional[str], optional): arbitrary text upto 1024 characters to store as description.
995
966
  This field can be updated at any time after logging. Defaults to `None`
996
967
  metadata (Optional[Dict[str, Any]], optional): arbitrary json serializable dictionary to store metadata.
@@ -1083,13 +1054,12 @@ class MlFoundryRun:
1083
1054
  run=self,
1084
1055
  name=name,
1085
1056
  model_file_or_folder=model_file_or_folder,
1086
- additional_files=additional_files,
1087
1057
  description=description,
1088
1058
  metadata=metadata,
1089
1059
  step=step,
1090
1060
  progress=progress,
1091
1061
  framework=framework,
1092
- model_schema=model_schema,
1062
+ environment=environment,
1093
1063
  )
1094
1064
  logger.info(f"Logged model successfully with fqn {model_version.fqn!r}")
1095
1065
  return model_version