wandb 0.17.0rc2__py3-none-macosx_11_0_arm64.whl → 0.17.1__py3-none-macosx_11_0_arm64.whl
Sign up to get free protection for your applications and to get access to all the features.
- wandb/__init__.py +1 -2
- wandb/apis/importers/internals/internal.py +0 -1
- wandb/apis/importers/wandb.py +12 -7
- wandb/apis/internal.py +0 -3
- wandb/apis/public/api.py +213 -79
- wandb/apis/public/artifacts.py +335 -100
- wandb/apis/public/files.py +9 -9
- wandb/apis/public/jobs.py +16 -4
- wandb/apis/public/projects.py +26 -28
- wandb/apis/public/query_generator.py +1 -1
- wandb/apis/public/runs.py +163 -65
- wandb/apis/public/sweeps.py +2 -2
- wandb/apis/reports/__init__.py +1 -7
- wandb/apis/reports/v1/__init__.py +5 -27
- wandb/apis/reports/v2/__init__.py +7 -19
- wandb/apis/workspaces/__init__.py +8 -0
- wandb/beta/workflows.py +8 -3
- wandb/bin/apple_gpu_stats +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +131 -59
- wandb/docker/__init__.py +1 -1
- wandb/errors/term.py +10 -2
- wandb/filesync/step_checksum.py +1 -4
- wandb/filesync/step_prepare.py +4 -24
- wandb/filesync/step_upload.py +5 -107
- wandb/filesync/upload_job.py +0 -76
- wandb/integration/gym/__init__.py +35 -15
- wandb/integration/openai/fine_tuning.py +21 -3
- wandb/integration/prodigy/prodigy.py +1 -1
- wandb/jupyter.py +16 -17
- wandb/plot/pr_curve.py +2 -1
- wandb/plot/roc_curve.py +2 -1
- wandb/{plots → plot}/utils.py +13 -25
- wandb/proto/v3/wandb_internal_pb2.py +54 -54
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v4/wandb_internal_pb2.py +54 -54
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_base_pb2.py +30 -0
- wandb/proto/v5/wandb_internal_pb2.py +355 -0
- wandb/proto/v5/wandb_server_pb2.py +63 -0
- wandb/proto/v5/wandb_settings_pb2.py +45 -0
- wandb/proto/v5/wandb_telemetry_pb2.py +41 -0
- wandb/proto/wandb_base_pb2.py +2 -0
- wandb/proto/wandb_deprecated.py +9 -1
- wandb/proto/wandb_generate_deprecated.py +34 -0
- wandb/proto/{wandb_internal_codegen.py → wandb_generate_proto.py} +1 -35
- wandb/proto/wandb_internal_pb2.py +2 -0
- wandb/proto/wandb_server_pb2.py +2 -0
- wandb/proto/wandb_settings_pb2.py +2 -0
- wandb/proto/wandb_telemetry_pb2.py +2 -0
- wandb/sdk/artifacts/artifact.py +68 -22
- wandb/sdk/artifacts/artifact_manifest.py +1 -1
- wandb/sdk/artifacts/artifact_manifest_entry.py +6 -3
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -1
- wandb/sdk/artifacts/artifact_saver.py +1 -10
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +6 -2
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +2 -42
- wandb/sdk/artifacts/storage_policy.py +1 -12
- wandb/sdk/data_types/image.py +1 -1
- wandb/sdk/data_types/video.py +4 -2
- wandb/sdk/interface/interface.py +13 -0
- wandb/sdk/interface/interface_shared.py +1 -1
- wandb/sdk/internal/file_pusher.py +2 -5
- wandb/sdk/internal/file_stream.py +6 -19
- wandb/sdk/internal/internal_api.py +148 -136
- wandb/sdk/internal/job_builder.py +207 -135
- wandb/sdk/internal/progress.py +0 -28
- wandb/sdk/internal/sender.py +102 -39
- wandb/sdk/internal/settings_static.py +8 -1
- wandb/sdk/internal/system/assets/trainium.py +3 -3
- wandb/sdk/internal/system/system_info.py +4 -2
- wandb/sdk/internal/update.py +1 -1
- wandb/sdk/launch/__init__.py +9 -1
- wandb/sdk/launch/_launch.py +4 -24
- wandb/sdk/launch/_launch_add.py +1 -3
- wandb/sdk/launch/_project_spec.py +184 -224
- wandb/sdk/launch/agent/agent.py +58 -18
- wandb/sdk/launch/agent/config.py +0 -3
- wandb/sdk/launch/builder/abstract.py +67 -0
- wandb/sdk/launch/builder/build.py +165 -576
- wandb/sdk/launch/builder/context_manager.py +235 -0
- wandb/sdk/launch/builder/docker_builder.py +7 -23
- wandb/sdk/launch/builder/kaniko_builder.py +10 -23
- wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
- wandb/sdk/launch/create_job.py +51 -45
- wandb/sdk/launch/environment/aws_environment.py +26 -1
- wandb/sdk/launch/inputs/files.py +148 -0
- wandb/sdk/launch/inputs/internal.py +224 -0
- wandb/sdk/launch/inputs/manage.py +95 -0
- wandb/sdk/launch/runner/abstract.py +2 -2
- wandb/sdk/launch/runner/kubernetes_monitor.py +45 -12
- wandb/sdk/launch/runner/kubernetes_runner.py +6 -8
- wandb/sdk/launch/runner/local_container.py +2 -3
- wandb/sdk/launch/runner/local_process.py +8 -29
- wandb/sdk/launch/runner/sagemaker_runner.py +20 -14
- wandb/sdk/launch/runner/vertex_runner.py +8 -7
- wandb/sdk/launch/sweeps/scheduler.py +2 -0
- wandb/sdk/launch/sweeps/utils.py +2 -2
- wandb/sdk/launch/utils.py +16 -138
- wandb/sdk/lib/_settings_toposort_generated.py +2 -5
- wandb/sdk/lib/apikey.py +4 -2
- wandb/sdk/lib/config_util.py +3 -3
- wandb/sdk/lib/proto_util.py +22 -1
- wandb/sdk/lib/redirect.py +1 -1
- wandb/sdk/service/service.py +2 -1
- wandb/sdk/service/streams.py +5 -5
- wandb/sdk/wandb_init.py +25 -59
- wandb/sdk/wandb_login.py +28 -25
- wandb/sdk/wandb_run.py +112 -45
- wandb/sdk/wandb_settings.py +33 -64
- wandb/sdk/wandb_watch.py +1 -1
- wandb/sklearn/plot/classifier.py +4 -6
- wandb/sync/sync.py +2 -2
- wandb/testing/relay.py +32 -17
- wandb/util.py +36 -37
- wandb/wandb_agent.py +3 -3
- wandb/wandb_controller.py +3 -2
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/METADATA +7 -9
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/RECORD +126 -148
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/WHEEL +1 -1
- wandb/apis/reports/v1/_blocks.py +0 -1406
- wandb/apis/reports/v1/_helpers.py +0 -70
- wandb/apis/reports/v1/_panels.py +0 -1282
- wandb/apis/reports/v1/_templates.py +0 -478
- wandb/apis/reports/v1/blocks.py +0 -27
- wandb/apis/reports/v1/helpers.py +0 -2
- wandb/apis/reports/v1/mutations.py +0 -66
- wandb/apis/reports/v1/panels.py +0 -17
- wandb/apis/reports/v1/report.py +0 -268
- wandb/apis/reports/v1/runset.py +0 -144
- wandb/apis/reports/v1/templates.py +0 -7
- wandb/apis/reports/v1/util.py +0 -406
- wandb/apis/reports/v1/validators.py +0 -131
- wandb/apis/reports/v2/blocks.py +0 -25
- wandb/apis/reports/v2/expr_parsing.py +0 -257
- wandb/apis/reports/v2/gql.py +0 -68
- wandb/apis/reports/v2/interface.py +0 -1911
- wandb/apis/reports/v2/internal.py +0 -867
- wandb/apis/reports/v2/metrics.py +0 -6
- wandb/apis/reports/v2/panels.py +0 -15
- wandb/catboost/__init__.py +0 -9
- wandb/fastai/__init__.py +0 -9
- wandb/keras/__init__.py +0 -19
- wandb/lightgbm/__init__.py +0 -9
- wandb/plots/__init__.py +0 -6
- wandb/plots/explain_text.py +0 -36
- wandb/plots/heatmap.py +0 -81
- wandb/plots/named_entity.py +0 -43
- wandb/plots/part_of_speech.py +0 -50
- wandb/plots/plot_definitions.py +0 -768
- wandb/plots/precision_recall.py +0 -121
- wandb/plots/roc.py +0 -103
- wandb/sacred/__init__.py +0 -3
- wandb/xgboost/__init__.py +0 -9
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/licenses/LICENSE +0 -0
wandb/proto/wandb_base_pb2.py
CHANGED
wandb/proto/wandb_deprecated.py
CHANGED
@@ -20,7 +20,11 @@ DEPRECATED_FEATURES = Literal[
|
|
20
20
|
"init__config_include_keys",
|
21
21
|
"init__config_exclude_keys",
|
22
22
|
"keras_callback__save_model",
|
23
|
-
"langchain_tracer"
|
23
|
+
"langchain_tracer",
|
24
|
+
"artifact__get_path",
|
25
|
+
"artifactmanifestentry__name",
|
26
|
+
"api__artifact_versions",
|
27
|
+
"artifact_collection__change_type",
|
24
28
|
]
|
25
29
|
|
26
30
|
|
@@ -35,3 +39,7 @@ class Deprecated:
|
|
35
39
|
init__config_exclude_keys: DEPRECATED_FEATURES = "init__config_exclude_keys"
|
36
40
|
keras_callback__save_model: DEPRECATED_FEATURES = "keras_callback__save_model"
|
37
41
|
langchain_tracer: DEPRECATED_FEATURES = "langchain_tracer"
|
42
|
+
artifact__get_path: DEPRECATED_FEATURES = "artifact__get_path"
|
43
|
+
artifactmanifestentry__name: DEPRECATED_FEATURES = "artifactmanifestentry__name"
|
44
|
+
api__artifact_versions: DEPRECATED_FEATURES = "api__artifact_versions"
|
45
|
+
artifact_collection__change_type: DEPRECATED_FEATURES = "artifact_collection__change_type"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
|
4
|
+
def generate_deprecated_class_definition() -> None:
|
5
|
+
"""Generate a class definition listing the deprecated features.
|
6
|
+
This is to allow static checks to ensure that proper field names are used.
|
7
|
+
"""
|
8
|
+
from wandb.proto.wandb_telemetry_pb2 import Deprecated # type: ignore[import]
|
9
|
+
|
10
|
+
deprecated_features = Deprecated.DESCRIPTOR.fields_by_name.keys()
|
11
|
+
|
12
|
+
code: str = (
|
13
|
+
"# Generated by wandb/proto/wandb_internal_codegen.py. DO NOT EDIT!\n\n\n"
|
14
|
+
"import sys\n\n\n"
|
15
|
+
"if sys.version_info >= (3, 8):\n"
|
16
|
+
" from typing import Literal\n"
|
17
|
+
"else:\n"
|
18
|
+
" from typing_extensions import Literal\n\n\n"
|
19
|
+
"DEPRECATED_FEATURES = Literal[\n"
|
20
|
+
+ ",\n".join(f' "{feature}"' for feature in deprecated_features)
|
21
|
+
+ ",\n"
|
22
|
+
+ "]\n\n\n"
|
23
|
+
"class Deprecated:\n"
|
24
|
+
+ "".join(
|
25
|
+
[
|
26
|
+
f' {feature}: DEPRECATED_FEATURES = "{feature}"\n'
|
27
|
+
for feature in deprecated_features
|
28
|
+
]
|
29
|
+
)
|
30
|
+
)
|
31
|
+
with open("wandb_deprecated.py", "w") as f:
|
32
|
+
f.write(code)
|
33
|
+
|
34
|
+
generate_deprecated_class_definition()
|
@@ -1,46 +1,14 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
|
3
|
+
import importlib.metadata
|
3
4
|
import os
|
4
5
|
import pathlib
|
5
6
|
|
6
7
|
import grpc_tools # type: ignore
|
7
8
|
from grpc_tools import protoc # type: ignore
|
8
|
-
import importlib.metadata
|
9
9
|
from packaging import version
|
10
10
|
|
11
11
|
|
12
|
-
def generate_deprecated_class_definition() -> None:
|
13
|
-
"""
|
14
|
-
Generate a class definition listing the deprecated features.
|
15
|
-
This is to allow static checks to ensure that proper field names are used.
|
16
|
-
"""
|
17
|
-
from wandb.proto.wandb_telemetry_pb2 import Deprecated # type: ignore[import]
|
18
|
-
|
19
|
-
deprecated_features = Deprecated.DESCRIPTOR.fields_by_name.keys()
|
20
|
-
|
21
|
-
code: str = (
|
22
|
-
"# Generated by wandb/proto/wandb_internal_codegen.py. DO NOT EDIT!\n\n\n"
|
23
|
-
"import sys\n\n\n"
|
24
|
-
"if sys.version_info >= (3, 8):\n"
|
25
|
-
" from typing import Literal\n"
|
26
|
-
"else:\n"
|
27
|
-
" from typing_extensions import Literal\n\n\n"
|
28
|
-
"DEPRECATED_FEATURES = Literal[\n"
|
29
|
-
+ ",\n".join(f' "{feature}"' for feature in deprecated_features)
|
30
|
-
+ "\n"
|
31
|
-
+ "]\n\n\n"
|
32
|
-
"class Deprecated:\n"
|
33
|
-
+ "".join(
|
34
|
-
[
|
35
|
-
f' {feature}: DEPRECATED_FEATURES = "{feature}"\n'
|
36
|
-
for feature in deprecated_features
|
37
|
-
]
|
38
|
-
)
|
39
|
-
)
|
40
|
-
with open("wandb/proto/wandb_deprecated.py", "w") as f:
|
41
|
-
f.write(code)
|
42
|
-
|
43
|
-
|
44
12
|
def get_pip_package_version(package_name: str) -> str:
|
45
13
|
try:
|
46
14
|
return importlib.metadata.version(package_name)
|
@@ -79,5 +47,3 @@ for p in (tmp_out / "wandb" / "proto").glob("*pb2*"):
|
|
79
47
|
p.rename(tmp_out / p.name)
|
80
48
|
os.rmdir(tmp_out / "wandb" / "proto")
|
81
49
|
os.rmdir(tmp_out / "wandb")
|
82
|
-
|
83
|
-
generate_deprecated_class_definition()
|
wandb/proto/wandb_server_pb2.py
CHANGED
wandb/sdk/artifacts/artifact.py
CHANGED
@@ -70,6 +70,7 @@ from wandb.sdk.data_types._dtypes import TypeRegistry
|
|
70
70
|
from wandb.sdk.internal.internal_api import Api as InternalApi
|
71
71
|
from wandb.sdk.internal.thread_local_settings import _thread_local_api_settings
|
72
72
|
from wandb.sdk.lib import filesystem, retry, runid, telemetry
|
73
|
+
from wandb.sdk.lib.deprecate import Deprecated, deprecate
|
73
74
|
from wandb.sdk.lib.hashutil import B64MD5, b64_to_hex_id, md5_file_b64
|
74
75
|
from wandb.sdk.lib.mailbox import Mailbox
|
75
76
|
from wandb.sdk.lib.paths import FilePathStr, LogicalPath, StrPath, URIStr
|
@@ -262,11 +263,12 @@ class Artifact:
|
|
262
263
|
"name": name,
|
263
264
|
},
|
264
265
|
)
|
265
|
-
|
266
|
-
if
|
267
|
-
raise ValueError(
|
268
|
-
|
269
|
-
|
266
|
+
project_attrs = response.get("project")
|
267
|
+
if not project_attrs:
|
268
|
+
raise ValueError(f"project '{project}' not found under entity '{entity}'")
|
269
|
+
attrs = project_attrs.get("artifact")
|
270
|
+
if not attrs:
|
271
|
+
raise ValueError(f"artifact '{name}' not found in '{entity}/{project}'")
|
270
272
|
return cls._from_attrs(entity, project, name, attrs, client)
|
271
273
|
|
272
274
|
@classmethod
|
@@ -425,7 +427,7 @@ class Artifact:
|
|
425
427
|
|
426
428
|
A collection is an ordered group of artifact versions.
|
427
429
|
If this artifact was retrieved from a portfolio / linked collection, that
|
428
|
-
collection will be returned rather than the
|
430
|
+
collection will be returned rather than the collection
|
429
431
|
that an artifact version originated from. The collection
|
430
432
|
that an artifact originates from is known as the source sequence.
|
431
433
|
"""
|
@@ -1180,7 +1182,7 @@ class Artifact:
|
|
1180
1182
|
"""
|
1181
1183
|
self._ensure_can_add()
|
1182
1184
|
if not os.path.isfile(local_path):
|
1183
|
-
raise ValueError("Path is not a file:
|
1185
|
+
raise ValueError("Path is not a file: {}".format(local_path))
|
1184
1186
|
|
1185
1187
|
name = LogicalPath(name or os.path.basename(local_path))
|
1186
1188
|
digest = md5_file_b64(local_path)
|
@@ -1221,11 +1223,12 @@ class Artifact:
|
|
1221
1223
|
"""
|
1222
1224
|
self._ensure_can_add()
|
1223
1225
|
if not os.path.isdir(local_path):
|
1224
|
-
raise ValueError("Path is not a directory:
|
1226
|
+
raise ValueError("Path is not a directory: {}".format(local_path))
|
1225
1227
|
|
1226
1228
|
termlog(
|
1227
|
-
"Adding directory to artifact (
|
1228
|
-
|
1229
|
+
"Adding directory to artifact ({})... ".format(
|
1230
|
+
os.path.join(".", os.path.normpath(local_path))
|
1231
|
+
),
|
1229
1232
|
newline=False,
|
1230
1233
|
)
|
1231
1234
|
start_time = time.time()
|
@@ -1503,8 +1506,9 @@ class Artifact:
|
|
1503
1506
|
|
1504
1507
|
def get_path(self, name: StrPath) -> ArtifactManifestEntry:
|
1505
1508
|
"""Deprecated. Use `get_entry(name)`."""
|
1506
|
-
|
1507
|
-
|
1509
|
+
deprecate(
|
1510
|
+
field_name=Deprecated.artifact__get_path,
|
1511
|
+
warning_message="Artifact.get_path(name) is deprecated, use Artifact.get_entry(name) instead.",
|
1508
1512
|
)
|
1509
1513
|
return self.get_entry(name)
|
1510
1514
|
|
@@ -1526,7 +1530,7 @@ class Artifact:
|
|
1526
1530
|
name = LogicalPath(name)
|
1527
1531
|
entry = self.manifest.entries.get(name) or self._get_obj_entry(name)[0]
|
1528
1532
|
if entry is None:
|
1529
|
-
raise KeyError("Path not contained in artifact:
|
1533
|
+
raise KeyError("Path not contained in artifact: {}".format(name))
|
1530
1534
|
entry._parent_artifact = self
|
1531
1535
|
return entry
|
1532
1536
|
|
@@ -1937,11 +1941,11 @@ class Artifact:
|
|
1937
1941
|
for entry in self.manifest.entries.values():
|
1938
1942
|
if entry.ref is None:
|
1939
1943
|
if md5_file_b64(os.path.join(root, entry.path)) != entry.digest:
|
1940
|
-
raise ValueError("Digest mismatch for file:
|
1944
|
+
raise ValueError("Digest mismatch for file: {}".format(entry.path))
|
1941
1945
|
else:
|
1942
1946
|
ref_count += 1
|
1943
1947
|
if ref_count > 0:
|
1944
|
-
print("Warning: skipped verification of
|
1948
|
+
print("Warning: skipped verification of {} refs".format(ref_count))
|
1945
1949
|
|
1946
1950
|
def file(self, root: Optional[str] = None) -> StrPath:
|
1947
1951
|
"""Download a single file artifact to the directory you specify with `root`.
|
@@ -2057,13 +2061,13 @@ class Artifact:
|
|
2057
2061
|
|
2058
2062
|
Arguments:
|
2059
2063
|
target_path: The path to the portfolio inside a project.
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2064
|
+
The target path must adhere to one of the following
|
2065
|
+
schemas `{portfolio}`, `{project}/{portfolio}` or
|
2066
|
+
`{entity}/{project}/{portfolio}`.
|
2067
|
+
To link the artifact to the Model Registry, rather than to a generic
|
2068
|
+
portfolio inside a project, set `target_path` to the following
|
2069
|
+
schema `{"model-registry"}/{Registered Model Name}` or
|
2070
|
+
`{entity}/{"model-registry"}/{Registered Model Name}`.
|
2067
2071
|
aliases: A list of strings that uniquely identifies the artifact inside the
|
2068
2072
|
specified portfolio.
|
2069
2073
|
|
@@ -2081,6 +2085,48 @@ class Artifact:
|
|
2081
2085
|
else:
|
2082
2086
|
wandb.run.link_artifact(self, target_path, aliases)
|
2083
2087
|
|
2088
|
+
def unlink(self) -> None:
|
2089
|
+
"""Unlink this artifact if it is currently a member of a portfolio (a promoted collection of artifacts).
|
2090
|
+
|
2091
|
+
Raises:
|
2092
|
+
ArtifactNotLoggedError: If the artifact is not logged.
|
2093
|
+
ValueError: If the artifact is not linked, i.e. it is not a member of a portfolio collection.
|
2094
|
+
"""
|
2095
|
+
self._ensure_logged("unlink")
|
2096
|
+
|
2097
|
+
# Fail early if this isn't a linked artifact to begin with
|
2098
|
+
if self.collection.is_sequence():
|
2099
|
+
raise ValueError(
|
2100
|
+
f"Artifact {self.qualified_name!r} is not a linked artifact and cannot be unlinked. "
|
2101
|
+
f"To delete it, use {self.delete.__qualname__!r} instead."
|
2102
|
+
)
|
2103
|
+
|
2104
|
+
self._unlink()
|
2105
|
+
|
2106
|
+
@normalize_exceptions
|
2107
|
+
def _unlink(self) -> None:
|
2108
|
+
mutation = gql(
|
2109
|
+
"""
|
2110
|
+
mutation UnlinkArtifact($artifactID: ID!, $artifactPortfolioID: ID!) {
|
2111
|
+
unlinkArtifact(
|
2112
|
+
input: { artifactID: $artifactID, artifactPortfolioID: $artifactPortfolioID }
|
2113
|
+
) {
|
2114
|
+
artifactID
|
2115
|
+
success
|
2116
|
+
clientMutationId
|
2117
|
+
}
|
2118
|
+
}
|
2119
|
+
"""
|
2120
|
+
)
|
2121
|
+
assert self._client is not None
|
2122
|
+
self._client.execute(
|
2123
|
+
mutation,
|
2124
|
+
variable_values={
|
2125
|
+
"artifactID": self.id,
|
2126
|
+
"artifactPortfolioID": self.collection.id,
|
2127
|
+
},
|
2128
|
+
)
|
2129
|
+
|
2084
2130
|
def used_by(self) -> List[Run]:
|
2085
2131
|
"""Get a list of the runs that have used this artifact.
|
2086
2132
|
|
@@ -51,7 +51,7 @@ class ArtifactManifest:
|
|
51
51
|
entry.path in self.entries
|
52
52
|
and entry.digest != self.entries[entry.path].digest
|
53
53
|
):
|
54
|
-
raise ValueError("Cannot add the same path twice:
|
54
|
+
raise ValueError("Cannot add the same path twice: {}".format(entry.path))
|
55
55
|
self.entries[entry.path] = entry
|
56
56
|
|
57
57
|
def remove_entry(self, entry: "ArtifactManifestEntry") -> None:
|
@@ -6,8 +6,8 @@ from pathlib import Path
|
|
6
6
|
from typing import TYPE_CHECKING, Dict, Optional, Union
|
7
7
|
from urllib.parse import urlparse
|
8
8
|
|
9
|
-
from wandb.errors.term import termwarn
|
10
9
|
from wandb.sdk.lib import filesystem
|
10
|
+
from wandb.sdk.lib.deprecate import Deprecated, deprecate
|
11
11
|
from wandb.sdk.lib.hashutil import (
|
12
12
|
B64MD5,
|
13
13
|
ETag,
|
@@ -94,8 +94,11 @@ class ArtifactManifestEntry:
|
|
94
94
|
|
95
95
|
@property
|
96
96
|
def name(self) -> LogicalPath:
|
97
|
-
|
98
|
-
|
97
|
+
"""Deprecated; use `path` instead."""
|
98
|
+
deprecate(
|
99
|
+
field_name=Deprecated.artifactmanifestentry__name,
|
100
|
+
warning_message="ArtifactManifestEntry.name is deprecated, use .path instead.",
|
101
|
+
)
|
99
102
|
return self.path
|
100
103
|
|
101
104
|
def parent_artifact(self) -> "Artifact":
|
@@ -20,7 +20,7 @@ class ArtifactManifestV1(ArtifactManifest):
|
|
20
20
|
) -> "ArtifactManifestV1":
|
21
21
|
if manifest_json["version"] != cls.version():
|
22
22
|
raise ValueError(
|
23
|
-
"Expected manifest version 1, got
|
23
|
+
"Expected manifest version 1, got {}".format(manifest_json["version"])
|
24
24
|
)
|
25
25
|
|
26
26
|
storage_policy_name = manifest_json["storagePolicy"]
|
@@ -173,16 +173,7 @@ class ArtifactSaver:
|
|
173
173
|
self._file_pusher.store_manifest_files(
|
174
174
|
self._manifest,
|
175
175
|
artifact_id,
|
176
|
-
lambda entry,
|
177
|
-
progress_callback: self._manifest.storage_policy.store_file_sync(
|
178
|
-
artifact_id,
|
179
|
-
artifact_manifest_id,
|
180
|
-
entry,
|
181
|
-
step_prepare,
|
182
|
-
progress_callback=progress_callback,
|
183
|
-
),
|
184
|
-
lambda entry,
|
185
|
-
progress_callback: self._manifest.storage_policy.store_file_async(
|
176
|
+
lambda entry, progress_callback: self._manifest.storage_policy.store_file(
|
186
177
|
artifact_id,
|
187
178
|
artifact_manifest_id,
|
188
179
|
entry,
|
@@ -43,7 +43,9 @@ class LocalFileHandler(StorageHandler):
|
|
43
43
|
local_path = util.local_file_uri_to_path(str(manifest_entry.ref))
|
44
44
|
if not os.path.exists(local_path):
|
45
45
|
raise ValueError(
|
46
|
-
"Local file reference: Failed to find file at path
|
46
|
+
"Local file reference: Failed to find file at path {}".format(
|
47
|
+
local_path
|
48
|
+
)
|
47
49
|
)
|
48
50
|
|
49
51
|
path, hit, cache_open = self._cache.check_md5_obj_path(
|
@@ -131,5 +133,7 @@ class LocalFileHandler(StorageHandler):
|
|
131
133
|
entries.append(entry)
|
132
134
|
else:
|
133
135
|
# TODO: update error message if we don't allow directories.
|
134
|
-
raise ValueError(
|
136
|
+
raise ValueError(
|
137
|
+
'Path "{}" must be a valid file or directory path'.format(path)
|
138
|
+
)
|
135
139
|
return entries
|
@@ -29,7 +29,7 @@ class MultiHandler(StorageHandler):
|
|
29
29
|
return handler
|
30
30
|
if self._default_handler is not None:
|
31
31
|
return self._default_handler
|
32
|
-
raise ValueError('No storage handler registered for url "
|
32
|
+
raise ValueError('No storage handler registered for url "{}"'.format(str(url)))
|
33
33
|
|
34
34
|
def load_path(
|
35
35
|
self,
|
@@ -57,12 +57,14 @@ class TrackingHandler(StorageHandler):
|
|
57
57
|
url = urlparse(path)
|
58
58
|
if name is None:
|
59
59
|
raise ValueError(
|
60
|
-
'You must pass name="<entry_name>" when tracking references with unknown schemes. ref:
|
61
|
-
|
60
|
+
'You must pass name="<entry_name>" when tracking references with unknown schemes. ref: {}'.format(
|
61
|
+
path
|
62
|
+
)
|
62
63
|
)
|
63
64
|
termwarn(
|
64
|
-
"Artifact references with unsupported schemes cannot be checksummed:
|
65
|
-
|
65
|
+
"Artifact references with unsupported schemes cannot be checksummed: {}".format(
|
66
|
+
path
|
67
|
+
)
|
66
68
|
)
|
67
69
|
name = name or url.path[1:] # strip leading slash
|
68
70
|
return [ArtifactManifestEntry(path=name, ref=path, digest=path)]
|
@@ -263,7 +263,7 @@ class WandbStoragePolicy(StoragePolicy):
|
|
263
263
|
return math.ceil(file_size / S3_MAX_PART_NUMBERS)
|
264
264
|
return default_chunk_size
|
265
265
|
|
266
|
-
def
|
266
|
+
def store_file(
|
267
267
|
self,
|
268
268
|
artifact_id: str,
|
269
269
|
artifact_manifest_id: str,
|
@@ -301,7 +301,7 @@ class WandbStoragePolicy(StoragePolicy):
|
|
301
301
|
hex_digests[part_number] = hex_digest
|
302
302
|
part_number += 1
|
303
303
|
|
304
|
-
resp = preparer.
|
304
|
+
resp = preparer.prepare(
|
305
305
|
{
|
306
306
|
"artifactID": artifact_id,
|
307
307
|
"artifactManifestID": artifact_manifest_id,
|
@@ -347,46 +347,6 @@ class WandbStoragePolicy(StoragePolicy):
|
|
347
347
|
|
348
348
|
return False
|
349
349
|
|
350
|
-
async def store_file_async(
|
351
|
-
self,
|
352
|
-
artifact_id: str,
|
353
|
-
artifact_manifest_id: str,
|
354
|
-
entry: "ArtifactManifestEntry",
|
355
|
-
preparer: "StepPrepare",
|
356
|
-
progress_callback: Optional["progress.ProgressFn"] = None,
|
357
|
-
) -> bool:
|
358
|
-
"""Async equivalent to `store_file_sync`."""
|
359
|
-
resp = await preparer.prepare_async(
|
360
|
-
{
|
361
|
-
"artifactID": artifact_id,
|
362
|
-
"artifactManifestID": artifact_manifest_id,
|
363
|
-
"name": entry.path,
|
364
|
-
"md5": entry.digest,
|
365
|
-
}
|
366
|
-
)
|
367
|
-
|
368
|
-
entry.birth_artifact_id = resp.birth_artifact_id
|
369
|
-
if resp.upload_url is None:
|
370
|
-
return True
|
371
|
-
if entry.local_path is None:
|
372
|
-
return False
|
373
|
-
|
374
|
-
with open(entry.local_path, "rb") as file:
|
375
|
-
# This fails if we don't send the first byte before the signed URL expires.
|
376
|
-
await self._api.upload_file_retry_async(
|
377
|
-
resp.upload_url,
|
378
|
-
file,
|
379
|
-
progress_callback,
|
380
|
-
extra_headers={
|
381
|
-
header.split(":", 1)[0]: header.split(":", 1)[1]
|
382
|
-
for header in (resp.upload_headers or {})
|
383
|
-
},
|
384
|
-
)
|
385
|
-
|
386
|
-
self._write_cache(entry)
|
387
|
-
|
388
|
-
return False
|
389
|
-
|
390
350
|
def _write_cache(self, entry: "ArtifactManifestEntry") -> None:
|
391
351
|
if entry.local_path is None:
|
392
352
|
return
|
@@ -43,7 +43,7 @@ class StoragePolicy:
|
|
43
43
|
) -> FilePathStr:
|
44
44
|
raise NotImplementedError
|
45
45
|
|
46
|
-
def
|
46
|
+
def store_file(
|
47
47
|
self,
|
48
48
|
artifact_id: str,
|
49
49
|
artifact_manifest_id: str,
|
@@ -53,17 +53,6 @@ class StoragePolicy:
|
|
53
53
|
) -> bool:
|
54
54
|
raise NotImplementedError
|
55
55
|
|
56
|
-
async def store_file_async(
|
57
|
-
self,
|
58
|
-
artifact_id: str,
|
59
|
-
artifact_manifest_id: str,
|
60
|
-
entry: "ArtifactManifestEntry",
|
61
|
-
preparer: "StepPrepare",
|
62
|
-
progress_callback: Optional["ProgressFn"] = None,
|
63
|
-
) -> bool:
|
64
|
-
"""Async equivalent to `store_file_sync`."""
|
65
|
-
raise NotImplementedError
|
66
|
-
|
67
56
|
def store_reference(
|
68
57
|
self,
|
69
58
|
artifact: "Artifact",
|
wandb/sdk/data_types/image.py
CHANGED
wandb/sdk/data_types/video.py
CHANGED
@@ -96,7 +96,9 @@ class Video(BatchableMedia):
|
|
96
96
|
self._channels = None
|
97
97
|
self._caption = caption
|
98
98
|
if self._format not in Video.EXTS:
|
99
|
-
raise ValueError(
|
99
|
+
raise ValueError(
|
100
|
+
"wandb.Video accepts {} formats".format(", ".join(Video.EXTS))
|
101
|
+
)
|
100
102
|
|
101
103
|
if isinstance(data_or_path, BytesIO):
|
102
104
|
filename = os.path.join(
|
@@ -110,7 +112,7 @@ class Video(BatchableMedia):
|
|
110
112
|
ext = ext[1:].lower()
|
111
113
|
if ext not in Video.EXTS:
|
112
114
|
raise ValueError(
|
113
|
-
"wandb.Video accepts
|
115
|
+
"wandb.Video accepts {} formats".format(", ".join(Video.EXTS))
|
114
116
|
)
|
115
117
|
self._set_file(data_or_path, is_tmp=False)
|
116
118
|
# ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 data_or_path
|
wandb/sdk/interface/interface.py
CHANGED
@@ -394,11 +394,23 @@ class InterfaceBase:
|
|
394
394
|
source.artifact.artifact = info_source.get("artifact", "")
|
395
395
|
source.artifact.entrypoint.extend(info_source.get("entrypoint", []))
|
396
396
|
source.artifact.notebook = info_source.get("notebook", False)
|
397
|
+
build_context = info_source.get("build_context")
|
398
|
+
if build_context:
|
399
|
+
source.artifact.build_context = build_context
|
400
|
+
dockerfile = info_source.get("dockerfile")
|
401
|
+
if dockerfile:
|
402
|
+
source.artifact.dockerfile = dockerfile
|
397
403
|
elif source_type == "repo":
|
398
404
|
source.git.git_info.remote = metadata.get("git", {}).get("remote", "")
|
399
405
|
source.git.git_info.commit = metadata.get("git", {}).get("commit", "")
|
400
406
|
source.git.entrypoint.extend(metadata.get("entrypoint", []))
|
401
407
|
source.git.notebook = metadata.get("notebook", False)
|
408
|
+
build_context = metadata.get("build_context")
|
409
|
+
if build_context:
|
410
|
+
source.git.build_context = build_context
|
411
|
+
dockerfile = metadata.get("dockerfile")
|
412
|
+
if dockerfile:
|
413
|
+
source.git.dockerfile = dockerfile
|
402
414
|
elif source_type == "image":
|
403
415
|
source.image.image = metadata.get("docker", "")
|
404
416
|
else:
|
@@ -775,6 +787,7 @@ class InterfaceBase:
|
|
775
787
|
source.file.CopyFrom(
|
776
788
|
pb.JobInputSource.ConfigFileSource(path=file_path),
|
777
789
|
)
|
790
|
+
request.input_source.CopyFrom(source)
|
778
791
|
|
779
792
|
return self._publish_job_input(request)
|
780
793
|
|
@@ -321,7 +321,7 @@ class InterfaceShared(InterfaceBase):
|
|
321
321
|
if result is None:
|
322
322
|
# TODO: friendlier error message here
|
323
323
|
raise wandb.Error(
|
324
|
-
"Couldn't communicate with backend after
|
324
|
+
"Couldn't communicate with backend after {} seconds".format(timeout)
|
325
325
|
)
|
326
326
|
login_response = result.response.login_response
|
327
327
|
assert login_response
|
@@ -14,7 +14,7 @@ from wandb.sdk.lib.paths import LogicalPath
|
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from wandb.sdk.artifacts.artifact_manifest import ArtifactManifest
|
17
|
-
from wandb.sdk.artifacts.artifact_saver import SaveFn
|
17
|
+
from wandb.sdk.artifacts.artifact_saver import SaveFn
|
18
18
|
from wandb.sdk.internal import file_stream, internal_api
|
19
19
|
from wandb.sdk.internal.settings_static import SettingsStatic
|
20
20
|
|
@@ -148,11 +148,8 @@ class FilePusher:
|
|
148
148
|
manifest: "ArtifactManifest",
|
149
149
|
artifact_id: str,
|
150
150
|
save_fn: "SaveFn",
|
151
|
-
save_fn_async: "SaveFnAsync",
|
152
151
|
) -> None:
|
153
|
-
event = step_checksum.RequestStoreManifestFiles(
|
154
|
-
manifest, artifact_id, save_fn, save_fn_async
|
155
|
-
)
|
152
|
+
event = step_checksum.RequestStoreManifestFiles(manifest, artifact_id, save_fn)
|
156
153
|
self._incoming_queue.put(event)
|
157
154
|
|
158
155
|
def commit_artifact(
|