wandb 0.17.0rc1__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/data_types.py +6 -3
- wandb/docker/__init__.py +2 -2
- wandb/env.py +3 -3
- 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/huggingface/resolver.py +2 -2
- wandb/integration/keras/callbacks/metrics_logger.py +1 -1
- wandb/integration/keras/keras.py +1 -1
- wandb/integration/openai/fine_tuning.py +21 -3
- wandb/integration/prodigy/prodigy.py +1 -1
- wandb/jupyter.py +16 -17
- wandb/old/summary.py +1 -1
- wandb/plot/confusion_matrix.py +1 -1
- 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/_dtypes.py +8 -8
- wandb/sdk/data_types/image.py +2 -2
- wandb/sdk/data_types/video.py +5 -3
- wandb/sdk/integration_utils/data_logging.py +5 -5
- wandb/sdk/interface/interface.py +14 -1
- 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 +208 -136
- 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 +187 -225
- wandb/sdk/launch/agent/agent.py +59 -19
- wandb/sdk/launch/agent/config.py +0 -3
- wandb/sdk/launch/builder/abstract.py +68 -1
- 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 +12 -25
- 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/registry/google_artifact_registry.py +1 -1
- 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 +5 -3
- wandb/sdk/launch/sweeps/scheduler_sweep.py +1 -1
- wandb/sdk/launch/sweeps/utils.py +4 -4
- 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/import_hooks.py +1 -1
- wandb/sdk/lib/proto_util.py +22 -1
- wandb/sdk/lib/redirect.py +20 -15
- wandb/sdk/lib/tracelog.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 +123 -53
- wandb/sdk/wandb_settings.py +33 -64
- wandb/sdk/wandb_setup.py +1 -1
- wandb/sdk/wandb_watch.py +1 -1
- wandb/sklearn/plot/classifier.py +10 -12
- wandb/sklearn/plot/clusterer.py +1 -1
- 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 +5 -4
- {wandb-0.17.0rc1.dist-info → wandb-0.17.1.dist-info}/METADATA +8 -10
- {wandb-0.17.0rc1.dist-info → wandb-0.17.1.dist-info}/RECORD +141 -163
- {wandb-0.17.0rc1.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.0rc1.dist-info → wandb-0.17.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.17.0rc1.dist-info → wandb-0.17.1.dist-info}/licenses/LICENSE +0 -0
wandb/cli/cli.py
CHANGED
@@ -30,10 +30,12 @@ import wandb
|
|
30
30
|
import wandb.env
|
31
31
|
|
32
32
|
# from wandb.old.core import wandb_dir
|
33
|
+
import wandb.errors
|
33
34
|
import wandb.sdk.verify.verify as wandb_verify
|
34
35
|
from wandb import Config, Error, env, util, wandb_agent, wandb_sdk
|
35
36
|
from wandb.apis import InternalApi, PublicApi
|
36
37
|
from wandb.apis.public import RunQueue
|
38
|
+
from wandb.errors import WandbCoreNotAvailableError
|
37
39
|
from wandb.integration.magic import magic_install
|
38
40
|
from wandb.sdk.artifacts.artifact_file_cache import get_artifact_file_cache
|
39
41
|
from wandb.sdk.launch import utils as launch_utils
|
@@ -44,6 +46,7 @@ from wandb.sdk.launch.sweeps.scheduler import Scheduler
|
|
44
46
|
from wandb.sdk.lib import filesystem
|
45
47
|
from wandb.sdk.lib.wburls import wburls
|
46
48
|
from wandb.sync import SyncManager, get_run_from_path, get_runs
|
49
|
+
from wandb.util import get_core_path
|
47
50
|
|
48
51
|
# Send cli logs to wandb/debug-cli.<username>.log by default and fallback to a temp dir.
|
49
52
|
_wandb_dir = wandb.old.core.wandb_dir(env.get_dir())
|
@@ -194,9 +197,9 @@ def projects(entity, display=True):
|
|
194
197
|
api = _get_cling_api()
|
195
198
|
projects = api.list_projects(entity=entity)
|
196
199
|
if len(projects) == 0:
|
197
|
-
message = "No projects found for
|
200
|
+
message = "No projects found for {}".format(entity)
|
198
201
|
else:
|
199
|
-
message = 'Latest projects for "
|
202
|
+
message = 'Latest projects for "{}"'.format(entity)
|
200
203
|
if display:
|
201
204
|
click.echo(click.style(message, bold=True))
|
202
205
|
for project in projects:
|
@@ -420,7 +423,7 @@ def init(ctx, project, entity, reset, mode):
|
|
420
423
|
"""
|
421
424
|
).format(
|
422
425
|
code1=click.style("import wandb", bold=True),
|
423
|
-
code2=click.style('wandb.init(project="
|
426
|
+
code2=click.style('wandb.init(project="{}")'.format(project), bold=True),
|
424
427
|
run=click.style("python <train.py>", bold=True),
|
425
428
|
)
|
426
429
|
)
|
@@ -430,14 +433,15 @@ def init(ctx, project, entity, reset, mode):
|
|
430
433
|
def beta():
|
431
434
|
"""Beta versions of wandb CLI commands. Requires wandb-core."""
|
432
435
|
# this is the future that requires wandb-core!
|
433
|
-
|
436
|
+
wandb._sentry.configure_scope(process_context="wandb_beta")
|
437
|
+
wandb.require("core")
|
434
438
|
|
435
|
-
|
439
|
+
try:
|
440
|
+
get_core_path()
|
441
|
+
except WandbCoreNotAvailableError as e:
|
442
|
+
wandb._sentry.exception(f"using `wandb beta`. failed with {e}")
|
436
443
|
click.secho(
|
437
|
-
(
|
438
|
-
"wandb beta commands require wandb-core, please install with"
|
439
|
-
" `pip install wandb-core`"
|
440
|
-
),
|
444
|
+
(e),
|
441
445
|
fg="red",
|
442
446
|
err=True,
|
443
447
|
)
|
@@ -923,7 +927,7 @@ def sweep(
|
|
923
927
|
"resume": "Resuming",
|
924
928
|
}
|
925
929
|
wandb.termlog(f"{ings[state]} sweep {entity}/{project}/{sweep_id}")
|
926
|
-
getattr(api, "
|
930
|
+
getattr(api, "{}_sweep".format(state))(sweep_id, entity=entity, project=project)
|
927
931
|
wandb.termlog("Done.")
|
928
932
|
return
|
929
933
|
else:
|
@@ -1307,7 +1311,14 @@ def launch_sweep(
|
|
1307
1311
|
|
1308
1312
|
|
1309
1313
|
@cli.command(help=f"Launch or queue a W&B Job. See {wburls.get('cli_launch')}")
|
1310
|
-
@click.option(
|
1314
|
+
@click.option(
|
1315
|
+
"--uri",
|
1316
|
+
"-u",
|
1317
|
+
metavar="(str)",
|
1318
|
+
default=None,
|
1319
|
+
help="Local path or git repo uri to launch. If provided this command will "
|
1320
|
+
"create a job from the specified uri.",
|
1321
|
+
)
|
1311
1322
|
@click.option(
|
1312
1323
|
"--job",
|
1313
1324
|
"-j",
|
@@ -1332,6 +1343,20 @@ def launch_sweep(
|
|
1332
1343
|
hidden=True,
|
1333
1344
|
help="Version of the project to run, as a Git commit reference for Git projects.",
|
1334
1345
|
)
|
1346
|
+
@click.option(
|
1347
|
+
"--build-context",
|
1348
|
+
metavar="(str)",
|
1349
|
+
help="Path to the build context within the source code. Defaults to the "
|
1350
|
+
"root of the source code. Compatible only with -u.",
|
1351
|
+
)
|
1352
|
+
@click.option(
|
1353
|
+
"--job-name",
|
1354
|
+
"-J",
|
1355
|
+
metavar="(str)",
|
1356
|
+
default=None,
|
1357
|
+
hidden=True,
|
1358
|
+
help="Name for the job created if the -u,--uri flag is passed in.",
|
1359
|
+
)
|
1335
1360
|
@click.option(
|
1336
1361
|
"--name",
|
1337
1362
|
envvar="WANDB_NAME",
|
@@ -1456,6 +1481,7 @@ def launch(
|
|
1456
1481
|
job,
|
1457
1482
|
entry_point,
|
1458
1483
|
git_version,
|
1484
|
+
build_context,
|
1459
1485
|
name,
|
1460
1486
|
resource,
|
1461
1487
|
entity,
|
@@ -1471,6 +1497,7 @@ def launch(
|
|
1471
1497
|
project_queue,
|
1472
1498
|
dockerfile,
|
1473
1499
|
priority,
|
1500
|
+
job_name,
|
1474
1501
|
):
|
1475
1502
|
"""Start a W&B run from the given URI.
|
1476
1503
|
|
@@ -1486,6 +1513,8 @@ def launch(
|
|
1486
1513
|
f"=== Launch called with kwargs {locals()} CLI Version: {wandb.__version__}==="
|
1487
1514
|
)
|
1488
1515
|
from wandb.sdk.launch._launch import _launch
|
1516
|
+
from wandb.sdk.launch.create_job import _create_job
|
1517
|
+
from wandb.sdk.launch.utils import _is_git_uri
|
1489
1518
|
|
1490
1519
|
api = _get_cling_api()
|
1491
1520
|
wandb._sentry.configure_scope(process_context="launch_cli")
|
@@ -1532,6 +1561,36 @@ def launch(
|
|
1532
1561
|
|
1533
1562
|
run_id = config.get("run_id")
|
1534
1563
|
|
1564
|
+
# If URI was provided, we need to create a job from it.
|
1565
|
+
if uri:
|
1566
|
+
if entry_point is None:
|
1567
|
+
raise LaunchError(
|
1568
|
+
"Cannot provide a uri without an entry point. Please provide an "
|
1569
|
+
"entry point with --entry-point or -E."
|
1570
|
+
)
|
1571
|
+
if job is not None:
|
1572
|
+
raise LaunchError("Cannot provide both a uri and a job name.")
|
1573
|
+
job_type = (
|
1574
|
+
"git" if _is_git_uri(uri) else "code"
|
1575
|
+
) # TODO: Add support for local URIs with git.
|
1576
|
+
if entity is None:
|
1577
|
+
entity = launch_utils.get_default_entity(api, config)
|
1578
|
+
artifact, _, _ = _create_job(
|
1579
|
+
api,
|
1580
|
+
job_type,
|
1581
|
+
uri,
|
1582
|
+
entrypoint=" ".join(entry_point),
|
1583
|
+
git_hash=git_version,
|
1584
|
+
name=job_name,
|
1585
|
+
project=project,
|
1586
|
+
build_context=build_context,
|
1587
|
+
dockerfile=dockerfile,
|
1588
|
+
entity=entity,
|
1589
|
+
)
|
1590
|
+
if artifact is None:
|
1591
|
+
raise LaunchError(f"Failed to create job from uri: {uri}")
|
1592
|
+
job = f"{entity}/{project}/{artifact.name}"
|
1593
|
+
|
1535
1594
|
if dockerfile:
|
1536
1595
|
if "overrides" in config:
|
1537
1596
|
config["overrides"]["dockerfile"] = dockerfile
|
@@ -1565,7 +1624,6 @@ def launch(
|
|
1565
1624
|
run = asyncio.run(
|
1566
1625
|
_launch(
|
1567
1626
|
api,
|
1568
|
-
uri,
|
1569
1627
|
job,
|
1570
1628
|
project=project,
|
1571
1629
|
entity=entity,
|
@@ -1602,7 +1660,6 @@ def launch(
|
|
1602
1660
|
try:
|
1603
1661
|
_launch_add(
|
1604
1662
|
api,
|
1605
|
-
uri,
|
1606
1663
|
job,
|
1607
1664
|
config,
|
1608
1665
|
template_variables,
|
@@ -1641,13 +1698,6 @@ def launch(
|
|
1641
1698
|
metavar="<queue(s)>",
|
1642
1699
|
help="The name of a queue for the agent to watch. Multiple -q flags supported.",
|
1643
1700
|
)
|
1644
|
-
@click.option(
|
1645
|
-
"--project",
|
1646
|
-
"-p",
|
1647
|
-
default=None,
|
1648
|
-
help="""Name of the project which the agent will watch.
|
1649
|
-
If passed in, will override the project value passed in using a config file.""",
|
1650
|
-
)
|
1651
1701
|
@click.option(
|
1652
1702
|
"--entity",
|
1653
1703
|
"-e",
|
@@ -1684,7 +1734,6 @@ def launch(
|
|
1684
1734
|
@display_error
|
1685
1735
|
def launch_agent(
|
1686
1736
|
ctx,
|
1687
|
-
project=None,
|
1688
1737
|
entity=None,
|
1689
1738
|
queues=None,
|
1690
1739
|
max_jobs=None,
|
@@ -1709,7 +1758,7 @@ def launch_agent(
|
|
1709
1758
|
api = _get_cling_api()
|
1710
1759
|
wandb._sentry.configure_scope(process_context="launch_agent")
|
1711
1760
|
agent_config, api = _launch.resolve_agent_config(
|
1712
|
-
entity,
|
1761
|
+
entity, max_jobs, queues, config, verbose
|
1713
1762
|
)
|
1714
1763
|
|
1715
1764
|
if len(agent_config.get("queues")) == 0:
|
@@ -1907,14 +1956,16 @@ def describe(job):
|
|
1907
1956
|
"--entry-point",
|
1908
1957
|
"-E",
|
1909
1958
|
"entrypoint",
|
1910
|
-
help="Entrypoint to the script, including an executable and an entrypoint
|
1959
|
+
help="Entrypoint to the script, including an executable and an entrypoint "
|
1960
|
+
"file. Required for code or repo jobs. If --build-context is provided, "
|
1961
|
+
"paths in the entrypoint command will be relative to the build context.",
|
1911
1962
|
)
|
1912
1963
|
@click.option(
|
1913
1964
|
"--git-hash",
|
1914
1965
|
"-g",
|
1915
1966
|
"git_hash",
|
1916
1967
|
type=str,
|
1917
|
-
help="
|
1968
|
+
help="Commit reference to use as the source for git jobs",
|
1918
1969
|
)
|
1919
1970
|
@click.option(
|
1920
1971
|
"--runtime",
|
@@ -1922,6 +1973,20 @@ def describe(job):
|
|
1922
1973
|
type=str,
|
1923
1974
|
help="Python runtime to execute the job",
|
1924
1975
|
)
|
1976
|
+
@click.option(
|
1977
|
+
"--build-context",
|
1978
|
+
"-b",
|
1979
|
+
type=str,
|
1980
|
+
help="Path to the build context from the root of the job source code. If "
|
1981
|
+
"provided, this is used as the base path for the Dockerfile and entrypoint.",
|
1982
|
+
)
|
1983
|
+
@click.option(
|
1984
|
+
"--dockerfile",
|
1985
|
+
"-D",
|
1986
|
+
type=str,
|
1987
|
+
help="Path to the Dockerfile for the job. If --build-context is provided, "
|
1988
|
+
"the Dockerfile path will be relative to the build context.",
|
1989
|
+
)
|
1925
1990
|
@click.argument(
|
1926
1991
|
"job_type",
|
1927
1992
|
type=click.Choice(("git", "code", "image")),
|
@@ -1938,6 +2003,8 @@ def create(
|
|
1938
2003
|
entrypoint,
|
1939
2004
|
git_hash,
|
1940
2005
|
runtime,
|
2006
|
+
build_context,
|
2007
|
+
dockerfile,
|
1941
2008
|
):
|
1942
2009
|
"""Create a job from a source, without a wandb run.
|
1943
2010
|
|
@@ -1980,6 +2047,8 @@ def create(
|
|
1980
2047
|
entrypoint=entrypoint,
|
1981
2048
|
git_hash=git_hash,
|
1982
2049
|
runtime=runtime,
|
2050
|
+
build_context=build_context,
|
2051
|
+
dockerfile=dockerfile,
|
1983
2052
|
)
|
1984
2053
|
if not artifact:
|
1985
2054
|
wandb.termerror("Job creation failed")
|
@@ -2038,13 +2107,13 @@ def docker_run(ctx, docker_run_args):
|
|
2038
2107
|
if image:
|
2039
2108
|
resolved_image = wandb.docker.image_id(image)
|
2040
2109
|
if resolved_image:
|
2041
|
-
args = ["-e", "WANDB_DOCKER
|
2110
|
+
args = ["-e", "WANDB_DOCKER={}".format(resolved_image)] + args
|
2042
2111
|
else:
|
2043
2112
|
wandb.termlog(
|
2044
2113
|
"Couldn't detect image argument, running command without the WANDB_DOCKER env variable"
|
2045
2114
|
)
|
2046
2115
|
if api.api_key:
|
2047
|
-
args = ["-e", "WANDB_API_KEY
|
2116
|
+
args = ["-e", "WANDB_API_KEY={}".format(api.api_key)] + args
|
2048
2117
|
else:
|
2049
2118
|
wandb.termlog(
|
2050
2119
|
"Not logged in, run `wandb login` from the host machine to enable result logging"
|
@@ -2135,14 +2204,17 @@ def docker(
|
|
2135
2204
|
resolved_image = wandb.docker.image_id(image)
|
2136
2205
|
if resolved_image is None:
|
2137
2206
|
raise ClickException(
|
2138
|
-
"Couldn't find image locally or in a registry, try running `docker pull
|
2139
|
-
|
2207
|
+
"Couldn't find image locally or in a registry, try running `docker pull {}`".format(
|
2208
|
+
image
|
2209
|
+
)
|
2140
2210
|
)
|
2141
2211
|
if digest:
|
2142
2212
|
sys.stdout.write(resolved_image)
|
2143
2213
|
exit(0)
|
2144
2214
|
|
2145
|
-
existing = wandb.docker.shell(
|
2215
|
+
existing = wandb.docker.shell(
|
2216
|
+
["ps", "-f", "ancestor={}".format(resolved_image), "-q"]
|
2217
|
+
)
|
2146
2218
|
if existing:
|
2147
2219
|
if click.confirm(
|
2148
2220
|
"Found running container with the same image, do you want to attach?"
|
@@ -2156,7 +2228,7 @@ def docker(
|
|
2156
2228
|
"-e",
|
2157
2229
|
"LANG=C.UTF-8",
|
2158
2230
|
"-e",
|
2159
|
-
"WANDB_DOCKER
|
2231
|
+
"WANDB_DOCKER={}".format(resolved_image),
|
2160
2232
|
"--ipc=host",
|
2161
2233
|
"-v",
|
2162
2234
|
wandb.docker.entrypoint + ":/wandb-entrypoint.sh",
|
@@ -2169,7 +2241,7 @@ def docker(
|
|
2169
2241
|
# TODO: We should default to the working directory if defined
|
2170
2242
|
command.extend(["-v", cwd + ":" + dir, "-w", dir])
|
2171
2243
|
if api.api_key:
|
2172
|
-
command.extend(["-e", "WANDB_API_KEY
|
2244
|
+
command.extend(["-e", "WANDB_API_KEY={}".format(api.api_key)])
|
2173
2245
|
else:
|
2174
2246
|
wandb.termlog(
|
2175
2247
|
"Couldn't find WANDB_API_KEY, run `wandb login` to enable streaming metrics"
|
@@ -2177,16 +2249,15 @@ def docker(
|
|
2177
2249
|
if jupyter:
|
2178
2250
|
command.extend(["-e", "WANDB_ENSURE_JUPYTER=1", "-p", port + ":8888"])
|
2179
2251
|
no_tty = True
|
2180
|
-
cmd = (
|
2181
|
-
|
2182
|
-
% dir
|
2252
|
+
cmd = "jupyter lab --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --notebook-dir {}".format(
|
2253
|
+
dir
|
2183
2254
|
)
|
2184
2255
|
command.extend(args)
|
2185
2256
|
if no_tty:
|
2186
2257
|
command.extend([image, shell, "-c", cmd])
|
2187
2258
|
else:
|
2188
2259
|
if cmd:
|
2189
|
-
command.extend(["-e", "WANDB_COMMAND
|
2260
|
+
command.extend(["-e", "WANDB_COMMAND={}".format(cmd)])
|
2190
2261
|
command.extend(["-it", image, shell])
|
2191
2262
|
wandb.termlog("Launching docker container \U0001f6a2")
|
2192
2263
|
subprocess.call(command)
|
@@ -2272,7 +2343,7 @@ def start(ctx, port, env, daemon, upgrade, edge):
|
|
2272
2343
|
exit(1)
|
2273
2344
|
image = "docker.pkg.github.com/wandb/core/local" if edge else "wandb/local"
|
2274
2345
|
username = getpass.getuser()
|
2275
|
-
env_vars = ["-e", "LOCAL_USERNAME
|
2346
|
+
env_vars = ["-e", "LOCAL_USERNAME={}".format(username)]
|
2276
2347
|
for e in env:
|
2277
2348
|
env_vars.append("-e")
|
2278
2349
|
env_vars.append(e)
|
@@ -2306,7 +2377,9 @@ def start(ctx, port, env, daemon, upgrade, edge):
|
|
2306
2377
|
)
|
2307
2378
|
exit(1)
|
2308
2379
|
else:
|
2309
|
-
wandb.termlog(
|
2380
|
+
wandb.termlog(
|
2381
|
+
"W&B server started at http://localhost:{} \U0001f680".format(port)
|
2382
|
+
)
|
2310
2383
|
wandb.termlog("You can stop the server by running `wandb server stop`")
|
2311
2384
|
if not api.api_key:
|
2312
2385
|
# Let the server start before potentially launching a browser
|
@@ -2443,7 +2516,7 @@ def get(path, root, type):
|
|
2443
2516
|
)
|
2444
2517
|
artifact = public_api.artifact(full_path, type=type)
|
2445
2518
|
path = artifact.download(root=root)
|
2446
|
-
wandb.termlog("Artifact downloaded to
|
2519
|
+
wandb.termlog("Artifact downloaded to {}".format(path))
|
2447
2520
|
except ValueError:
|
2448
2521
|
raise ClickException("Unable to download artifact")
|
2449
2522
|
|
@@ -2521,17 +2594,17 @@ def pull(run, project, entity):
|
|
2521
2594
|
|
2522
2595
|
for name in urls:
|
2523
2596
|
if api.file_current(name, urls[name]["md5"]):
|
2524
|
-
click.echo("File
|
2597
|
+
click.echo("File {} is up to date".format(name))
|
2525
2598
|
else:
|
2526
2599
|
length, response = api.download_file(urls[name]["url"])
|
2527
2600
|
# TODO: I had to add this because some versions in CI broke click.progressbar
|
2528
|
-
sys.stdout.write("File
|
2601
|
+
sys.stdout.write("File {}\r".format(name))
|
2529
2602
|
dirname = os.path.dirname(name)
|
2530
2603
|
if dirname != "":
|
2531
2604
|
filesystem.mkdir_exists_ok(dirname)
|
2532
2605
|
with click.progressbar(
|
2533
2606
|
length=length,
|
2534
|
-
label="File
|
2607
|
+
label="File {}".format(name),
|
2535
2608
|
fill_char=click.style("&", fg="green"),
|
2536
2609
|
) as bar:
|
2537
2610
|
with open(name, "wb") as f:
|
@@ -2577,11 +2650,8 @@ def restore(ctx, run, no_git, branch, project, entity):
|
|
2577
2650
|
)
|
2578
2651
|
repo = metadata.get("git", {}).get("repo")
|
2579
2652
|
image = metadata.get("docker")
|
2580
|
-
restore_message =
|
2581
|
-
|
2582
|
-
Run `git clone %s` and restore from there or pass the --no-git flag."""
|
2583
|
-
% repo
|
2584
|
-
)
|
2653
|
+
restore_message = """`wandb restore` needs to be run from the same git repository as the original run.
|
2654
|
+
Run `git clone {}` and restore from there or pass the --no-git flag.""".format(repo)
|
2585
2655
|
if no_git:
|
2586
2656
|
commit = None
|
2587
2657
|
elif not api.git.enabled:
|
@@ -2626,18 +2696,21 @@ Run `git clone %s` and restore from there or pass the --no-git flag."""
|
|
2626
2696
|
else:
|
2627
2697
|
patch_path = None
|
2628
2698
|
|
2629
|
-
branch_name = "wandb
|
2699
|
+
branch_name = "wandb/{}".format(run)
|
2630
2700
|
if branch and branch_name not in api.git.repo.branches:
|
2631
2701
|
api.git.repo.git.checkout(commit, b=branch_name)
|
2632
|
-
wandb.termlog(
|
2702
|
+
wandb.termlog(
|
2703
|
+
"Created branch {}".format(click.style(branch_name, bold=True))
|
2704
|
+
)
|
2633
2705
|
elif branch:
|
2634
2706
|
wandb.termlog(
|
2635
|
-
"Using existing branch, run `git branch -D
|
2636
|
-
|
2707
|
+
"Using existing branch, run `git branch -D {}` from master for a clean checkout".format(
|
2708
|
+
branch_name
|
2709
|
+
)
|
2637
2710
|
)
|
2638
2711
|
api.git.repo.git.checkout(branch_name)
|
2639
2712
|
else:
|
2640
|
-
wandb.termlog("Checking out
|
2713
|
+
wandb.termlog("Checking out {} in detached mode".format(commit))
|
2641
2714
|
api.git.repo.git.checkout(commit)
|
2642
2715
|
|
2643
2716
|
if patch_path:
|
@@ -2675,7 +2748,7 @@ Run `git clone %s` and restore from there or pass the --no-git flag."""
|
|
2675
2748
|
with open(config_path, "w") as f:
|
2676
2749
|
f.write(s)
|
2677
2750
|
|
2678
|
-
wandb.termlog("Restored config variables to
|
2751
|
+
wandb.termlog("Restored config variables to {}".format(config_path))
|
2679
2752
|
if image:
|
2680
2753
|
if not metadata["program"].startswith("<") and metadata.get("args") is not None:
|
2681
2754
|
# TODO: we may not want to default to python here.
|
@@ -2710,7 +2783,9 @@ def magic(ctx, program, args):
|
|
2710
2783
|
with open(program, "rb") as fp:
|
2711
2784
|
code = compile(fp.read(), program, "exec")
|
2712
2785
|
except OSError:
|
2713
|
-
click.echo(
|
2786
|
+
click.echo(
|
2787
|
+
click.style("Could not launch program: {}".format(program), fg="red")
|
2788
|
+
)
|
2714
2789
|
sys.exit(1)
|
2715
2790
|
globs = {
|
2716
2791
|
"__file__": program,
|
@@ -2718,14 +2793,11 @@ def magic(ctx, program, args):
|
|
2718
2793
|
"__package__": None,
|
2719
2794
|
"wandb_magic_install": magic_install,
|
2720
2795
|
}
|
2721
|
-
prep =
|
2722
|
-
"""
|
2796
|
+
prep = """
|
2723
2797
|
import __main__
|
2724
|
-
__main__.__file__ = "
|
2798
|
+
__main__.__file__ = "{}"
|
2725
2799
|
wandb_magic_install()
|
2726
|
-
"""
|
2727
|
-
% program
|
2728
|
-
)
|
2800
|
+
""".format(program)
|
2729
2801
|
magic_run(prep, globs, None)
|
2730
2802
|
magic_run(code, globs, None)
|
2731
2803
|
|
wandb/data_types.py
CHANGED
@@ -191,7 +191,7 @@ class Table(Media):
|
|
191
191
|
):
|
192
192
|
"""Initializes a Table object.
|
193
193
|
|
194
|
-
The rows is
|
194
|
+
The rows is available for legacy reasons and should not be used.
|
195
195
|
The Table class uses data to mimic the Pandas API.
|
196
196
|
"""
|
197
197
|
super().__init__()
|
@@ -280,7 +280,10 @@ class Table(Media):
|
|
280
280
|
self.cast(col_name, dt, opt)
|
281
281
|
|
282
282
|
def cast(self, col_name, dtype, optional=False):
|
283
|
-
"""Casts a column to a specific data type.
|
283
|
+
"""Casts a column to a specific data type.
|
284
|
+
|
285
|
+
This can be one of the normal python classes, an internal W&B type, or an
|
286
|
+
example object, like an instance of wandb.Image or wandb.Classes.
|
284
287
|
|
285
288
|
Arguments:
|
286
289
|
col_name: (str) - The name of the column to cast.
|
@@ -763,7 +766,7 @@ class Table(Media):
|
|
763
766
|
|
764
767
|
Arguments:
|
765
768
|
name: (str) - the unique name of the column
|
766
|
-
data: (list | np.array) - a column of
|
769
|
+
data: (list | np.array) - a column of homogeneous data
|
767
770
|
optional: (bool) - if null-like values are permitted
|
768
771
|
"""
|
769
772
|
assert isinstance(name, str) and name not in self.columns
|
wandb/docker/__init__.py
CHANGED
@@ -202,7 +202,7 @@ def default_image(gpu: bool = False) -> str:
|
|
202
202
|
tag = "all"
|
203
203
|
if not gpu:
|
204
204
|
tag += "-cpu"
|
205
|
-
return "wandb/deepo
|
205
|
+
return "wandb/deepo:{}".format(tag)
|
206
206
|
|
207
207
|
|
208
208
|
def parse_repository_tag(repo_name: str) -> Tuple[str, Optional[str]]:
|
@@ -289,7 +289,7 @@ def image_id_from_registry(image_name: str) -> Optional[str]:
|
|
289
289
|
|
290
290
|
|
291
291
|
def image_id(image_name: str) -> Optional[str]:
|
292
|
-
"""
|
292
|
+
"""Retrieve the image id from the local docker daemon or remote registry."""
|
293
293
|
if "@sha256:" in image_name:
|
294
294
|
return image_name
|
295
295
|
else:
|
wandb/env.py
CHANGED
@@ -16,7 +16,7 @@ import sys
|
|
16
16
|
from pathlib import Path
|
17
17
|
from typing import List, MutableMapping, Optional, Union
|
18
18
|
|
19
|
-
import
|
19
|
+
import platformdirs # type: ignore
|
20
20
|
|
21
21
|
Env = Optional[MutableMapping]
|
22
22
|
|
@@ -385,7 +385,7 @@ def get_magic(
|
|
385
385
|
|
386
386
|
|
387
387
|
def get_data_dir(env: Optional[Env] = None) -> str:
|
388
|
-
default_dir =
|
388
|
+
default_dir = platformdirs.user_data_dir("wandb")
|
389
389
|
if env is None:
|
390
390
|
env = os.environ
|
391
391
|
val = env.get(DATA_DIR, default_dir)
|
@@ -410,7 +410,7 @@ def get_artifact_fetch_file_url_batch_size(env: Optional[Env] = None) -> int:
|
|
410
410
|
|
411
411
|
def get_cache_dir(env: Optional[Env] = None) -> Path:
|
412
412
|
env = env or os.environ
|
413
|
-
return Path(env.get(CACHE_DIR,
|
413
|
+
return Path(env.get(CACHE_DIR, platformdirs.user_cache_dir("wandb")))
|
414
414
|
|
415
415
|
|
416
416
|
def get_use_v1_artifacts(env: Optional[Env] = None) -> bool:
|
wandb/errors/term.py
CHANGED
@@ -27,7 +27,10 @@ def termsetup(settings, logger) -> None:
|
|
27
27
|
|
28
28
|
|
29
29
|
def termlog(
|
30
|
-
string: str = "",
|
30
|
+
string: str = "",
|
31
|
+
newline: bool = True,
|
32
|
+
repeat: bool = True,
|
33
|
+
prefix: bool = True,
|
31
34
|
) -> None:
|
32
35
|
"""Log to standard error with formatting.
|
33
36
|
|
@@ -68,7 +71,12 @@ def termerror(string: str, **kwargs: Any) -> None:
|
|
68
71
|
|
69
72
|
|
70
73
|
def _log(
|
71
|
-
string="",
|
74
|
+
string="",
|
75
|
+
newline=True,
|
76
|
+
repeat=True,
|
77
|
+
prefix=True,
|
78
|
+
silent=False,
|
79
|
+
level=logging.INFO,
|
72
80
|
):
|
73
81
|
global _logger
|
74
82
|
silent = silent or _silent
|
wandb/filesync/step_checksum.py
CHANGED
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
|
17
17
|
|
18
18
|
from wandb.filesync import stats
|
19
19
|
from wandb.sdk.artifacts.artifact_manifest import ArtifactManifest
|
20
|
-
from wandb.sdk.artifacts.artifact_saver import SaveFn
|
20
|
+
from wandb.sdk.artifacts.artifact_saver import SaveFn
|
21
21
|
from wandb.sdk.internal import internal_api
|
22
22
|
|
23
23
|
|
@@ -31,7 +31,6 @@ class RequestStoreManifestFiles(NamedTuple):
|
|
31
31
|
manifest: "ArtifactManifest"
|
32
32
|
artifact_id: str
|
33
33
|
save_fn: "SaveFn"
|
34
|
-
save_fn_async: "SaveFnAsync"
|
35
34
|
|
36
35
|
|
37
36
|
class RequestCommitArtifact(NamedTuple):
|
@@ -96,7 +95,6 @@ class StepChecksum:
|
|
96
95
|
req.copy,
|
97
96
|
None,
|
98
97
|
None,
|
99
|
-
None,
|
100
98
|
)
|
101
99
|
)
|
102
100
|
elif isinstance(req, RequestStoreManifestFiles):
|
@@ -115,7 +113,6 @@ class StepChecksum:
|
|
115
113
|
entry.digest,
|
116
114
|
False,
|
117
115
|
functools.partial(req.save_fn, entry),
|
118
|
-
functools.partial(req.save_fn_async, entry),
|
119
116
|
entry.digest,
|
120
117
|
)
|
121
118
|
)
|
wandb/filesync/step_prepare.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
"""Batching file prepare requests to our API."""
|
2
2
|
|
3
|
-
import asyncio
|
4
|
-
import functools
|
5
3
|
import queue
|
6
4
|
import threading
|
7
5
|
import time
|
@@ -29,10 +27,7 @@ if TYPE_CHECKING:
|
|
29
27
|
# Request for a file to be prepared.
|
30
28
|
class RequestPrepare(NamedTuple):
|
31
29
|
file_spec: "CreateArtifactFileSpecInput"
|
32
|
-
response_channel:
|
33
|
-
"queue.Queue[ResponsePrepare]",
|
34
|
-
Tuple["asyncio.AbstractEventLoop", "asyncio.Future[ResponsePrepare]"],
|
35
|
-
]
|
30
|
+
response_channel: "queue.Queue[ResponsePrepare]"
|
36
31
|
|
37
32
|
|
38
33
|
class RequestFinish(NamedTuple):
|
@@ -110,7 +105,7 @@ def prepare_response(response: "CreateArtifactFilesResponseFile") -> ResponsePre
|
|
110
105
|
class StepPrepare:
|
111
106
|
"""A thread that batches requests to our file prepare API.
|
112
107
|
|
113
|
-
Any number of threads may call
|
108
|
+
Any number of threads may call prepare() in parallel. The PrepareBatcher thread
|
114
109
|
will batch requests up and send them all to the backend at once.
|
115
110
|
"""
|
116
111
|
|
@@ -145,11 +140,7 @@ class StepPrepare:
|
|
145
140
|
name = prepare_request.file_spec["name"]
|
146
141
|
response_file = batch_response[name]
|
147
142
|
response = prepare_response(response_file)
|
148
|
-
|
149
|
-
prepare_request.response_channel.put(response)
|
150
|
-
else:
|
151
|
-
loop, future = prepare_request.response_channel
|
152
|
-
loop.call_soon_threadsafe(future.set_result, response)
|
143
|
+
prepare_request.response_channel.put(response)
|
153
144
|
if finish:
|
154
145
|
break
|
155
146
|
|
@@ -167,18 +158,7 @@ class StepPrepare:
|
|
167
158
|
"""
|
168
159
|
return self._api.create_artifact_files([req.file_spec for req in batch])
|
169
160
|
|
170
|
-
def
|
171
|
-
self, file_spec: "CreateArtifactFileSpecInput"
|
172
|
-
) -> "asyncio.Future[ResponsePrepare]":
|
173
|
-
"""Request the backend to prepare a file for upload."""
|
174
|
-
response: asyncio.Future[ResponsePrepare] = asyncio.Future()
|
175
|
-
self._request_queue.put(
|
176
|
-
RequestPrepare(file_spec, (asyncio.get_event_loop(), response))
|
177
|
-
)
|
178
|
-
return response
|
179
|
-
|
180
|
-
@functools.wraps(prepare_async)
|
181
|
-
def prepare_sync(
|
161
|
+
def prepare(
|
182
162
|
self, file_spec: "CreateArtifactFileSpecInput"
|
183
163
|
) -> "queue.Queue[ResponsePrepare]":
|
184
164
|
response_queue: queue.Queue[ResponsePrepare] = queue.Queue()
|