truefoundry 0.5.2rc1__py3-none-any.whl → 0.5.3rc2__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/autodeploy/cli.py +1 -1
  2. truefoundry/cli/__main__.py +92 -2
  3. truefoundry/{deploy/cli → cli}/display_util.py +9 -4
  4. truefoundry/{deploy/cli → cli}/util.py +2 -11
  5. truefoundry/common/constants.py +2 -0
  6. truefoundry/common/utils.py +10 -0
  7. truefoundry/deploy/auto_gen/models.py +3 -3
  8. truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -1
  9. truefoundry/deploy/cli/commands/apply_command.py +3 -3
  10. truefoundry/deploy/cli/commands/build_command.py +3 -3
  11. truefoundry/deploy/cli/commands/build_logs_command.py +2 -2
  12. truefoundry/deploy/cli/commands/create_command.py +3 -3
  13. truefoundry/deploy/cli/commands/delete_command.py +4 -4
  14. truefoundry/deploy/cli/commands/deploy_command.py +2 -2
  15. truefoundry/deploy/cli/commands/deploy_init_command.py +1 -1
  16. truefoundry/deploy/cli/commands/get_command.py +5 -5
  17. truefoundry/deploy/cli/commands/list_command.py +4 -4
  18. truefoundry/deploy/cli/commands/login_command.py +3 -3
  19. truefoundry/deploy/cli/commands/logout_command.py +2 -2
  20. truefoundry/deploy/cli/commands/logs_command.py +2 -2
  21. truefoundry/deploy/cli/commands/patch_application_command.py +2 -2
  22. truefoundry/deploy/cli/commands/patch_command.py +2 -2
  23. truefoundry/deploy/cli/commands/redeploy_command.py +2 -2
  24. truefoundry/deploy/cli/commands/terminate_comand.py +3 -3
  25. truefoundry/deploy/cli/commands/trigger_command.py +2 -2
  26. truefoundry/deploy/lib/const.py +0 -3
  27. truefoundry/deploy/lib/dao/workspace.py +1 -1
  28. truefoundry/deploy/lib/model/entity.py +2 -2
  29. truefoundry/deploy/lib/util.py +0 -14
  30. truefoundry/ml/autogen/client/__init__.py +3 -0
  31. truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +147 -0
  32. truefoundry/ml/autogen/client/models/__init__.py +3 -0
  33. truefoundry/ml/autogen/client/models/artifact_version_manifest.py +7 -1
  34. truefoundry/ml/autogen/client/models/get_artifact_tags_response_dto.py +65 -0
  35. truefoundry/ml/autogen/client/models/model_version_manifest.py +7 -0
  36. truefoundry/ml/autogen/client_README.md +2 -0
  37. truefoundry/ml/autogen/entities/artifacts.py +12 -1
  38. truefoundry/ml/cli/cli.py +5 -1
  39. truefoundry/ml/cli/commands/download.py +16 -3
  40. truefoundry/ml/cli/commands/model_init.py +3 -3
  41. truefoundry/ml/log_types/artifacts/artifact.py +36 -4
  42. truefoundry/ml/log_types/artifacts/model.py +49 -9
  43. truefoundry/ml/model_framework.py +3 -2
  44. {truefoundry-0.5.2rc1.dist-info → truefoundry-0.5.3rc2.dist-info}/METADATA +1 -1
  45. {truefoundry-0.5.2rc1.dist-info → truefoundry-0.5.3rc2.dist-info}/RECORD +50 -52
  46. truefoundry/deploy/cli/cli.py +0 -96
  47. truefoundry/deploy/json_util.py +0 -7
  48. truefoundry/deploy/lib/exceptions.py +0 -10
  49. /truefoundry/{deploy/cli → cli}/config.py +0 -0
  50. /truefoundry/{deploy/cli → cli}/console.py +0 -0
  51. /truefoundry/{deploy/cli → cli}/const.py +0 -0
  52. {truefoundry-0.5.2rc1.dist-info → truefoundry-0.5.3rc2.dist-info}/WHEEL +0 -0
  53. {truefoundry-0.5.2rc1.dist-info → truefoundry-0.5.3rc2.dist-info}/entry_points.txt +0 -0
