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
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ FastAPI
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+ import json
15
+ import re # noqa: F401
16
+
17
+ from aenum import Enum
18
+
19
+
20
+ class ModelServer(str, Enum):
21
+ """
22
+ An enumeration.
23
+ """
24
+
25
+ """
26
+ allowed enum values
27
+ """
28
+ TRITON = "triton"
29
+ FASTAPI = "fastapi"
30
+
31
+ @classmethod
32
+ def from_json(cls, json_str: str) -> ModelServer:
33
+ """Create an instance of ModelServer from a JSON string"""
34
+ return ModelServer(json.loads(json_str))
@@ -0,0 +1,97 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ FastAPI
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import pprint
18
+ import re # noqa: F401
19
+ from typing import Optional
20
+
21
+ from truefoundry.pydantic_v1 import (
22
+ BaseModel,
23
+ Field,
24
+ StrictStr,
25
+ conlist,
26
+ constr,
27
+ validator,
28
+ )
29
+
30
+
31
+ class ModelVersionEnvironment(BaseModel):
32
+ """
33
+ +label=Environment # noqa: E501
34
+ """
35
+
36
+ python_version: Optional[constr(strict=True)] = Field(
37
+ default=None,
38
+ description="+label=Python Version +usage=Python version for the model version",
39
+ )
40
+ pip_packages: Optional[conlist(StrictStr)] = Field(
41
+ default=None,
42
+ description="+label=PIP Packages +usage=PIP packages for the model version",
43
+ )
44
+ __properties = ["python_version", "pip_packages"]
45
+
46
+ @validator("python_version")
47
+ def python_version_validate_regular_expression(cls, value):
48
+ """Validates the regular expression"""
49
+ if value is None:
50
+ return value
51
+
52
+ if not re.match(r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$", value):
53
+ raise ValueError(
54
+ r"must validate the regular expression /^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$/"
55
+ )
56
+ return value
57
+
58
+ class Config:
59
+ """Pydantic configuration"""
60
+
61
+ allow_population_by_field_name = True
62
+ validate_assignment = True
63
+
64
+ def to_str(self) -> str:
65
+ """Returns the string representation of the model using alias"""
66
+ return pprint.pformat(self.dict(by_alias=True))
67
+
68
+ def to_json(self) -> str:
69
+ """Returns the JSON representation of the model using alias"""
70
+ return json.dumps(self.to_dict())
71
+
72
+ @classmethod
73
+ def from_json(cls, json_str: str) -> ModelVersionEnvironment:
74
+ """Create an instance of ModelVersionEnvironment from a JSON string"""
75
+ return cls.from_dict(json.loads(json_str))
76
+
77
+ def to_dict(self):
78
+ """Returns the dictionary representation of the model using alias"""
79
+ _dict = self.dict(by_alias=True, exclude={}, exclude_none=True)
80
+ return _dict
81
+
82
+ @classmethod
83
+ def from_dict(cls, obj: dict) -> ModelVersionEnvironment:
84
+ """Create an instance of ModelVersionEnvironment from a dict"""
85
+ if obj is None:
86
+ return None
87
+
88
+ if not isinstance(obj, dict):
89
+ return ModelVersionEnvironment.parse_obj(obj)
90
+
91
+ _obj = ModelVersionEnvironment.parse_obj(
92
+ {
93
+ "python_version": obj.get("python_version"),
94
+ "pip_packages": obj.get("pip_packages"),
95
+ }
96
+ )
97
+ return _obj
@@ -19,6 +19,9 @@ import re # noqa: F401
19
19
  from typing import Any, Dict, Optional
20
20
 
21
21
  from truefoundry.ml.autogen.client.models.framework import Framework
22
+ from truefoundry.ml.autogen.client.models.model_version_environment import (
23
+ ModelVersionEnvironment,
24
+ )
22
25
  from truefoundry.ml.autogen.client.models.source1 import Source1
23
26
  from truefoundry.pydantic_v1 import (
24
27
  BaseModel,
@@ -37,21 +40,22 @@ class ModelVersionManifest(BaseModel):
37
40
 
38
41
  description: Optional[constr(strict=True, max_length=512)] = Field(
39
42
  default=None,
40
- description="+label=Description +docs=Description of the artifact version",
43
+ description="+label=Description +usage=Description of the artifact or model version +docs=Description of the artifact or model version",
41
44
  )
42
45
  metadata: Dict[str, Any] = Field(
43
46
  default=...,
44
- description="+label=Metadata +docs=Metadata for the model version +usage=Metadata for the model version +uiType=JsonInput",
47
+ description="+label=Metadata +docs=Metadata for the artifact or model version +usage=Metadata for the artifact or model version +uiType=JsonInput",
45
48
  )
46
49
  type: Optional[StrictStr] = "model-version"
47
50
  source: Source1 = Field(...)
48
51
  framework: Optional[Framework] = None
52
+ environment: Optional[ModelVersionEnvironment] = None
49
53
  step: Optional[conint(strict=True, ge=0)] = Field(
50
54
  default=0, description="+label=Step"
51
55
  )
52
56
  model_schema: Optional[Dict[str, Any]] = Field(
53
57
  default=None,
54
- description="+label=Model Schema +usage=Schema of the model +uiType=Hidden",
58
+ description="+label=Model Schema +usage=Schema of the model +uiType=JsonInput",
55
59
  )
56
60
  __properties = [
57
61
  "description",
@@ -59,6 +63,7 @@ class ModelVersionManifest(BaseModel):
59
63
  "type",
60
64
  "source",
61
65
  "framework",
66
+ "environment",
62
67
  "step",
63
68
  "model_schema",
64
69
  ]
@@ -101,6 +106,9 @@ class ModelVersionManifest(BaseModel):
101
106
  # override the default output from truefoundry.pydantic_v1 by calling `to_dict()` of framework
102
107
  if self.framework:
103
108
  _dict["framework"] = self.framework.to_dict()
109
+ # override the default output from truefoundry.pydantic_v1 by calling `to_dict()` of environment
110
+ if self.environment:
111
+ _dict["environment"] = self.environment.to_dict()
104
112
  return _dict
105
113
 
106
114
  @classmethod
@@ -125,6 +133,9 @@ class ModelVersionManifest(BaseModel):
125
133
  "framework": Framework.from_dict(obj.get("framework"))
126
134
  if obj.get("framework") is not None
127
135
  else None,
136
+ "environment": ModelVersionEnvironment.from_dict(obj.get("environment"))
137
+ if obj.get("environment") is not None
138
+ else None,
128
139
  "step": obj.get("step") if obj.get("step") is not None else 0,
129
140
  "model_schema": obj.get("model_schema"),
130
141
  }
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ FastAPI
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document: 0.1.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+ import json
15
+ import re # noqa: F401
16
+
17
+ from aenum import Enum
18
+
19
+
20
+ class SerializationFormat(str, Enum):
21
+ """
22
+ +label=Serialization format +usage=Serialization format used for the model
23
+ """
24
+
25
+ """
26
+ allowed enum values
27
+ """
28
+ CLOUDPICKLE = "cloudpickle"
29
+ JOBLIB = "joblib"
30
+ PICKLE = "pickle"
31
+
32
+ @classmethod
33
+ def from_json(cls, json_str: str) -> SerializationFormat:
34
+ """Create an instance of SerializationFormat from a JSON string"""
35
+ return SerializationFormat(json.loads(json_str))
@@ -16,7 +16,12 @@ from __future__ import annotations
16
16
  import json
17
17
  import pprint
18
18
  import re # noqa: F401
19
+ from typing import Optional
19
20
 
21
+ from truefoundry.ml.autogen.client.models.infer_method_name import InferMethodName
22
+ from truefoundry.ml.autogen.client.models.serialization_format import (
23
+ SerializationFormat,
24
+ )
20
25
  from truefoundry.pydantic_v1 import BaseModel, Field, StrictStr, validator
21
26
 
22
27
 
@@ -29,7 +34,24 @@ class SklearnFramework(BaseModel):
29
34
  default=...,
30
35
  description="+label=Type +usage=Type of the framework +value=sklearn",
31
36
  )
