wandb 0.17.0rc2__py3-none-any.whl → 0.17.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. wandb/__init__.py +4 -2
  2. wandb/apis/importers/internals/internal.py +0 -1
  3. wandb/apis/importers/wandb.py +12 -7
  4. wandb/apis/internal.py +0 -3
  5. wandb/apis/public/api.py +213 -79
  6. wandb/apis/public/artifacts.py +335 -100
  7. wandb/apis/public/files.py +9 -9
  8. wandb/apis/public/jobs.py +16 -4
  9. wandb/apis/public/projects.py +26 -28
  10. wandb/apis/public/query_generator.py +1 -1
  11. wandb/apis/public/runs.py +163 -65
  12. wandb/apis/public/sweeps.py +2 -2
  13. wandb/apis/reports/__init__.py +1 -7
  14. wandb/apis/reports/v1/__init__.py +5 -27
  15. wandb/apis/reports/v2/__init__.py +7 -19
  16. wandb/apis/workspaces/__init__.py +8 -0
  17. wandb/beta/workflows.py +8 -3
  18. wandb/cli/cli.py +151 -59
  19. wandb/docker/__init__.py +1 -1
  20. wandb/errors/term.py +10 -2
  21. wandb/filesync/step_checksum.py +1 -4
  22. wandb/filesync/step_prepare.py +4 -24
  23. wandb/filesync/step_upload.py +5 -107
  24. wandb/filesync/upload_job.py +0 -76
  25. wandb/integration/gym/__init__.py +35 -15
  26. wandb/integration/openai/fine_tuning.py +21 -3
  27. wandb/integration/prodigy/prodigy.py +1 -1
  28. wandb/jupyter.py +16 -17
  29. wandb/old/summary.py +5 -0
  30. wandb/plot/pr_curve.py +2 -1
  31. wandb/plot/roc_curve.py +2 -1
  32. wandb/{plots → plot}/utils.py +13 -25
  33. wandb/proto/v3/wandb_internal_pb2.py +54 -54
  34. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  35. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  36. wandb/proto/v4/wandb_internal_pb2.py +54 -54
  37. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  38. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  39. wandb/proto/v5/wandb_base_pb2.py +30 -0
  40. wandb/proto/v5/wandb_internal_pb2.py +355 -0
  41. wandb/proto/v5/wandb_server_pb2.py +63 -0
  42. wandb/proto/v5/wandb_settings_pb2.py +45 -0
  43. wandb/proto/v5/wandb_telemetry_pb2.py +41 -0
  44. wandb/proto/wandb_base_pb2.py +2 -0
  45. wandb/proto/wandb_deprecated.py +9 -1
  46. wandb/proto/wandb_generate_deprecated.py +34 -0
  47. wandb/proto/{wandb_internal_codegen.py → wandb_generate_proto.py} +1 -35
  48. wandb/proto/wandb_internal_pb2.py +2 -0
  49. wandb/proto/wandb_server_pb2.py +2 -0
  50. wandb/proto/wandb_settings_pb2.py +2 -0
  51. wandb/proto/wandb_telemetry_pb2.py +2 -0
  52. wandb/sdk/artifacts/artifact.py +76 -23
  53. wandb/sdk/artifacts/artifact_manifest.py +1 -1
  54. wandb/sdk/artifacts/artifact_manifest_entry.py +6 -3
  55. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -1
  56. wandb/sdk/artifacts/artifact_saver.py +1 -10
  57. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +6 -2
  58. wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
  59. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
  60. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +2 -42
  61. wandb/sdk/artifacts/storage_policy.py +1 -12
  62. wandb/sdk/data_types/_dtypes.py +5 -2
  63. wandb/sdk/data_types/html.py +1 -1
  64. wandb/sdk/data_types/image.py +1 -1
  65. wandb/sdk/data_types/object_3d.py +1 -1
  66. wandb/sdk/data_types/video.py +4 -2
  67. wandb/sdk/interface/interface.py +13 -0
  68. wandb/sdk/interface/interface_shared.py +1 -1
  69. wandb/sdk/internal/file_pusher.py +2 -5
  70. wandb/sdk/internal/file_stream.py +6 -19
  71. wandb/sdk/internal/internal_api.py +160 -138
  72. wandb/sdk/internal/job_builder.py +207 -135
  73. wandb/sdk/internal/progress.py +0 -28
  74. wandb/sdk/internal/sender.py +105 -42
  75. wandb/sdk/internal/settings_static.py +8 -1
  76. wandb/sdk/internal/system/assets/gpu.py +2 -0
  77. wandb/sdk/internal/system/assets/trainium.py +3 -3
  78. wandb/sdk/internal/system/system_info.py +4 -2
  79. wandb/sdk/internal/update.py +1 -1
  80. wandb/sdk/launch/__init__.py +9 -1
  81. wandb/sdk/launch/_launch.py +4 -24
  82. wandb/sdk/launch/_launch_add.py +1 -3
  83. wandb/sdk/launch/_project_spec.py +184 -224
  84. wandb/sdk/launch/agent/agent.py +58 -18
  85. wandb/sdk/launch/agent/config.py +0 -3
  86. wandb/sdk/launch/builder/abstract.py +67 -0
  87. wandb/sdk/launch/builder/build.py +165 -576
  88. wandb/sdk/launch/builder/context_manager.py +235 -0
  89. wandb/sdk/launch/builder/docker_builder.py +7 -23
  90. wandb/sdk/launch/builder/kaniko_builder.py +10 -23
  91. wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
  92. wandb/sdk/launch/create_job.py +51 -45
  93. wandb/sdk/launch/environment/aws_environment.py +26 -1
  94. wandb/sdk/launch/inputs/files.py +148 -0
  95. wandb/sdk/launch/inputs/internal.py +224 -0
  96. wandb/sdk/launch/inputs/manage.py +95 -0
  97. wandb/sdk/launch/runner/abstract.py +2 -2
  98. wandb/sdk/launch/runner/kubernetes_monitor.py +45 -12
  99. wandb/sdk/launch/runner/kubernetes_runner.py +6 -8
  100. wandb/sdk/launch/runner/local_container.py +2 -3
  101. wandb/sdk/launch/runner/local_process.py +8 -29
  102. wandb/sdk/launch/runner/sagemaker_runner.py +20 -14
  103. wandb/sdk/launch/runner/vertex_runner.py +8 -7
  104. wandb/sdk/launch/sweeps/scheduler.py +2 -0
  105. wandb/sdk/launch/sweeps/utils.py +2 -2
  106. wandb/sdk/launch/utils.py +16 -138
  107. wandb/sdk/lib/_settings_toposort_generated.py +2 -5
  108. wandb/sdk/lib/apikey.py +4 -2
  109. wandb/sdk/lib/config_util.py +3 -3
  110. wandb/sdk/lib/proto_util.py +22 -1
  111. wandb/sdk/lib/redirect.py +1 -1
  112. wandb/sdk/service/service.py +2 -1
  113. wandb/sdk/service/streams.py +5 -5
  114. wandb/sdk/wandb_init.py +25 -59
  115. wandb/sdk/wandb_login.py +28 -25
  116. wandb/sdk/wandb_run.py +135 -70
  117. wandb/sdk/wandb_settings.py +33 -64
  118. wandb/sdk/wandb_watch.py +1 -1
  119. wandb/sklearn/plot/classifier.py +4 -6
  120. wandb/sync/sync.py +2 -2
  121. wandb/testing/relay.py +32 -17
  122. wandb/util.py +39 -37
  123. wandb/wandb_agent.py +3 -3
  124. wandb/wandb_controller.py +3 -2
  125. {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/METADATA +7 -9
  126. {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/RECORD +129 -151
  127. {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/WHEEL +1 -1
  128. wandb/apis/reports/v1/_blocks.py +0 -1406
  129. wandb/apis/reports/v1/_helpers.py +0 -70
  130. wandb/apis/reports/v1/_panels.py +0 -1282
  131. wandb/apis/reports/v1/_templates.py +0 -478
  132. wandb/apis/reports/v1/blocks.py +0 -27
  133. wandb/apis/reports/v1/helpers.py +0 -2
  134. wandb/apis/reports/v1/mutations.py +0 -66
  135. wandb/apis/reports/v1/panels.py +0 -17
  136. wandb/apis/reports/v1/report.py +0 -268
  137. wandb/apis/reports/v1/runset.py +0 -144
  138. wandb/apis/reports/v1/templates.py +0 -7
  139. wandb/apis/reports/v1/util.py +0 -406
  140. wandb/apis/reports/v1/validators.py +0 -131
  141. wandb/apis/reports/v2/blocks.py +0 -25
  142. wandb/apis/reports/v2/expr_parsing.py +0 -257
  143. wandb/apis/reports/v2/gql.py +0 -68
  144. wandb/apis/reports/v2/interface.py +0 -1911
  145. wandb/apis/reports/v2/internal.py +0 -867
  146. wandb/apis/reports/v2/metrics.py +0 -6
  147. wandb/apis/reports/v2/panels.py +0 -15
  148. wandb/catboost/__init__.py +0 -9
  149. wandb/fastai/__init__.py +0 -9
  150. wandb/keras/__init__.py +0 -19
  151. wandb/lightgbm/__init__.py +0 -9
  152. wandb/plots/__init__.py +0 -6
  153. wandb/plots/explain_text.py +0 -36
  154. wandb/plots/heatmap.py +0 -81
  155. wandb/plots/named_entity.py +0 -43
  156. wandb/plots/part_of_speech.py +0 -50
  157. wandb/plots/plot_definitions.py +0 -768
  158. wandb/plots/precision_recall.py +0 -121
  159. wandb/plots/roc.py +0 -103
  160. wandb/sacred/__init__.py +0 -3
  161. wandb/xgboost/__init__.py +0 -9
  162. {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/entry_points.txt +0 -0
  163. {wandb-0.17.0rc2.dist-info → wandb-0.17.2.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 %s" % entity
200
+ message = "No projects found for {}".format(entity)
198
201
  else:
199
- message = 'Latest projects for "%s"' % entity
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="%s")' % project, bold=True),
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
- from wandb.util import get_core_path
436
+ wandb._sentry.configure_scope(process_context="wandb_beta")
437
+ wandb.require("core")
434
438
 
435
- if not get_core_path():
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
  )
@@ -876,6 +880,14 @@ def sync(
876
880
  default=False,
877
881
  help="Resume a sweep to continue running new runs.",
878
882
  )
883
+ @click.option(
884
+ "--prior_run",
885
+ "-R",
886
+ "prior_runs",
887
+ multiple=True,
888
+ default=None,
889
+ help="ID of an existing run to add to this sweep",
890
+ )
879
891
  @click.argument("config_yaml_or_sweep_id")
880
892
  @click.pass_context
881
893
  @display_error
@@ -893,6 +905,7 @@ def sweep(
893
905
  cancel,
894
906
  pause,
895
907
  resume,
908
+ prior_runs,
896
909
  config_yaml_or_sweep_id,
897
910
  ):
898
911
  state_args = "stop", "cancel", "pause", "resume"
@@ -923,7 +936,7 @@ def sweep(
923
936
  "resume": "Resuming",
924
937
  }
925
938
  wandb.termlog(f"{ings[state]} sweep {entity}/{project}/{sweep_id}")
926
- getattr(api, "%s_sweep" % state)(sweep_id, entity=entity, project=project)
939
+ getattr(api, "{}_sweep".format(state))(sweep_id, entity=entity, project=project)
927
940
  wandb.termlog("Done.")
928
941
  return
929
942
  else:
@@ -1034,6 +1047,7 @@ def sweep(
1034
1047
  project=project,
1035
1048
  entity=entity,
1036
1049
  obj_id=sweep_obj_id,
1050
+ prior_runs=prior_runs,
1037
1051
  )
1038
1052
  sweep_utils.handle_sweep_config_violations(warnings)
1039
1053
 
@@ -1100,6 +1114,14 @@ def sweep(
1100
1114
  default=None,
1101
1115
  help="Resume a launch sweep by passing an 8-char sweep id. Queue required",
1102
1116
  )
1117
+ @click.option(
1118
+ "--prior_run",
1119
+ "-R",
1120
+ "prior_runs",
1121
+ multiple=True,
1122
+ default=None,
1123
+ help="ID of an existing run to add to this sweep",
1124
+ )
1103
1125
  @click.argument("config", required=False, type=click.Path(exists=True))
1104
1126
  @click.pass_context
1105
1127
  @display_error
@@ -1110,6 +1132,7 @@ def launch_sweep(
1110
1132
  queue,
1111
1133
  config,
1112
1134
  resume_id,
1135
+ prior_runs,
1113
1136
  ):
1114
1137
  api = _get_cling_api()
1115
1138
  env = os.environ
@@ -1294,6 +1317,7 @@ def launch_sweep(
1294
1317
  obj_id=sweep_obj_id, # if resuming
1295
1318
  launch_scheduler=launch_scheduler_with_queue,
1296
1319
  state="PENDING",
1320
+ prior_runs=prior_runs,
1297
1321
  )
1298
1322
  sweep_utils.handle_sweep_config_violations(warnings)
1299
1323
  # Log nicely formatted sweep information
@@ -1307,7 +1331,14 @@ def launch_sweep(
1307
1331
 
1308
1332
 
1309
1333
  @cli.command(help=f"Launch or queue a W&B Job. See {wburls.get('cli_launch')}")
1310
- @click.option("--uri", "-u", metavar="(str)", default=None, hidden=True)
1334
+ @click.option(
1335
+ "--uri",
1336
+ "-u",
1337
+ metavar="(str)",
1338
+ default=None,
1339
+ help="Local path or git repo uri to launch. If provided this command will "
1340
+ "create a job from the specified uri.",
1341
+ )
1311
1342
  @click.option(
1312
1343
  "--job",
1313
1344
  "-j",
@@ -1332,6 +1363,20 @@ def launch_sweep(
1332
1363
  hidden=True,
1333
1364
  help="Version of the project to run, as a Git commit reference for Git projects.",
1334
1365
  )
1366
+ @click.option(
1367
+ "--build-context",
1368
+ metavar="(str)",
1369
+ help="Path to the build context within the source code. Defaults to the "
1370
+ "root of the source code. Compatible only with -u.",
1371
+ )
1372
+ @click.option(
1373
+ "--job-name",
1374
+ "-J",
1375
+ metavar="(str)",
1376
+ default=None,
1377
+ hidden=True,
1378
+ help="Name for the job created if the -u,--uri flag is passed in.",
1379
+ )
1335
1380
  @click.option(
1336
1381
  "--name",
1337
1382
  envvar="WANDB_NAME",
@@ -1456,6 +1501,7 @@ def launch(
1456
1501
  job,
1457
1502
  entry_point,
1458
1503
  git_version,
1504
+ build_context,
1459
1505
  name,
1460
1506
  resource,
1461
1507
  entity,
@@ -1471,6 +1517,7 @@ def launch(
1471
1517
  project_queue,
1472
1518
  dockerfile,
1473
1519
  priority,
1520
+ job_name,
1474
1521
  ):
1475
1522
  """Start a W&B run from the given URI.
1476
1523
 
@@ -1486,6 +1533,8 @@ def launch(
1486
1533
  f"=== Launch called with kwargs {locals()} CLI Version: {wandb.__version__}==="
1487
1534
  )
1488
1535
  from wandb.sdk.launch._launch import _launch
1536
+ from wandb.sdk.launch.create_job import _create_job
1537
+ from wandb.sdk.launch.utils import _is_git_uri
1489
1538
 
1490
1539
  api = _get_cling_api()
1491
1540
  wandb._sentry.configure_scope(process_context="launch_cli")
@@ -1532,6 +1581,36 @@ def launch(
1532
1581
 
1533
1582
  run_id = config.get("run_id")
1534
1583
 
1584
+ # If URI was provided, we need to create a job from it.
1585
+ if uri:
1586
+ if entry_point is None:
1587
+ raise LaunchError(
1588
+ "Cannot provide a uri without an entry point. Please provide an "
1589
+ "entry point with --entry-point or -E."
1590
+ )
1591
+ if job is not None:
1592
+ raise LaunchError("Cannot provide both a uri and a job name.")
1593
+ job_type = (
1594
+ "git" if _is_git_uri(uri) else "code"
1595
+ ) # TODO: Add support for local URIs with git.
1596
+ if entity is None:
1597
+ entity = launch_utils.get_default_entity(api, config)
1598
+ artifact, _, _ = _create_job(
1599
+ api,
1600
+ job_type,
1601
+ uri,
1602
+ entrypoint=" ".join(entry_point),
1603
+ git_hash=git_version,
1604
+ name=job_name,
1605
+ project=project,
1606
+ build_context=build_context,
1607
+ dockerfile=dockerfile,
1608
+ entity=entity,
1609
+ )
1610
+ if artifact is None:
1611
+ raise LaunchError(f"Failed to create job from uri: {uri}")
1612
+ job = f"{entity}/{project}/{artifact.name}"
1613
+
1535
1614
  if dockerfile:
1536
1615
  if "overrides" in config:
1537
1616
  config["overrides"]["dockerfile"] = dockerfile
@@ -1565,7 +1644,6 @@ def launch(
1565
1644
  run = asyncio.run(
1566
1645
  _launch(
1567
1646
  api,
1568
- uri,
1569
1647
  job,
1570
1648
  project=project,
1571
1649
  entity=entity,
@@ -1602,7 +1680,6 @@ def launch(
1602
1680
  try:
1603
1681
  _launch_add(
1604
1682
  api,
1605
- uri,
1606
1683
  job,
1607
1684
  config,
1608
1685
  template_variables,
@@ -1641,13 +1718,6 @@ def launch(
1641
1718
  metavar="<queue(s)>",
1642
1719
  help="The name of a queue for the agent to watch. Multiple -q flags supported.",
1643
1720
  )
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
1721
  @click.option(
1652
1722
  "--entity",
1653
1723
  "-e",
@@ -1684,7 +1754,6 @@ def launch(
1684
1754
  @display_error
1685
1755
  def launch_agent(
1686
1756
  ctx,
1687
- project=None,
1688
1757
  entity=None,
1689
1758
  queues=None,
1690
1759
  max_jobs=None,
@@ -1709,7 +1778,7 @@ def launch_agent(
1709
1778
  api = _get_cling_api()
1710
1779
  wandb._sentry.configure_scope(process_context="launch_agent")
1711
1780
  agent_config, api = _launch.resolve_agent_config(
1712
- entity, project, max_jobs, queues, config, verbose
1781
+ entity, max_jobs, queues, config, verbose
1713
1782
  )
1714
1783
 
1715
1784
  if len(agent_config.get("queues")) == 0:
@@ -1907,14 +1976,16 @@ def describe(job):
1907
1976
  "--entry-point",
1908
1977
  "-E",
1909
1978
  "entrypoint",
1910
- help="Entrypoint to the script, including an executable and an entrypoint file. Required for code or repo jobs",
1979
+ help="Entrypoint to the script, including an executable and an entrypoint "
1980
+ "file. Required for code or repo jobs. If --build-context is provided, "
1981
+ "paths in the entrypoint command will be relative to the build context.",
1911
1982
  )
1912
1983
  @click.option(
1913
1984
  "--git-hash",
1914
1985
  "-g",
1915
1986
  "git_hash",
1916
1987
  type=str,
1917
- help="Hash to a specific git commit.",
1988
+ help="Commit reference to use as the source for git jobs",
1918
1989
  )
1919
1990
  @click.option(
1920
1991
  "--runtime",
@@ -1922,6 +1993,20 @@ def describe(job):
1922
1993
  type=str,
1923
1994
  help="Python runtime to execute the job",
1924
1995
  )
1996
+ @click.option(
1997
+ "--build-context",
1998
+ "-b",
1999
+ type=str,
2000
+ help="Path to the build context from the root of the job source code. If "
2001
+ "provided, this is used as the base path for the Dockerfile and entrypoint.",
2002
+ )
2003
+ @click.option(
2004
+ "--dockerfile",
2005
+ "-D",
2006
+ type=str,
2007
+ help="Path to the Dockerfile for the job. If --build-context is provided, "
2008
+ "the Dockerfile path will be relative to the build context.",
2009
+ )
1925
2010
  @click.argument(
1926
2011
  "job_type",
1927
2012
  type=click.Choice(("git", "code", "image")),
@@ -1938,6 +2023,8 @@ def create(
1938
2023
  entrypoint,
1939
2024
  git_hash,
1940
2025
  runtime,
2026
+ build_context,
2027
+ dockerfile,
1941
2028
  ):
1942
2029
  """Create a job from a source, without a wandb run.
1943
2030
 
@@ -1980,6 +2067,8 @@ def create(
1980
2067
  entrypoint=entrypoint,
1981
2068
  git_hash=git_hash,
1982
2069
  runtime=runtime,
2070
+ build_context=build_context,
2071
+ dockerfile=dockerfile,
1983
2072
  )
1984
2073
  if not artifact:
1985
2074
  wandb.termerror("Job creation failed")
@@ -2038,13 +2127,13 @@ def docker_run(ctx, docker_run_args):
2038
2127
  if image:
2039
2128
  resolved_image = wandb.docker.image_id(image)
2040
2129
  if resolved_image:
2041
- args = ["-e", "WANDB_DOCKER=%s" % resolved_image] + args
2130
+ args = ["-e", "WANDB_DOCKER={}".format(resolved_image)] + args
2042
2131
  else:
2043
2132
  wandb.termlog(
2044
2133
  "Couldn't detect image argument, running command without the WANDB_DOCKER env variable"
2045
2134
  )
2046
2135
  if api.api_key:
2047
- args = ["-e", "WANDB_API_KEY=%s" % api.api_key] + args
2136
+ args = ["-e", "WANDB_API_KEY={}".format(api.api_key)] + args
2048
2137
  else:
2049
2138
  wandb.termlog(
2050
2139
  "Not logged in, run `wandb login` from the host machine to enable result logging"
@@ -2135,14 +2224,17 @@ def docker(
2135
2224
  resolved_image = wandb.docker.image_id(image)
2136
2225
  if resolved_image is None:
2137
2226
  raise ClickException(
2138
- "Couldn't find image locally or in a registry, try running `docker pull %s`"
2139
- % image
2227
+ "Couldn't find image locally or in a registry, try running `docker pull {}`".format(
2228
+ image
2229
+ )
2140
2230
  )
2141
2231
  if digest:
2142
2232
  sys.stdout.write(resolved_image)
2143
2233
  exit(0)
2144
2234
 
2145
- existing = wandb.docker.shell(["ps", "-f", "ancestor=%s" % resolved_image, "-q"])
2235
+ existing = wandb.docker.shell(
2236
+ ["ps", "-f", "ancestor={}".format(resolved_image), "-q"]
2237
+ )
2146
2238
  if existing:
2147
2239
  if click.confirm(
2148
2240
  "Found running container with the same image, do you want to attach?"
@@ -2156,7 +2248,7 @@ def docker(
2156
2248
  "-e",
2157
2249
  "LANG=C.UTF-8",
2158
2250
  "-e",
2159
- "WANDB_DOCKER=%s" % resolved_image,
2251
+ "WANDB_DOCKER={}".format(resolved_image),
2160
2252
  "--ipc=host",
2161
2253
  "-v",
2162
2254
  wandb.docker.entrypoint + ":/wandb-entrypoint.sh",
@@ -2169,7 +2261,7 @@ def docker(
2169
2261
  # TODO: We should default to the working directory if defined
2170
2262
  command.extend(["-v", cwd + ":" + dir, "-w", dir])
2171
2263
  if api.api_key:
2172
- command.extend(["-e", "WANDB_API_KEY=%s" % api.api_key])
2264
+ command.extend(["-e", "WANDB_API_KEY={}".format(api.api_key)])
2173
2265
  else:
2174
2266
  wandb.termlog(
2175
2267
  "Couldn't find WANDB_API_KEY, run `wandb login` to enable streaming metrics"
@@ -2177,16 +2269,15 @@ def docker(
2177
2269
  if jupyter:
2178
2270
  command.extend(["-e", "WANDB_ENSURE_JUPYTER=1", "-p", port + ":8888"])
2179
2271
  no_tty = True
2180
- cmd = (
2181
- "jupyter lab --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --notebook-dir %s"
2182
- % dir
2272
+ cmd = "jupyter lab --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --notebook-dir {}".format(
2273
+ dir
2183
2274
  )
2184
2275
  command.extend(args)
2185
2276
  if no_tty:
2186
2277
  command.extend([image, shell, "-c", cmd])
2187
2278
  else:
2188
2279
  if cmd:
2189
- command.extend(["-e", "WANDB_COMMAND=%s" % cmd])
2280
+ command.extend(["-e", "WANDB_COMMAND={}".format(cmd)])
2190
2281
  command.extend(["-it", image, shell])
2191
2282
  wandb.termlog("Launching docker container \U0001f6a2")
2192
2283
  subprocess.call(command)
@@ -2272,7 +2363,7 @@ def start(ctx, port, env, daemon, upgrade, edge):
2272
2363
  exit(1)
2273
2364
  image = "docker.pkg.github.com/wandb/core/local" if edge else "wandb/local"
2274
2365
  username = getpass.getuser()
2275
- env_vars = ["-e", "LOCAL_USERNAME=%s" % username]
2366
+ env_vars = ["-e", "LOCAL_USERNAME={}".format(username)]
2276
2367
  for e in env:
2277
2368
  env_vars.append("-e")
2278
2369
  env_vars.append(e)
@@ -2306,7 +2397,9 @@ def start(ctx, port, env, daemon, upgrade, edge):
2306
2397
  )
2307
2398
  exit(1)
2308
2399
  else:
2309
- wandb.termlog("W&B server started at http://localhost:%s \U0001f680" % port)
2400
+ wandb.termlog(
2401
+ "W&B server started at http://localhost:{} \U0001f680".format(port)
2402
+ )
2310
2403
  wandb.termlog("You can stop the server by running `wandb server stop`")
2311
2404
  if not api.api_key:
2312
2405
  # Let the server start before potentially launching a browser
@@ -2443,7 +2536,7 @@ def get(path, root, type):
2443
2536
  )
2444
2537
  artifact = public_api.artifact(full_path, type=type)
2445
2538
  path = artifact.download(root=root)
2446
- wandb.termlog("Artifact downloaded to %s" % path)
2539
+ wandb.termlog("Artifact downloaded to {}".format(path))
2447
2540
  except ValueError:
2448
2541
  raise ClickException("Unable to download artifact")
2449
2542
 
@@ -2521,17 +2614,17 @@ def pull(run, project, entity):
2521
2614
 
2522
2615
  for name in urls:
2523
2616
  if api.file_current(name, urls[name]["md5"]):
2524
- click.echo("File %s is up to date" % name)
2617
+ click.echo("File {} is up to date".format(name))
2525
2618
  else:
2526
2619
  length, response = api.download_file(urls[name]["url"])
2527
2620
  # TODO: I had to add this because some versions in CI broke click.progressbar
2528
- sys.stdout.write("File %s\r" % name)
2621
+ sys.stdout.write("File {}\r".format(name))
2529
2622
  dirname = os.path.dirname(name)
2530
2623
  if dirname != "":
2531
2624
  filesystem.mkdir_exists_ok(dirname)
2532
2625
  with click.progressbar(
2533
2626
  length=length,
2534
- label="File %s" % name,
2627
+ label="File {}".format(name),
2535
2628
  fill_char=click.style("&", fg="green"),
2536
2629
  ) as bar:
2537
2630
  with open(name, "wb") as f:
@@ -2577,11 +2670,8 @@ def restore(ctx, run, no_git, branch, project, entity):
2577
2670
  )
2578
2671
  repo = metadata.get("git", {}).get("repo")
2579
2672
  image = metadata.get("docker")
2580
- restore_message = (
2581
- """`wandb restore` needs to be run from the same git repository as the original run.
2582
- Run `git clone %s` and restore from there or pass the --no-git flag."""
2583
- % repo
2584
- )
2673
+ restore_message = """`wandb restore` needs to be run from the same git repository as the original run.
2674
+ Run `git clone {}` and restore from there or pass the --no-git flag.""".format(repo)
2585
2675
  if no_git:
2586
2676
  commit = None
2587
2677
  elif not api.git.enabled:
@@ -2626,18 +2716,21 @@ Run `git clone %s` and restore from there or pass the --no-git flag."""
2626
2716
  else:
2627
2717
  patch_path = None
2628
2718
 
2629
- branch_name = "wandb/%s" % run
2719
+ branch_name = "wandb/{}".format(run)
2630
2720
  if branch and branch_name not in api.git.repo.branches:
2631
2721
  api.git.repo.git.checkout(commit, b=branch_name)
2632
- wandb.termlog("Created branch %s" % click.style(branch_name, bold=True))
2722
+ wandb.termlog(
2723
+ "Created branch {}".format(click.style(branch_name, bold=True))
2724
+ )
2633
2725
  elif branch:
2634
2726
  wandb.termlog(
2635
- "Using existing branch, run `git branch -D %s` from master for a clean checkout"
2636
- % branch_name
2727
+ "Using existing branch, run `git branch -D {}` from master for a clean checkout".format(
2728
+ branch_name
2729
+ )
2637
2730
  )
2638
2731
  api.git.repo.git.checkout(branch_name)
2639
2732
  else:
2640
- wandb.termlog("Checking out %s in detached mode" % commit)
2733
+ wandb.termlog("Checking out {} in detached mode".format(commit))
2641
2734
  api.git.repo.git.checkout(commit)
2642
2735
 
2643
2736
  if patch_path:
@@ -2675,7 +2768,7 @@ Run `git clone %s` and restore from there or pass the --no-git flag."""
2675
2768
  with open(config_path, "w") as f:
2676
2769
  f.write(s)
2677
2770
 
2678
- wandb.termlog("Restored config variables to %s" % config_path)
2771
+ wandb.termlog("Restored config variables to {}".format(config_path))
2679
2772
  if image:
2680
2773
  if not metadata["program"].startswith("<") and metadata.get("args") is not None:
2681
2774
  # TODO: we may not want to default to python here.
@@ -2710,7 +2803,9 @@ def magic(ctx, program, args):
2710
2803
  with open(program, "rb") as fp:
2711
2804
  code = compile(fp.read(), program, "exec")
2712
2805
  except OSError:
2713
- click.echo(click.style("Could not launch program: %s" % program, fg="red"))
2806
+ click.echo(
2807
+ click.style("Could not launch program: {}".format(program), fg="red")
2808
+ )
2714
2809
  sys.exit(1)
2715
2810
  globs = {
2716
2811
  "__file__": program,
@@ -2718,14 +2813,11 @@ def magic(ctx, program, args):
2718
2813
  "__package__": None,
2719
2814
  "wandb_magic_install": magic_install,
2720
2815
  }
2721
- prep = (
2722
- """
2816
+ prep = """
2723
2817
  import __main__
2724
- __main__.__file__ = "%s"
2818
+ __main__.__file__ = "{}"
2725
2819
  wandb_magic_install()
2726
- """
2727
- % program
2728
- )
2820
+ """.format(program)
2729
2821
  magic_run(prep, globs, None)
2730
2822
  magic_run(code, globs, None)
2731
2823
 
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:%s" % tag
205
+ return "wandb/deepo:{}".format(tag)
206
206
 
207
207
 
208
208
  def parse_repository_tag(repo_name: str) -> Tuple[str, Optional[str]]:
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 = "", newline: bool = True, repeat: bool = True, prefix: bool = True
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="", newline=True, repeat=True, prefix=True, silent=False, level=logging.INFO
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
@@ -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, SaveFnAsync
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
  )
@@ -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: Union[
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 prepare_async() in parallel. The PrepareBatcher thread
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
- if isinstance(prepare_request.response_channel, queue.Queue):
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 prepare_async(
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()