@@ -79,6 +79,9 @@ from truefoundry.ml.autogen.client.models.export_deployment_files_request_dto im
79
79
  from truefoundry.ml.autogen.client.models.finalize_artifact_version_request_dto import (
80
80
  FinalizeArtifactVersionRequestDto,
81
81
  )
82
+ from truefoundry.ml.autogen.client.models.get_artifact_tags_response_dto import (
83
+ GetArtifactTagsResponseDto,
84
+ )
82
85
  from truefoundry.ml.autogen.client.models.get_signed_url_for_dataset_write_request_dto import (
83
86
  GetSignedURLForDatasetWriteRequestDto,
84
87
  )
@@ -5338,6 +5341,150 @@ class MlfoundryArtifactsApi:
5338
5341
  _request_auth=_params.get("_request_auth"),
5339
5342
  )
5340
5343
 
5344
+ @validate_arguments
5345
+ def get_tags_for_artifact_get(
5346
+ self, artifact_id: StrictStr, **kwargs
5347
+ ) -> GetArtifactTagsResponseDto: # noqa: E501
5348
+ """Get Tags For Artifact # noqa: E501
5349
+
5350
+ This method makes a synchronous HTTP request by default. To make an
5351
+ asynchronous HTTP request, please pass async_req=True
5352
+
5353
+ >>> thread = api.get_tags_for_artifact_get(artifact_id, async_req=True)
5354
+ >>> result = thread.get()
5355
+
5356
+ :param artifact_id: (required)
5357
+ :type artifact_id: str
5358
+ :param async_req: Whether to execute the request asynchronously.
5359
+ :type async_req: bool, optional
5360
+ :param _request_timeout: timeout setting for this request.
5361
+ If one number provided, it will be total request
5362
+ timeout. It can also be a pair (tuple) of
5363
+ (connection, read) timeouts.
5364
+ :return: Returns the result object.
5365
+ If the method is called asynchronously,
5366
+ returns the request thread.
5367
+ :rtype: GetArtifactTagsResponseDto
5368
+ """
5369
+ kwargs["_return_http_data_only"] = True
5370
+ if "_preload_content" in kwargs:
5371
+ message = "Error! Please call the get_tags_for_artifact_get_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
5372
+ raise ValueError(message)
5373
+ return self.get_tags_for_artifact_get_with_http_info(artifact_id, **kwargs) # noqa: E501
5374
+
5375
+ @validate_arguments
5376
+ def get_tags_for_artifact_get_with_http_info(
5377
+ self, artifact_id: StrictStr, **kwargs
5378
+ ) -> ApiResponse: # noqa: E501
5379
+ """Get Tags For Artifact # noqa: E501
5380
+
5381
+ This method makes a synchronous HTTP request by default. To make an
5382
+ asynchronous HTTP request, please pass async_req=True
5383
+
5384
+ >>> thread = api.get_tags_for_artifact_get_with_http_info(artifact_id, async_req=True)
5385
+ >>> result = thread.get()
5386
+
5387
+ :param artifact_id: (required)
5388
+ :type artifact_id: str
5389
+ :param async_req: Whether to execute the request asynchronously.
5390
+ :type async_req: bool, optional
5391
+ :param _preload_content: if False, the ApiResponse.data will
5392
+ be set to none and raw_data will store the
5393
+ HTTP response body without reading/decoding.
5394
+ Default is True.
5395
+ :type _preload_content: bool, optional
5396
+ :param _return_http_data_only: response data instead of ApiResponse
5397
+ object with status code, headers, etc
5398
+ :type _return_http_data_only: bool, optional
5399
+ :param _request_timeout: timeout setting for this request. If one
5400
+ number provided, it will be total request
5401
+ timeout. It can also be a pair (tuple) of
5402
+ (connection, read) timeouts.
5403
+ :param _request_auth: set to override the auth_settings for an a single
5404
+ request; this effectively ignores the authentication
5405
+ in the spec for a single request.
5406
+ :type _request_auth: dict, optional
5407
+ :type _content_type: string, optional: force content-type for the request
5408
+ :return: Returns the result object.
5409
+ If the method is called asynchronously,
5410
+ returns the request thread.
5411
+ :rtype: tuple(GetArtifactTagsResponseDto, status_code(int), headers(HTTPHeaderDict))
5412
+ """
5413
+
5414
+ _params = locals()
5415
+
5416
+ _all_params = ["artifact_id"]
5417
+ _all_params.extend(
5418
+ [
5419
+ "async_req",
5420
+ "_return_http_data_only",
5421
+ "_preload_content",
5422
+ "_request_timeout",
5423
+ "_request_auth",
5424
+ "_content_type",
5425
+ "_headers",
5426
+ ]
5427
+ )
5428
+
5429
+ # validate the arguments
5430
+ for _key, _val in _params["kwargs"].items():
5431
+ if _key not in _all_params:
5432
+ raise ApiTypeError(
5433
+ "Got an unexpected keyword argument '%s'"
5434
+ " to method get_tags_for_artifact_get" % _key
5435
+ )
5436
+ _params[_key] = _val
5437
+ del _params["kwargs"]
5438
+
5439
+ _collection_formats = {}
5440
+
5441
+ # process the path parameters
5442
+ _path_params = {}
5443
+
5444
+ # process the query parameters
5445
+ _query_params = []
5446
+ if _params.get("artifact_id") is not None: # noqa: E501
5447
+ _query_params.append(("artifact_id", _params["artifact_id"]))
5448
+
5449
+ # process the header parameters
5450
+ _header_params = dict(_params.get("_headers", {}))
5451
+ # process the form parameters
5452
+ _form_params = []
5453
+ _files = {}
5454
+ # process the body parameter
5455
+ _body_params = None
5456
+ # set the HTTP header `Accept`
5457
+ _header_params["Accept"] = self.api_client.select_header_accept(
5458
+ ["application/json"]
5459
+ ) # noqa: E501
5460
+
5461
+ # authentication setting
5462
+ _auth_settings = ["HTTPBearer", "APIKeyCookie"] # noqa: E501
5463
+
5464
+ _response_types_map = {
5465
+ "200": "GetArtifactTagsResponseDto",
5466
+ "422": "HTTPValidationError",
5467
+ }
5468
+
5469
+ return self.api_client.call_api(
5470
+ "/api/2.0/mlflow/mlfoundry-artifacts/artifacts/get-tags",
5471
+ "GET",
5472
+ _path_params,
5473
+ _query_params,
5474
+ _header_params,
5475
+ body=_body_params,
5476
+ post_params=_form_params,
5477
+ files=_files,
5478
+ response_types_map=_response_types_map,
5479
+ auth_settings=_auth_settings,
5480
+ async_req=_params.get("async_req"),
5481
+ _return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501
5482
+ _preload_content=_params.get("_preload_content", True),
5483
+ _request_timeout=_params.get("_request_timeout"),
5484
+ collection_formats=_collection_formats,
5485
+ _request_auth=_params.get("_request_auth"),
5486
+ )
5487
+
5341
5488
  @validate_arguments
