truefoundry 0.5.2__py3-none-any.whl → 0.5.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truefoundry might be problematic. Click here for more details.
- truefoundry/__init__.py +10 -1
- truefoundry/autodeploy/agents/base.py +1 -1
- truefoundry/autodeploy/agents/developer.py +1 -1
- truefoundry/autodeploy/agents/project_identifier.py +1 -1
- truefoundry/autodeploy/agents/tester.py +1 -1
- truefoundry/autodeploy/cli.py +2 -2
- truefoundry/autodeploy/tools/base.py +2 -1
- truefoundry/autodeploy/tools/commit.py +1 -1
- truefoundry/autodeploy/tools/docker_build.py +1 -1
- truefoundry/autodeploy/tools/docker_run.py +1 -1
- truefoundry/autodeploy/tools/file_type_counts.py +1 -1
- truefoundry/autodeploy/tools/list_files.py +1 -1
- truefoundry/autodeploy/tools/read_file.py +1 -2
- truefoundry/autodeploy/tools/send_request.py +1 -1
- truefoundry/autodeploy/tools/write_file.py +1 -1
- truefoundry/cli/util.py +12 -3
- truefoundry/common/auth_service_client.py +7 -4
- truefoundry/common/constants.py +3 -0
- truefoundry/common/credential_provider.py +7 -8
- truefoundry/common/exceptions.py +11 -7
- truefoundry/common/request_utils.py +96 -14
- truefoundry/common/servicefoundry_client.py +31 -29
- truefoundry/common/session.py +93 -0
- truefoundry/common/storage_provider_utils.py +331 -0
- truefoundry/common/utils.py +9 -9
- truefoundry/common/warnings.py +21 -0
- truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +8 -21
- truefoundry/deploy/cli/commands/deploy_command.py +4 -4
- truefoundry/deploy/lib/clients/servicefoundry_client.py +13 -14
- truefoundry/deploy/lib/dao/application.py +2 -2
- truefoundry/deploy/lib/dao/workspace.py +1 -1
- truefoundry/deploy/lib/session.py +1 -1
- truefoundry/deploy/v2/lib/deploy.py +2 -2
- truefoundry/deploy/v2/lib/deploy_workflow.py +1 -1
- truefoundry/deploy/v2/lib/patched_models.py +70 -4
- truefoundry/deploy/v2/lib/source.py +2 -1
- truefoundry/ml/artifact/truefoundry_artifact_repo.py +33 -297
- truefoundry/ml/autogen/client/__init__.py +3 -0
- truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +149 -0
- truefoundry/ml/autogen/client/models/__init__.py +3 -0
- truefoundry/ml/autogen/client/models/artifact_version_manifest.py +25 -1
- truefoundry/ml/autogen/client/models/get_artifact_version_aliases_response_dto.py +67 -0
- truefoundry/ml/autogen/client/models/model_version_manifest.py +18 -0
- truefoundry/ml/autogen/client_README.md +2 -0
- truefoundry/ml/autogen/entities/artifacts.py +7 -1
- truefoundry/ml/clients/servicefoundry_client.py +36 -15
- truefoundry/ml/exceptions.py +2 -1
- truefoundry/ml/log_types/artifacts/artifact.py +37 -4
- truefoundry/ml/log_types/artifacts/model.py +51 -10
- truefoundry/ml/log_types/artifacts/utils.py +2 -2
- truefoundry/ml/mlfoundry_api.py +6 -38
- truefoundry/ml/mlfoundry_run.py +6 -15
- truefoundry/ml/model_framework.py +5 -3
- truefoundry/ml/session.py +69 -97
- truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py +42 -9
- truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py +126 -7
- {truefoundry-0.5.2.dist-info → truefoundry-0.5.3.dist-info}/METADATA +2 -2
- {truefoundry-0.5.2.dist-info → truefoundry-0.5.3.dist-info}/RECORD +60 -59
- {truefoundry-0.5.2.dist-info → truefoundry-0.5.3.dist-info}/WHEEL +1 -1
- truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -61
- truefoundry/ml/clients/entities.py +0 -8
- truefoundry/ml/clients/utils.py +0 -122
- {truefoundry-0.5.2.dist-info → truefoundry-0.5.3.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_version_aliases_response_dto import (
|
|
83
|
+
GetArtifactVersionAliasesResponseDto,
|
|
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,152 @@ class MlfoundryArtifactsApi:
|
|
|
5338
5341
|
_request_auth=_params.get("_request_auth"),
|
|
5339
5342
|
)
|
|
5340
5343
|
|
|
5344
|
+
@validate_arguments
|
|
5345
|
+
def get_version_aliases_for_artifact_get(
|
|
5346
|
+
self, artifact_id: StrictStr, **kwargs
|
|
5347
|
+
) -> GetArtifactVersionAliasesResponseDto: # noqa: E501
|
|
5348
|
+
"""Get Version Aliases 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_version_aliases_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: GetArtifactVersionAliasesResponseDto
|
|
5368
|
+
"""
|
|
5369
|
+
kwargs["_return_http_data_only"] = True
|
|
5370
|
+
if "_preload_content" in kwargs:
|
|
5371
|
+
message = "Error! Please call the get_version_aliases_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_version_aliases_for_artifact_get_with_http_info(
|
|
5374
|
+
artifact_id, **kwargs
|
|
5375
|
+
) # noqa: E501
|
|
5376
|
+
|
|
5377
|
+
@validate_arguments
|
|
5378
|
+
def get_version_aliases_for_artifact_get_with_http_info(
|
|
5379
|
+
self, artifact_id: StrictStr, **kwargs
|
|
5380
|
+
) -> ApiResponse: # noqa: E501
|
|
5381
|
+
"""Get Version Aliases For Artifact # noqa: E501
|
|
5382
|
+
|
|
5383
|
+
This method makes a synchronous HTTP request by default. To make an
|
|
5384
|
+
asynchronous HTTP request, please pass async_req=True
|
|
5385
|
+
|
|
5386
|
+
>>> thread = api.get_version_aliases_for_artifact_get_with_http_info(artifact_id, async_req=True)
|
|
5387
|
+
>>> result = thread.get()
|
|
5388
|
+
|
|
5389
|
+
:param artifact_id: (required)
|
|
5390
|
+
:type artifact_id: str
|
|
5391
|
+
:param async_req: Whether to execute the request asynchronously.
|
|
5392
|
+
:type async_req: bool, optional
|
|
5393
|
+
:param _preload_content: if False, the ApiResponse.data will
|
|
5394
|
+
be set to none and raw_data will store the
|
|
5395
|
+
HTTP response body without reading/decoding.
|
|
5396
|
+
Default is True.
|
|
5397
|
+
:type _preload_content: bool, optional
|
|
5398
|
+
:param _return_http_data_only: response data instead of ApiResponse
|
|
5399
|
+
object with status code, headers, etc
|
|
5400
|
+
:type _return_http_data_only: bool, optional
|
|
5401
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
5402
|
+
number provided, it will be total request
|
|
5403
|
+
timeout. It can also be a pair (tuple) of
|
|
5404
|
+
(connection, read) timeouts.
|
|
5405
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
5406
|
+
request; this effectively ignores the authentication
|
|
5407
|
+
in the spec for a single request.
|
|
5408
|
+
:type _request_auth: dict, optional
|
|
5409
|
+
:type _content_type: string, optional: force content-type for the request
|
|
5410
|
+
:return: Returns the result object.
|
|
5411
|
+
If the method is called asynchronously,
|
|
5412
|
+
returns the request thread.
|
|
5413
|
+
:rtype: tuple(GetArtifactVersionAliasesResponseDto, status_code(int), headers(HTTPHeaderDict))
|
|
5414
|
+
"""
|
|
5415
|
+
|
|
5416
|
+
_params = locals()
|
|
5417
|
+
|
|
5418
|
+
_all_params = ["artifact_id"]
|
|
5419
|
+
_all_params.extend(
|
|
5420
|
+
[
|
|
5421
|
+
"async_req",
|
|
5422
|
+
"_return_http_data_only",
|
|
5423
|
+
"_preload_content",
|
|
5424
|
+
"_request_timeout",
|
|
5425
|
+
"_request_auth",
|
|
5426
|
+
"_content_type",
|
|
5427
|
+
"_headers",
|
|
5428
|
+
]
|
|
5429
|
+
)
|
|
5430
|
+
|
|
5431
|
+
# validate the arguments
|
|
5432
|
+
for _key, _val in _params["kwargs"].items():
|
|
5433
|
+
if _key not in _all_params:
|
|
5434
|
+
raise ApiTypeError(
|
|
5435
|
+
"Got an unexpected keyword argument '%s'"
|
|
5436
|
+
" to method get_version_aliases_for_artifact_get" % _key
|
|
5437
|
+
)
|
|
5438
|
+
_params[_key] = _val
|
|
5439
|
+
del _params["kwargs"]
|
|
5440
|
+
|
|
5441
|
+
_collection_formats = {}
|
|
5442
|
+
|
|
5443
|
+
# process the path parameters
|
|
5444
|
+
_path_params = {}
|
|
5445
|
+
|
|
5446
|
+
# process the query parameters
|
|
5447
|
+
_query_params = []
|
|
5448
|
+
if _params.get("artifact_id") is not None: # noqa: E501
|
|
5449
|
+
_query_params.append(("artifact_id", _params["artifact_id"]))
|
|
5450
|
+
|
|
5451
|
+
# process the header parameters
|
|
5452
|
+
_header_params = dict(_params.get("_headers", {}))
|
|
5453
|
+
# process the form parameters
|
|
5454
|
+
_form_params = []
|
|
5455
|
+
_files = {}
|
|
5456
|
+
# process the body parameter
|
|
5457
|
+
_body_params = None
|
|
5458
|
+
# set the HTTP header `Accept`
|
|
5459
|
+
_header_params["Accept"] = self.api_client.select_header_accept(
|
|
5460
|
+
["application/json"]
|
|
5461
|
+
) # noqa: E501
|
|
5462
|
+
|
|
5463
|
+
# authentication setting
|
|
5464
|
+
_auth_settings = ["HTTPBearer", "APIKeyCookie"] # noqa: E501
|
|
5465
|
+
|
|
5466
|
+
_response_types_map = {
|
|
5467
|
+
"200": "GetArtifactVersionAliasesResponseDto",
|
|
5468
|
+
"422": "HTTPValidationError",
|
|
5469
|
+
}
|
|
5470
|
+
|
|
5471
|
+
return self.api_client.call_api(
|
|
5472
|
+
"/api/2.0/mlflow/mlfoundry-artifacts/artifacts/get-version-aliases",
|
|
5473
|
+
"GET",
|
|
5474
|
+
_path_params,
|
|
5475
|
+
_query_params,
|
|
5476
|
+
_header_params,
|
|
5477
|
+
body=_body_params,
|
|
5478
|
+
post_params=_form_params,
|
|
5479
|
+
files=_files,
|
|
5480
|
+
response_types_map=_response_types_map,
|
|
5481
|
+
auth_settings=_auth_settings,
|
|
5482
|
+
async_req=_params.get("async_req"),
|
|
5483
|
+
_return_http_data_only=_params.get("_return_http_data_only"), # noqa: E501
|
|
5484
|
+
_preload_content=_params.get("_preload_content", True),
|
|
5485
|
+
_request_timeout=_params.get("_request_timeout"),
|
|
5486
|
+
collection_formats=_collection_formats,
|
|
5487
|
+
_request_auth=_params.get("_request_auth"),
|
|
5488
|
+
)
|
|
5489
|
+
|
|
5341
5490
|
@validate_arguments
|
|
5342
5491
|
def list_artifact_versions_post(
|
|
5343
5492
|
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_version_aliases_response_dto import (
|
|
159
|
+
GetArtifactVersionAliasesResponseDto,
|
|
160
|
+
)
|
|
158
161
|
from truefoundry.ml.autogen.client.models.get_experiment_response_dto import (
|
|
159
162
|
GetExperimentResponseDto,
|
|
160
163
|
)
|
|
@@ -42,12 +42,35 @@ class ArtifactVersionManifest(BaseModel):
|
|
|
42
42
|
default=...,
|
|
43
43
|
description="+label=Metadata +docs=Metadata for the artifact or model version +usage=Metadata for the artifact or model version +uiType=JsonInput",
|
|
44
44
|
)
|
|
45
|
+
version_alias: Optional[constr(strict=True, max_length=128)] = Field(
|
|
46
|
+
default=None,
|
|
47
|
+
description="+label=Version Alias +usage=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc) +docs=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc) +message=The version alias should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc)",
|
|
48
|
+
)
|
|
45
49
|
type: Optional[StrictStr] = "artifact-version"
|
|
46
50
|
source: Source = Field(...)
|
|
47
51
|
step: Optional[conint(strict=True, ge=0)] = Field(
|
|
48
52
|
default=0, description="+label=Step"
|
|
49
53
|
)
|
|
50
|
-
__properties = [
|
|
54
|
+
__properties = [
|
|
55
|
+
"description",
|
|
56
|
+
"metadata",
|
|
57
|
+
"version_alias",
|
|
58
|
+
"type",
|
|
59
|
+
"source",
|
|
60
|
+
"step",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
@validator("version_alias")
|
|
64
|
+
def version_alias_validate_regular_expression(cls, value):
|
|
65
|
+
"""Validates the regular expression"""
|
|
66
|
+
if value is None:
|
|
67
|
+
return value
|
|
68
|
+
|
|
69
|
+
if not re.match(r"^v[a-zA-Z0-9.-]*([a-zA-Z0-9]+)$", value):
|
|
70
|
+
raise ValueError(
|
|
71
|
+
r"must validate the regular expression /^v[a-zA-Z0-9.-]*([a-zA-Z0-9]+)$/"
|
|
72
|
+
)
|
|
73
|
+
return value
|
|
51
74
|
|
|
52
75
|
@validator("type")
|
|
53
76
|
def type_validate_enum(cls, value):
|
|
@@ -99,6 +122,7 @@ class ArtifactVersionManifest(BaseModel):
|
|
|
99
122
|
{
|
|
100
123
|
"description": obj.get("description"),
|
|
101
124
|
"metadata": obj.get("metadata"),
|
|
125
|
+
"version_alias": obj.get("version_alias"),
|
|
102
126
|
"type": obj.get("type")
|
|
103
127
|
if obj.get("type") is not None
|
|
104
128
|
else "artifact-version",
|
|
@@ -0,0 +1,67 @@
|
|
|
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 GetArtifactVersionAliasesResponseDto(BaseModel):
|
|
24
|
+
"""
|
|
25
|
+
GetArtifactVersionAliasesResponseDto
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
version_aliases: conlist(StrictStr) = Field(...)
|
|
29
|
+
__properties = ["version_aliases"]
|
|
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) -> GetArtifactVersionAliasesResponseDto:
|
|
47
|
+
"""Create an instance of GetArtifactVersionAliasesResponseDto 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) -> GetArtifactVersionAliasesResponseDto:
|
|
57
|
+
"""Create an instance of GetArtifactVersionAliasesResponseDto from a dict"""
|
|
58
|
+
if obj is None:
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
if not isinstance(obj, dict):
|
|
62
|
+
return GetArtifactVersionAliasesResponseDto.parse_obj(obj)
|
|
63
|
+
|
|
64
|
+
_obj = GetArtifactVersionAliasesResponseDto.parse_obj(
|
|
65
|
+
{"version_aliases": obj.get("version_aliases")}
|
|
66
|
+
)
|
|
67
|
+
return _obj
|
|
@@ -46,6 +46,10 @@ class ModelVersionManifest(BaseModel):
|
|
|
46
46
|
default=...,
|
|
47
47
|
description="+label=Metadata +docs=Metadata for the artifact or model version +usage=Metadata for the artifact or model version +uiType=JsonInput",
|
|
48
48
|
)
|
|
49
|
+
version_alias: Optional[constr(strict=True, max_length=128)] = Field(
|
|
50
|
+
default=None,
|
|
51
|
+
description="+label=Version Alias +usage=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc) +docs=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc) +message=The version alias should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc)",
|
|
52
|
+
)
|
|
49
53
|
type: Optional[StrictStr] = "model-version"
|
|
50
54
|
source: Source1 = Field(...)
|
|
51
55
|
framework: Optional[Framework] = None
|
|
@@ -56,6 +60,7 @@ class ModelVersionManifest(BaseModel):
|
|
|
56
60
|
__properties = [
|
|
57
61
|
"description",
|
|
58
62
|
"metadata",
|
|
63
|
+
"version_alias",
|
|
59
64
|
"type",
|
|
60
65
|
"source",
|
|
61
66
|
"framework",
|
|
@@ -63,6 +68,18 @@ class ModelVersionManifest(BaseModel):
|
|
|
63
68
|
"step",
|
|
64
69
|
]
|
|
65
70
|
|
|
71
|
+
@validator("version_alias")
|
|
72
|
+
def version_alias_validate_regular_expression(cls, value):
|
|
73
|
+
"""Validates the regular expression"""
|
|
74
|
+
if value is None:
|
|
75
|
+
return value
|
|
76
|
+
|
|
77
|
+
if not re.match(r"^v[a-zA-Z0-9.-]*([a-zA-Z0-9]+)$", value):
|
|
78
|
+
raise ValueError(
|
|
79
|
+
r"must validate the regular expression /^v[a-zA-Z0-9.-]*([a-zA-Z0-9]+)$/"
|
|
80
|
+
)
|
|
81
|
+
return value
|
|
82
|
+
|
|
66
83
|
@validator("type")
|
|
67
84
|
def type_validate_enum(cls, value):
|
|
68
85
|
"""Validates the enum"""
|
|
@@ -119,6 +136,7 @@ class ModelVersionManifest(BaseModel):
|
|
|
119
136
|
{
|
|
120
137
|
"description": obj.get("description"),
|
|
121
138
|
"metadata": obj.get("metadata"),
|
|
139
|
+
"version_alias": obj.get("version_alias"),
|
|
122
140
|
"type": obj.get("type")
|
|
123
141
|
if obj.get("type") is not None
|
|
124
142
|
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_version_aliases_for_artifact_get**](truefoundry/ml/autogen/client/docs/MlfoundryArtifactsApi.md#get_version_aliases_for_artifact_get) | **GET** /api/2.0/mlflow/mlfoundry-artifacts/artifacts/get-version-aliases | Get Version Aliases 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
|
+
- [GetArtifactVersionAliasesResponseDto](truefoundry/ml/autogen/client/docs/GetArtifactVersionAliasesResponseDto.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:
|
|
3
|
+
# timestamp: 2025-01-03T09:11:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -58,6 +58,12 @@ 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
|
+
version_alias: Optional[
|
|
62
|
+
constr(regex=r"^v[a-zA-Z0-9.-]*([a-zA-Z0-9]+)$", max_length=128)
|
|
63
|
+
] = Field(
|
|
64
|
+
None,
|
|
65
|
+
description="+label=Version Alias\n+usage=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc)\n+docs=The version alias for artifact or model version which should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc)\n+message=The version alias should start with 'v' followed by alphanumeric and it can include '.' and '-' in between (e.g. v1.0.0, v-prod, v-dev, etc)",
|
|
66
|
+
)
|
|
61
67
|
|
|
62
68
|
|
|
63
69
|
class MimeType(str, Enum):
|
|
@@ -1,36 +1,57 @@
|
|
|
1
|
-
|
|
1
|
+
import functools
|
|
2
2
|
|
|
3
3
|
from truefoundry.common.constants import (
|
|
4
4
|
SERVICEFOUNDRY_CLIENT_MAX_RETRIES,
|
|
5
5
|
VERSION_PREFIX,
|
|
6
6
|
)
|
|
7
|
+
from truefoundry.common.exceptions import HttpRequestException
|
|
8
|
+
from truefoundry.common.request_utils import (
|
|
9
|
+
http_request,
|
|
10
|
+
request_handling,
|
|
11
|
+
requests_retry_session,
|
|
12
|
+
)
|
|
7
13
|
from truefoundry.common.servicefoundry_client import (
|
|
8
14
|
ServiceFoundryServiceClient as BaseServiceFoundryServiceClient,
|
|
9
15
|
)
|
|
10
|
-
from truefoundry.ml.clients.entities import (
|
|
11
|
-
HostCreds,
|
|
12
|
-
)
|
|
13
|
-
from truefoundry.ml.clients.utils import http_request_safe
|
|
14
16
|
from truefoundry.ml.exceptions import MlFoundryException
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class ServiceFoundryServiceClient(BaseServiceFoundryServiceClient):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
def __init__(self, tfy_host: str, token: str):
|
|
21
|
+
super().__init__(tfy_host=tfy_host)
|
|
22
|
+
self._token = token
|
|
23
|
+
|
|
24
|
+
@functools.cached_property
|
|
25
|
+
def _min_cli_version_required(self) -> str:
|
|
26
|
+
# TODO (chiragjn): read the mlfoundry min cli version from the config?
|
|
27
|
+
return self.python_sdk_config.truefoundry_cli_min_version
|
|
22
28
|
|
|
23
29
|
def get_integration_from_id(self, integration_id: str):
|
|
24
30
|
integration_id = integration_id or ""
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
endpoint=f"{VERSION_PREFIX}/provider-accounts/provider-integrations",
|
|
28
|
-
params={"id": integration_id, "type": "blob-storage"},
|
|
31
|
+
session = requests_retry_session(retries=SERVICEFOUNDRY_CLIENT_MAX_RETRIES)
|
|
32
|
+
response = http_request(
|
|
29
33
|
method="get",
|
|
34
|
+
url=f"{self._api_server_url}/{VERSION_PREFIX}/provider-accounts/provider-integrations",
|
|
35
|
+
token=self._token,
|
|
30
36
|
timeout=3,
|
|
31
|
-
|
|
37
|
+
params={"id": integration_id, "type": "blob-storage"},
|
|
38
|
+
session=session,
|
|
32
39
|
)
|
|
33
|
-
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
data = request_handling(response)
|
|
43
|
+
assert isinstance(data, dict)
|
|
44
|
+
except HttpRequestException as he:
|
|
45
|
+
raise MlFoundryException(
|
|
46
|
+
f"Failed to get storage integration from id: {integration_id}. Error: {he.message}",
|
|
47
|
+
status_code=he.status_code,
|
|
48
|
+
) from None
|
|
49
|
+
except Exception as e:
|
|
50
|
+
raise MlFoundryException(
|
|
51
|
+
f"Failed to get storage integration from id: {integration_id}. Error: {str(e)}"
|
|
52
|
+
) from None
|
|
53
|
+
|
|
54
|
+
# TODO (chiragjn): Parse this using Pydantic
|
|
34
55
|
if (
|
|
35
56
|
data.get("providerIntegrations")
|
|
36
57
|
and len(data["providerIntegrations"]) > 0
|
truefoundry/ml/exceptions.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
# TODO (chiragjn): We need to establish uniform exception handling across codebase
|
|
4
5
|
class MlFoundryException(Exception):
|
|
5
|
-
def __init__(self, message, status_code: Optional[int] = None):
|
|
6
|
+
def __init__(self, message: str, status_code: Optional[int] = None):
|
|
6
7
|
self.message = str(message)
|
|
7
8
|
self.status_code = status_code
|
|
8
9
|
super().__init__(message)
|
|
@@ -5,11 +5,11 @@ 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
|
|
12
|
-
|
|
12
|
+
from truefoundry.common.warnings import TrueFoundryDeprecationWarning
|
|
13
13
|
from truefoundry.ml.artifact.truefoundry_artifact_repo import (
|
|
14
14
|
ArtifactIdentifier,
|
|
15
15
|
MlFoundryArtifactsRepository,
|
|
@@ -43,7 +43,7 @@ from truefoundry.ml.log_types.artifacts.utils import (
|
|
|
43
43
|
)
|
|
44
44
|
from truefoundry.ml.logger import logger
|
|
45
45
|
from truefoundry.ml.session import _get_api_client
|
|
46
|
-
from truefoundry.pydantic_v1 import BaseModel, Extra
|
|
46
|
+
from truefoundry.pydantic_v1 import BaseModel, Extra, StrictStr
|
|
47
47
|
|
|
48
48
|
if TYPE_CHECKING:
|
|
49
49
|
from truefoundry.ml.mlfoundry_run import MlFoundryRun
|
|
@@ -84,6 +84,7 @@ class ArtifactVersion:
|
|
|
84
84
|
self._deleted = False
|
|
85
85
|
self._description: str = ""
|
|
86
86
|
self._metadata: Dict[str, Any] = {}
|
|
87
|
+
self._version_alias: Optional[str] = None
|
|
87
88
|
self._set_mutable_attrs()
|
|
88
89
|
|
|
89
90
|
@classmethod
|
|
@@ -131,9 +132,13 @@ class ArtifactVersion:
|
|
|
131
132
|
manifest = self._artifact_version.manifest.actual_instance
|
|
132
133
|
self._description = manifest.description or ""
|
|
133
134
|
self._metadata = copy.deepcopy(manifest.metadata)
|
|
135
|
+
self._version_alias = manifest.version_alias or None
|
|
134
136
|
else:
|
|
135
137
|
self._description = self._artifact_version.description or ""
|
|
136
|
-
self._metadata = copy.deepcopy(
|
|
138
|
+
self._metadata = copy.deepcopy(
|
|
139
|
+
self._artifact_version.artifact_metadata or {}
|
|
140
|
+
)
|
|
141
|
+
self._version_alias = None
|
|
137
142
|
|
|
138
143
|
def _refetch_artifact_version(self, reset_mutable_attrs: bool = True):
|
|
139
144
|
_artifact_version = (
|
|
@@ -205,6 +210,33 @@ class ArtifactVersion:
|
|
|
205
210
|
_validate_artifact_metadata(value)
|
|
206
211
|
self._metadata = copy.deepcopy(value)
|
|
207
212
|
|
|
213
|
+
@property
|
|
214
|
+
def version_alias(self) -> Optional[str]:
|
|
215
|
+
"""
|
|
216
|
+
Get version alias for the current artifact version
|
|
217
|
+
"""
|
|
218
|
+
if not self._artifact_version.manifest:
|
|
219
|
+
warnings.warn(
|
|
220
|
+
message="This artifact version was created using an older serialization format. version alias does not exist",
|
|
221
|
+
category=TrueFoundryDeprecationWarning,
|
|
222
|
+
stacklevel=2,
|
|
223
|
+
)
|
|
224
|
+
return self._version_alias
|
|
225
|
+
|
|
226
|
+
@version_alias.setter
|
|
227
|
+
def version_alias(self, value: Optional[str]):
|
|
228
|
+
"""
|
|
229
|
+
Set the version alias for current artifact version
|
|
230
|
+
"""
|
|
231
|
+
if not self._artifact_version.manifest:
|
|
232
|
+
warnings.warn(
|
|
233
|
+
message="This artifact version was created using an older serialization format. version alias will not be updated",
|
|
234
|
+
category=TrueFoundryDeprecationWarning,
|
|
235
|
+
stacklevel=2,
|
|
236
|
+
)
|
|
237
|
+
return
|
|
238
|
+
self._version_alias = value
|
|
239
|
+
|
|
208
240
|
@property
|
|
209
241
|
def created_at(self) -> Optional[datetime.datetime]:
|
|
210
242
|
"""Get the time at which artifact was created"""
|
|
@@ -367,6 +399,7 @@ class ArtifactVersion:
|
|
|
367
399
|
assert isinstance(manifest, ArtifactVersionManifest)
|
|
368
400
|
manifest.description = self.description
|
|
369
401
|
manifest.metadata = self.metadata
|
|
402
|
+
manifest.version_alias = self.version_alias
|
|
370
403
|
else:
|
|
371
404
|
manifest = None
|
|
372
405
|
try:
|
|
@@ -10,6 +10,7 @@ import warnings
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
12
12
|
|
|
13
|
+
from truefoundry.common.warnings import TrueFoundryDeprecationWarning
|
|
13
14
|
from truefoundry.ml.artifact.truefoundry_artifact_repo import (
|
|
14
15
|
ArtifactIdentifier,
|
|
15
16
|
MlFoundryArtifactsRepository,
|
|
@@ -52,7 +53,7 @@ from truefoundry.ml.model_framework import (
|
|
|
52
53
|
auto_update_model_framework_details,
|
|
53
54
|
)
|
|
54
55
|
from truefoundry.ml.session import _get_api_client
|
|
55
|
-
from truefoundry.pydantic_v1 import BaseModel, Extra
|
|
56
|
+
from truefoundry.pydantic_v1 import BaseModel, Extra, parse_obj_as
|
|
56
57
|
|
|
57
58
|
if TYPE_CHECKING:
|
|
58
59
|
import numpy as np
|
|
@@ -108,6 +109,7 @@ class ModelVersion:
|
|
|
108
109
|
self._metadata: Dict[str, Any] = {}
|
|
109
110
|
self._environment: Optional[ModelVersionEnvironment] = None
|
|
110
111
|
self._framework: Optional[ModelFrameworkType] = None
|
|
112
|
+
self._version_alias: Optional[str] = None
|
|
111
113
|
self._set_mutable_attrs()
|
|
112
114
|
|
|
113
115
|
@classmethod
|
|
@@ -147,21 +149,26 @@ class ModelVersion:
|
|
|
147
149
|
|
|
148
150
|
def _set_mutable_attrs(self):
|
|
149
151
|
if self._model_version.manifest:
|
|
150
|
-
|
|
151
|
-
self.
|
|
152
|
-
self.
|
|
152
|
+
manifest = self._model_version.manifest
|
|
153
|
+
self._description = manifest.description or ""
|
|
154
|
+
self._metadata = copy.deepcopy(manifest.metadata)
|
|
155
|
+
self._environment = copy.deepcopy(manifest.environment)
|
|
153
156
|
self._framework = (
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
parse_obj_as(
|
|
158
|
+
ModelFrameworkType, manifest.framework.actual_instance.to_dict()
|
|
159
|
+
)
|
|
160
|
+
if manifest.framework
|
|
156
161
|
else None
|
|
157
162
|
)
|
|
163
|
+
self._version_alias = self._model_version.manifest.version_alias or None
|
|
158
164
|
else:
|
|
159
165
|
self._description = self._model_version.description or ""
|
|
160
|
-
self._metadata = copy.deepcopy(self._model_version.artifact_metadata)
|
|
166
|
+
self._metadata = copy.deepcopy(self._model_version.artifact_metadata or {})
|
|
161
167
|
self._environment = None
|
|
162
168
|
self._framework = _ModelFramework.to_model_framework_type(
|
|
163
169
|
self._model_version.model_framework
|
|
164
170
|
)
|
|
171
|
+
self._version_alias = None
|
|
165
172
|
|
|
166
173
|
def _refetch_model_version(self, reset_mutable_attrs: bool = True):
|
|
167
174
|
_model_version = self._mlfoundry_artifacts_api.get_model_version_get(
|
|
@@ -231,18 +238,51 @@ class ModelVersion:
|
|
|
231
238
|
_validate_artifact_metadata(value)
|
|
232
239
|
self._metadata = copy.deepcopy(value)
|
|
233
240
|
|
|
241
|
+
@property
|
|
242
|
+
def version_alias(self) -> Optional[str]:
|
|
243
|
+
"""
|
|
244
|
+
Get version alias for the current model version
|
|
245
|
+
"""
|
|
246
|
+
if not self._model_version.manifest:
|
|
247
|
+
warnings.warn(
|
|
248
|
+
message="This model version was created using an older serialization format. version alias does not exist",
|
|
249
|
+
category=TrueFoundryDeprecationWarning,
|
|
250
|
+
stacklevel=2,
|
|
251
|
+
)
|
|
252
|
+
return self._version_alias
|
|
253
|
+
|
|
254
|
+
@version_alias.setter
|
|
255
|
+
def version_alias(self, value: Optional[str]):
|
|
256
|
+
"""
|
|
257
|
+
Set the version alias for current artifact version
|
|
258
|
+
"""
|
|
259
|
+
if not self._model_version.manifest:
|
|
260
|
+
warnings.warn(
|
|
261
|
+
message="This model version was created using an older serialization format. version alias will not be updated",
|
|
262
|
+
category=TrueFoundryDeprecationWarning,
|
|
263
|
+
stacklevel=2,
|
|
264
|
+
)
|
|
265
|
+
return
|
|
266
|
+
self._version_alias = value
|
|
267
|
+
|
|
234
268
|
@property
|
|
235
269
|
def environment(self) -> Optional[ModelVersionEnvironment]:
|
|
236
270
|
"""Get the environment details for the model"""
|
|
271
|
+
if not self._model_version.manifest:
|
|
272
|
+
warnings.warn(
|
|
273
|
+
message="This model version was created using an older serialization format. environment does not exist, returning None",
|
|
274
|
+
category=TrueFoundryDeprecationWarning,
|
|
275
|
+
stacklevel=2,
|
|
276
|
+
)
|
|
237
277
|
return self._environment
|
|
238
278
|
|
|
239
279
|
@environment.setter
|
|
240
|
-
def environment(self, value: Optional[
|
|
280
|
+
def environment(self, value: Optional[ModelVersionEnvironment]):
|
|
241
281
|
"""set the environment details for the model"""
|
|
242
282
|
if not self._model_version.manifest:
|
|
243
283
|
warnings.warn(
|
|
244
284
|
message="This model version was created using an older serialization format. Environment will not be updated",
|
|
245
|
-
category=
|
|
285
|
+
category=TrueFoundryDeprecationWarning,
|
|
246
286
|
stacklevel=2,
|
|
247
287
|
)
|
|
248
288
|
return
|
|
@@ -261,7 +301,7 @@ class ModelVersion:
|
|
|
261
301
|
if not self._model_version.manifest:
|
|
262
302
|
warnings.warn(
|
|
263
303
|
message="This model version was created using an older serialization format. Framework will not be updated",
|
|
264
|
-
category=
|
|
304
|
+
category=TrueFoundryDeprecationWarning,
|
|
265
305
|
stacklevel=2,
|
|
266
306
|
)
|
|
267
307
|
return
|
|
@@ -449,6 +489,7 @@ class ModelVersion:
|
|
|
449
489
|
self._model_version.manifest.framework = (
|
|
450
490
|
Framework.from_dict(self.framework.dict()) if self.framework else None
|
|
451
491
|
)
|
|
492
|
+
self._model_version.manifest.version_alias = self.version_alias
|
|
452
493
|
try:
|
|
453
494
|
_model_version = self._mlfoundry_artifacts_api.update_model_version_post(
|
|
454
495
|
update_model_version_request_dto=UpdateModelVersionRequestDto(
|