32
- __properties = ["type"]
37
+ serialization_format: Optional[SerializationFormat] = Field(
38
+ default=None,
39
+ description="+label=Serialization format +usage=Serialization format used for the model",
40
+ )
41
+ model_filepath: Optional[StrictStr] = Field(
42
+ default=None,
43
+ description="+label=Model file path +usage=Relative path to the model file",
44
+ )
45
+ infer_method_name: Optional[InferMethodName] = Field(
46
+ default=None,
47
+ description="+label=Inference method name +usage=Name of the method used for inference",
48
+ )
49
+ __properties = [
50
+ "type",
51
+ "serialization_format",
52
+ "model_filepath",
53
+ "infer_method_name",
54
+ ]
33
55
 
34
56
  @validator("type")
35
57
  def type_validate_enum(cls, value):
@@ -71,5 +93,12 @@ class SklearnFramework(BaseModel):
71
93
  if not isinstance(obj, dict):
72
94
  return SklearnFramework.parse_obj(obj)
73
95
 
74
- _obj = SklearnFramework.parse_obj({"type": obj.get("type")})
96
+ _obj = SklearnFramework.parse_obj(
97
+ {
98
+ "type": obj.get("type"),
99
+ "serialization_format": obj.get("serialization_format"),
100
+ "model_filepath": obj.get("model_filepath"),
101
+ "infer_method_name": obj.get("infer_method_name"),
102
+ }
103
+ )
75
104
  return _obj