5342
5489
  def list_artifact_versions_post(
5343
5490
  self,
@@ -155,6 +155,9 @@ from truefoundry.ml.autogen.client.models.finalize_artifact_version_request_dto
155
155
  FinalizeArtifactVersionRequestDto,
156
156
  )
157
157
  from truefoundry.ml.autogen.client.models.framework import Framework
158
+ from truefoundry.ml.autogen.client.models.get_artifact_tags_response_dto import (
159
+ GetArtifactTagsResponseDto,
160
+ )
158
161
  from truefoundry.ml.autogen.client.models.get_experiment_response_dto import (
159
162
  GetExperimentResponseDto,
160
163
  )
@@ -24,6 +24,7 @@ from truefoundry.pydantic_v1 import (
24
24
  Field,
25
25
  StrictStr,
26
26
  conint,
27
+ conlist,
27
28
  constr,
28
29
  validator,
29
30
  )
@@ -42,12 +43,16 @@ class ArtifactVersionManifest(BaseModel):
42
43
  default=...,
43
44
  description="+label=Metadata +docs=Metadata for the artifact or model version +usage=Metadata for the artifact or model version +uiType=JsonInput",
44
45
  )
46
+ tags: Optional[conlist(constr(strict=True, max_length=128))] = Field(
47
+ default=None,
48
+ description="+label=Tags +usage=Tags for the artifact or model version +docs=Tags for the artifact or model version",
49
+ )
45
50
  type: Optional[StrictStr] = "artifact-version"
