truefoundry 0.5.0rc3__py3-none-any.whl → 0.5.0rc4__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/deploy/v2/lib/deploy_workflow.py +8 -2
- truefoundry/ml/__init__.py +6 -3
- truefoundry/ml/autogen/client/__init__.py +9 -4
- truefoundry/ml/autogen/client/models/__init__.py +9 -4
- truefoundry/ml/autogen/client/models/artifact_version_dto.py +3 -5
- truefoundry/ml/autogen/client/models/artifact_version_manifest.py +111 -0
- truefoundry/ml/autogen/client/models/{external_model_source.py → external_artifact_source.py} +8 -8
- truefoundry/ml/autogen/client/models/finalize_artifact_version_request_dto.py +3 -5
- truefoundry/ml/autogen/client/models/manifest.py +154 -0
- truefoundry/ml/autogen/client/models/model_version_manifest.py +3 -3
- truefoundry/ml/autogen/client/models/source.py +23 -23
- truefoundry/ml/autogen/client/models/source1.py +154 -0
- truefoundry/ml/autogen/client/models/transformers_framework.py +6 -1
- truefoundry/ml/autogen/client/models/{truefoundry_model_source.py → true_foundry_artifact_source.py} +9 -9
- truefoundry/ml/autogen/client/models/update_artifact_version_request_dto.py +11 -1
- truefoundry/ml/autogen/client_README.md +5 -2
- truefoundry/ml/autogen/entities/artifacts.py +22 -8
- truefoundry/ml/log_types/artifacts/artifact.py +131 -63
- truefoundry/ml/log_types/artifacts/general_artifact.py +7 -26
- truefoundry/ml/log_types/artifacts/model.py +74 -81
- truefoundry/ml/mlfoundry_api.py +4 -4
- truefoundry/ml/mlfoundry_run.py +8 -5
- truefoundry/ml/model_framework.py +2 -2
- {truefoundry-0.5.0rc3.dist-info → truefoundry-0.5.0rc4.dist-info}/METADATA +2 -2
- {truefoundry-0.5.0rc3.dist-info → truefoundry-0.5.0rc4.dist-info}/RECORD +27 -24
- {truefoundry-0.5.0rc3.dist-info → truefoundry-0.5.0rc4.dist-info}/WHEEL +0 -0
- {truefoundry-0.5.0rc3.dist-info → truefoundry-0.5.0rc4.dist-info}/entry_points.txt +0 -0
|
@@ -3,9 +3,12 @@ import datetime
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import tempfile
|
|
6
|
+
import typing
|
|
6
7
|
import uuid
|
|
7
8
|
from pathlib import Path
|
|
8
|
-
from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional,
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional, Union
|
|
10
|
+
|
|
11
|
+
from pydantic import StrictStr
|
|
9
12
|
|
|
10
13
|
from truefoundry.ml.artifact.truefoundry_artifact_repo import (
|
|
11
14
|
ArtifactIdentifier,
|
|
@@ -15,11 +18,15 @@ from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
|
15
18
|
ArtifactDto,
|
|
16
19
|
ArtifactType,
|
|
17
20
|
ArtifactVersionDto,
|
|
21
|
+
ArtifactVersionManifest,
|
|
18
22
|
CreateArtifactVersionRequestDto,
|
|
19
23
|
DeleteArtifactVersionsRequestDto,
|
|
24
|
+
ExternalArtifactSource,
|
|
20
25
|
FinalizeArtifactVersionRequestDto,
|
|
26
|
+
Manifest,
|
|
21
27
|
MlfoundryArtifactsApi,
|
|
22
28
|
NotifyArtifactVersionFailureDto,
|
|
29
|
+
TrueFoundryArtifactSource,
|
|
23
30
|
UpdateArtifactVersionRequestDto,
|
|
24
31
|
)
|
|
25
32
|
from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
@@ -47,6 +54,10 @@ class ArtifactPath(NamedTuple):
|
|
|
47
54
|
dest: Optional[str] = None
|
|
48
55
|
|
|
49
56
|
|
|
57
|
+
class BlobStorageDirectory(BaseModel):
|
|
58
|
+
uri: StrictStr
|
|
59
|
+
|
|
60
|
+
|
|
50
61
|
class ArtifactVersionInternalMetadata(BaseModel):
|
|
51
62
|
class Config:
|
|
52
63
|
extra = Extra.allow
|
|
@@ -56,7 +67,6 @@ class ArtifactVersionInternalMetadata(BaseModel):
|
|
|
56
67
|
|
|
57
68
|
class ArtifactVersionDownloadInfo(BaseModel):
|
|
58
69
|
download_dir: str
|
|
59
|
-
content_dir: str
|
|
60
70
|
|
|
61
71
|
|
|
62
72
|
class ArtifactVersion:
|
|
@@ -116,16 +126,24 @@ class ArtifactVersion:
|
|
|
116
126
|
"Artifact Version was deleted, cannot access a deleted version"
|
|
117
127
|
)
|
|
118
128
|
|
|
119
|
-
def _set_mutable_attrs(self
|
|
120
|
-
if
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
129
|
+
def _set_mutable_attrs(self):
|
|
130
|
+
if self._artifact_version.manifest:
|
|
131
|
+
manifest = self._artifact_version.manifest.actual_instance
|
|
132
|
+
self._description = manifest.description or ""
|
|
133
|
+
self._metadata = copy.deepcopy(manifest.metadata)
|
|
134
|
+
else:
|
|
135
|
+
self._description = self._artifact_version.description or ""
|
|
136
|
+
self._metadata = copy.deepcopy(self._artifact_version.artifact_metadata)
|
|
137
|
+
|
|
138
|
+
def _refetch_artifact_version(self, reset_mutable_attrs: bool = True):
|
|
139
|
+
_artifact_version = (
|
|
140
|
+
self._mlfoundry_artifacts_api.get_artifact_version_by_id_get(
|
|
141
|
+
id=self._artifact_version.id
|
|
125
142
|
)
|
|
126
|
-
|
|
127
|
-
self.
|
|
128
|
-
|
|
143
|
+
)
|
|
144
|
+
self._artifact_version = _artifact_version.artifact_version
|
|
145
|
+
if reset_mutable_attrs:
|
|
146
|
+
self._set_mutable_attrs()
|
|
129
147
|
|
|
130
148
|
def __repr__(self):
|
|
131
149
|
return f"{self.__class__.__name__}(fqn={self.fqn!r})"
|
|
@@ -159,12 +177,14 @@ class ArtifactVersion:
|
|
|
159
177
|
return self._artifact_version.fqn
|
|
160
178
|
|
|
161
179
|
@property
|
|
162
|
-
def step(self) -> int:
|
|
180
|
+
def step(self) -> Optional[int]:
|
|
163
181
|
"""Get the step in which artifact was created"""
|
|
182
|
+
if self._artifact_version.manifest:
|
|
183
|
+
return self._artifact_version.manifest.actual_instance.step
|
|
164
184
|
return self._artifact_version.step
|
|
165
185
|
|
|
166
186
|
@property
|
|
167
|
-
def description(self) ->
|
|
187
|
+
def description(self) -> str:
|
|
168
188
|
"""Get description of the artifact"""
|
|
169
189
|
return self._description
|
|
170
190
|
|
|
@@ -183,15 +203,15 @@ class ArtifactVersion:
|
|
|
183
203
|
def metadata(self, value: Dict[str, Any]):
|
|
184
204
|
"""set the metadata for current artifact"""
|
|
185
205
|
_validate_artifact_metadata(value)
|
|
186
|
-
self._metadata = value
|
|
206
|
+
self._metadata = copy.deepcopy(value)
|
|
187
207
|
|
|
188
208
|
@property
|
|
189
|
-
def created_at(self) -> datetime.datetime:
|
|
209
|
+
def created_at(self) -> Optional[datetime.datetime]:
|
|
190
210
|
"""Get the time at which artifact was created"""
|
|
191
211
|
return self._artifact_version.created_at
|
|
192
212
|
|
|
193
213
|
@property
|
|
194
|
-
def updated_at(self) -> datetime.datetime:
|
|
214
|
+
def updated_at(self) -> Optional[datetime.datetime]:
|
|
195
215
|
"""Get the information about when the artifact was updated"""
|
|
196
216
|
return self._artifact_version.updated_at
|
|
197
217
|
|
|
@@ -240,11 +260,17 @@ class ArtifactVersion:
|
|
|
240
260
|
path: Optional[Union[str, Path]],
|
|
241
261
|
overwrite: bool = False,
|
|
242
262
|
progress: Optional[bool] = None,
|
|
243
|
-
) ->
|
|
263
|
+
) -> ArtifactVersionDownloadInfo:
|
|
244
264
|
self._ensure_not_deleted()
|
|
245
265
|
download_dir = self.raw_download(
|
|
246
266
|
path=path, overwrite=overwrite, progress=progress
|
|
247
267
|
)
|
|
268
|
+
if self._artifact_version.manifest:
|
|
269
|
+
download_info = ArtifactVersionDownloadInfo(
|
|
270
|
+
download_dir=download_dir,
|
|
271
|
+
)
|
|
272
|
+
return download_info
|
|
273
|
+
|
|
248
274
|
internal_metadata_path = os.path.join(download_dir, INTERNAL_METADATA_PATH)
|
|
249
275
|
if not os.path.exists(internal_metadata_path):
|
|
250
276
|
raise MlFoundryException(
|
|
@@ -254,7 +280,7 @@ class ArtifactVersion:
|
|
|
254
280
|
with open(internal_metadata_path) as f:
|
|
255
281
|
internal_metadata = ArtifactVersionInternalMetadata.parse_obj(json.load(f))
|
|
256
282
|
download_path = os.path.join(download_dir, internal_metadata.files_dir)
|
|
257
|
-
return
|
|
283
|
+
return ArtifactVersionDownloadInfo(download_dir=download_path)
|
|
258
284
|
|
|
259
285
|
def download(
|
|
260
286
|
self,
|
|
@@ -289,10 +315,10 @@ class ArtifactVersion:
|
|
|
289
315
|
artifact_version.download(path="<your-desired-download-path>")
|
|
290
316
|
```
|
|
291
317
|
"""
|
|
292
|
-
|
|
318
|
+
download_path = self._download(
|
|
293
319
|
path=path, overwrite=overwrite, progress=progress
|
|
294
320
|
)
|
|
295
|
-
return download_path
|
|
321
|
+
return download_path.download_dir
|
|
296
322
|
|
|
297
323
|
def delete(self) -> bool:
|
|
298
324
|
"""
|
|
@@ -336,16 +362,31 @@ class ArtifactVersion:
|
|
|
336
362
|
```
|
|
337
363
|
"""
|
|
338
364
|
self._ensure_not_deleted()
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
365
|
+
if self._artifact_version.manifest:
|
|
366
|
+
manifest = self._artifact_version.manifest.actual_instance
|
|
367
|
+
assert isinstance(manifest, ArtifactVersionManifest)
|
|
368
|
+
manifest.description = self.description
|
|
369
|
+
manifest.metadata = self.metadata
|
|
370
|
+
else:
|
|
371
|
+
manifest = None
|
|
372
|
+
try:
|
|
373
|
+
_artifact_version = (
|
|
374
|
+
self._mlfoundry_artifacts_api.update_artifact_version_post(
|
|
375
|
+
update_artifact_version_request_dto=UpdateArtifactVersionRequestDto(
|
|
376
|
+
id=self._artifact_version.id,
|
|
377
|
+
description=self.description,
|
|
378
|
+
artifact_metadata=self.metadata,
|
|
379
|
+
manifest=manifest,
|
|
380
|
+
)
|
|
381
|
+
)
|
|
345
382
|
)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
383
|
+
except Exception:
|
|
384
|
+
# rollback edits to internal object
|
|
385
|
+
self._refetch_artifact_version(reset_mutable_attrs=False)
|
|
386
|
+
raise
|
|
387
|
+
else:
|
|
388
|
+
self._artifact_version = _artifact_version.artifact_version
|
|
389
|
+
self._set_mutable_attrs()
|
|
349
390
|
|
|
350
391
|
|
|
351
392
|
class ChatPromptVersion(ArtifactVersion):
|
|
@@ -404,12 +445,15 @@ class ChatPromptVersion(ArtifactVersion):
|
|
|
404
445
|
def variables(self) -> Dict[str, Any]:
|
|
405
446
|
return self._chat_prompt.variables or {}
|
|
406
447
|
|
|
448
|
+
def update(self):
|
|
449
|
+
raise NotImplementedError("ChatPromptVersion does not support update operation")
|
|
450
|
+
|
|
407
451
|
|
|
408
452
|
def _log_artifact_version_helper(
|
|
409
|
-
run: "MlFoundryRun",
|
|
453
|
+
run: Optional["MlFoundryRun"],
|
|
410
454
|
name: str,
|
|
411
455
|
artifact_type: ArtifactType,
|
|
412
|
-
artifact_dir: tempfile.TemporaryDirectory,
|
|
456
|
+
artifact_dir: Union[tempfile.TemporaryDirectory, BlobStorageDirectory],
|
|
413
457
|
dest_to_src_map: Dict[str, str],
|
|
414
458
|
mlfoundry_artifacts_api: Optional[MlfoundryArtifactsApi] = None,
|
|
415
459
|
ml_repo_id: Optional[str] = None,
|
|
@@ -439,48 +483,72 @@ def _log_artifact_version_helper(
|
|
|
439
483
|
)
|
|
440
484
|
)
|
|
441
485
|
version_id = _create_artifact_response.id
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
)
|
|
448
|
-
|
|
449
|
-
total_size = calculate_total_size(list(dest_to_src_map.values()))
|
|
450
|
-
try:
|
|
451
|
-
logger.info(
|
|
452
|
-
"Packaging and uploading files to remote with size: %.6f MB",
|
|
453
|
-
total_size / 1000000.0,
|
|
486
|
+
artifact_storage_root = _create_artifact_response.artifact_storage_root
|
|
487
|
+
if isinstance(artifact_dir, tempfile.TemporaryDirectory):
|
|
488
|
+
# Source is of type TrueFoundryArtifactSource
|
|
489
|
+
source = TrueFoundryArtifactSource(
|
|
490
|
+
type="truefoundry", uri=artifact_storage_root
|
|
454
491
|
)
|
|
455
|
-
|
|
456
|
-
|
|
492
|
+
artifacts_repo = MlFoundryArtifactsRepository(
|
|
493
|
+
artifact_identifier=ArtifactIdentifier(
|
|
494
|
+
artifact_version_id=uuid.UUID(version_id),
|
|
495
|
+
),
|
|
496
|
+
api_client=mlfoundry_artifacts_api.api_client,
|
|
457
497
|
)
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
498
|
+
|
|
499
|
+
total_size = calculate_total_size(list(dest_to_src_map.values()))
|
|
500
|
+
try:
|
|
501
|
+
logger.info(
|
|
502
|
+
"Packaging and uploading files to remote with size: %.6f MB",
|
|
503
|
+
total_size / 1000000.0,
|
|
504
|
+
)
|
|
505
|
+
src_dest_pairs = _get_src_dest_pairs(
|
|
506
|
+
root_dir=artifact_dir.name, dest_to_src_map=dest_to_src_map
|
|
507
|
+
)
|
|
508
|
+
artifacts_repo.log_artifacts(
|
|
509
|
+
src_dest_pairs=src_dest_pairs, progress=progress
|
|
463
510
|
)
|
|
511
|
+
except Exception as e:
|
|
512
|
+
mlfoundry_artifacts_api.notify_failure_post(
|
|
513
|
+
notify_artifact_version_failure_dto=NotifyArtifactVersionFailureDto(
|
|
514
|
+
id=version_id
|
|
515
|
+
)
|
|
516
|
+
)
|
|
517
|
+
raise MlFoundryException("Failed to log Artifact") from e
|
|
518
|
+
finally:
|
|
519
|
+
artifact_dir.cleanup()
|
|
520
|
+
|
|
521
|
+
# Note: Here we call from_dict instead of directly passing in init and relying on it
|
|
522
|
+
# to convert because the complicated union of types generates a custom type to handle casting
|
|
523
|
+
# Check the source of `InternalMetadataDto` to see the generated code
|
|
524
|
+
internal_metadata_dto = InternalMetadataDto.from_dict(
|
|
525
|
+
internal_metadata.dict() if internal_metadata is not None else {}
|
|
526
|
+
)
|
|
527
|
+
elif isinstance(artifact_dir, BlobStorageDirectory):
|
|
528
|
+
source = ExternalArtifactSource(type="external", uri=artifact_dir.uri)
|
|
529
|
+
else:
|
|
530
|
+
raise MlFoundryException("Invalid artifact_dir provided")
|
|
531
|
+
|
|
532
|
+
artifact_manifest = None
|
|
533
|
+
if artifact_type == ArtifactType.ARTIFACT:
|
|
534
|
+
_source_cls = typing.get_type_hints(ArtifactVersionManifest)["source"]
|
|
535
|
+
artifact_manifest = ArtifactVersionManifest(
|
|
536
|
+
description=description,
|
|
537
|
+
metadata=metadata or {},
|
|
538
|
+
source=_source_cls.from_dict(source.dict()),
|
|
539
|
+
step=step,
|
|
464
540
|
)
|
|
465
|
-
raise MlFoundryException("Failed to log Artifact") from e
|
|
466
|
-
finally:
|
|
467
|
-
artifact_dir.cleanup()
|
|
468
|
-
|
|
469
|
-
# Note: Here we call from_dict instead of directly passing in init and relying on it
|
|
470
|
-
# to convert because the complicated union of types generates a custom type to handle casting
|
|
471
|
-
# Check the source of `InternalMetadataDto` to see the generated code
|
|
472
|
-
internal_metadata_dto = InternalMetadataDto.from_dict(
|
|
473
|
-
internal_metadata.dict() if internal_metadata is not None else {}
|
|
474
|
-
)
|
|
475
541
|
finalize_artifact_version_request_dto = FinalizeArtifactVersionRequestDto(
|
|
476
542
|
id=version_id,
|
|
477
543
|
run_uuid=run.run_id if run else None,
|
|
478
|
-
|
|
479
|
-
internal_metadata=internal_metadata_dto,
|
|
544
|
+
internal_metadata=internal_metadata_dto if internal_metadata else None,
|
|
480
545
|
artifact_metadata=metadata,
|
|
481
|
-
data_path=INTERNAL_METADATA_PATH,
|
|
546
|
+
data_path=INTERNAL_METADATA_PATH if internal_metadata else None,
|
|
482
547
|
step=step,
|
|
483
548
|
artifact_size=total_size,
|
|
549
|
+
manifest=Manifest.from_dict(artifact_manifest.to_dict())
|
|
550
|
+
if artifact_manifest
|
|
551
|
+
else None,
|
|
484
552
|
)
|
|
485
553
|
_artifact_version = mlfoundry_artifacts_api.finalize_artifact_version_post(
|
|
486
554
|
finalize_artifact_version_request_dto=finalize_artifact_version_request_dto
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import collections
|
|
2
|
-
import json
|
|
3
|
-
import os.path
|
|
4
2
|
import tempfile
|
|
5
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
|
|
6
4
|
|
|
7
5
|
from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
|
|
8
6
|
ArtifactType,
|
|
@@ -12,13 +10,8 @@ from truefoundry.ml.exceptions import MlFoundryException
|
|
|
12
10
|
from truefoundry.ml.log_types.artifacts.artifact import (
|
|
13
11
|
ArtifactPath,
|
|
14
12
|
ArtifactVersion,
|
|
15
|
-
ArtifactVersionInternalMetadata,
|
|
16
13
|
_log_artifact_version_helper,
|
|
17
14
|
)
|
|
18
|
-
from truefoundry.ml.log_types.artifacts.constants import (
|
|
19
|
-
FILES_DIR,
|
|
20
|
-
INTERNAL_METADATA_PATH,
|
|
21
|
-
)
|
|
22
15
|
from truefoundry.ml.log_types.artifacts.utils import (
|
|
23
16
|
_copy_additional_files,
|
|
24
17
|
_validate_artifact_metadata,
|
|
@@ -26,9 +19,12 @@ from truefoundry.ml.log_types.artifacts.utils import (
|
|
|
26
19
|
)
|
|
27
20
|
from truefoundry.ml.logger import logger
|
|
28
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from truefoundry.ml.mlfoundry_run import MlFoundryRun
|
|
24
|
+
|
|
29
25
|
|
|
30
26
|
def _log_artifact_version(
|
|
31
|
-
run,
|
|
27
|
+
run: Optional["MlFoundryRun"],
|
|
32
28
|
name: str,
|
|
33
29
|
artifact_paths: List[Union[ArtifactPath, Tuple[str, Optional[str]], Tuple[str]]],
|
|
34
30
|
mlfoundry_artifacts_api: Optional[MlfoundryArtifactsApi] = None,
|
|
@@ -68,18 +64,10 @@ def _log_artifact_version(
|
|
|
68
64
|
logger.info("Logging the artifact, this might take a while ...")
|
|
69
65
|
temp_dir = tempfile.TemporaryDirectory(prefix="truefoundry-")
|
|
70
66
|
|
|
71
|
-
internal_metadata = ArtifactVersionInternalMetadata(
|
|
72
|
-
files_dir=FILES_DIR,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
67
|
try:
|
|
76
|
-
local_files_dir = os.path.join(temp_dir.name, internal_metadata.files_dir)
|
|
77
|
-
os.makedirs(local_files_dir, exist_ok=True)
|
|
78
|
-
|
|
79
|
-
logger.info("Copying the files to log")
|
|
80
68
|
temp_dest_to_src_map = _copy_additional_files(
|
|
81
69
|
root_dir=temp_dir.name,
|
|
82
|
-
files_dir=
|
|
70
|
+
files_dir="",
|
|
83
71
|
model_dir=None,
|
|
84
72
|
additional_files=artifact_paths,
|
|
85
73
|
)
|
|
@@ -89,13 +77,6 @@ def _log_artifact_version(
|
|
|
89
77
|
temp_dir.cleanup()
|
|
90
78
|
raise MlFoundryException("Failed to log artifact") from e
|
|
91
79
|
|
|
92
|
-
# save internal metadata
|
|
93
|
-
local_internal_metadata_path = os.path.join(temp_dir.name, INTERNAL_METADATA_PATH)
|
|
94
|
-
os.makedirs(os.path.dirname(local_internal_metadata_path), exist_ok=True)
|
|
95
|
-
with open(local_internal_metadata_path, "w") as f:
|
|
96
|
-
json.dump(internal_metadata.dict(), f)
|
|
97
|
-
temp_dest_to_src_map[local_internal_metadata_path] = local_internal_metadata_path
|
|
98
|
-
|
|
99
80
|
return _log_artifact_version_helper(
|
|
100
81
|
run=run,
|
|
101
82
|
ml_repo_id=ml_repo_id,
|
|
@@ -105,7 +86,7 @@ def _log_artifact_version(
|
|
|
105
86
|
dest_to_src_map=temp_dest_to_src_map,
|
|
106
87
|
mlfoundry_artifacts_api=mlfoundry_artifacts_api,
|
|
107
88
|
description=description,
|
|
108
|
-
internal_metadata=
|
|
89
|
+
internal_metadata=None,
|
|
109
90
|
metadata=metadata,
|
|
110
91
|
step=step,
|
|
111
92
|
progress=progress,
|