@@ -37,11 +37,11 @@ class TransformersFramework(BaseModel):
37
37
  )
38
38
  pipeline_tag: Optional[StrictStr] = Field(
39
39
  default=None,
40
- description="+label=Pipeline Tag +usage=Pipeline tag +docs=Pipeline tag for the framework",
40
+ description="+label=Pipeline Tag +usage=The `pipeline()` task this model can be used with e.g. `text-generation`. See [huggingface docs](https://huggingface.co/docs/transformers/main/en/main_classes/pipelines#transformers.pipeline.task) for all possible values +docs=Pipeline tag for the framework",
41
41
  )
42
42
  base_model: Optional[StrictStr] = Field(
43
43
  default=None,
44
- description="+label=Base Model +usage=Base model +docs=Base model Id. If this is a finetuned model, this points to the base model used for finetuning",
44
+ description="+label=Base Model +usage=Base model Id. If this is a finetuned model, this points to the base model used for finetuning +docs=Base model Id. If this is a finetuned model, this points to the base model used for finetuning",
45
45
  )
46
46
  __properties = ["type", "library_name", "pipeline_tag", "base_model"]
47
47
 
@@ -16,7 +16,11 @@ from __future__ import annotations
16
16
  import json
17
17
  import pprint
18
18
  import re # noqa: F401
19
+ from typing import Optional
19
20
 
21
+ from truefoundry.ml.autogen.client.models.serialization_format import (
22
+ SerializationFormat,
23
+ )
20
24
  from truefoundry.pydantic_v1 import BaseModel, Field, StrictStr, validator
21
25
 
22
26
 
@@ -29,7 +33,15 @@ class XGBoostFramework(BaseModel):
29
33
  default=...,
30
34
  description="+label=Type +usage=Type of the framework +value=xgboost",
31
35
  )
32
- __properties = ["type"]
36
+ serialization_format: Optional[SerializationFormat] = Field(
37
+ default=None,
38
+ description="+label=Serialization format +usage=Serialization format used for the model",
39
+ )
40
+ model_filepath: Optional[StrictStr] = Field(
41
+ default=None,
42
+ description="+label=Model file path +usage=Relative path to the model file",
43
+ )
44
+ __properties = ["type", "serialization_format", "model_filepath"]
33
45
 
34
46
  @validator("type")
35
47
  def type_validate_enum(cls, value):
@@ -71,5 +83,11 @@ class XGBoostFramework(BaseModel):
71
83
  if not isinstance(obj, dict):
72
84
  return XGBoostFramework.parse_obj(obj)
73
85
 