46
51
  source: Source = Field(...)
47
52
  step: Optional[conint(strict=True, ge=0)] = Field(
48
53
  default=0, description="+label=Step"
49
54
  )
50
- __properties = ["description", "metadata", "type", "source", "step"]
55
+ __properties = ["description", "metadata", "tags", "type", "source", "step"]
51
56
 
52
57
  @validator("type")
53
58
  def type_validate_enum(cls, value):
@@ -99,6 +104,7 @@ class ArtifactVersionManifest(BaseModel):
99
104
  {
100
105
  "description": obj.get("description"),
101
106
  "metadata": obj.get("metadata"),
107
+ "tags": obj.get("tags"),
102
108
  "type": obj.get("type")
103
109
  if obj.get("type") is not None
104
110
  else "artifact-version",
@@ -0,0 +1,65 @@
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
+
20
+ from truefoundry.pydantic_v1 import BaseModel, Field, StrictStr, conlist
21
+
22
+
23
+ class GetArtifactTagsResponseDto(BaseModel):
24
+ """
25
+ GetArtifactTagsResponseDto
26
+ """
27
+
28
+ tags: conlist(StrictStr) = Field(...)
29
+ __properties = ["tags"]
30
+
31
+ class Config:
32
+ """Pydantic configuration"""
33
+
34
+ allow_population_by_field_name = True
35
+ validate_assignment = True
36
+
37
+ def to_str(self) -> str:
38
+ """Returns the string representation of the model using alias"""
39
+ return pprint.pformat(self.dict(by_alias=True))
40
+
41
+ def to_json(self) -> str:
42
+ """Returns the JSON representation of the model using alias"""
43
+ return json.dumps(self.to_dict())
44
+
45
+ @classmethod
46
+ def from_json(cls, json_str: str) -> GetArtifactTagsResponseDto:
47
+ """Create an instance of GetArtifactTagsResponseDto from a JSON string"""
48
+ return cls.from_dict(json.loads(json_str))
49
+
50
+ def to_dict(self):
51
+ """Returns the dictionary representation of the model using alias"""
52
+ _dict = self.dict(by_alias=True, exclude={}, exclude_none=True)
53
+ return _dict
54
+
55
+ @classmethod
56
+ def from_dict(cls, obj: dict) -> GetArtifactTagsResponseDto:
57
+ """Create an instance of GetArtifactTagsResponseDto from a dict"""
58
+ if obj is None:
59
+ return None
60
+
61
+ if not isinstance(obj, dict):
62
+ return GetArtifactTagsResponseDto.parse_obj(obj)
63
+
64
+ _obj = GetArtifactTagsResponseDto.parse_obj({"tags": obj.get("tags")})
65
+ return _obj
@@ -28,6 +28,7 @@ from truefoundry.pydantic_v1 import (
28
28
  Field,
29
29
  StrictStr,
30
30
  conint,
31
+ conlist,
31
32
  constr,
32
33
  validator,
33
34
  )
@@ -46,6 +47,10 @@ class ModelVersionManifest(BaseModel):
46
47
  default=...,
47
48
  description="+label=Metadata +docs=Metadata for the artifact or model version +usage=Metadata for the artifact or model version +uiType=JsonInput",
48
49
  )
