wandb 0.18.5__py3-none-macosx_11_0_arm64.whl → 0.18.7__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 +2 -2
- wandb/__init__.pyi +22 -20
- wandb/agents/pyagent.py +1 -1
- wandb/apis/importers/wandb.py +1 -1
- wandb/apis/normalize.py +2 -18
- wandb/apis/public/api.py +126 -62
- wandb/apis/public/artifacts.py +8 -3
- wandb/apis/public/files.py +17 -2
- wandb/apis/public/jobs.py +2 -2
- wandb/apis/public/query_generator.py +1 -1
- wandb/apis/public/runs.py +8 -8
- wandb/apis/public/teams.py +3 -3
- wandb/apis/public/users.py +1 -1
- wandb/apis/public/utils.py +68 -0
- wandb/bin/gpu_stats +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +12 -3
- wandb/data_types.py +1 -1
- wandb/docker/__init__.py +2 -1
- wandb/docker/auth.py +2 -3
- wandb/errors/links.py +73 -0
- wandb/errors/term.py +7 -6
- wandb/filesync/step_prepare.py +1 -1
- wandb/filesync/upload_job.py +1 -1
- wandb/integration/catboost/catboost.py +2 -2
- wandb/integration/diffusers/pipeline_resolver.py +1 -1
- wandb/integration/diffusers/resolvers/multimodal.py +6 -6
- wandb/integration/diffusers/resolvers/utils.py +1 -1
- wandb/integration/fastai/__init__.py +3 -2
- wandb/integration/keras/callbacks/metrics_logger.py +1 -1
- wandb/integration/keras/callbacks/model_checkpoint.py +1 -1
- wandb/integration/keras/keras.py +1 -1
- wandb/integration/kfp/kfp_patch.py +1 -1
- wandb/integration/lightgbm/__init__.py +2 -2
- wandb/integration/magic.py +2 -2
- wandb/integration/metaflow/metaflow.py +1 -1
- wandb/integration/sacred/__init__.py +1 -1
- wandb/integration/sagemaker/auth.py +1 -1
- wandb/integration/sklearn/plot/classifier.py +7 -7
- wandb/integration/sklearn/plot/clusterer.py +3 -3
- wandb/integration/sklearn/plot/regressor.py +3 -3
- wandb/integration/sklearn/plot/shared.py +2 -2
- wandb/integration/tensorboard/log.py +2 -2
- wandb/integration/ultralytics/callback.py +2 -2
- wandb/integration/xgboost/xgboost.py +1 -1
- wandb/jupyter.py +0 -1
- wandb/plot/__init__.py +17 -8
- wandb/plot/bar.py +53 -27
- wandb/plot/confusion_matrix.py +151 -70
- wandb/plot/custom_chart.py +124 -0
- wandb/plot/histogram.py +46 -20
- wandb/plot/line.py +57 -26
- wandb/plot/line_series.py +148 -60
- wandb/plot/pr_curve.py +89 -44
- wandb/plot/roc_curve.py +82 -37
- wandb/plot/scatter.py +53 -20
- wandb/plot/viz.py +20 -102
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
- wandb/proto/wandb_deprecated.py +2 -0
- wandb/sdk/artifacts/artifact.py +281 -329
- wandb/sdk/artifacts/artifact_manifest.py +10 -9
- wandb/sdk/artifacts/artifact_manifest_entry.py +1 -1
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +9 -4
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +1 -3
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +2 -2
- wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -1
- wandb/sdk/backend/backend.py +0 -1
- wandb/sdk/data_types/audio.py +1 -1
- wandb/sdk/data_types/base_types/media.py +66 -5
- wandb/sdk/data_types/base_types/wb_value.py +20 -10
- wandb/sdk/data_types/bokeh.py +1 -1
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -1
- wandb/sdk/data_types/helper_types/image_mask.py +2 -2
- wandb/sdk/data_types/histogram.py +1 -1
- wandb/sdk/data_types/html.py +1 -1
- wandb/sdk/data_types/image.py +1 -1
- wandb/sdk/data_types/molecule.py +3 -3
- wandb/sdk/data_types/object_3d.py +4 -4
- wandb/sdk/data_types/plotly.py +1 -1
- wandb/sdk/data_types/saved_model.py +0 -1
- wandb/sdk/data_types/table.py +7 -7
- wandb/sdk/data_types/trace_tree.py +1 -1
- wandb/sdk/data_types/video.py +4 -3
- wandb/sdk/interface/interface_queue.py +0 -6
- wandb/sdk/interface/router.py +1 -4
- wandb/sdk/interface/router_queue.py +0 -3
- wandb/sdk/interface/router_relay.py +0 -2
- wandb/sdk/internal/datastore.py +1 -1
- wandb/sdk/internal/file_pusher.py +1 -1
- wandb/sdk/internal/file_stream.py +4 -4
- wandb/sdk/internal/handler.py +3 -4
- wandb/sdk/internal/internal.py +1 -15
- wandb/sdk/internal/internal_api.py +178 -63
- wandb/sdk/internal/internal_util.py +0 -3
- wandb/sdk/internal/job_builder.py +4 -3
- wandb/sdk/internal/sender.py +0 -2
- wandb/sdk/internal/system/assets/__init__.py +0 -2
- wandb/sdk/internal/tb_watcher.py +11 -10
- wandb/sdk/internal/writer.py +1 -3
- wandb/sdk/launch/__init__.py +2 -1
- wandb/sdk/launch/_launch.py +4 -3
- wandb/sdk/launch/_launch_add.py +2 -2
- wandb/sdk/launch/builder/kaniko_builder.py +0 -1
- wandb/sdk/launch/create_job.py +1 -0
- wandb/sdk/launch/environment/local_environment.py +0 -1
- wandb/sdk/launch/errors.py +0 -6
- wandb/sdk/launch/registry/local_registry.py +0 -2
- wandb/sdk/launch/runner/abstract.py +0 -5
- wandb/sdk/launch/sweeps/__init__.py +0 -2
- wandb/sdk/launch/sweeps/scheduler.py +0 -2
- wandb/sdk/launch/sweeps/scheduler_sweep.py +0 -1
- wandb/sdk/lib/_settings_toposort_generated.py +1 -0
- wandb/sdk/lib/apikey.py +3 -3
- wandb/sdk/lib/file_stream_utils.py +1 -1
- wandb/sdk/lib/filesystem.py +1 -1
- wandb/sdk/lib/ipython.py +16 -9
- wandb/sdk/lib/mailbox.py +0 -4
- wandb/sdk/lib/printer.py +44 -8
- wandb/sdk/lib/retry.py +1 -1
- wandb/sdk/lib/sock_client.py +0 -5
- wandb/sdk/service/server.py +2 -11
- wandb/sdk/service/server_sock.py +0 -2
- wandb/sdk/service/service.py +3 -3
- wandb/sdk/service/streams.py +2 -4
- wandb/sdk/wandb_init.py +20 -20
- wandb/sdk/wandb_login.py +1 -1
- wandb/sdk/wandb_require.py +1 -4
- wandb/sdk/wandb_run.py +97 -115
- wandb/sdk/wandb_settings.py +23 -6
- wandb/sdk/wandb_setup.py +1 -5
- wandb/sdk/wandb_sync.py +2 -1
- wandb/util.py +49 -21
- wandb/wandb_agent.py +3 -3
- wandb/wandb_controller.py +2 -2
- {wandb-0.18.5.dist-info → wandb-0.18.7.dist-info}/METADATA +1 -1
- {wandb-0.18.5.dist-info → wandb-0.18.7.dist-info}/RECORD +145 -147
- wandb/sdk/internal/system/assets/gpu_apple.py +0 -177
- wandb/sdk/lib/_wburls_generate.py +0 -25
- wandb/sdk/lib/_wburls_generated.py +0 -22
- wandb/sdk/lib/tracelog.py +0 -255
- wandb/sdk/lib/wburls.py +0 -46
- {wandb-0.18.5.dist-info → wandb-0.18.7.dist-info}/WHEEL +0 -0
- {wandb-0.18.5.dist-info → wandb-0.18.7.dist-info}/entry_points.txt +0 -0
- {wandb-0.18.5.dist-info → wandb-0.18.7.dist-info}/licenses/LICENSE +0 -0
@@ -575,7 +575,7 @@ class FileStreamApi:
|
|
575
575
|
def push(self, filename: str, data: str) -> None:
|
576
576
|
"""Push a chunk of a file to the streaming endpoint.
|
577
577
|
|
578
|
-
|
578
|
+
Args:
|
579
579
|
filename: Name of file to append to.
|
580
580
|
data: Text to append to the file.
|
581
581
|
"""
|
@@ -584,7 +584,7 @@ class FileStreamApi:
|
|
584
584
|
def push_success(self, artifact_id: str, save_name: str) -> None:
|
585
585
|
"""Notification that a file upload has been successfully completed.
|
586
586
|
|
587
|
-
|
587
|
+
Args:
|
588
588
|
artifact_id: ID of artifact
|
589
589
|
save_name: saved name of the uploaded file
|
590
590
|
"""
|
@@ -595,7 +595,7 @@ class FileStreamApi:
|
|
595
595
|
|
596
596
|
Anything pushed after finish will be dropped.
|
597
597
|
|
598
|
-
|
598
|
+
Args:
|
599
599
|
exitcode: The exitcode of the watched process.
|
600
600
|
"""
|
601
601
|
logger.info("file stream finish called")
|
@@ -620,7 +620,7 @@ def request_with_retry(
|
|
620
620
|
) -> Union["requests.Response", "requests.RequestException"]:
|
621
621
|
"""Perform a requests http call, retrying with exponential backoff.
|
622
622
|
|
623
|
-
|
623
|
+
Args:
|
624
624
|
func: An http-requesting function to call, like requests.post
|
625
625
|
max_retries: Maximum retries before giving up.
|
626
626
|
By default, we retry 30 times in ~2 hours before dropping the chunk
|
wandb/sdk/internal/handler.py
CHANGED
@@ -21,6 +21,7 @@ from typing import (
|
|
21
21
|
cast,
|
22
22
|
)
|
23
23
|
|
24
|
+
from wandb.errors.links import url_registry
|
24
25
|
from wandb.proto.wandb_internal_pb2 import (
|
25
26
|
HistoryRecord,
|
26
27
|
InternalMessages,
|
@@ -37,7 +38,7 @@ from wandb.proto.wandb_internal_pb2 import (
|
|
37
38
|
)
|
38
39
|
|
39
40
|
from ..interface.interface_queue import InterfaceQueue
|
40
|
-
from ..lib import handler_util, proto_util
|
41
|
+
from ..lib import handler_util, proto_util
|
41
42
|
from . import context, sample, tb_watcher
|
42
43
|
from .settings_static import SettingsStatic
|
43
44
|
from .system.system_monitor import SystemMonitor
|
@@ -162,11 +163,9 @@ class HandleManager:
|
|
162
163
|
def _dispatch_record(self, record: Record, always_send: bool = False) -> None:
|
163
164
|
if always_send:
|
164
165
|
record.control.always_send = True
|
165
|
-
tracelog.log_message_queue(record, self._writer_q)
|
166
166
|
self._writer_q.put(record)
|
167
167
|
|
168
168
|
def _respond_result(self, result: Result) -> None:
|
169
|
-
tracelog.log_message_queue(result, self._result_q)
|
170
169
|
context_id = context.context_id_from_result(result)
|
171
170
|
self._context_keeper.release(context_id)
|
172
171
|
self._result_q.put(result)
|
@@ -578,7 +577,7 @@ class HandleManager:
|
|
578
577
|
if not self._dropped_history:
|
579
578
|
message = (
|
580
579
|
"Step only supports monotonically increasing values, use define_metric to set a custom x "
|
581
|
-
f"axis. For details see: {
|
580
|
+
f"axis. For details see: {url_registry.url('define-metric')}"
|
582
581
|
)
|
583
582
|
self._internal_messages.warning.append(message)
|
584
583
|
self._dropped_history = True
|
wandb/sdk/internal/internal.py
CHANGED
@@ -28,7 +28,6 @@ import psutil
|
|
28
28
|
import wandb
|
29
29
|
|
30
30
|
from ..interface.interface_queue import InterfaceQueue
|
31
|
-
from ..lib import tracelog
|
32
31
|
from . import context, handler, internal_util, sender, writer
|
33
32
|
|
34
33
|
if TYPE_CHECKING:
|
@@ -55,7 +54,7 @@ def wandb_internal(
|
|
55
54
|
|
56
55
|
Read from record queue and dispatch work to various threads.
|
57
56
|
|
58
|
-
|
57
|
+
Args:
|
59
58
|
settings: settings object
|
60
59
|
record_q: records to be handled
|
61
60
|
result_q: for sending results back
|
@@ -63,7 +62,6 @@ def wandb_internal(
|
|
63
62
|
"""
|
64
63
|
# mark this process as internal
|
65
64
|
wandb._set_internal_process() # type: ignore
|
66
|
-
_setup_tracelog()
|
67
65
|
started = time.time()
|
68
66
|
|
69
67
|
# any sentry events in the internal process will be tagged as such
|
@@ -88,8 +86,6 @@ def wandb_internal(
|
|
88
86
|
datetime.fromtimestamp(started),
|
89
87
|
)
|
90
88
|
|
91
|
-
tracelog.annotate_queue(record_q, "record_q")
|
92
|
-
tracelog.annotate_queue(result_q, "result_q")
|
93
89
|
publish_interface = InterfaceQueue(record_q=record_q)
|
94
90
|
|
95
91
|
stopped = threading.Event()
|
@@ -98,10 +94,8 @@ def wandb_internal(
|
|
98
94
|
context_keeper = context.ContextKeeper()
|
99
95
|
|
100
96
|
send_record_q: Queue[Record] = queue.Queue()
|
101
|
-
tracelog.annotate_queue(send_record_q, "send_q")
|
102
97
|
|
103
98
|
write_record_q: Queue[Record] = queue.Queue()
|
104
|
-
tracelog.annotate_queue(write_record_q, "write_q")
|
105
99
|
|
106
100
|
record_sender_thread = SenderThread(
|
107
101
|
settings=_settings,
|
@@ -184,14 +178,6 @@ def wandb_internal(
|
|
184
178
|
close_internal_log()
|
185
179
|
|
186
180
|
|
187
|
-
def _setup_tracelog() -> None:
|
188
|
-
# TODO: remove this temporary hack, need to find a better way to pass settings
|
189
|
-
# to the server. for now lets just look at the environment variable we need
|
190
|
-
tracelog_mode = os.environ.get("WANDB_TRACELOG")
|
191
|
-
if tracelog_mode:
|
192
|
-
tracelog.enable(tracelog_mode)
|
193
|
-
|
194
|
-
|
195
181
|
def configure_logging(
|
196
182
|
log_fname: str, log_level: int, run_id: Optional[str] = None
|
197
183
|
) -> None:
|
@@ -22,6 +22,7 @@ from typing import (
|
|
22
22
|
List,
|
23
23
|
Mapping,
|
24
24
|
MutableMapping,
|
25
|
+
NamedTuple,
|
25
26
|
Optional,
|
26
27
|
Sequence,
|
27
28
|
TextIO,
|
@@ -169,6 +170,50 @@ class _ThreadLocalData(threading.local):
|
|
169
170
|
self.context = None
|
170
171
|
|
171
172
|
|
173
|
+
class _OrgNames(NamedTuple):
|
174
|
+
entity_name: str
|
175
|
+
display_name: str
|
176
|
+
|
177
|
+
|
178
|
+
def _match_org_with_fetched_org_entities(
|
179
|
+
organization: str, orgs: Sequence[_OrgNames]
|
180
|
+
) -> str:
|
181
|
+
"""Match the organization provided in the path with the org entity or org name of the input entity.
|
182
|
+
|
183
|
+
Args:
|
184
|
+
organization: The organization name to match
|
185
|
+
orgs: List of tuples containing (org_entity_name, org_display_name)
|
186
|
+
|
187
|
+
Returns:
|
188
|
+
str: The matched org entity name
|
189
|
+
|
190
|
+
Raises:
|
191
|
+
ValueError: If no matching organization is found or if multiple orgs exist without a match
|
192
|
+
"""
|
193
|
+
for org_names in orgs:
|
194
|
+
if organization in org_names:
|
195
|
+
wandb.termwarn(
|
196
|
+
"Registries can be linked/fetched using a shorthand form without specifying the organization name. "
|
197
|
+
"Try using shorthand path format: <my_registry_name>/<artifact_name> or "
|
198
|
+
"just <my_registry_name> if fetching just the project."
|
199
|
+
)
|
200
|
+
return org_names.entity_name
|
201
|
+
|
202
|
+
if len(orgs) == 1:
|
203
|
+
raise ValueError(
|
204
|
+
f"Expecting the organization name or entity name to match {orgs[0].display_name!r} "
|
205
|
+
f"and cannot be linked/fetched with {organization!r}. "
|
206
|
+
"Please update the target path with the correct organization name."
|
207
|
+
)
|
208
|
+
|
209
|
+
raise ValueError(
|
210
|
+
"Personal entity belongs to multiple organizations "
|
211
|
+
f"and cannot be linked/fetched with {organization!r}. "
|
212
|
+
"Please update the target path with the correct organization name "
|
213
|
+
"or use a team entity in the entity settings."
|
214
|
+
)
|
215
|
+
|
216
|
+
|
172
217
|
class Api:
|
173
218
|
"""W&B Internal Api wrapper.
|
174
219
|
|
@@ -178,7 +223,7 @@ class Api:
|
|
178
223
|
directory. If none can be found, we look in the current user's home
|
179
224
|
directory.
|
180
225
|
|
181
|
-
|
226
|
+
Args:
|
182
227
|
default_settings(dict, optional): If you aren't using a settings
|
183
228
|
file, or you wish to override the section to use in the settings file
|
184
229
|
Override the settings here.
|
@@ -313,6 +358,7 @@ class Api:
|
|
313
358
|
self.server_create_artifact_input_info: Optional[List[str]] = None
|
314
359
|
self.server_artifact_fields_info: Optional[List[str]] = None
|
315
360
|
self.server_organization_type_fields_info: Optional[List[str]] = None
|
361
|
+
self.server_supports_enabling_artifact_usage_tracking: Optional[bool] = None
|
316
362
|
self._max_cli_version: Optional[str] = None
|
317
363
|
self._server_settings_type: Optional[List[str]] = None
|
318
364
|
self.fail_run_queue_item_input_info: Optional[List[str]] = None
|
@@ -434,7 +480,7 @@ class Api:
|
|
434
480
|
def settings(self, key: Optional[str] = None, section: Optional[str] = None) -> Any:
|
435
481
|
"""The settings overridden from the wandb/settings file.
|
436
482
|
|
437
|
-
|
483
|
+
Args:
|
438
484
|
key (str, optional): If provided only this setting is returned
|
439
485
|
section (str, optional): If provided this section of the setting file is
|
440
486
|
used, defaults to "default"
|
@@ -514,7 +560,7 @@ class Api:
|
|
514
560
|
) -> Tuple[str, str]:
|
515
561
|
"""Parse a slug into a project and run.
|
516
562
|
|
517
|
-
|
563
|
+
Args:
|
518
564
|
slug (str): The slug to parse
|
519
565
|
project (str, optional): The project to use, if not provided it will be
|
520
566
|
inferred from the slug
|
@@ -953,7 +999,7 @@ class Api:
|
|
953
999
|
def list_projects(self, entity: Optional[str] = None) -> List[Dict[str, str]]:
|
954
1000
|
"""List projects in W&B scoped by entity.
|
955
1001
|
|
956
|
-
|
1002
|
+
Args:
|
957
1003
|
entity (str, optional): The entity to scope this project to.
|
958
1004
|
|
959
1005
|
Returns:
|
@@ -985,7 +1031,7 @@ class Api:
|
|
985
1031
|
def project(self, project: str, entity: Optional[str] = None) -> "_Response":
|
986
1032
|
"""Retrieve project.
|
987
1033
|
|
988
|
-
|
1034
|
+
Args:
|
989
1035
|
project (str): The project to get details for
|
990
1036
|
entity (str, optional): The entity to scope this project to.
|
991
1037
|
|
@@ -1020,7 +1066,7 @@ class Api:
|
|
1020
1066
|
) -> Dict[str, Any]:
|
1021
1067
|
"""Retrieve sweep.
|
1022
1068
|
|
1023
|
-
|
1069
|
+
Args:
|
1024
1070
|
sweep (str): The sweep to get details for
|
1025
1071
|
specs (str): history specs
|
1026
1072
|
project (str, optional): The project to scope this sweep to.
|
@@ -1093,7 +1139,7 @@ class Api:
|
|
1093
1139
|
) -> List[Dict[str, str]]:
|
1094
1140
|
"""List runs in W&B scoped by project.
|
1095
1141
|
|
1096
|
-
|
1142
|
+
Args:
|
1097
1143
|
project (str): The project to scope the runs to
|
1098
1144
|
entity (str, optional): The entity to scope this project to. Defaults to public models
|
1099
1145
|
|
@@ -1134,7 +1180,7 @@ class Api:
|
|
1134
1180
|
) -> Tuple[str, Dict[str, Any], Optional[str], Dict[str, Any]]:
|
1135
1181
|
"""Get the relevant configs for a run.
|
1136
1182
|
|
1137
|
-
|
1183
|
+
Args:
|
1138
1184
|
project (str): The project to download, (can include bucket)
|
1139
1185
|
run (str, optional): The run to download
|
1140
1186
|
entity (str, optional): The entity to scope this project to.
|
@@ -1223,7 +1269,7 @@ class Api:
|
|
1223
1269
|
) -> Optional[Dict[str, Any]]:
|
1224
1270
|
"""Check if a run exists and get resume information.
|
1225
1271
|
|
1226
|
-
|
1272
|
+
Args:
|
1227
1273
|
entity (str): The entity to scope this project to.
|
1228
1274
|
project_name (str): The project to download, (can include bucket)
|
1229
1275
|
name (str): The run to download
|
@@ -1328,7 +1374,7 @@ class Api:
|
|
1328
1374
|
) -> Dict[str, Any]:
|
1329
1375
|
"""Create a new project.
|
1330
1376
|
|
1331
|
-
|
1377
|
+
Args:
|
1332
1378
|
project (str): The project to create
|
1333
1379
|
description (str, optional): A description of this project
|
1334
1380
|
entity (str, optional): The entity to scope this project to.
|
@@ -2156,7 +2202,7 @@ class Api:
|
|
2156
2202
|
) -> Tuple[dict, bool, Optional[List]]:
|
2157
2203
|
"""Update a run.
|
2158
2204
|
|
2159
|
-
|
2205
|
+
Args:
|
2160
2206
|
id (str, optional): The existing run to update
|
2161
2207
|
name (str, optional): The name of the run to create
|
2162
2208
|
group (str, optional): Name of the group this run is a part of
|
@@ -2343,7 +2389,7 @@ class Api:
|
|
2343
2389
|
) -> dict:
|
2344
2390
|
"""Rewinds a run to a previous state.
|
2345
2391
|
|
2346
|
-
|
2392
|
+
Args:
|
2347
2393
|
run_name (str): The name of the run to rewind
|
2348
2394
|
metric_name (str): The name of the metric to rewind to
|
2349
2395
|
metric_value (float): The value of the metric to rewind to
|
@@ -2530,7 +2576,7 @@ class Api:
|
|
2530
2576
|
) -> Tuple[str, List[str], Dict[str, Dict[str, Any]]]:
|
2531
2577
|
"""Generate temporary resumable upload urls.
|
2532
2578
|
|
2533
|
-
|
2579
|
+
Args:
|
2534
2580
|
project (str): The project to download
|
2535
2581
|
files (list or dict): The filenames to upload
|
2536
2582
|
run (str, optional): The run to upload to
|
@@ -2667,7 +2713,7 @@ class Api:
|
|
2667
2713
|
) -> Dict[str, Dict[str, str]]:
|
2668
2714
|
"""Generate download urls.
|
2669
2715
|
|
2670
|
-
|
2716
|
+
Args:
|
2671
2717
|
project (str): The project to download
|
2672
2718
|
run (str): The run to upload to
|
2673
2719
|
entity (str, optional): The entity to scope this project to. Defaults to wandb models
|
@@ -2726,7 +2772,7 @@ class Api:
|
|
2726
2772
|
) -> Optional[Dict[str, str]]:
|
2727
2773
|
"""Generate download urls.
|
2728
2774
|
|
2729
|
-
|
2775
|
+
Args:
|
2730
2776
|
project (str): The project to download
|
2731
2777
|
file_name (str): The name of the file to download
|
2732
2778
|
run (str): The run to upload to
|
@@ -2779,7 +2825,7 @@ class Api:
|
|
2779
2825
|
def download_file(self, url: str) -> Tuple[int, requests.Response]:
|
2780
2826
|
"""Initiate a streaming download.
|
2781
2827
|
|
2782
|
-
|
2828
|
+
Args:
|
2783
2829
|
url (str): The url to download
|
2784
2830
|
|
2785
2831
|
Returns:
|
@@ -2813,7 +2859,7 @@ class Api:
|
|
2813
2859
|
) -> Tuple[str, Optional[requests.Response]]:
|
2814
2860
|
"""Download a file from a run and write it to wandb/.
|
2815
2861
|
|
2816
|
-
|
2862
|
+
Args:
|
2817
2863
|
metadata (obj): The metadata object for the file to download. Comes from Api.download_urls().
|
2818
2864
|
out_dir (str, optional): The directory to write the file to. Defaults to wandb/
|
2819
2865
|
|
@@ -2877,7 +2923,7 @@ class Api:
|
|
2877
2923
|
) -> Optional[requests.Response]:
|
2878
2924
|
"""Upload a file chunk to S3 with failure resumption.
|
2879
2925
|
|
2880
|
-
|
2926
|
+
Args:
|
2881
2927
|
url: The url to download
|
2882
2928
|
upload_chunk: The path to the file you want to upload
|
2883
2929
|
extra_headers: A dictionary of extra headers to send with the request
|
@@ -2930,7 +2976,7 @@ class Api:
|
|
2930
2976
|
) -> Optional[requests.Response]:
|
2931
2977
|
"""Upload a file to W&B with failure resumption.
|
2932
2978
|
|
2933
|
-
|
2979
|
+
Args:
|
2934
2980
|
url: The url to download
|
2935
2981
|
file: The path to the file you want to upload
|
2936
2982
|
callback: A callback which is passed the number of
|
@@ -3002,7 +3048,7 @@ class Api:
|
|
3002
3048
|
) -> dict:
|
3003
3049
|
"""Register a new agent.
|
3004
3050
|
|
3005
|
-
|
3051
|
+
Args:
|
3006
3052
|
host (str): hostname
|
3007
3053
|
sweep_id (str): sweep id
|
3008
3054
|
project_name: (str): model that contains sweep
|
@@ -3052,7 +3098,7 @@ class Api:
|
|
3052
3098
|
) -> List[Dict[str, Any]]:
|
3053
3099
|
"""Notify server about agent state, receive commands.
|
3054
3100
|
|
3055
|
-
|
3101
|
+
Args:
|
3056
3102
|
agent_id (str): agent_id
|
3057
3103
|
metrics (dict): system metrics
|
3058
3104
|
run_states (dict): run_id: state mapping
|
@@ -3161,7 +3207,7 @@ class Api:
|
|
3161
3207
|
) -> Tuple[str, List[str]]:
|
3162
3208
|
"""Upsert a sweep object.
|
3163
3209
|
|
3164
|
-
|
3210
|
+
Args:
|
3165
3211
|
config (dict): sweep config (will be converted to yaml)
|
3166
3212
|
controller (str): controller to use
|
3167
3213
|
launch_scheduler (str): launch scheduler to use
|
@@ -3342,7 +3388,7 @@ class Api:
|
|
3342
3388
|
) -> "List[requests.Response]":
|
3343
3389
|
"""Download files from W&B.
|
3344
3390
|
|
3345
|
-
|
3391
|
+
Args:
|
3346
3392
|
project (str): The project to download
|
3347
3393
|
run (str, optional): The run to upload to
|
3348
3394
|
entity (str, optional): The entity to scope this project to. Defaults to wandb models
|
@@ -3377,7 +3423,7 @@ class Api:
|
|
3377
3423
|
) -> "List[Optional[requests.Response]]":
|
3378
3424
|
"""Uploads multiple files to W&B.
|
3379
3425
|
|
3380
|
-
|
3426
|
+
Args:
|
3381
3427
|
files (list or dict): The filenames to upload, when dict the values are open files
|
3382
3428
|
run (str, optional): The run to upload to
|
3383
3429
|
entity (str, optional): The entity to scope this project to. Defaults to wandb models
|
@@ -3496,7 +3542,9 @@ class Api:
|
|
3496
3542
|
org_entity = ""
|
3497
3543
|
if is_artifact_registry_project(project):
|
3498
3544
|
try:
|
3499
|
-
org_entity = self._resolve_org_entity_name(
|
3545
|
+
org_entity = self._resolve_org_entity_name(
|
3546
|
+
entity=entity, organization=organization
|
3547
|
+
)
|
3500
3548
|
except ValueError as e:
|
3501
3549
|
wandb.termerror(str(e))
|
3502
3550
|
raise
|
@@ -3538,47 +3586,67 @@ class Api:
|
|
3538
3586
|
# the organization parameter, or an error if it is empty. Otherwise, this returns the
|
3539
3587
|
# fetched value after validating that the given organization, if not empty, matches
|
3540
3588
|
# either the org's display or entity name.
|
3589
|
+
|
3590
|
+
if not entity:
|
3591
|
+
raise ValueError("Entity name is required to resolve org entity name.")
|
3592
|
+
|
3541
3593
|
org_fields = self.server_organization_type_introspection()
|
3542
|
-
|
3543
|
-
if not organization and not
|
3594
|
+
can_shorthand_org_entity = "orgEntity" in org_fields
|
3595
|
+
if not organization and not can_shorthand_org_entity:
|
3544
3596
|
raise ValueError(
|
3545
3597
|
"Fetching Registry artifacts without inputting an organization "
|
3546
3598
|
"is unavailable for your server version. "
|
3547
3599
|
"Please upgrade your server to 0.50.0 or later."
|
3548
3600
|
)
|
3549
|
-
if not
|
3601
|
+
if not can_shorthand_org_entity:
|
3550
3602
|
# Server doesn't support fetching org entity to validate,
|
3551
3603
|
# assume org entity is correctly inputted
|
3552
3604
|
return organization
|
3553
3605
|
|
3554
|
-
|
3606
|
+
orgs_from_entity = self._fetch_orgs_and_org_entities_from_entity(entity)
|
3555
3607
|
if organization:
|
3556
|
-
|
3557
|
-
|
3558
|
-
|
3559
|
-
|
3560
|
-
|
3561
|
-
|
3562
|
-
|
3563
|
-
"
|
3564
|
-
"
|
3608
|
+
return _match_org_with_fetched_org_entities(organization, orgs_from_entity)
|
3609
|
+
|
3610
|
+
# If no input organization provided, error if entity belongs to multiple orgs because we
|
3611
|
+
# cannot determine which one to use.
|
3612
|
+
if len(orgs_from_entity) > 1:
|
3613
|
+
raise ValueError(
|
3614
|
+
f"Personal entity {entity!r} belongs to multiple organizations "
|
3615
|
+
"and cannot be used without specifying the organization name. "
|
3616
|
+
"Please specify the organization in the Registry path or use a team entity in the entity settings."
|
3565
3617
|
)
|
3566
|
-
return
|
3618
|
+
return orgs_from_entity[0].entity_name
|
3619
|
+
|
3620
|
+
def _fetch_orgs_and_org_entities_from_entity(self, entity: str) -> List[_OrgNames]:
|
3621
|
+
"""Fetches organization entity names and display names for a given entity.
|
3567
3622
|
|
3568
|
-
|
3623
|
+
Args:
|
3624
|
+
entity (str): Entity name to lookup. Can be either a personal or team entity.
|
3625
|
+
|
3626
|
+
Returns:
|
3627
|
+
List[_OrgNames]: List of _OrgNames tuples. (_OrgNames(entity_name, display_name))
|
3628
|
+
|
3629
|
+
Raises:
|
3630
|
+
ValueError: If entity is not found, has no organizations, or other validation errors.
|
3631
|
+
"""
|
3569
3632
|
query = gql(
|
3570
3633
|
"""
|
3571
|
-
query FetchOrgEntityFromEntity(
|
3572
|
-
$entityName: String!,
|
3573
|
-
) {
|
3634
|
+
query FetchOrgEntityFromEntity($entityName: String!) {
|
3574
3635
|
entity(name: $entityName) {
|
3575
|
-
isTeam
|
3576
3636
|
organization {
|
3577
3637
|
name
|
3578
3638
|
orgEntity {
|
3579
3639
|
name
|
3580
3640
|
}
|
3581
3641
|
}
|
3642
|
+
user {
|
3643
|
+
organizations {
|
3644
|
+
name
|
3645
|
+
orgEntity {
|
3646
|
+
name
|
3647
|
+
}
|
3648
|
+
}
|
3649
|
+
}
|
3582
3650
|
}
|
3583
3651
|
}
|
3584
3652
|
"""
|
@@ -3589,28 +3657,40 @@ class Api:
|
|
3589
3657
|
"entityName": entity,
|
3590
3658
|
},
|
3591
3659
|
)
|
3592
|
-
|
3593
|
-
|
3594
|
-
|
3595
|
-
|
3596
|
-
|
3597
|
-
|
3598
|
-
|
3599
|
-
|
3660
|
+
|
3661
|
+
# Parse organization from response
|
3662
|
+
entity_resp = response["entity"]["organization"]
|
3663
|
+
user_resp = response["entity"]["user"]
|
3664
|
+
# Check for organization under team/org entity type
|
3665
|
+
if entity_resp:
|
3666
|
+
org_name = entity_resp.get("name")
|
3667
|
+
org_entity_name = entity_resp.get("orgEntity") and entity_resp[
|
3668
|
+
"orgEntity"
|
3669
|
+
].get("name")
|
3670
|
+
if not org_name or not org_entity_name:
|
3600
3671
|
raise ValueError(
|
3601
|
-
f"Unable to find an organization under entity {entity!r}.
|
3602
|
-
)
|
3603
|
-
|
3672
|
+
f"Unable to find an organization under entity {entity!r}."
|
3673
|
+
)
|
3674
|
+
return [_OrgNames(entity_name=org_entity_name, display_name=org_name)]
|
3675
|
+
# Check for organization under personal entity type, where a user can belong to multiple orgs
|
3676
|
+
elif user_resp:
|
3677
|
+
orgs = user_resp.get("organizations", [])
|
3678
|
+
org_entities_return = [
|
3679
|
+
_OrgNames(
|
3680
|
+
entity_name=org["orgEntity"]["name"], display_name=org["name"]
|
3681
|
+
)
|
3682
|
+
for org in orgs
|
3683
|
+
if org.get("orgEntity") and org.get("name")
|
3684
|
+
]
|
3685
|
+
if not org_entities_return:
|
3604
3686
|
raise ValueError(
|
3605
|
-
f"Unable to resolve an organization associated with
|
3606
|
-
"
|
3607
|
-
|
3608
|
-
|
3609
|
-
|
3610
|
-
"or wandb.init(entity='<my_team_entity>') "
|
3611
|
-
) from e
|
3687
|
+
f"Unable to resolve an organization associated with personal entity: {entity!r}. "
|
3688
|
+
"This could be because its a personal entity that doesn't belong to any organizations. "
|
3689
|
+
"Please specify the organization in the Registry path or use a team entity in the entity settings."
|
3690
|
+
)
|
3691
|
+
return org_entities_return
|
3612
3692
|
else:
|
3613
|
-
|
3693
|
+
raise ValueError(f"Unable to find an organization under entity {entity!r}.")
|
3614
3694
|
|
3615
3695
|
def use_artifact(
|
3616
3696
|
self,
|
@@ -3701,6 +3781,41 @@ class Api:
|
|
3701
3781
|
|
3702
3782
|
return self.server_organization_type_fields_info
|
3703
3783
|
|
3784
|
+
# Fetch input arguments for the "artifact" endpoint on the "Project" type
|
3785
|
+
def server_project_type_introspection(self) -> bool:
|
3786
|
+
if self.server_supports_enabling_artifact_usage_tracking is not None:
|
3787
|
+
return self.server_supports_enabling_artifact_usage_tracking
|
3788
|
+
|
3789
|
+
query_string = """
|
3790
|
+
query ProbeServerProjectInfo {
|
3791
|
+
ProjectInfoType: __type(name:"Project") {
|
3792
|
+
fields {
|
3793
|
+
name
|
3794
|
+
args {
|
3795
|
+
name
|
3796
|
+
}
|
3797
|
+
}
|
3798
|
+
}
|
3799
|
+
}
|
3800
|
+
"""
|
3801
|
+
|
3802
|
+
query = gql(query_string)
|
3803
|
+
res = self.gql(query)
|
3804
|
+
input_fields = res.get("ProjectInfoType", {}).get("fields", [{}])
|
3805
|
+
artifact_args: List[Dict[str, str]] = next(
|
3806
|
+
(
|
3807
|
+
field.get("args", [])
|
3808
|
+
for field in input_fields
|
3809
|
+
if field.get("name") == "artifact"
|
3810
|
+
),
|
3811
|
+
[],
|
3812
|
+
)
|
3813
|
+
self.server_supports_enabling_artifact_usage_tracking = any(
|
3814
|
+
arg.get("name") == "enableTracking" for arg in artifact_args
|
3815
|
+
)
|
3816
|
+
|
3817
|
+
return self.server_supports_enabling_artifact_usage_tracking
|
3818
|
+
|
3704
3819
|
def create_artifact_type(
|
3705
3820
|
self,
|
3706
3821
|
artifact_type_name: str,
|
@@ -11,8 +11,6 @@ import threading
|
|
11
11
|
import time
|
12
12
|
from typing import TYPE_CHECKING, Optional, Tuple, Type, Union
|
13
13
|
|
14
|
-
from ..lib import tracelog
|
15
|
-
|
16
14
|
if TYPE_CHECKING:
|
17
15
|
from queue import Queue
|
18
16
|
from threading import Event
|
@@ -95,6 +93,5 @@ class RecordLoopThread(ExceptionThread):
|
|
95
93
|
record = self._input_record_q.get(timeout=1)
|
96
94
|
except queue.Empty:
|
97
95
|
continue
|
98
|
-
tracelog.log_message_dequeue(record, self._input_record_q)
|
99
96
|
self._process(record)
|
100
97
|
self._finish()
|
@@ -313,7 +313,8 @@ class JobBuilder:
|
|
313
313
|
"build_context": metadata.get("build_context"),
|
314
314
|
"dockerfile": metadata.get("dockerfile"),
|
315
315
|
}
|
316
|
-
|
316
|
+
artifact_basename, *_ = self._logged_code_artifact["name"].split(":")
|
317
|
+
name = self._make_job_name(artifact_basename)
|
317
318
|
|
318
319
|
return source, name
|
319
320
|
|
@@ -380,7 +381,7 @@ class JobBuilder:
|
|
380
381
|
]:
|
381
382
|
"""Construct a job source dict and name from the current run.
|
382
383
|
|
383
|
-
|
384
|
+
Args:
|
384
385
|
source_type (str): The type of source to build the job from. One of
|
385
386
|
"repo", "artifact", or "image".
|
386
387
|
"""
|
@@ -427,7 +428,7 @@ class JobBuilder:
|
|
427
428
|
) -> Optional[Artifact]:
|
428
429
|
"""Build a job artifact from the current run.
|
429
430
|
|
430
|
-
|
431
|
+
Args:
|
431
432
|
api (Api): The API object to use to create the job artifact.
|
432
433
|
build_context (Optional[str]): Path within the job source code to
|
433
434
|
the image build context. Saved as part of the job for future
|
wandb/sdk/internal/sender.py
CHANGED
@@ -53,7 +53,6 @@ from wandb.sdk.lib import (
|
|
53
53
|
proto_util,
|
54
54
|
redirect,
|
55
55
|
telemetry,
|
56
|
-
tracelog,
|
57
56
|
)
|
58
57
|
from wandb.sdk.lib.mailbox import ContextCancelledError
|
59
58
|
from wandb.sdk.lib.proto_util import message_to_dict
|
@@ -418,7 +417,6 @@ class SendManager:
|
|
418
417
|
send_handler(record)
|
419
418
|
|
420
419
|
def _respond_result(self, result: "Result") -> None:
|
421
|
-
tracelog.log_message_queue(result, self._result_q)
|
422
420
|
context_id = context.context_id_from_result(result)
|
423
421
|
self._context_keeper.release(context_id)
|
424
422
|
self._result_q.put(result)
|