wandb 0.20.2rc20250616__py3-none-win_amd64.whl → 0.21.1__py3-none-win_amd64.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.
- wandb/__init__.py +16 -14
- wandb/__init__.pyi +450 -472
- wandb/agents/pyagent.py +41 -12
- wandb/analytics/sentry.py +7 -2
- wandb/apis/importers/mlflow.py +1 -1
- wandb/apis/internal.py +3 -0
- wandb/apis/paginator.py +17 -4
- wandb/apis/public/__init__.py +1 -1
- wandb/apis/public/api.py +606 -359
- wandb/apis/public/artifacts.py +214 -16
- wandb/apis/public/automations.py +19 -3
- wandb/apis/public/files.py +177 -38
- wandb/apis/public/history.py +67 -15
- wandb/apis/public/integrations.py +25 -2
- wandb/apis/public/jobs.py +90 -2
- wandb/apis/public/projects.py +161 -69
- wandb/apis/public/query_generator.py +11 -1
- wandb/apis/public/registries/registries_search.py +7 -15
- wandb/apis/public/reports.py +147 -13
- wandb/apis/public/runs.py +315 -128
- wandb/apis/public/sweeps.py +222 -22
- wandb/apis/public/teams.py +41 -4
- wandb/apis/public/users.py +45 -4
- wandb/automations/__init__.py +10 -10
- wandb/automations/_filters/run_metrics.py +0 -2
- wandb/automations/_utils.py +0 -2
- wandb/automations/actions.py +0 -2
- wandb/automations/automations.py +0 -2
- wandb/automations/events.py +0 -2
- wandb/beta/workflows.py +66 -30
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +80 -1
- wandb/env.py +8 -0
- wandb/errors/errors.py +4 -1
- wandb/integration/catboost/catboost.py +6 -2
- wandb/integration/kfp/kfp_patch.py +3 -1
- wandb/integration/lightning/fabric/logger.py +3 -4
- wandb/integration/metaflow/__init__.py +6 -0
- wandb/integration/metaflow/data_pandas.py +74 -0
- wandb/integration/metaflow/errors.py +13 -0
- wandb/integration/metaflow/metaflow.py +205 -190
- wandb/integration/openai/fine_tuning.py +1 -2
- wandb/integration/sb3/sb3.py +3 -3
- wandb/integration/ultralytics/callback.py +6 -2
- wandb/jupyter.py +5 -5
- wandb/plot/__init__.py +2 -0
- wandb/plot/bar.py +30 -29
- wandb/plot/confusion_matrix.py +75 -71
- wandb/plot/custom_chart.py +30 -7
- wandb/plot/histogram.py +26 -25
- wandb/plot/line.py +33 -32
- wandb/plot/line_series.py +100 -103
- wandb/plot/pr_curve.py +33 -32
- wandb/plot/roc_curve.py +38 -38
- wandb/plot/scatter.py +27 -27
- wandb/proto/v3/wandb_internal_pb2.py +366 -385
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v4/wandb_internal_pb2.py +352 -356
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v5/wandb_internal_pb2.py +352 -356
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v6/wandb_internal_pb2.py +352 -356
- wandb/proto/v6/wandb_settings_pb2.py +2 -2
- wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
- wandb/proto/wandb_deprecated.py +6 -0
- wandb/sdk/artifacts/_generated/__init__.py +12 -1
- wandb/sdk/artifacts/_generated/input_types.py +20 -2
- wandb/sdk/artifacts/_generated/link_artifact.py +21 -0
- wandb/sdk/artifacts/_generated/operations.py +9 -0
- wandb/sdk/artifacts/_internal_artifact.py +19 -8
- wandb/sdk/artifacts/_validators.py +48 -2
- wandb/sdk/artifacts/artifact.py +269 -96
- wandb/sdk/data_types/audio.py +38 -10
- wandb/sdk/data_types/base_types/media.py +15 -63
- wandb/sdk/data_types/base_types/wb_value.py +6 -6
- wandb/sdk/data_types/graph.py +48 -14
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
- wandb/sdk/data_types/helper_types/image_mask.py +1 -3
- wandb/sdk/data_types/histogram.py +34 -21
- wandb/sdk/data_types/html.py +35 -12
- wandb/sdk/data_types/image.py +104 -68
- wandb/sdk/data_types/molecule.py +32 -19
- wandb/sdk/data_types/object_3d.py +36 -17
- wandb/sdk/data_types/plotly.py +18 -5
- wandb/sdk/data_types/saved_model.py +7 -9
- wandb/sdk/data_types/table.py +99 -70
- wandb/sdk/data_types/trace_tree.py +12 -12
- wandb/sdk/data_types/video.py +53 -26
- wandb/sdk/integration_utils/auto_logging.py +2 -2
- wandb/sdk/interface/interface.py +8 -19
- wandb/sdk/interface/interface_shared.py +7 -16
- wandb/sdk/internal/datastore.py +18 -18
- wandb/sdk/internal/handler.py +3 -5
- wandb/sdk/internal/internal_api.py +60 -0
- wandb/sdk/internal/job_builder.py +6 -0
- wandb/sdk/internal/sender.py +23 -3
- wandb/sdk/internal/sender_config.py +9 -0
- wandb/sdk/launch/_project_spec.py +3 -3
- wandb/sdk/launch/agent/agent.py +11 -4
- wandb/sdk/launch/agent/job_status_tracker.py +3 -1
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
- wandb/sdk/launch/create_job.py +3 -1
- wandb/sdk/launch/inputs/internal.py +3 -4
- wandb/sdk/launch/inputs/schema.py +1 -0
- wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +328 -1
- wandb/sdk/launch/sweeps/scheduler.py +2 -3
- wandb/sdk/launch/utils.py +3 -3
- wandb/sdk/lib/asyncio_compat.py +3 -0
- wandb/sdk/lib/console_capture.py +66 -19
- wandb/sdk/lib/deprecate.py +1 -7
- wandb/sdk/lib/disabled.py +1 -1
- wandb/sdk/lib/hashutil.py +14 -1
- wandb/sdk/lib/module.py +7 -13
- wandb/sdk/lib/progress.py +0 -19
- wandb/sdk/lib/sock_client.py +0 -4
- wandb/sdk/wandb_init.py +67 -93
- wandb/sdk/wandb_login.py +18 -14
- wandb/sdk/wandb_metric.py +2 -0
- wandb/sdk/wandb_require.py +0 -1
- wandb/sdk/wandb_run.py +429 -527
- wandb/sdk/wandb_settings.py +364 -74
- wandb/sdk/wandb_setup.py +28 -28
- wandb/sdk/wandb_sweep.py +14 -13
- wandb/sdk/wandb_watch.py +4 -6
- wandb/sync/sync.py +10 -0
- wandb/util.py +57 -0
- wandb/wandb_run.py +1 -2
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/METADATA +1 -1
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/RECORD +137 -137
- wandb/sdk/wandb_metadata.py +0 -623
- wandb/vendor/pynvml/__init__.py +0 -0
- wandb/vendor/pynvml/pynvml.py +0 -4779
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/WHEEL +0 -0
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/licenses/LICENSE +0 -0
wandb/apis/public/api.py
CHANGED
@@ -51,6 +51,7 @@ from wandb.apis.public.utils import (
|
|
51
51
|
)
|
52
52
|
from wandb.proto.wandb_deprecated import Deprecated
|
53
53
|
from wandb.proto.wandb_internal_pb2 import ServerFeature
|
54
|
+
from wandb.sdk import wandb_login
|
54
55
|
from wandb.sdk.artifacts._validators import is_artifact_registry_project
|
55
56
|
from wandb.sdk.internal.internal_api import Api as InternalApi
|
56
57
|
from wandb.sdk.internal.thread_local_settings import _thread_local_api_settings
|
@@ -75,6 +76,11 @@ logger = logging.getLogger(__name__)
|
|
75
76
|
|
76
77
|
|
77
78
|
class RetryingClient:
|
79
|
+
"""A GraphQL client that retries requests on failure.
|
80
|
+
|
81
|
+
<!-- lazydoc-ignore-class: internal -->
|
82
|
+
"""
|
83
|
+
|
78
84
|
INFO_QUERY = gql(
|
79
85
|
"""
|
80
86
|
query ServerInfo{
|
@@ -135,16 +141,14 @@ class RetryingClient:
|
|
135
141
|
|
136
142
|
|
137
143
|
class Api:
|
138
|
-
"""Used for querying the
|
144
|
+
"""Used for querying the W&B server.
|
139
145
|
|
140
146
|
Examples:
|
141
|
-
|
142
|
-
|
147
|
+
```python
|
148
|
+
import wandb
|
143
149
|
|
144
|
-
|
145
|
-
|
146
|
-
other than https://api.wandb.ai.
|
147
|
-
You can also set defaults for `entity`, `project`, and `run`.
|
150
|
+
wandb.Api()
|
151
|
+
```
|
148
152
|
"""
|
149
153
|
|
150
154
|
_HTTP_TIMEOUT = env.get_http_timeout(19)
|
@@ -275,6 +279,17 @@ class Api:
|
|
275
279
|
timeout: Optional[int] = None,
|
276
280
|
api_key: Optional[str] = None,
|
277
281
|
) -> None:
|
282
|
+
"""Initialize the API.
|
283
|
+
|
284
|
+
Args:
|
285
|
+
overrides: You can set `base_url` if you are
|
286
|
+
using a W&B server other than `https://api.wandb.ai`. You can also
|
287
|
+
set defaults for `entity`, `project`, and `run`.
|
288
|
+
timeout: HTTP timeout in seconds for API requests. If not
|
289
|
+
specified, the default timeout will be used.
|
290
|
+
api_key: API key to use for authentication. If not provided,
|
291
|
+
the API key from the current environment or configuration will be used.
|
292
|
+
"""
|
278
293
|
self.settings = InternalApi().settings()
|
279
294
|
|
280
295
|
_overrides = overrides or {}
|
@@ -289,8 +304,18 @@ class Api:
|
|
289
304
|
self.settings["entity"] = _overrides["username"]
|
290
305
|
|
291
306
|
self._api_key = api_key
|
292
|
-
if
|
293
|
-
|
307
|
+
if _thread_local_api_settings.cookies is None:
|
308
|
+
wandb_login._login(
|
309
|
+
host=self.settings["base_url"],
|
310
|
+
key=self.api_key,
|
311
|
+
verify=True,
|
312
|
+
_silent=(
|
313
|
+
self.settings.get("silent", False)
|
314
|
+
or self.settings.get("quiet", False)
|
315
|
+
),
|
316
|
+
update_api_key=False,
|
317
|
+
_disable_warning=True,
|
318
|
+
)
|
294
319
|
|
295
320
|
self._viewer = None
|
296
321
|
self._projects = {}
|
@@ -323,13 +348,32 @@ class Api:
|
|
323
348
|
)
|
324
349
|
)
|
325
350
|
self._client = RetryingClient(self._base_client)
|
351
|
+
self._sentry = wandb.analytics.sentry.Sentry()
|
352
|
+
self._configure_sentry()
|
353
|
+
|
354
|
+
def _configure_sentry(self) -> None:
|
355
|
+
try:
|
356
|
+
viewer = self.viewer
|
357
|
+
except (ValueError, requests.RequestException):
|
358
|
+
# we need the viewer to configure the entity, and user email
|
359
|
+
return
|
360
|
+
|
361
|
+
email = viewer.email if viewer else None
|
362
|
+
entity = self.default_entity
|
363
|
+
|
364
|
+
self._sentry.configure_scope(
|
365
|
+
tags={
|
366
|
+
"entity": entity,
|
367
|
+
"email": email,
|
368
|
+
},
|
369
|
+
)
|
326
370
|
|
327
371
|
def create_project(self, name: str, entity: str) -> None:
|
328
372
|
"""Create a new project.
|
329
373
|
|
330
374
|
Args:
|
331
|
-
name:
|
332
|
-
entity:
|
375
|
+
name: The name of the new project.
|
376
|
+
entity: The entity of the new project.
|
333
377
|
"""
|
334
378
|
self.client.execute(self.CREATE_PROJECT, {"entityName": entity, "name": name})
|
335
379
|
|
@@ -343,10 +387,12 @@ class Api:
|
|
343
387
|
"""Create a new run.
|
344
388
|
|
345
389
|
Args:
|
346
|
-
run_id:
|
347
|
-
|
348
|
-
project:
|
349
|
-
|
390
|
+
run_id: The ID to assign to the run. If not specified, W&B
|
391
|
+
creates a random ID.
|
392
|
+
project: The project where to log the run to. If no project is specified,
|
393
|
+
log the run to a project called "Uncategorized".
|
394
|
+
entity: The entity that owns the project. If no entity is
|
395
|
+
specified, log the run to the default entity.
|
350
396
|
|
351
397
|
Returns:
|
352
398
|
The newly created `Run`.
|
@@ -364,33 +410,28 @@ class Api:
|
|
364
410
|
config: Optional[dict] = None,
|
365
411
|
template_variables: Optional[dict] = None,
|
366
412
|
) -> "public.RunQueue":
|
367
|
-
"""Create a new run queue
|
413
|
+
"""Create a new run queue in W&B Launch.
|
368
414
|
|
369
415
|
Args:
|
370
|
-
name:
|
371
|
-
type:
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
"maximum": (optional maximum),
|
383
|
-
"enum": [..."(options)"]
|
384
|
-
}
|
385
|
-
}
|
386
|
-
}`
|
416
|
+
name: Name of the queue to create
|
417
|
+
type: Type of resource to be used for the queue. One of
|
418
|
+
"local-container", "local-process", "kubernetes","sagemaker",
|
419
|
+
or "gcp-vertex".
|
420
|
+
entity: Name of the entity to create the queue. If `None`, use
|
421
|
+
the configured or default entity.
|
422
|
+
prioritization_mode: Version of prioritization to use.
|
423
|
+
Either "V0" or `None`.
|
424
|
+
config: Default resource configuration to be used for the queue.
|
425
|
+
Use handlebars (eg. `{{var}}`) to specify template variables.
|
426
|
+
template_variables: A dictionary of template variable schemas to
|
427
|
+
use with the config.
|
387
428
|
|
388
429
|
Returns:
|
389
|
-
The newly created `RunQueue
|
430
|
+
The newly created `RunQueue`.
|
390
431
|
|
391
432
|
Raises:
|
392
|
-
ValueError if any of the parameters are invalid
|
393
|
-
wandb.Error on wandb API errors
|
433
|
+
`ValueError` if any of the parameters are invalid
|
434
|
+
`wandb.Error` on wandb API errors
|
394
435
|
"""
|
395
436
|
# TODO(np): Need to check server capabilities for this feature
|
396
437
|
# 0. assert params are valid/normalized
|
@@ -467,6 +508,85 @@ class Api:
|
|
467
508
|
_default_resource_config=config,
|
468
509
|
)
|
469
510
|
|
511
|
+
def create_custom_chart(
|
512
|
+
self,
|
513
|
+
entity: str,
|
514
|
+
name: str,
|
515
|
+
display_name: str,
|
516
|
+
spec_type: Literal["vega2"],
|
517
|
+
access: Literal["private", "public"],
|
518
|
+
spec: Union[str, dict],
|
519
|
+
) -> str:
|
520
|
+
"""Create a custom chart preset and return its id.
|
521
|
+
|
522
|
+
Args:
|
523
|
+
entity: The entity (user or team) that owns the chart
|
524
|
+
name: Unique identifier for the chart preset
|
525
|
+
display_name: Human-readable name shown in the UI
|
526
|
+
spec_type: Type of specification. Must be "vega2" for Vega-Lite v2 specifications.
|
527
|
+
access: Access level for the chart:
|
528
|
+
- "private": Chart is only accessible to the entity that created it
|
529
|
+
- "public": Chart is publicly accessible
|
530
|
+
spec: The Vega/Vega-Lite specification as a dictionary or JSON string
|
531
|
+
|
532
|
+
Returns:
|
533
|
+
The ID of the created chart preset in the format "entity/name"
|
534
|
+
|
535
|
+
Raises:
|
536
|
+
wandb.Error: If chart creation fails
|
537
|
+
UnsupportedError: If the server doesn't support custom charts
|
538
|
+
|
539
|
+
Example:
|
540
|
+
```python
|
541
|
+
import wandb
|
542
|
+
|
543
|
+
api = wandb.Api()
|
544
|
+
|
545
|
+
# Define a simple bar chart specification
|
546
|
+
vega_spec = {
|
547
|
+
"$schema": "https://vega.github.io/schema/vega-lite/v6.json",
|
548
|
+
"mark": "bar",
|
549
|
+
"data": {"name": "wandb"},
|
550
|
+
"encoding": {
|
551
|
+
"x": {"field": "${field:x}", "type": "ordinal"},
|
552
|
+
"y": {"field": "${field:y}", "type": "quantitative"},
|
553
|
+
},
|
554
|
+
}
|
555
|
+
|
556
|
+
# Create the custom chart
|
557
|
+
chart_id = api.create_custom_chart(
|
558
|
+
entity="my-team",
|
559
|
+
name="my-bar-chart",
|
560
|
+
display_name="My Custom Bar Chart",
|
561
|
+
spec_type="vega2",
|
562
|
+
access="private",
|
563
|
+
spec=vega_spec,
|
564
|
+
)
|
565
|
+
|
566
|
+
# Use with wandb.plot_table()
|
567
|
+
chart = wandb.plot_table(
|
568
|
+
vega_spec_name=chart_id,
|
569
|
+
data_table=my_table,
|
570
|
+
fields={"x": "category", "y": "value"},
|
571
|
+
)
|
572
|
+
```
|
573
|
+
"""
|
574
|
+
# Convert user-facing lowercase access to backend uppercase
|
575
|
+
backend_access = access.upper()
|
576
|
+
|
577
|
+
api = InternalApi(retry_timedelta=RETRY_TIMEDELTA)
|
578
|
+
result = api.create_custom_chart(
|
579
|
+
entity=entity,
|
580
|
+
name=name,
|
581
|
+
display_name=display_name,
|
582
|
+
spec_type=spec_type,
|
583
|
+
access=backend_access,
|
584
|
+
spec=spec,
|
585
|
+
)
|
586
|
+
if result is None or result.get("chart") is None:
|
587
|
+
raise wandb.Error("failed to create custom chart")
|
588
|
+
return result["chart"]["id"]
|
589
|
+
|
470
590
|
def upsert_run_queue(
|
471
591
|
self,
|
472
592
|
name: str,
|
@@ -477,30 +597,24 @@ class Api:
|
|
477
597
|
external_links: Optional[dict] = None,
|
478
598
|
prioritization_mode: Optional["public.RunQueuePrioritizationMode"] = None,
|
479
599
|
):
|
480
|
-
"""Upsert a run queue
|
600
|
+
"""Upsert a run queue in W&B Launch.
|
481
601
|
|
482
602
|
Args:
|
483
|
-
name:
|
484
|
-
entity:
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
}`
|
499
|
-
external_links: (dict) Optional dictionary of external links to be used with the queue. Expected format of:
|
500
|
-
`{
|
501
|
-
"name": "url"
|
502
|
-
}`
|
503
|
-
prioritization_mode: (str) Optional version of prioritization to use. Either "V0" or None
|
603
|
+
name: Name of the queue to create
|
604
|
+
entity: Optional name of the entity to create the queue. If `None`,
|
605
|
+
use the configured or default entity.
|
606
|
+
resource_config: Optional default resource configuration to be used
|
607
|
+
for the queue. Use handlebars (eg. `{{var}}`) to specify
|
608
|
+
template variables.
|
609
|
+
resource_type: Type of resource to be used for the queue. One of
|
610
|
+
"local-container", "local-process", "kubernetes", "sagemaker",
|
611
|
+
or "gcp-vertex".
|
612
|
+
template_variables: A dictionary of template variable schemas to
|
613
|
+
be used with the config.
|
614
|
+
external_links: Optional dictionary of external links to be used
|
615
|
+
with the queue.
|
616
|
+
prioritization_mode: Optional version of prioritization to use.
|
617
|
+
Either "V0" or None
|
504
618
|
|
505
619
|
Returns:
|
506
620
|
The upserted `RunQueue`.
|
@@ -582,15 +696,15 @@ class Api:
|
|
582
696
|
entity=entity,
|
583
697
|
)
|
584
698
|
|
585
|
-
def create_user(self, email, admin=False):
|
699
|
+
def create_user(self, email: str, admin: Optional[bool] = False):
|
586
700
|
"""Create a new user.
|
587
701
|
|
588
702
|
Args:
|
589
|
-
email:
|
590
|
-
admin:
|
703
|
+
email: The email address of the user.
|
704
|
+
admin: Set user as a global instance administrator.
|
591
705
|
|
592
706
|
Returns:
|
593
|
-
A `User` object
|
707
|
+
A `User` object.
|
594
708
|
"""
|
595
709
|
return public.User.create(self, email, admin)
|
596
710
|
|
@@ -620,14 +734,17 @@ class Api:
|
|
620
734
|
|
621
735
|
@property
|
622
736
|
def client(self) -> RetryingClient:
|
737
|
+
"""Returns the client object."""
|
623
738
|
return self._client
|
624
739
|
|
625
740
|
@property
|
626
741
|
def user_agent(self) -> str:
|
742
|
+
"""Returns W&B public user agent."""
|
627
743
|
return "W&B Public Client {}".format(wandb.__version__)
|
628
744
|
|
629
745
|
@property
|
630
746
|
def api_key(self) -> Optional[str]:
|
747
|
+
"""Returns W&B API key."""
|
631
748
|
# just use thread local api key if it's set
|
632
749
|
if _thread_local_api_settings.api_key:
|
633
750
|
return _thread_local_api_settings.api_key
|
@@ -645,6 +762,7 @@ class Api:
|
|
645
762
|
|
646
763
|
@property
|
647
764
|
def default_entity(self) -> Optional[str]:
|
765
|
+
"""Returns the default W&B entity."""
|
648
766
|
if self._default_entity is None:
|
649
767
|
res = self._client.execute(self.DEFAULT_ENTITY_QUERY)
|
650
768
|
self._default_entity = (res.get("viewer") or {}).get("entity")
|
@@ -652,42 +770,62 @@ class Api:
|
|
652
770
|
|
653
771
|
@property
|
654
772
|
def viewer(self) -> "public.User":
|
773
|
+
"""Returns the viewer object.
|
774
|
+
|
775
|
+
Raises:
|
776
|
+
ValueError: If viewer data is not able to be fetched from W&B.
|
777
|
+
requests.RequestException: If an error occurs while making the graphql request.
|
778
|
+
"""
|
655
779
|
if self._viewer is None:
|
656
|
-
|
657
|
-
|
658
|
-
|
780
|
+
viewer = self._client.execute(self.VIEWER_QUERY).get("viewer")
|
781
|
+
|
782
|
+
if viewer is None:
|
783
|
+
raise ValueError(
|
784
|
+
"Unable to fetch user data from W&B,"
|
785
|
+
" please verify your API key is valid."
|
786
|
+
)
|
787
|
+
|
788
|
+
self._viewer = public.User(self._client, viewer)
|
659
789
|
self._default_entity = self._viewer.entity
|
660
790
|
return self._viewer
|
661
791
|
|
662
792
|
def flush(self):
|
663
793
|
"""Flush the local cache.
|
664
794
|
|
665
|
-
The api object keeps a local cache of runs, so if the state of the run
|
666
|
-
change while executing your script you must clear the local cache
|
667
|
-
`api.flush()` to get the latest values associated with the run.
|
795
|
+
The api object keeps a local cache of runs, so if the state of the run
|
796
|
+
may change while executing your script you must clear the local cache
|
797
|
+
with `api.flush()` to get the latest values associated with the run.
|
668
798
|
"""
|
669
799
|
self._runs = {}
|
670
800
|
|
671
|
-
def from_path(self, path):
|
801
|
+
def from_path(self, path: str):
|
672
802
|
"""Return a run, sweep, project or report from a path.
|
673
803
|
|
674
|
-
Examples:
|
675
|
-
```
|
676
|
-
project = api.from_path("my_project")
|
677
|
-
team_project = api.from_path("my_team/my_project")
|
678
|
-
run = api.from_path("my_team/my_project/runs/id")
|
679
|
-
sweep = api.from_path("my_team/my_project/sweeps/id")
|
680
|
-
report = api.from_path("my_team/my_project/reports/My-Report-Vm11dsdf")
|
681
|
-
```
|
682
|
-
|
683
804
|
Args:
|
684
|
-
path:
|
805
|
+
path: The path to the project, run, sweep or report
|
685
806
|
|
686
807
|
Returns:
|
687
808
|
A `Project`, `Run`, `Sweep`, or `BetaReport` instance.
|
688
809
|
|
689
810
|
Raises:
|
690
|
-
wandb.Error if path is invalid or the object doesn't exist
|
811
|
+
`wandb.Error` if path is invalid or the object doesn't exist.
|
812
|
+
|
813
|
+
Examples:
|
814
|
+
In the proceeding code snippets "project", "team", "run_id", "sweep_id",
|
815
|
+
and "report_name" are placeholders for the project, team, run ID,
|
816
|
+
sweep ID, and the name of a specific report, respectively.
|
817
|
+
|
818
|
+
```python
|
819
|
+
import wandb
|
820
|
+
|
821
|
+
api = wandb.Api()
|
822
|
+
|
823
|
+
project = api.from_path("project")
|
824
|
+
team_project = api.from_path("team/project")
|
825
|
+
run = api.from_path("team/project/runs/run_id")
|
826
|
+
sweep = api.from_path("team/project/sweeps/sweep_id")
|
827
|
+
report = api.from_path("team/project/reports/report_name")
|
828
|
+
```
|
691
829
|
"""
|
692
830
|
parts = path.strip("/ ").split("/")
|
693
831
|
if len(parts) == 1:
|
@@ -713,7 +851,7 @@ class Api:
|
|
713
851
|
return public.BetaReport(
|
714
852
|
self.client,
|
715
853
|
{
|
716
|
-
"
|
854
|
+
"displayName": urllib.parse.unquote(name.replace("-", " ")),
|
717
855
|
"id": id,
|
718
856
|
"spec": "{}",
|
719
857
|
},
|
@@ -795,12 +933,14 @@ class Api:
|
|
795
933
|
"""Get projects for a given entity.
|
796
934
|
|
797
935
|
Args:
|
798
|
-
entity:
|
799
|
-
default entity passed to `Api`. If no default entity,
|
800
|
-
|
936
|
+
entity: Name of the entity requested. If None, will fall back to
|
937
|
+
the default entity passed to `Api`. If no default entity,
|
938
|
+
will raise a `ValueError`.
|
939
|
+
per_page: Sets the page size for query pagination. If set to `None`,
|
940
|
+
use the default size. Usually there is no reason to change this.
|
801
941
|
|
802
942
|
Returns:
|
803
|
-
A `Projects` object which is an iterable collection of `Project`
|
943
|
+
A `Projects` object which is an iterable collection of `Project`objects.
|
804
944
|
"""
|
805
945
|
if entity is None:
|
806
946
|
entity = self.settings["entity"] or self.default_entity
|
@@ -818,9 +958,10 @@ class Api:
|
|
818
958
|
"""Return the `Project` with the given name (and entity, if given).
|
819
959
|
|
820
960
|
Args:
|
821
|
-
name:
|
822
|
-
entity:
|
823
|
-
default entity passed to `Api`. If no default entity, will
|
961
|
+
name: The project name.
|
962
|
+
entity: Name of the entity requested. If None, will fall back to the
|
963
|
+
default entity passed to `Api`. If no default entity, will
|
964
|
+
raise a `ValueError`.
|
824
965
|
|
825
966
|
Returns:
|
826
967
|
A `Project` object.
|
@@ -844,15 +985,29 @@ class Api:
|
|
844
985
|
) -> "public.Reports":
|
845
986
|
"""Get reports for a given project path.
|
846
987
|
|
847
|
-
|
988
|
+
Note: `wandb.Api.reports()` API is in beta and will likely change in
|
989
|
+
future releases.
|
848
990
|
|
849
991
|
Args:
|
850
|
-
path:
|
851
|
-
|
852
|
-
|
992
|
+
path: The path to project the report resides in. Specify the
|
993
|
+
entity that created the project as a prefix followed by a
|
994
|
+
forward slash.
|
995
|
+
name: Name of the report requested.
|
996
|
+
per_page: Sets the page size for query pagination. If set to
|
997
|
+
`None`, use the default size. Usually there is no reason to
|
998
|
+
change this.
|
853
999
|
|
854
1000
|
Returns:
|
855
|
-
A `Reports` object which is an iterable collection of
|
1001
|
+
A `Reports` object which is an iterable collection of
|
1002
|
+
`BetaReport` objects.
|
1003
|
+
|
1004
|
+
Examples:
|
1005
|
+
```python
|
1006
|
+
import wandb
|
1007
|
+
|
1008
|
+
wandb.Api.reports("entity/project")
|
1009
|
+
```
|
1010
|
+
|
856
1011
|
"""
|
857
1012
|
entity, project, _ = self._parse_path(path + "/fake_run")
|
858
1013
|
|
@@ -871,15 +1026,18 @@ class Api:
|
|
871
1026
|
)
|
872
1027
|
return self._reports[key]
|
873
1028
|
|
874
|
-
def create_team(
|
1029
|
+
def create_team(
|
1030
|
+
self, team: str, admin_username: Optional[str] = None
|
1031
|
+
) -> "public.Team":
|
875
1032
|
"""Create a new team.
|
876
1033
|
|
877
1034
|
Args:
|
878
|
-
team:
|
879
|
-
admin_username:
|
1035
|
+
team: The name of the team
|
1036
|
+
admin_username: Username of the admin user of the team.
|
1037
|
+
Defaults to the current user.
|
880
1038
|
|
881
1039
|
Returns:
|
882
|
-
A `Team` object
|
1040
|
+
A `Team` object.
|
883
1041
|
"""
|
884
1042
|
return public.Team.create(self, team, admin_username)
|
885
1043
|
|
@@ -887,7 +1045,7 @@ class Api:
|
|
887
1045
|
"""Return the matching `Team` with the given name.
|
888
1046
|
|
889
1047
|
Args:
|
890
|
-
team:
|
1048
|
+
team: The name of the team.
|
891
1049
|
|
892
1050
|
Returns:
|
893
1051
|
A `Team` object.
|
@@ -897,13 +1055,14 @@ class Api:
|
|
897
1055
|
def user(self, username_or_email: str) -> Optional["public.User"]:
|
898
1056
|
"""Return a user from a username or email address.
|
899
1057
|
|
900
|
-
|
1058
|
+
This function only works for local administrators. Use `api.viewer`
|
1059
|
+
to get your own user object.
|
901
1060
|
|
902
1061
|
Args:
|
903
|
-
username_or_email:
|
1062
|
+
username_or_email: The username or email address of the user.
|
904
1063
|
|
905
1064
|
Returns:
|
906
|
-
A `User` object or None if a user
|
1065
|
+
A `User` object or None if a user is not found.
|
907
1066
|
"""
|
908
1067
|
res = self._client.execute(self.USERS_QUERY, {"query": username_or_email})
|
909
1068
|
if len(res["users"]["edges"]) == 0:
|
@@ -919,13 +1078,14 @@ class Api:
|
|
919
1078
|
def users(self, username_or_email: str) -> List["public.User"]:
|
920
1079
|
"""Return all users from a partial username or email address query.
|
921
1080
|
|
922
|
-
|
1081
|
+
This function only works for local administrators. Use `api.viewer`
|
1082
|
+
to get your own user object.
|
923
1083
|
|
924
1084
|
Args:
|
925
|
-
username_or_email:
|
1085
|
+
username_or_email: The prefix or suffix of the user you want to find.
|
926
1086
|
|
927
1087
|
Returns:
|
928
|
-
An array of `User` objects
|
1088
|
+
An array of `User` objects.
|
929
1089
|
"""
|
930
1090
|
res = self._client.execute(self.USERS_QUERY, {"query": username_or_email})
|
931
1091
|
return [
|
@@ -940,7 +1100,7 @@ class Api:
|
|
940
1100
|
per_page: int = 50,
|
941
1101
|
include_sweeps: bool = True,
|
942
1102
|
):
|
943
|
-
"""
|
1103
|
+
"""Returns a `Runs` object, which lazily iterates over `Run` objects.
|
944
1104
|
|
945
1105
|
Fields you can filter by include:
|
946
1106
|
- `createdAt`: The timestamp when the run was created. (in ISO 8601 format, e.g. "2023-01-01T12:00:00Z")
|
@@ -975,64 +1135,6 @@ class Api:
|
|
975
1135
|
- `$regex`
|
976
1136
|
|
977
1137
|
|
978
|
-
Examples:
|
979
|
-
Find runs in my_project where config.experiment_name has been set to "foo"
|
980
|
-
```
|
981
|
-
api.runs(
|
982
|
-
path="my_entity/my_project",
|
983
|
-
filters={"config.experiment_name": "foo"},
|
984
|
-
)
|
985
|
-
```
|
986
|
-
|
987
|
-
Find runs in my_project where config.experiment_name has been set to "foo" or "bar"
|
988
|
-
```
|
989
|
-
api.runs(
|
990
|
-
path="my_entity/my_project",
|
991
|
-
filters={
|
992
|
-
"$or": [
|
993
|
-
{"config.experiment_name": "foo"},
|
994
|
-
{"config.experiment_name": "bar"},
|
995
|
-
]
|
996
|
-
},
|
997
|
-
)
|
998
|
-
```
|
999
|
-
|
1000
|
-
Find runs in my_project where config.experiment_name matches a regex (anchors are not supported)
|
1001
|
-
```
|
1002
|
-
api.runs(
|
1003
|
-
path="my_entity/my_project",
|
1004
|
-
filters={"config.experiment_name": {"$regex": "b.*"}},
|
1005
|
-
)
|
1006
|
-
```
|
1007
|
-
|
1008
|
-
Find runs in my_project where the run name matches a regex (anchors are not supported)
|
1009
|
-
```
|
1010
|
-
api.runs(
|
1011
|
-
path="my_entity/my_project",
|
1012
|
-
filters={"display_name": {"$regex": "^foo.*"}},
|
1013
|
-
)
|
1014
|
-
```
|
1015
|
-
|
1016
|
-
Find runs in my_project where config.experiment contains a nested field "category" with value "testing"
|
1017
|
-
```
|
1018
|
-
api.runs(
|
1019
|
-
path="my_entity/my_project",
|
1020
|
-
filters={"config.experiment.category": "testing"},
|
1021
|
-
)
|
1022
|
-
```
|
1023
|
-
|
1024
|
-
Find runs in my_project with a loss value of 0.5 nested in a dictionary under model1 in the summary metrics
|
1025
|
-
```
|
1026
|
-
api.runs(
|
1027
|
-
path="my_entity/my_project",
|
1028
|
-
filters={"summary_metrics.model1.loss": 0.5},
|
1029
|
-
)
|
1030
|
-
```
|
1031
|
-
|
1032
|
-
Find runs in my_project sorted by ascending loss
|
1033
|
-
```
|
1034
|
-
api.runs(path="my_entity/my_project", order="+summary_metrics.loss")
|
1035
|
-
```
|
1036
1138
|
|
1037
1139
|
Args:
|
1038
1140
|
path: (str) path to project, should be in the form: "entity/project"
|
@@ -1041,14 +1143,55 @@ class Api:
|
|
1041
1143
|
For example: `{"config.experiment_name": "foo"}` would find runs with a config entry
|
1042
1144
|
of experiment name set to "foo"
|
1043
1145
|
order: (str) Order can be `created_at`, `heartbeat_at`, `config.*.value`, or `summary_metrics.*`.
|
1044
|
-
If you prepend order with a + order is ascending.
|
1045
|
-
If you prepend order with a - order is descending
|
1146
|
+
If you prepend order with a + order is ascending (default).
|
1147
|
+
If you prepend order with a - order is descending.
|
1046
1148
|
The default order is run.created_at from oldest to newest.
|
1047
1149
|
per_page: (int) Sets the page size for query pagination.
|
1048
1150
|
include_sweeps: (bool) Whether to include the sweep runs in the results.
|
1049
1151
|
|
1050
1152
|
Returns:
|
1051
1153
|
A `Runs` object, which is an iterable collection of `Run` objects.
|
1154
|
+
|
1155
|
+
Examples:
|
1156
|
+
```python
|
1157
|
+
# Find runs in project where config.experiment_name has been set to "foo"
|
1158
|
+
api.runs(path="my_entity/project", filters={"config.experiment_name": "foo"})
|
1159
|
+
```
|
1160
|
+
|
1161
|
+
```python
|
1162
|
+
# Find runs in project where config.experiment_name has been set to "foo" or "bar"
|
1163
|
+
api.runs(
|
1164
|
+
path="my_entity/project",
|
1165
|
+
filters={
|
1166
|
+
"$or": [
|
1167
|
+
{"config.experiment_name": "foo"},
|
1168
|
+
{"config.experiment_name": "bar"},
|
1169
|
+
]
|
1170
|
+
},
|
1171
|
+
)
|
1172
|
+
```
|
1173
|
+
|
1174
|
+
```python
|
1175
|
+
# Find runs in project where config.experiment_name matches a regex
|
1176
|
+
# (anchors are not supported)
|
1177
|
+
api.runs(
|
1178
|
+
path="my_entity/project",
|
1179
|
+
filters={"config.experiment_name": {"$regex": "b.*"}},
|
1180
|
+
)
|
1181
|
+
```
|
1182
|
+
|
1183
|
+
```python
|
1184
|
+
# Find runs in project where the run name matches a regex
|
1185
|
+
# (anchors are not supported)
|
1186
|
+
api.runs(
|
1187
|
+
path="my_entity/project", filters={"display_name": {"$regex": "^foo.*"}}
|
1188
|
+
)
|
1189
|
+
```
|
1190
|
+
|
1191
|
+
```python
|
1192
|
+
# Find runs in project sorted by ascending loss
|
1193
|
+
api.runs(path="my_entity/project", order="+summary_metrics.loss")
|
1194
|
+
```
|
1052
1195
|
"""
|
1053
1196
|
entity, project = self._parse_project_path(path)
|
1054
1197
|
filters = filters or {}
|
@@ -1067,10 +1210,10 @@ class Api:
|
|
1067
1210
|
|
1068
1211
|
@normalize_exceptions
|
1069
1212
|
def run(self, path=""):
|
1070
|
-
"""Return a single run by parsing path in the form entity/project/run_id
|
1213
|
+
"""Return a single run by parsing path in the form `entity/project/run_id`.
|
1071
1214
|
|
1072
1215
|
Args:
|
1073
|
-
path:
|
1216
|
+
path: Path to run in the form `entity/project/run_id`.
|
1074
1217
|
If `api.entity` is set, this can be in the form `project/run_id`
|
1075
1218
|
and if `api.project` is set this can just be the run_id.
|
1076
1219
|
|
@@ -1084,16 +1227,16 @@ class Api:
|
|
1084
1227
|
|
1085
1228
|
def queued_run(
|
1086
1229
|
self,
|
1087
|
-
entity,
|
1088
|
-
project,
|
1089
|
-
queue_name,
|
1090
|
-
run_queue_item_id,
|
1230
|
+
entity: str,
|
1231
|
+
project: str,
|
1232
|
+
queue_name: str,
|
1233
|
+
run_queue_item_id: str,
|
1091
1234
|
project_queue=None,
|
1092
1235
|
priority=None,
|
1093
1236
|
):
|
1094
1237
|
"""Return a single queued run based on the path.
|
1095
1238
|
|
1096
|
-
Parses paths of the form entity/project/queue_id/run_queue_item_id
|
1239
|
+
Parses paths of the form `entity/project/queue_id/run_queue_item_id`.
|
1097
1240
|
"""
|
1098
1241
|
return public.QueuedRun(
|
1099
1242
|
self.client,
|
@@ -1107,12 +1250,12 @@ class Api:
|
|
1107
1250
|
|
1108
1251
|
def run_queue(
|
1109
1252
|
self,
|
1110
|
-
entity,
|
1111
|
-
name,
|
1253
|
+
entity: str,
|
1254
|
+
name: str,
|
1112
1255
|
):
|
1113
1256
|
"""Return the named `RunQueue` for entity.
|
1114
1257
|
|
1115
|
-
|
1258
|
+
See `Api.create_run_queue` for more information on how to create a run queue.
|
1116
1259
|
"""
|
1117
1260
|
return public.RunQueue(
|
1118
1261
|
self.client,
|
@@ -1125,8 +1268,9 @@ class Api:
|
|
1125
1268
|
"""Return a sweep by parsing path in the form `entity/project/sweep_id`.
|
1126
1269
|
|
1127
1270
|
Args:
|
1128
|
-
path:
|
1129
|
-
is set, this can be in the form
|
1271
|
+
path: Path to sweep in the form entity/project/sweep_id.
|
1272
|
+
If `api.entity` is set, this can be in the form
|
1273
|
+
project/sweep_id and if `api.project` is set
|
1130
1274
|
this can just be the sweep_id.
|
1131
1275
|
|
1132
1276
|
Returns:
|
@@ -1139,10 +1283,10 @@ class Api:
|
|
1139
1283
|
|
1140
1284
|
@normalize_exceptions
|
1141
1285
|
def artifact_types(self, project: Optional[str] = None) -> "public.ArtifactTypes":
|
1142
|
-
"""
|
1286
|
+
"""Returns a collection of matching artifact types.
|
1143
1287
|
|
1144
1288
|
Args:
|
1145
|
-
project:
|
1289
|
+
project: The project name or path to filter on.
|
1146
1290
|
|
1147
1291
|
Returns:
|
1148
1292
|
An iterable `ArtifactTypes` object.
|
@@ -1162,11 +1306,11 @@ class Api:
|
|
1162
1306
|
def artifact_type(
|
1163
1307
|
self, type_name: str, project: Optional[str] = None
|
1164
1308
|
) -> "public.ArtifactType":
|
1165
|
-
"""
|
1309
|
+
"""Returns the matching `ArtifactType`.
|
1166
1310
|
|
1167
1311
|
Args:
|
1168
|
-
type_name:
|
1169
|
-
project:
|
1312
|
+
type_name: The name of the artifact type to retrieve.
|
1313
|
+
project: If given, a project name or path to filter on.
|
1170
1314
|
|
1171
1315
|
Returns:
|
1172
1316
|
An `ArtifactType` object.
|
@@ -1186,12 +1330,13 @@ class Api:
|
|
1186
1330
|
def artifact_collections(
|
1187
1331
|
self, project_name: str, type_name: str, per_page: int = 50
|
1188
1332
|
) -> "public.ArtifactCollections":
|
1189
|
-
"""
|
1333
|
+
"""Returns a collection of matching artifact collections.
|
1190
1334
|
|
1191
1335
|
Args:
|
1192
|
-
project_name:
|
1193
|
-
type_name:
|
1194
|
-
per_page:
|
1336
|
+
project_name: The name of the project to filter on.
|
1337
|
+
type_name: The name of the artifact type to filter on.
|
1338
|
+
per_page: Sets the page size for query pagination. None will use the default size.
|
1339
|
+
Usually there is no reason to change this.
|
1195
1340
|
|
1196
1341
|
Returns:
|
1197
1342
|
An iterable `ArtifactCollections` object.
|
@@ -1212,14 +1357,39 @@ class Api:
|
|
1212
1357
|
def artifact_collection(
|
1213
1358
|
self, type_name: str, name: str
|
1214
1359
|
) -> "public.ArtifactCollection":
|
1215
|
-
"""
|
1360
|
+
"""Returns a single artifact collection by type.
|
1361
|
+
|
1362
|
+
You can use the returned `ArtifactCollection` object to retrieve
|
1363
|
+
information about specific artifacts in that collection, and more.
|
1216
1364
|
|
1217
1365
|
Args:
|
1218
|
-
type_name:
|
1219
|
-
name:
|
1366
|
+
type_name: The type of artifact collection to fetch.
|
1367
|
+
name: An artifact collection name. Optionally append the entity
|
1368
|
+
that logged the artifact as a prefix followed by a forward
|
1369
|
+
slash.
|
1220
1370
|
|
1221
1371
|
Returns:
|
1222
1372
|
An `ArtifactCollection` object.
|
1373
|
+
|
1374
|
+
Examples:
|
1375
|
+
In the proceeding code snippet "type", "entity", "project", and
|
1376
|
+
"artifact_name" are placeholders for the collection type, your W&B
|
1377
|
+
entity, name of the project the artifact is in, and the name of
|
1378
|
+
the artifact, respectively.
|
1379
|
+
|
1380
|
+
```python
|
1381
|
+
import wandb
|
1382
|
+
|
1383
|
+
collections = wandb.Api().artifact_collection(
|
1384
|
+
type_name="type", name="entity/project/artifact_name"
|
1385
|
+
)
|
1386
|
+
|
1387
|
+
# Get the first artifact in the collection
|
1388
|
+
artifact_example = collections.artifacts()[0]
|
1389
|
+
|
1390
|
+
# Download the contents of the artifact to the specified root directory.
|
1391
|
+
artifact_example.download()
|
1392
|
+
```
|
1223
1393
|
"""
|
1224
1394
|
entity, project, collection_name = self._parse_artifact_path(name)
|
1225
1395
|
# If its an Registry artifact, the entity is considered to be an org instead
|
@@ -1241,7 +1411,7 @@ class Api:
|
|
1241
1411
|
|
1242
1412
|
@normalize_exceptions
|
1243
1413
|
def artifact_versions(self, type_name, name, per_page=50):
|
1244
|
-
"""Deprecated
|
1414
|
+
"""Deprecated. Use `Api.artifacts(type_name, name)` method instead."""
|
1245
1415
|
deprecate(
|
1246
1416
|
field_name=Deprecated.api__artifact_versions,
|
1247
1417
|
warning_message=(
|
@@ -1259,16 +1429,32 @@ class Api:
|
|
1259
1429
|
per_page: int = 50,
|
1260
1430
|
tags: Optional[List[str]] = None,
|
1261
1431
|
) -> "public.Artifacts":
|
1262
|
-
"""Return an `Artifacts` collection
|
1432
|
+
"""Return an `Artifacts` collection.
|
1263
1433
|
|
1264
1434
|
Args:
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1435
|
+
type_name: The type of artifacts to fetch.
|
1436
|
+
name: The artifact's collection name. Optionally append the
|
1437
|
+
entity that logged the artifact as a prefix followed by
|
1438
|
+
a forward slash.
|
1439
|
+
per_page: Sets the page size for query pagination. If set to
|
1440
|
+
`None`, use the default size. Usually there is no reason
|
1441
|
+
to change this.
|
1442
|
+
tags: Only return artifacts with all of these tags.
|
1269
1443
|
|
1270
1444
|
Returns:
|
1271
1445
|
An iterable `Artifacts` object.
|
1446
|
+
|
1447
|
+
Examples:
|
1448
|
+
In the proceeding code snippet, "type", "entity", "project", and
|
1449
|
+
"artifact_name" are placeholders for the artifact type, W&B entity,
|
1450
|
+
name of the project the artifact was logged to,
|
1451
|
+
and the name of the artifact, respectively.
|
1452
|
+
|
1453
|
+
```python
|
1454
|
+
import wandb
|
1455
|
+
|
1456
|
+
wandb.Api().artifacts(type_name="type", name="entity/project/artifact_name")
|
1457
|
+
```
|
1272
1458
|
"""
|
1273
1459
|
entity, project, collection_name = self._parse_artifact_path(name)
|
1274
1460
|
# If its an Registry project, the entity is considered to be an org instead
|
@@ -1331,22 +1517,47 @@ class Api:
|
|
1331
1517
|
|
1332
1518
|
@normalize_exceptions
|
1333
1519
|
def artifact(self, name: str, type: Optional[str] = None):
|
1334
|
-
"""
|
1520
|
+
"""Returns a single artifact.
|
1335
1521
|
|
1336
1522
|
Args:
|
1337
|
-
name:
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1523
|
+
name: The artifact's name. The name of an artifact resembles a
|
1524
|
+
filepath that consists, at a minimum, the name of the project
|
1525
|
+
the artifact was logged to, the name of the artifact, and the
|
1526
|
+
artifact's version or alias. Optionally append the entity that
|
1527
|
+
logged the artifact as a prefix followed by a forward slash.
|
1528
|
+
If no entity is specified in the name, the Run or API
|
1529
|
+
setting's entity is used.
|
1530
|
+
type: The type of artifact to fetch.
|
1343
1531
|
|
1344
1532
|
Returns:
|
1345
1533
|
An `Artifact` object.
|
1346
1534
|
|
1347
1535
|
Raises:
|
1348
1536
|
ValueError: If the artifact name is not specified.
|
1349
|
-
ValueError: If the artifact type is specified but does not
|
1537
|
+
ValueError: If the artifact type is specified but does not
|
1538
|
+
match the type of the fetched artifact.
|
1539
|
+
|
1540
|
+
Examples:
|
1541
|
+
In the proceeding code snippets "entity", "project", "artifact",
|
1542
|
+
"version", and "alias" are placeholders for your W&B entity, name
|
1543
|
+
of the project the artifact is in, the name of the artifact,
|
1544
|
+
and artifact's version, respectively.
|
1545
|
+
|
1546
|
+
```python
|
1547
|
+
import wandb
|
1548
|
+
|
1549
|
+
# Specify the project, artifact's name, and the artifact's alias
|
1550
|
+
wandb.Api().artifact(name="project/artifact:alias")
|
1551
|
+
|
1552
|
+
# Specify the project, artifact's name, and a specific artifact version
|
1553
|
+
wandb.Api().artifact(name="project/artifact:version")
|
1554
|
+
|
1555
|
+
# Specify the entity, project, artifact's name, and the artifact's alias
|
1556
|
+
wandb.Api().artifact(name="entity/project/artifact:alias")
|
1557
|
+
|
1558
|
+
# Specify the entity, project, artifact's name, and a specific artifact version
|
1559
|
+
wandb.Api().artifact(name="entity/project/artifact:version")
|
1560
|
+
```
|
1350
1561
|
|
1351
1562
|
Note:
|
1352
1563
|
This method is intended for external use only. Do not call `api.artifact()` within the wandb repository code.
|
@@ -1355,11 +1566,11 @@ class Api:
|
|
1355
1566
|
|
1356
1567
|
@normalize_exceptions
|
1357
1568
|
def job(self, name: Optional[str], path: Optional[str] = None) -> "public.Job":
|
1358
|
-
"""Return a `Job`
|
1569
|
+
"""Return a `Job` object.
|
1359
1570
|
|
1360
1571
|
Args:
|
1361
|
-
name:
|
1362
|
-
path:
|
1572
|
+
name: The name of the job.
|
1573
|
+
path: The root path to download the job artifact.
|
1363
1574
|
|
1364
1575
|
Returns:
|
1365
1576
|
A `Job` object.
|
@@ -1377,8 +1588,8 @@ class Api:
|
|
1377
1588
|
"""Return a list of jobs, if any, for the given entity and project.
|
1378
1589
|
|
1379
1590
|
Args:
|
1380
|
-
entity:
|
1381
|
-
project:
|
1591
|
+
entity: The entity for the listed jobs.
|
1592
|
+
project: The project for the listed jobs.
|
1382
1593
|
|
1383
1594
|
Returns:
|
1384
1595
|
A list of matching jobs.
|
@@ -1452,19 +1663,33 @@ class Api:
|
|
1452
1663
|
|
1453
1664
|
@normalize_exceptions
|
1454
1665
|
def artifact_exists(self, name: str, type: Optional[str] = None) -> bool:
|
1455
|
-
"""
|
1666
|
+
"""Whether an artifact version exists within the specified project and entity.
|
1456
1667
|
|
1457
1668
|
Args:
|
1458
|
-
name:
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
type:
|
1669
|
+
name: The name of artifact. Add the artifact's entity and project
|
1670
|
+
as a prefix. Append the version or the alias of the artifact
|
1671
|
+
with a colon. If the entity or project is not specified,
|
1672
|
+
W&B uses override parameters if populated. Otherwise, the
|
1673
|
+
entity is pulled from the user settings and the project is
|
1674
|
+
set to "Uncategorized".
|
1675
|
+
type: The type of artifact.
|
1465
1676
|
|
1466
1677
|
Returns:
|
1467
1678
|
True if the artifact version exists, False otherwise.
|
1679
|
+
|
1680
|
+
Examples:
|
1681
|
+
In the proceeding code snippets "entity", "project", "artifact",
|
1682
|
+
"version", and "alias" are placeholders for your W&B entity, name of
|
1683
|
+
the project the artifact is in, the name of the artifact, and
|
1684
|
+
artifact's version, respectively.
|
1685
|
+
|
1686
|
+
```python
|
1687
|
+
import wandb
|
1688
|
+
|
1689
|
+
wandb.Api().artifact_exists("entity/project/artifact:version")
|
1690
|
+
wandb.Api().artifact_exists("entity/project/artifact:alias")
|
1691
|
+
```
|
1692
|
+
|
1468
1693
|
"""
|
1469
1694
|
try:
|
1470
1695
|
self._artifact(name, type)
|
@@ -1475,16 +1700,29 @@ class Api:
|
|
1475
1700
|
|
1476
1701
|
@normalize_exceptions
|
1477
1702
|
def artifact_collection_exists(self, name: str, type: str) -> bool:
|
1478
|
-
"""
|
1703
|
+
"""Whether an artifact collection exists within a specified project and entity.
|
1479
1704
|
|
1480
1705
|
Args:
|
1481
|
-
name:
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1706
|
+
name: An artifact collection name. Optionally append the
|
1707
|
+
entity that logged the artifact as a prefix followed by
|
1708
|
+
a forward slash. If entity or project is not specified,
|
1709
|
+
infer the collection from the override params if they exist.
|
1710
|
+
Otherwise, entity is pulled from the user settings and project
|
1711
|
+
will default to "uncategorized".
|
1712
|
+
type: The type of artifact collection.
|
1485
1713
|
|
1486
1714
|
Returns:
|
1487
1715
|
True if the artifact collection exists, False otherwise.
|
1716
|
+
|
1717
|
+
Examples:
|
1718
|
+
In the proceeding code snippet "type", and "collection_name" refer to the type
|
1719
|
+
of the artifact collection and the name of the collection, respectively.
|
1720
|
+
|
1721
|
+
```python
|
1722
|
+
import wandb
|
1723
|
+
|
1724
|
+
wandb.Api.artifact_collection_exists(type="type", name="collection_name")
|
1725
|
+
```
|
1488
1726
|
"""
|
1489
1727
|
try:
|
1490
1728
|
self.artifact_collection(type, name)
|
@@ -1498,44 +1736,16 @@ class Api:
|
|
1498
1736
|
organization: Optional[str] = None,
|
1499
1737
|
filter: Optional[Dict[str, Any]] = None,
|
1500
1738
|
) -> Registries:
|
1501
|
-
"""Returns a Registry
|
1739
|
+
"""Returns a lazy iterator of `Registry` objects.
|
1502
1740
|
|
1503
1741
|
Use the iterator to search and filter registries, collections,
|
1504
1742
|
or artifact versions across your organization's registry.
|
1505
1743
|
|
1506
|
-
Examples:
|
1507
|
-
Find all registries with the names that contain "model"
|
1508
|
-
```python
|
1509
|
-
import wandb
|
1510
|
-
|
1511
|
-
api = wandb.Api() # specify an org if your entity belongs to multiple orgs
|
1512
|
-
api.registries(filter={"name": {"$regex": "model"}})
|
1513
|
-
```
|
1514
|
-
|
1515
|
-
Find all collections in the registries with the name "my_collection" and the tag "my_tag"
|
1516
|
-
```python
|
1517
|
-
api.registries().collections(filter={"name": "my_collection", "tag": "my_tag"})
|
1518
|
-
```
|
1519
|
-
|
1520
|
-
Find all artifact versions in the registries with a collection name that contains "my_collection" and a version that has the alias "best"
|
1521
|
-
```python
|
1522
|
-
api.registries().collections(
|
1523
|
-
filter={"name": {"$regex": "my_collection"}}
|
1524
|
-
).versions(filter={"alias": "best"})
|
1525
|
-
```
|
1526
|
-
|
1527
|
-
Find all artifact versions in the registries that contain "model" and have the tag "prod" or alias "best"
|
1528
|
-
```python
|
1529
|
-
api.registries(filter={"name": {"$regex": "model"}}).versions(
|
1530
|
-
filter={"$or": [{"tag": "prod"}, {"alias": "best"}]}
|
1531
|
-
)
|
1532
|
-
```
|
1533
|
-
|
1534
1744
|
Args:
|
1535
1745
|
organization: (str, optional) The organization of the registry to fetch.
|
1536
1746
|
If not specified, use the organization specified in the user's settings.
|
1537
|
-
filter: (dict, optional) MongoDB-style filter to apply to each object in the registry iterator.
|
1538
|
-
Fields available to filter for
|
1747
|
+
filter: (dict, optional) MongoDB-style filter to apply to each object in the lazy registry iterator.
|
1748
|
+
Fields available to filter for registries are
|
1539
1749
|
`name`, `description`, `created_at`, `updated_at`.
|
1540
1750
|
Fields available to filter for collections are
|
1541
1751
|
`name`, `tag`, `description`, `created_at`, `updated_at`
|
@@ -1543,7 +1753,39 @@ class Api:
|
|
1543
1753
|
`tag`, `alias`, `created_at`, `updated_at`, `metadata`
|
1544
1754
|
|
1545
1755
|
Returns:
|
1546
|
-
A
|
1756
|
+
A lazy iterator of `Registry` objects.
|
1757
|
+
|
1758
|
+
Examples:
|
1759
|
+
Find all registries with the names that contain "model"
|
1760
|
+
|
1761
|
+
```python
|
1762
|
+
import wandb
|
1763
|
+
|
1764
|
+
api = wandb.Api() # specify an org if your entity belongs to multiple orgs
|
1765
|
+
api.registries(filter={"name": {"$regex": "model"}})
|
1766
|
+
```
|
1767
|
+
|
1768
|
+
Find all collections in the registries with the name "my_collection" and the tag "my_tag"
|
1769
|
+
|
1770
|
+
```python
|
1771
|
+
api.registries().collections(filter={"name": "my_collection", "tag": "my_tag"})
|
1772
|
+
```
|
1773
|
+
|
1774
|
+
Find all artifact versions in the registries with a collection name that contains "my_collection" and a version that has the alias "best"
|
1775
|
+
|
1776
|
+
```python
|
1777
|
+
api.registries().collections(
|
1778
|
+
filter={"name": {"$regex": "my_collection"}}
|
1779
|
+
).versions(filter={"alias": "best"})
|
1780
|
+
```
|
1781
|
+
|
1782
|
+
Find all artifact versions in the registries that contain "model" and have the tag "prod" or alias "best"
|
1783
|
+
|
1784
|
+
```python
|
1785
|
+
api.registries(filter={"name": {"$regex": "model"}}).versions(
|
1786
|
+
filter={"$or": [{"tag": "prod"}, {"alias": "best"}]}
|
1787
|
+
)
|
1788
|
+
```
|
1547
1789
|
"""
|
1548
1790
|
if not InternalApi()._server_supports(ServerFeature.ARTIFACT_REGISTRY_SEARCH):
|
1549
1791
|
raise RuntimeError(
|
@@ -1571,15 +1813,16 @@ class Api:
|
|
1571
1813
|
A registry object.
|
1572
1814
|
|
1573
1815
|
Examples:
|
1574
|
-
|
1575
|
-
```python
|
1576
|
-
import wandb
|
1816
|
+
Fetch and update a registry
|
1577
1817
|
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1818
|
+
```python
|
1819
|
+
import wandb
|
1820
|
+
|
1821
|
+
api = wandb.Api()
|
1822
|
+
registry = api.registry(name="my-registry", organization="my-org")
|
1823
|
+
registry.description = "This is an updated description"
|
1824
|
+
registry.save()
|
1825
|
+
```
|
1583
1826
|
"""
|
1584
1827
|
if not InternalApi()._server_supports(ServerFeature.ARTIFACT_REGISTRY_SEARCH):
|
1585
1828
|
raise RuntimeError(
|
@@ -1624,18 +1867,18 @@ class Api:
|
|
1624
1867
|
A registry object.
|
1625
1868
|
|
1626
1869
|
Examples:
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1870
|
+
```python
|
1871
|
+
import wandb
|
1872
|
+
|
1873
|
+
api = wandb.Api()
|
1874
|
+
registry = api.create_registry(
|
1875
|
+
name="my-registry",
|
1876
|
+
visibility="restricted",
|
1877
|
+
organization="my-org",
|
1878
|
+
description="This is a test registry",
|
1879
|
+
artifact_types=["model"],
|
1880
|
+
)
|
1881
|
+
```
|
1639
1882
|
"""
|
1640
1883
|
if not InternalApi()._server_supports(
|
1641
1884
|
ServerFeature.INCLUDE_ARTIFACT_TYPES_IN_REGISTRY_CREATION
|
@@ -1707,23 +1950,25 @@ class Api:
|
|
1707
1950
|
Iterator[WebhookIntegration]: An iterator of webhook integrations.
|
1708
1951
|
|
1709
1952
|
Examples:
|
1710
|
-
|
1711
|
-
```python
|
1712
|
-
import wandb
|
1953
|
+
Get all registered webhook integrations for the team "my-team":
|
1713
1954
|
|
1714
|
-
|
1715
|
-
|
1716
|
-
```
|
1955
|
+
```python
|
1956
|
+
import wandb
|
1717
1957
|
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1958
|
+
api = wandb.Api()
|
1959
|
+
webhook_integrations = api.webhook_integrations(entity="my-team")
|
1960
|
+
```
|
1961
|
+
|
1962
|
+
Find only webhook integrations that post requests to "https://my-fake-url.com":
|
1963
|
+
|
1964
|
+
```python
|
1965
|
+
webhook_integrations = api.webhook_integrations(entity="my-team")
|
1966
|
+
my_webhooks = [
|
1967
|
+
ig
|
1968
|
+
for ig in webhook_integrations
|
1969
|
+
if ig.url_endpoint.startswith("https://my-fake-url.com")
|
1970
|
+
]
|
1971
|
+
```
|
1727
1972
|
"""
|
1728
1973
|
from wandb.apis.public.integrations import WebhookIntegrations
|
1729
1974
|
|
@@ -1748,23 +1993,25 @@ class Api:
|
|
1748
1993
|
Iterator[SlackIntegration]: An iterator of Slack integrations.
|
1749
1994
|
|
1750
1995
|
Examples:
|
1751
|
-
|
1752
|
-
```python
|
1753
|
-
import wandb
|
1996
|
+
Get all registered Slack integrations for the team "my-team":
|
1754
1997
|
|
1755
|
-
|
1756
|
-
|
1757
|
-
```
|
1998
|
+
```python
|
1999
|
+
import wandb
|
1758
2000
|
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
2001
|
+
api = wandb.Api()
|
2002
|
+
slack_integrations = api.slack_integrations(entity="my-team")
|
2003
|
+
```
|
2004
|
+
|
2005
|
+
Find only Slack integrations that post to channel names starting with "team-alerts-":
|
2006
|
+
|
2007
|
+
```python
|
2008
|
+
slack_integrations = api.slack_integrations(entity="my-team")
|
2009
|
+
team_alert_integrations = [
|
2010
|
+
ig
|
2011
|
+
for ig in slack_integrations
|
2012
|
+
if ig.channel_name.startswith("team-alerts-")
|
2013
|
+
]
|
2014
|
+
```
|
1768
2015
|
"""
|
1769
2016
|
from wandb.apis.public.integrations import SlackIntegrations
|
1770
2017
|
|
@@ -1862,20 +2109,20 @@ class Api:
|
|
1862
2109
|
ValueError: If zero or multiple Automations match the search criteria.
|
1863
2110
|
|
1864
2111
|
Examples:
|
1865
|
-
|
2112
|
+
Get an existing automation named "my-automation":
|
1866
2113
|
|
1867
|
-
|
1868
|
-
|
2114
|
+
```python
|
2115
|
+
import wandb
|
1869
2116
|
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
2117
|
+
api = wandb.Api()
|
2118
|
+
automation = api.automation(name="my-automation")
|
2119
|
+
```
|
1873
2120
|
|
1874
|
-
|
2121
|
+
Get an existing automation named "other-automation", from the entity "my-team":
|
1875
2122
|
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
2123
|
+
```python
|
2124
|
+
automation = api.automation(name="other-automation", entity="my-team")
|
2125
|
+
```
|
1879
2126
|
"""
|
1880
2127
|
return one(
|
1881
2128
|
self.automations(entity=entity, name=name),
|
@@ -1905,14 +2152,14 @@ class Api:
|
|
1905
2152
|
A list of automations.
|
1906
2153
|
|
1907
2154
|
Examples:
|
1908
|
-
|
2155
|
+
Fetch all existing automations for the entity "my-team":
|
1909
2156
|
|
1910
|
-
|
1911
|
-
|
2157
|
+
```python
|
2158
|
+
import wandb
|
1912
2159
|
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
2160
|
+
api = wandb.Api()
|
2161
|
+
automations = api.automations(entity="my-team")
|
2162
|
+
```
|
1916
2163
|
"""
|
1917
2164
|
from wandb.apis.public.automations import Automations
|
1918
2165
|
from wandb.automations._generated import (
|
@@ -1970,32 +2217,32 @@ class Api:
|
|
1970
2217
|
The saved Automation.
|
1971
2218
|
|
1972
2219
|
Examples:
|
1973
|
-
|
1974
|
-
|
2220
|
+
Create a new automation named "my-automation" that sends a Slack notification
|
2221
|
+
when a run within a specific project logs a metric exceeding a custom threshold:
|
1975
2222
|
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
2223
|
+
```python
|
2224
|
+
import wandb
|
2225
|
+
from wandb.automations import OnRunMetric, RunEvent, SendNotification
|
1979
2226
|
|
1980
|
-
|
2227
|
+
api = wandb.Api()
|
1981
2228
|
|
1982
|
-
|
2229
|
+
project = api.project("my-project", entity="my-team")
|
1983
2230
|
|
1984
|
-
|
1985
|
-
|
2231
|
+
# Use the first Slack integration for the team
|
2232
|
+
slack_hook = next(api.slack_integrations(entity="my-team"))
|
1986
2233
|
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
2234
|
+
event = OnRunMetric(
|
2235
|
+
scope=project,
|
2236
|
+
filter=RunEvent.metric("custom-metric") > 10,
|
2237
|
+
)
|
2238
|
+
action = SendNotification.from_integration(slack_hook)
|
1992
2239
|
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
2240
|
+
automation = api.create_automation(
|
2241
|
+
event >> action,
|
2242
|
+
name="my-automation",
|
2243
|
+
description="Send a Slack message whenever 'custom-metric' exceeds 10.",
|
2244
|
+
)
|
2245
|
+
```
|
1999
2246
|
"""
|
2000
2247
|
from wandb.automations import Automation
|
2001
2248
|
from wandb.automations._generated import CREATE_AUTOMATION_GQL, CreateAutomation
|
@@ -2075,35 +2322,35 @@ class Api:
|
|
2075
2322
|
The updated automation.
|
2076
2323
|
|
2077
2324
|
Examples:
|
2078
|
-
|
2325
|
+
Disable and edit the description of an existing automation ("my-automation"):
|
2079
2326
|
|
2080
|
-
|
2081
|
-
|
2327
|
+
```python
|
2328
|
+
import wandb
|
2082
2329
|
|
2083
|
-
|
2330
|
+
api = wandb.Api()
|
2084
2331
|
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2332
|
+
automation = api.automation(name="my-automation")
|
2333
|
+
automation.enabled = False
|
2334
|
+
automation.description = "Kept for reference, but no longer used."
|
2088
2335
|
|
2089
|
-
|
2090
|
-
|
2336
|
+
updated_automation = api.update_automation(automation)
|
2337
|
+
```
|
2091
2338
|
|
2092
|
-
|
2339
|
+
OR
|
2093
2340
|
|
2094
|
-
|
2095
|
-
|
2341
|
+
```python
|
2342
|
+
import wandb
|
2096
2343
|
|
2097
|
-
|
2344
|
+
api = wandb.Api()
|
2098
2345
|
|
2099
|
-
|
2346
|
+
automation = api.automation(name="my-automation")
|
2100
2347
|
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2348
|
+
updated_automation = api.update_automation(
|
2349
|
+
automation,
|
2350
|
+
enabled=False,
|
2351
|
+
description="Kept for reference, but no longer used.",
|
2352
|
+
)
|
2353
|
+
```
|
2107
2354
|
"""
|
2108
2355
|
from wandb.automations import ActionType, Automation
|
2109
2356
|
from wandb.automations._generated import UPDATE_AUTOMATION_GQL, UpdateAutomation
|