74
- _obj = XGBoostFramework.parse_obj({"type": obj.get("type")})
86
+ _obj = XGBoostFramework.parse_obj(
87
+ {
88
+ "type": obj.get("type"),
89
+ "serialization_format": obj.get("serialization_format"),
90
+ "model_filepath": obj.get("model_filepath"),
91
+ }
92
+ )
75
93
  return _obj
@@ -102,6 +102,7 @@ Class | Method | HTTP request | Description
102
102
  *MlfoundryArtifactsApi* | [**delete_dataset_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#delete_dataset_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/datasets/delete | Delete Dataset
103
103
  *MlfoundryArtifactsApi* | [**delete_files_for_dataset_delete**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#delete_files_for_dataset_delete) | **DELETE** /api/2.0/mlflow/mlfoundry-artifacts/datasets/files/ | Delete Files For Dataset
104
104
  *MlfoundryArtifactsApi* | [**delete_model_version_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#delete_model_version_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/model-versions/delete | Delete Model Version
105
+ *MlfoundryArtifactsApi* | [**export_deployment_files_by_fqn_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#export_deployment_files_by_fqn_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/model-versions/export-deployment-files-by-fqn | Export Deployment Files By Fqn
105
106
  *MlfoundryArtifactsApi* | [**finalize_artifact_version_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#finalize_artifact_version_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/artifact-versions/finalize | Finalize Artifact Version
106
107
  *MlfoundryArtifactsApi* | [**get_artifact_by_fqn_get**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_artifact_by_fqn_get) | **GET** /api/2.0/mlflow/mlfoundry-artifacts/artifacts/get-by-fqn | Get Artifact By Fqn
107
108
  *MlfoundryArtifactsApi* | [**get_artifact_by_id_get**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_artifact_by_id_get) | **GET** /api/2.0/mlflow/mlfoundry-artifacts/artifacts/get | Get Artifact By Id
@@ -211,6 +212,7 @@ Class | Method | HTTP request | Description
211
212
  - [ExperimentIdRequestDto](truefoundry/ml/autogen/client/docs/ExperimentIdRequestDto.md)
212
213
  - [ExperimentResponseDto](truefoundry/ml/autogen/client/docs/ExperimentResponseDto.md)
213
214
  - [ExperimentTagDto](truefoundry/ml/autogen/client/docs/ExperimentTagDto.md)
215
+ - [ExportDeploymentFilesRequestDto](truefoundry/ml/autogen/client/docs/ExportDeploymentFilesRequestDto.md)
214
216
  - [ExternalArtifactSource](truefoundry/ml/autogen/client/docs/ExternalArtifactSource.md)
215
217
  - [FastAIFramework](truefoundry/ml/autogen/client/docs/FastAIFramework.md)
216
218
  - [FileInfoDto](truefoundry/ml/autogen/client/docs/FileInfoDto.md)
@@ -233,6 +235,7 @@ Class | Method | HTTP request | Description
233
235
  - [HTTPValidationError](truefoundry/ml/autogen/client/docs/HTTPValidationError.md)
234
236
  - [ImageContentPart](truefoundry/ml/autogen/client/docs/ImageContentPart.md)
235
237
  - [ImageUrl](truefoundry/ml/autogen/client/docs/ImageUrl.md)
238
+ - [InferMethodName](truefoundry/ml/autogen/client/docs/InferMethodName.md)
236
239
  - [InternalMetadata](truefoundry/ml/autogen/client/docs/InternalMetadata.md)
237
240
  - [KerasFramework](truefoundry/ml/autogen/client/docs/KerasFramework.md)
238
241
  - [LatestRunLogDto](truefoundry/ml/autogen/client/docs/LatestRunLogDto.md)
@@ -270,7 +273,9 @@ Class | Method | HTTP request | Description
270
273
  - [ModelConfiguration](truefoundry/ml/autogen/client/docs/ModelConfiguration.md)
271
274
  - [ModelDto](truefoundry/ml/autogen/client/docs/ModelDto.md)
272
275
  - [ModelResponseDto](truefoundry/ml/autogen/client/docs/ModelResponseDto.md)
276
+ - [ModelServer](truefoundry/ml/autogen/client/docs/ModelServer.md)
273
277
  - [ModelVersionDto](truefoundry/ml/autogen/client/docs/ModelVersionDto.md)
278
+ - [ModelVersionEnvironment](truefoundry/ml/autogen/client/docs/ModelVersionEnvironment.md)
274
279
  - [ModelVersionManifest](truefoundry/ml/autogen/client/docs/ModelVersionManifest.md)
275
280
  - [ModelVersionResponseDto](truefoundry/ml/autogen/client/docs/ModelVersionResponseDto.md)
276
281
  - [MultiPartUploadDto](truefoundry/ml/autogen/client/docs/MultiPartUploadDto.md)
@@ -294,6 +299,7 @@ Class | Method | HTTP request | Description
294
299
  - [RunTagDto](truefoundry/ml/autogen/client/docs/RunTagDto.md)
295
300
  - [SearchRunsRequestDto](truefoundry/ml/autogen/client/docs/SearchRunsRequestDto.md)
296
301
  - [SearchRunsResponseDto](truefoundry/ml/autogen/client/docs/SearchRunsResponseDto.md)
302
+ - [SerializationFormat](truefoundry/ml/autogen/client/docs/SerializationFormat.md)
297
303
  - [SetExperimentTagRequestDto](truefoundry/ml/autogen/client/docs/SetExperimentTagRequestDto.md)
298
304
  - [SetTagRequestDto](truefoundry/ml/autogen/client/docs/SetTagRequestDto.md)
299
305
  - [SignedURLDto](truefoundry/ml/autogen/client/docs/SignedURLDto.md)
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: artifacts.json
3
- # timestamp: 2024-11-22T19:31:48+00:00
3
+ # timestamp: 2024-12-04T12:00:28+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -52,11 +52,11 @@ class AgentWithFQN(Agent):
52
52
  class BaseArtifactVersion(BaseModel):
53
53
  description: Optional[constr(max_length=512)] = Field(
54
54
  None,
55
- description="+label=Description\n+docs=Description of the artifact version",
55
+ description="+label=Description\n+usage=Description of the artifact or model version\n+docs=Description of the artifact or model version",
56
56
  )
57
57
  metadata: Dict[str, Any] = Field(
58
58
  ...,
59
- description="+label=Metadata\n+docs=Metadata for the model version\n+usage=Metadata for the model version\n+uiType=JsonInput",
59
+ description="+label=Metadata\n+docs=Metadata for the artifact or model version\n+usage=Metadata for the artifact or model version\n+uiType=JsonInput",
60
60
  )
61
61
 
62
62
 
@@ -226,6 +226,23 @@ class ModelConfiguration(BaseModel):
226
226
  )
227
227
 
228
228
 
229
+ class ModelVersionEnvironment(BaseModel):
230
+ """
231
+ +label=Environment
232
+ """
233
+
234
+ python_version: Optional[constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$")] = (
235
+ Field(
236
+ None,
237
+ description="+label=Python Version\n+usage=Python version for the model version",
238
+ )
239
+ )
240
+ pip_packages: Optional[List[str]] = Field(
241
+ None,
242
+ description="+label=PIP Packages\n+usage=PIP packages for the model version",
243
+ )
244
+
245
+
229
246
  class ONNXFramework(BaseModel):
230
247
  """
231
248
  +docs=ONNX framework for the model version
@@ -259,6 +276,27 @@ class PyTorchFramework(BaseModel):
259
276
  )
260
277
 
261
278
 
279
+ class SerializationFormat(str, Enum):
280
+ """
281
+ +label=Serialization format
282
+ +usage=Serialization format used for the model
283
+ """
284
+
285
+ cloudpickle = "cloudpickle"
286
+ joblib = "joblib"
287
+ pickle = "pickle"
288
+
289
+
290
+ class InferMethodName(str, Enum):
291
+ """
292
+ +label=Inference method name
293
+ +usage=Name of the method used for inference
294
+ """
295
+
296
+ predict = "predict"
297
+ predict_proba = "predict_proba"
298
+
299
+
262
300
  class SklearnFramework(BaseModel):
263
301
  """
264
302
  +docs=Scikit-learn framework for the model version
@@ -268,6 +306,18 @@ class SklearnFramework(BaseModel):
268
306
  type: Literal["sklearn"] = Field(
269
307
  ..., description="+label=Type\n+usage=Type of the framework\n+value=sklearn"
270
308
  )
309
+ serialization_format: Optional[SerializationFormat] = Field(
310
+ None,
311
+ description="+label=Serialization format\n+usage=Serialization format used for the model",
312
+ )
313
+ model_filepath: Optional[str] = Field(
314
+ None,
315
+ description="+label=Model file path\n+usage=Relative path to the model file",
316
+ )
317
+ infer_method_name: Optional[InferMethodName] = Field(
318
+ None,
319
+ description="+label=Inference method name\n+usage=Name of the method used for inference",
320
+ )
271
321
 
272
322
 
273
323
  class SpaCyFramework(BaseModel):
@@ -357,11 +407,11 @@ class TransformersFramework(BaseModel):
357
407
  )
358
408
  pipeline_tag: Optional[str] = Field(
359
409
  None,
360
- description="+label=Pipeline Tag\n+usage=Pipeline tag\n+docs=Pipeline tag for the framework",
410
+ description="+label=Pipeline Tag\n+usage=The `pipeline()` task this model can be used with e.g. `text-generation`. See [huggingface docs](https://huggingface.co/docs/transformers/main/en/main_classes/pipelines#transformers.pipeline.task) for all possible values\n+docs=Pipeline tag for the framework",
361
411
  )
362
412
  base_model: Optional[str] = Field(
363
413
  None,
364
- description="+label=Base Model\n+usage=Base model\n+docs=Base model Id. If this is a finetuned model, this points to the base model used for finetuning",
414
+ description="+label=Base Model\n+usage=Base model Id. If this is a finetuned model, this points to the base model used for finetuning\n+docs=Base model Id. If this is a finetuned model, this points to the base model used for finetuning",
365
415
  )
366
416
 
367
417
 
@@ -410,6 +460,14 @@ class XGBoostFramework(BaseModel):
410
460
  type: Literal["xgboost"] = Field(
411
461
  ..., description="+label=Type\n+usage=Type of the framework\n+value=xgboost"
412
462
  )
463
+ serialization_format: Optional[SerializationFormat] = Field(
464
+ None,
465
+ description="+label=Serialization format\n+usage=Serialization format used for the model",
466
+ )
467
+ model_filepath: Optional[str] = Field(
468
+ None,
469
+ description="+label=Model file path\n+usage=Relative path to the model file",
470
+ )
413
471
 
414
472
 
415
473
  class AgentOpenAPITool(BaseModel):
@@ -533,10 +591,11 @@ class ModelVersion(BaseArtifactVersion):
533
591
  ] = Field(
534
592
  None, description="+label=Framework\n+usage=Framework for the model version"
535
593
  )
594
+ environment: Optional[ModelVersionEnvironment] = None
536
595
  step: conint(ge=0) = Field(0, description="+label=Step")
537
596
  model_schema: Optional[Dict[str, Any]] = Field(
538
597
  None,
539
- description="+label=Model Schema\n+usage=Schema of the model\n+uiType=Hidden",
598
+ description="+label=Model Schema\n+usage=Schema of the model\n+uiType=JsonInput",
540
599
  )
541
600
 
542
601
 
@@ -0,0 +1,97 @@
1
+ import os
2
+ from typing import Optional
3
+
4
+ import rich_click as click
5
+
6
+ from truefoundry.deploy.cli.console import console
7
+ from truefoundry.deploy.cli.const import COMMAND_CLS
8
+ from truefoundry.deploy.cli.util import handle_exception_wrapper
9
+ from truefoundry.ml.autogen.client.models import ModelServer
10
+ from truefoundry.ml.cli.utils import (
11
+ AppName,
12
+ NonEmptyString,
13
+ )
14
+ from truefoundry.ml.mlfoundry_api import get_client
15
+
16
+
17
+ @click.command(
18
+ name="model",
19
+ cls=COMMAND_CLS,
20
+ help="Generating application code for the specified model version.",
21
+ )
22
+ @click.option(
23
+ "--name",
24
+ required=True,
25
+ type=AppName(),
26
+ help="Name for the model server deployment",
27
+ show_default=True,
28
+ )
29
+ @click.option(
30
+ "--model-version-fqn",
31
+ "--model_version_fqn",
32
+ type=NonEmptyString(),
33
+ required=True,
34
+ show_default=True,
35
+ help="Fully Qualified Name (FQN) of the model version to deploy, e.g., 'model:tenant_name/my-model/linear-regression:2'",
36
+ )
37
+ @click.option(
38
+ "-w",
39
+ "--workspace-fqn",
40
+ "--workspace_fqn",
41
+ type=NonEmptyString(),
42
+ required=True,
43
+ show_default=True,
44
+ help="Fully Qualified Name (FQN) of the workspace to deploy",
45
+ )
46
+ @click.option(
47
+ "--model-server",
48
+ "--model_server",
49
+ type=click.Choice(ModelServer, case_sensitive=False),
50
+ default=ModelServer.FASTAPI.value,
51
+ show_default=True,
52
+ help="Specify the model server (Case Insensitive).",
53
+ )
54
+ @click.option(
55
+ "--output-dir",
56
+ "--output_dir",
57
+ type=click.Path(exists=True, file_okay=False, writable=True),
58
+ help="Output directory for the model server code",
59
+ required=False,
60
+ show_default=True,
61
+ default=os.getcwd(),
62
+ )
63
+ @handle_exception_wrapper
64
+ def model_init_command(
65
+ name: str,
66
+ model_version_fqn: str,
67
+ workspace_fqn: str,
68
+ model_server: ModelServer,
69
+ output_dir: Optional[str],
70
+ ):
71
+ """
72
+ Generates application code for the specified model version.
73
+ """
74
+ ml_client = get_client()
75
+ console.print(f"Generating application code for {model_version_fqn!r}")
76
+ output_dir = ml_client._initialize_model_server(
77
+ name=name,
78
+ model_version_fqn=model_version_fqn,
79
+ workspace_fqn=workspace_fqn,
80
+ model_server=ModelServer[model_server.upper()],
81
+ output_dir=output_dir,
82
+ )
83
+ message = f"""
84
+ [bold green]Model Server code initialized successfully![/bold green]
85
+
86
+ [bold]Code Location:[/bold] {output_dir}
87
+
88
+ [bold]Next Steps:[/bold]
89
+ - Navigate to the model server directory:
90
+ [green]cd {output_dir}[/green]
91
+ - Refer to the README file in the directory for further instructions.
92
+ """
93
+ console.print(message)
94
+
95
+
96
+ def get_model_init_command():
97
+ return model_init_command
@@ -0,0 +1,34 @@
1
+ import rich_click as click
2
+
3
+ from truefoundry.ml import MlFoundryException
4
+ from truefoundry.ml.validation_utils import (
5
+ _APP_NAME_REGEX,
6
+ )
7
+
8
+
9
+ class AppName(click.ParamType):
10
+ """
11
+ Custom ParamType to validate application names.
12
+ """
13
+
14
+ name = "application-name"
15
+
16
+ def convert(self, value, param, ctx):
17
+ try:
18
+ if not value or not _APP_NAME_REGEX.match(value):
19
+ raise MlFoundryException(
20
+ f"{value!r} must be lowercase and cannot contain spaces. It can only contain alphanumeric characters and hyphens. "
21
+ f"Length must be between 1 and 30 characters."
22
+ )
23
+ except MlFoundryException as e:
24
+ self.fail(str(e), param, ctx)
25
+ return value
26
+
27
+
28
+ class NonEmptyString(click.ParamType):
29
+ name = "non-empty-string"
30
+
31
+ def convert(self, value, param, ctx):
32
+ if isinstance(value, str) and not value.strip():
33
+ self.fail("Value cannot be empty or contain only spaces.", param, ctx)
34
+ return value