50
+ tags: Optional[conlist(constr(strict=True, max_length=128))] = Field(
51
+ default=None,
52
+ description="+label=Tags +usage=Tags for the artifact or model version +docs=Tags for the artifact or model version",
53
+ )
49
54
  type: Optional[StrictStr] = "model-version"
50
55
  source: Source1 = Field(...)
51
56
  framework: Optional[Framework] = None
@@ -56,6 +61,7 @@ class ModelVersionManifest(BaseModel):
56
61
  __properties = [
57
62
  "description",
58
63
  "metadata",
64
+ "tags",
59
65
  "type",
60
66
  "source",
61
67
  "framework",
@@ -119,6 +125,7 @@ class ModelVersionManifest(BaseModel):
119
125
  {
120
126
  "description": obj.get("description"),
121
127
  "metadata": obj.get("metadata"),
128
+ "tags": obj.get("tags"),
122
129
  "type": obj.get("type")
123
130
  if obj.get("type") is not None
124
131
  else "model-version",
@@ -121,6 +121,7 @@ Class | Method | HTTP request | Description
121
121
  *MlfoundryArtifactsApi* | [**get_signed_urls_for_dataset_write_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_signed_urls_for_dataset_write_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/datasets/get-signed-urls-for-write | Get Signed Urls For Dataset Write
122
122
  *MlfoundryArtifactsApi* | [**get_signed_urls_for_read_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_signed_urls_for_read_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/artifact-versions/get-signed-urls-for-read | Get Signed Urls For Read
123
123
  *MlfoundryArtifactsApi* | [**get_signed_urls_for_write_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_signed_urls_for_write_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/artifact-versions/get-signed-urls-for-write | Get Signed Urls For Write
124
+ *MlfoundryArtifactsApi* | [**get_tags_for_artifact_get**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_tags_for_artifact_get) | **GET** /api/2.0/mlflow/mlfoundry-artifacts/artifacts/get-tags | Get Tags For Artifact
124
125
  *MlfoundryArtifactsApi* | [**list_artifact_versions_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#list_artifact_versions_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/artifact-versions/list | List Artifact Versions
125
126
  *MlfoundryArtifactsApi* | [**list_artifacts_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#list_artifacts_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/artifacts/list | List Artifacts
126
127
  *MlfoundryArtifactsApi* | [**list_datasets_post**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#list_datasets_post) | **POST** /api/2.0/mlflow/mlfoundry-artifacts/datasets/list | List Datasets
@@ -219,6 +220,7 @@ Class | Method | HTTP request | Description
219
220
  - [FileInfoDto](truefoundry/ml/autogen/client/docs/FileInfoDto.md)
220
221
  - [FinalizeArtifactVersionRequestDto](truefoundry/ml/autogen/client/docs/FinalizeArtifactVersionRequestDto.md)
221
222
  - [Framework](truefoundry/ml/autogen/client/docs/Framework.md)
223
+ - [GetArtifactTagsResponseDto](truefoundry/ml/autogen/client/docs/GetArtifactTagsResponseDto.md)
222
224
  - [GetExperimentResponseDto](truefoundry/ml/autogen/client/docs/GetExperimentResponseDto.md)
223
225
  - [GetLatestRunLogResponseDto](truefoundry/ml/autogen/client/docs/GetLatestRunLogResponseDto.md)
224
226
  - [GetMetricHistoryResponse](truefoundry/ml/autogen/client/docs/GetMetricHistoryResponse.md)
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: artifacts.json
3
- # timestamp: 2024-12-09T09:04:12+00:00
3
+ # timestamp: 2024-12-16T06:57:32+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -58,6 +58,17 @@ class BaseArtifactVersion(BaseModel):
58
58
  ...,
59
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
+ tags: Optional[
62
+ List[
63
+ constr(
64
+ regex=r"^(?!^\d+$)(?!.*[._-]{2,})[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*$",
65
+ max_length=128,
66
+ )
67
+ ]
68
+ ] = Field(
69
+ None,
70
+ description="+label=Tags\n+usage=Tags for the artifact or model version\n+docs=Tags for the artifact or model version",
71
+ )
61
72
 
62
73
 
63
74
  class MimeType(str, Enum):
truefoundry/ml/cli/cli.py CHANGED
@@ -1,11 +1,15 @@
1
1
  import rich_click as click
2
2
 
3
+ from truefoundry.cli.const import GROUP_CLS
3
4
  from truefoundry.ml.cli.commands import download
4
5
 
5
6
  click.rich_click.USE_RICH_MARKUP = True
6
7
 
7
8
 
8
- @click.group()
9
+ @click.group(
10
+ name="ml",
11
+ cls=GROUP_CLS,
12
+ )
9
13
  def ml():
10
14
  """
11
15
  TrueFoundry ML CLI
@@ -2,14 +2,23 @@ from typing import Optional
2
2
 
3
3
  import click
4
4
 
5
+ from truefoundry.cli.const import COMMAND_CLS, GROUP_CLS
5
6
  from truefoundry.ml import get_client
6
7
 
7
8
 
8
- @click.group(help="Download files of artifact/model logged with Mlfoundry")
9
+ @click.group(
10
+ name="download",
11
+ cls=GROUP_CLS,
12
+ help="Download artifact/model versions logged with TrueFoundry",
13
+ )
9
14
  def download(): ...
10
15
 
11
16
 
12
- @download.command(short_help="Download files of logged model")
17
+ @download.command(
18
+ name="model",
19
+ cls=COMMAND_CLS,
20
+ help="Download a model version logged with TrueFoundry",
21
+ )
13
22
  @click.option(
14
23
  "--fqn",
15
24
  required=True,
@@ -48,7 +57,11 @@ def model(fqn: str, path: str, overwrite: bool, progress: Optional[bool] = None)
48
57
  print(f"Downloaded model files to {download_path}")
49
58
 
50
59
 
51
- @download.command(short_help="Download files of logged artifact")
60
+ @download.command(
61
+ name="artifact",
62
+ cls=COMMAND_CLS,
63
+ short_help="Download a artifact version logged with TrueFoundry",
64
+ )
52
65
  @click.option(
53
66
  "--fqn",
54
67
  required=True,
@@ -3,9 +3,9 @@ from typing import Optional
3
3
 
4
4
  import rich_click as click
5
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
6
+ from truefoundry.cli.console import console
7
+ from truefoundry.cli.const import COMMAND_CLS
8
+ from truefoundry.cli.util import handle_exception_wrapper
9
9
  from truefoundry.ml.autogen.client import ModelServer # type: ignore[attr-defined]
10
10
  from truefoundry.ml.cli.utils import (
11
11
  AppName,
@@ -5,11 +5,10 @@ import os
5
5
  import tempfile
6
6
  import typing
7
7
  import uuid
8
+ import warnings
8
9
  from pathlib import Path
9
10
  from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional, Union
10
11
 
11
- from pydantic import StrictStr
12
-
13
12
  from truefoundry.ml.artifact.truefoundry_artifact_repo import (
14
13
  ArtifactIdentifier,
15
14
  MlFoundryArtifactsRepository,
@@ -43,7 +42,7 @@ from truefoundry.ml.log_types.artifacts.utils import (
43
42
  )
44
43
  from truefoundry.ml.logger import logger
45
44
  from truefoundry.ml.session import _get_api_client
46
- from truefoundry.pydantic_v1 import BaseModel, Extra
45
+ from truefoundry.pydantic_v1 import BaseModel, Extra, StrictStr
47
46
 
48
47
  if TYPE_CHECKING:
49
48
  from truefoundry.ml.mlfoundry_run import MlFoundryRun
@@ -84,6 +83,7 @@ class ArtifactVersion:
84
83
  self._deleted = False
85
84
  self._description: str = ""
86
85
  self._metadata: Dict[str, Any] = {}
86
+ self._tags: List[str] = []
87
87
  self._set_mutable_attrs()
88
88
 
89
89
  @classmethod
@@ -131,9 +131,13 @@ class ArtifactVersion:
131
131
  manifest = self._artifact_version.manifest.actual_instance
132
132
  self._description = manifest.description or ""
133
133
  self._metadata = copy.deepcopy(manifest.metadata)
134
+ self._tags = copy.deepcopy(manifest.tags or [])
134
135
  else:
135
136
  self._description = self._artifact_version.description or ""
136
- self._metadata = copy.deepcopy(self._artifact_version.artifact_metadata)
137
+ self._metadata = copy.deepcopy(
138
+ self._artifact_version.artifact_metadata or {}
139
+ )
140
+ self._tags = []
137
141
 
138
142
  def _refetch_artifact_version(self, reset_mutable_attrs: bool = True):
139
143
  _artifact_version = (
@@ -205,6 +209,33 @@ class ArtifactVersion:
205
209
  _validate_artifact_metadata(value)
206
210
  self._metadata = copy.deepcopy(value)
207
211
 
212
+ @property
213
+ def tags(self) -> List[str]:
214
+ """
215
+ Get tags for the current model version
216
+ """
217
+ if not self._artifact_version.manifest:
218
+ warnings.warn(
219
+ message="This model version was created using an older serialization format. tags do not exist, returning empty list",
220
+ category=DeprecationWarning,
221
+ stacklevel=2,
222
+ )
223
+ return self._tags
224
+
225
+ @tags.setter
226
+ def tags(self, value: List[str]):
227
+ """
228
+ Set the tags for current model version
229
+ """
230
+ if not self._artifact_version.manifest:
231
+ warnings.warn(
232
+ message="This model version was created using an older serialization format. Tags will not be updated",
233
+ category=DeprecationWarning,
234
+ stacklevel=2,
235
+ )
236
+ return
237
+ self._tags = copy.deepcopy(value)
238
+
208
239
  @property
209
240
  def created_at(self) -> Optional[datetime.datetime]:
210
241
  """Get the time at which artifact was created"""
@@ -367,6 +398,7 @@ class ArtifactVersion:
367
398
  assert isinstance(manifest, ArtifactVersionManifest)
368
399
  manifest.description = self.description
369
400
  manifest.metadata = self.metadata
401
+ manifest.tags = self.tags
370
402
  else:
371
403
  manifest = None
372
404
  try:
@@ -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, Union
11
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
12
12
 
13
13
  from truefoundry.ml.artifact.truefoundry_artifact_repo import (
14
14
  ArtifactIdentifier,
@@ -52,7 +52,7 @@ from truefoundry.ml.model_framework import (
52
52
  auto_update_model_framework_details,
53
53
  )
54
54
  from truefoundry.ml.session import _get_api_client
55
- from truefoundry.pydantic_v1 import BaseModel, Extra
55
+ from truefoundry.pydantic_v1 import BaseModel, Extra, parse_obj_as
56
56
 
57
57
  if TYPE_CHECKING:
58
58
  import numpy as np
@@ -108,6 +108,7 @@ class ModelVersion:
108
108
  self._metadata: Dict[str, Any] = {}
109
109
  self._environment: Optional[ModelVersionEnvironment] = None
110
110
  self._framework: Optional[ModelFrameworkType] = None
111
+ self._tags: List[str] = []
111
112
  self._set_mutable_attrs()
112
113
 
113
114
  @classmethod
@@ -147,21 +148,26 @@ class ModelVersion:
147
148
 
148
149
  def _set_mutable_attrs(self):
149
150
  if self._model_version.manifest:
150
- self._description = self._model_version.manifest.description or ""
151
- self._metadata = copy.deepcopy(self._model_version.manifest.metadata)
152
- self._environment = copy.deepcopy(self._model_version.manifest.environment)
151
+ manifest = self._model_version.manifest
152
+ self._description = manifest.description or ""
153
+ self._metadata = copy.deepcopy(manifest.metadata)
154
+ self._environment = copy.deepcopy(manifest.environment)
153
155
  self._framework = (
154
- copy.deepcopy(self._model_version.manifest.framework.actual_instance)
155
- if self._model_version.manifest.framework
156
+ parse_obj_as(
157
+ ModelFrameworkType, manifest.framework.actual_instance.to_dict()
158
+ )
159
+ if manifest.framework
156
160
  else None
157
161
  )
162
+ self._tags = copy.deepcopy(self._model_version.manifest.tags) or []
158
163
  else:
159
164
  self._description = self._model_version.description or ""
160
- self._metadata = copy.deepcopy(self._model_version.artifact_metadata)
165
+ self._metadata = copy.deepcopy(self._model_version.artifact_metadata or {})
161
166
  self._environment = None
162
167
  self._framework = _ModelFramework.to_model_framework_type(
163
168
  self._model_version.model_framework
164
169
  )
170
+ self._tags = []
165
171
 
166
172
  def _refetch_model_version(self, reset_mutable_attrs: bool = True):
167
173
  _model_version = self._mlfoundry_artifacts_api.get_model_version_get(
@@ -231,13 +237,46 @@ class ModelVersion:
231
237
  _validate_artifact_metadata(value)
232
238
  self._metadata = copy.deepcopy(value)
233
239
 
240
+ @property
241
+ def tags(self) -> List[str]:
242
+ """
243
+ Get tags for the current artifact version
244
+ """
245
+ if not self._model_version.manifest:
246
+ warnings.warn(
247
+ message="This model version was created using an older serialization format. tags do not exist, returning empty list",
248
+ category=DeprecationWarning,
249
+ stacklevel=2,
250
+ )
251
+ return self._tags
252
+
253
+ @tags.setter
254
+ def tags(self, value: List[str]):
255
+ """
256
+ Set the tags for current artifact version
257
+ """
258
+ if not self._model_version.manifest:
259
+ warnings.warn(
260
+ message="This model version was created using an older serialization format. Tags will not be updated",
261
+ category=DeprecationWarning,
262
+ stacklevel=2,
263
+ )
264
+ return
265
+ self._tags = copy.deepcopy(value)
266
+
234
267
  @property
235
268
  def environment(self) -> Optional[ModelVersionEnvironment]:
236
269
  """Get the environment details for the model"""
270
+ if not self._model_version.manifest:
271
+ warnings.warn(
272
+ message="This model version was created using an older serialization format. environment does not exist, returning None",
273
+ category=DeprecationWarning,
274
+ stacklevel=2,
275
+ )
237
276
  return self._environment
238
277
 
239
278
  @environment.setter
240
- def environment(self, value: Optional[Dict[str, Any]]):
279
+ def environment(self, value: Optional[ModelVersionEnvironment]):
241
280
  """set the environment details for the model"""
242
281
  if not self._model_version.manifest:
243
282
  warnings.warn(
@@ -449,6 +488,7 @@ class ModelVersion:
449
488
  self._model_version.manifest.framework = (
450
489
  Framework.from_dict(self.framework.dict()) if self.framework else None
451
490
  )
491
+ self._model_version.manifest.tags = self.tags
452
492
  try:
453
493
  _model_version = self._mlfoundry_artifacts_api.update_model_version_post(
454
494
  update_model_version_request_dto=UpdateModelVersionRequestDto(
@@ -20,7 +20,8 @@ from truefoundry.common.utils import (
20
20
  get_python_version_major_minor,
21
21
  list_pip_packages_installed,
22
22
  )
23
- from truefoundry.ml.autogen.client import (
23
+ from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
24
+ ModelVersionEnvironment,
24
25
  SklearnSerializationFormat,
25
26
  XGBoostSerializationFormat,
26
27
  )
@@ -344,7 +345,7 @@ def _fetch_framework_specific_pip_packages(
344
345
 
345
346
 
346
347
  def auto_update_environment_details(
347
- environment: autogen_artifacts.ModelVersionEnvironment,
348
+ environment: ModelVersionEnvironment,
348
349
  framework: Optional[ModelFrameworkType],
349
350
  ):
350
351
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truefoundry
3
- Version: 0.5.2rc1
3
+ Version: 0.5.3rc2
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com