wandb 0.16.6__py3-none-any.whl → 0.17.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. package_readme.md +95 -0
  2. wandb/__init__.py +2 -3
  3. wandb/agents/pyagent.py +0 -1
  4. wandb/analytics/sentry.py +2 -1
  5. wandb/apis/importers/internals/internal.py +0 -1
  6. wandb/apis/importers/internals/protocols.py +30 -56
  7. wandb/apis/importers/mlflow.py +13 -26
  8. wandb/apis/importers/wandb.py +8 -14
  9. wandb/apis/internal.py +0 -3
  10. wandb/apis/public/api.py +55 -3
  11. wandb/apis/public/artifacts.py +1 -0
  12. wandb/apis/public/files.py +1 -0
  13. wandb/apis/public/history.py +1 -0
  14. wandb/apis/public/jobs.py +17 -4
  15. wandb/apis/public/projects.py +1 -0
  16. wandb/apis/public/reports.py +1 -0
  17. wandb/apis/public/runs.py +15 -17
  18. wandb/apis/public/sweeps.py +1 -0
  19. wandb/apis/public/teams.py +1 -0
  20. wandb/apis/public/users.py +1 -0
  21. wandb/apis/reports/v1/_blocks.py +3 -7
  22. wandb/apis/reports/v2/gql.py +1 -0
  23. wandb/apis/reports/v2/interface.py +3 -4
  24. wandb/apis/reports/v2/internal.py +5 -8
  25. wandb/cli/cli.py +92 -22
  26. wandb/data_types.py +9 -6
  27. wandb/docker/__init__.py +1 -1
  28. wandb/env.py +38 -8
  29. wandb/errors/__init__.py +5 -0
  30. wandb/errors/term.py +10 -2
  31. wandb/filesync/step_checksum.py +1 -4
  32. wandb/filesync/step_prepare.py +4 -24
  33. wandb/filesync/step_upload.py +4 -106
  34. wandb/filesync/upload_job.py +0 -76
  35. wandb/integration/catboost/catboost.py +1 -1
  36. wandb/integration/fastai/__init__.py +1 -0
  37. wandb/integration/huggingface/resolver.py +2 -2
  38. wandb/integration/keras/__init__.py +1 -0
  39. wandb/integration/keras/callbacks/metrics_logger.py +1 -1
  40. wandb/integration/keras/keras.py +7 -7
  41. wandb/integration/langchain/wandb_tracer.py +1 -0
  42. wandb/integration/lightning/fabric/logger.py +1 -3
  43. wandb/integration/metaflow/metaflow.py +41 -6
  44. wandb/integration/openai/fine_tuning.py +3 -3
  45. wandb/integration/prodigy/prodigy.py +1 -1
  46. wandb/old/summary.py +1 -1
  47. wandb/plot/confusion_matrix.py +1 -1
  48. wandb/plot/pr_curve.py +2 -1
  49. wandb/plot/roc_curve.py +2 -1
  50. wandb/{plots → plot}/utils.py +13 -25
  51. wandb/proto/v3/wandb_internal_pb2.py +364 -332
  52. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  53. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  54. wandb/proto/v4/wandb_internal_pb2.py +322 -316
  55. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  56. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  57. wandb/proto/wandb_deprecated.py +7 -1
  58. wandb/proto/wandb_internal_codegen.py +3 -29
  59. wandb/sdk/artifacts/artifact.py +26 -11
  60. wandb/sdk/artifacts/artifact_download_logger.py +1 -0
  61. wandb/sdk/artifacts/artifact_file_cache.py +18 -4
  62. wandb/sdk/artifacts/artifact_instance_cache.py +1 -0
  63. wandb/sdk/artifacts/artifact_manifest.py +1 -0
  64. wandb/sdk/artifacts/artifact_manifest_entry.py +7 -3
  65. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -0
  66. wandb/sdk/artifacts/artifact_saver.py +2 -8
  67. wandb/sdk/artifacts/artifact_state.py +1 -0
  68. wandb/sdk/artifacts/artifact_ttl.py +1 -0
  69. wandb/sdk/artifacts/exceptions.py +1 -0
  70. wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
  71. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +13 -18
  72. wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -0
  73. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +1 -0
  74. wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -0
  75. wandb/sdk/artifacts/storage_handlers/s3_handler.py +5 -3
  76. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +1 -0
  77. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +1 -0
  78. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -0
  79. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +3 -42
  80. wandb/sdk/artifacts/storage_policy.py +2 -12
  81. wandb/sdk/data_types/_dtypes.py +8 -8
  82. wandb/sdk/data_types/base_types/media.py +3 -6
  83. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +3 -1
  84. wandb/sdk/data_types/image.py +1 -1
  85. wandb/sdk/data_types/video.py +1 -1
  86. wandb/sdk/integration_utils/auto_logging.py +5 -6
  87. wandb/sdk/integration_utils/data_logging.py +10 -6
  88. wandb/sdk/interface/interface.py +68 -32
  89. wandb/sdk/interface/interface_shared.py +7 -13
  90. wandb/sdk/internal/datastore.py +1 -1
  91. wandb/sdk/internal/file_pusher.py +2 -5
  92. wandb/sdk/internal/file_stream.py +5 -18
  93. wandb/sdk/internal/handler.py +18 -2
  94. wandb/sdk/internal/internal.py +0 -1
  95. wandb/sdk/internal/internal_api.py +1 -129
  96. wandb/sdk/internal/internal_util.py +0 -1
  97. wandb/sdk/internal/job_builder.py +159 -45
  98. wandb/sdk/internal/profiler.py +1 -0
  99. wandb/sdk/internal/progress.py +0 -28
  100. wandb/sdk/internal/run.py +1 -0
  101. wandb/sdk/internal/sender.py +1 -2
  102. wandb/sdk/internal/system/assets/gpu_amd.py +44 -44
  103. wandb/sdk/internal/system/assets/gpu_apple.py +56 -11
  104. wandb/sdk/internal/system/assets/interfaces.py +6 -8
  105. wandb/sdk/internal/system/assets/open_metrics.py +2 -2
  106. wandb/sdk/internal/system/assets/trainium.py +1 -3
  107. wandb/sdk/launch/__init__.py +9 -1
  108. wandb/sdk/launch/_launch.py +4 -24
  109. wandb/sdk/launch/_launch_add.py +1 -3
  110. wandb/sdk/launch/_project_spec.py +186 -224
  111. wandb/sdk/launch/agent/agent.py +37 -13
  112. wandb/sdk/launch/agent/config.py +72 -14
  113. wandb/sdk/launch/builder/abstract.py +69 -1
  114. wandb/sdk/launch/builder/build.py +156 -555
  115. wandb/sdk/launch/builder/context_manager.py +235 -0
  116. wandb/sdk/launch/builder/docker_builder.py +8 -23
  117. wandb/sdk/launch/builder/kaniko_builder.py +12 -25
  118. wandb/sdk/launch/builder/noop.py +1 -0
  119. wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
  120. wandb/sdk/launch/create_job.py +47 -37
  121. wandb/sdk/launch/environment/abstract.py +1 -0
  122. wandb/sdk/launch/environment/gcp_environment.py +1 -0
  123. wandb/sdk/launch/environment/local_environment.py +1 -0
  124. wandb/sdk/launch/inputs/files.py +148 -0
  125. wandb/sdk/launch/inputs/internal.py +217 -0
  126. wandb/sdk/launch/inputs/manage.py +95 -0
  127. wandb/sdk/launch/loader.py +1 -0
  128. wandb/sdk/launch/registry/abstract.py +1 -0
  129. wandb/sdk/launch/registry/azure_container_registry.py +1 -0
  130. wandb/sdk/launch/registry/elastic_container_registry.py +1 -0
  131. wandb/sdk/launch/registry/google_artifact_registry.py +2 -1
  132. wandb/sdk/launch/registry/local_registry.py +1 -0
  133. wandb/sdk/launch/runner/abstract.py +1 -0
  134. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  135. wandb/sdk/launch/runner/kubernetes_runner.py +9 -10
  136. wandb/sdk/launch/runner/local_container.py +2 -3
  137. wandb/sdk/launch/runner/local_process.py +8 -29
  138. wandb/sdk/launch/runner/sagemaker_runner.py +21 -20
  139. wandb/sdk/launch/runner/vertex_runner.py +8 -7
  140. wandb/sdk/launch/sweeps/scheduler.py +4 -3
  141. wandb/sdk/launch/sweeps/scheduler_sweep.py +2 -1
  142. wandb/sdk/launch/sweeps/utils.py +3 -3
  143. wandb/sdk/launch/utils.py +15 -140
  144. wandb/sdk/lib/_settings_toposort_generated.py +0 -5
  145. wandb/sdk/lib/fsm.py +8 -12
  146. wandb/sdk/lib/gitlib.py +4 -4
  147. wandb/sdk/lib/import_hooks.py +1 -1
  148. wandb/sdk/lib/lazyloader.py +0 -1
  149. wandb/sdk/lib/proto_util.py +23 -2
  150. wandb/sdk/lib/redirect.py +19 -14
  151. wandb/sdk/lib/retry.py +3 -2
  152. wandb/sdk/lib/tracelog.py +1 -1
  153. wandb/sdk/service/service.py +19 -16
  154. wandb/sdk/verify/verify.py +2 -1
  155. wandb/sdk/wandb_init.py +14 -55
  156. wandb/sdk/wandb_manager.py +2 -2
  157. wandb/sdk/wandb_require.py +5 -0
  158. wandb/sdk/wandb_run.py +114 -56
  159. wandb/sdk/wandb_settings.py +0 -48
  160. wandb/sdk/wandb_setup.py +1 -1
  161. wandb/sklearn/__init__.py +1 -0
  162. wandb/sklearn/plot/__init__.py +1 -0
  163. wandb/sklearn/plot/classifier.py +11 -12
  164. wandb/sklearn/plot/clusterer.py +2 -1
  165. wandb/sklearn/plot/regressor.py +1 -0
  166. wandb/sklearn/plot/shared.py +1 -0
  167. wandb/sklearn/utils.py +1 -0
  168. wandb/testing/relay.py +4 -4
  169. wandb/trigger.py +1 -0
  170. wandb/util.py +67 -54
  171. wandb/wandb_controller.py +2 -3
  172. wandb/wandb_torch.py +1 -2
  173. {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/METADATA +67 -70
  174. {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/RECORD +177 -187
  175. {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/WHEEL +1 -2
  176. wandb/bin/apple_gpu_stats +0 -0
  177. wandb/catboost/__init__.py +0 -9
  178. wandb/fastai/__init__.py +0 -9
  179. wandb/keras/__init__.py +0 -18
  180. wandb/lightgbm/__init__.py +0 -9
  181. wandb/plots/__init__.py +0 -6
  182. wandb/plots/explain_text.py +0 -36
  183. wandb/plots/heatmap.py +0 -81
  184. wandb/plots/named_entity.py +0 -43
  185. wandb/plots/part_of_speech.py +0 -50
  186. wandb/plots/plot_definitions.py +0 -768
  187. wandb/plots/precision_recall.py +0 -121
  188. wandb/plots/roc.py +0 -103
  189. wandb/sacred/__init__.py +0 -3
  190. wandb/xgboost/__init__.py +0 -9
  191. wandb-0.16.6.dist-info/top_level.txt +0 -1
  192. {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/entry_points.txt +0 -0
  193. {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info/licenses}/LICENSE +0 -0
@@ -716,16 +716,12 @@ class WeaveBlockSummaryTable(Block):
716
716
  "fromOp"
717
717
  ]["inputs"]["run"]["fromOp"]["inputs"]["project"]["fromOp"]["inputs"][
718
718
  "entityName"
719
- ][
720
- "val"
721
- ]
719
+ ]["val"]
722
720
  project = spec["config"]["panelConfig"]["exp"]["fromOp"]["inputs"]["obj"][
723
721
  "fromOp"
724
722
  ]["inputs"]["run"]["fromOp"]["inputs"]["project"]["fromOp"]["inputs"][
725
723
  "projectName"
726
- ][
727
- "val"
728
- ]
724
+ ]["val"]
729
725
  table_name = spec["config"]["panelConfig"]["exp"]["fromOp"]["inputs"]["key"][
730
726
  "val"
731
727
  ]
@@ -1064,7 +1060,7 @@ class WeaveBlockArtifact(Block):
1064
1060
 
1065
1061
 
1066
1062
  class WeaveBlockArtifactVersionedFile(Block):
1067
- """This is a hacky solution to support the most common way of getting Weave artifact verions for now..."""
1063
+ """This is a hacky solution to support the most common way of getting Weave artifact versions for now..."""
1068
1064
 
1069
1065
  entity: str = Attr()
1070
1066
  project: str = Attr()
@@ -1,4 +1,5 @@
1
1
  """GraphQL queries and mutations."""
2
+
2
3
  from wandb_gql import gql
3
4
 
4
5
  view_report = gql(
@@ -1,4 +1,5 @@
1
1
  """Public interfaces for the Report API."""
2
+
2
3
  import os
3
4
  from datetime import datetime
4
5
  from typing import Dict, Iterable, Optional, Tuple, Union
@@ -100,8 +101,7 @@ class Layout(Base):
100
101
 
101
102
 
102
103
  @dataclass(config=dataclass_config)
103
- class Block(Base):
104
- ...
104
+ class Block(Base): ...
105
105
 
106
106
 
107
107
  @dataclass(config=ConfigDict(validate_assignment=True, extra="allow", slots=True))
@@ -706,8 +706,7 @@ class Twitter(Block):
706
706
 
707
707
 
708
708
  @dataclass(config=dataclass_config)
709
- class WeaveBlock(Block):
710
- ...
709
+ class WeaveBlock(Block): ...
711
710
 
712
711
 
713
712
  BlockTypes = Union[
@@ -1,4 +1,5 @@
1
1
  """JSONSchema for internal types. Hopefully this is auto-generated one day!"""
2
+
2
3
  import json
3
4
  import random
4
5
  from copy import deepcopy
@@ -102,16 +103,13 @@ class TextLikeMixin:
102
103
  return obj
103
104
 
104
105
 
105
- class Sentinel(BaseModel):
106
- ...
106
+ class Sentinel(BaseModel): ...
107
107
 
108
108
 
109
- class ReportEntity(Sentinel):
110
- ...
109
+ class ReportEntity(Sentinel): ...
111
110
 
112
111
 
113
- class ReportProject(Sentinel):
114
- ...
112
+ class ReportProject(Sentinel): ...
115
113
 
116
114
 
117
115
  class ReportAPIBaseModel(BaseModel):
@@ -271,8 +269,7 @@ class PanelGridMetadata(ReportAPIBaseModel):
271
269
  # )
272
270
 
273
271
 
274
- class Block(ReportAPIBaseModel):
275
- ...
272
+ class Block(ReportAPIBaseModel): ...
276
273
 
277
274
 
278
275
  class PanelGrid(Block):
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())
@@ -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
  )
@@ -1307,7 +1311,15 @@ 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("--uri", "-u", metavar="(str)", default=None, hidden=True)
1314
+ @click.option(
1315
+ "--uri",
1316
+ "-u",
1317
+ metavar="(str)",
1318
+ default=None,
1319
+ hidden=True,
1320
+ help="Local path or git repo uri to launch. If provided this command will "
1321
+ "create a job from the specified uri.",
1322
+ )
1311
1323
  @click.option(
1312
1324
  "--job",
1313
1325
  "-j",
@@ -1332,6 +1344,20 @@ def launch_sweep(
1332
1344
  hidden=True,
1333
1345
  help="Version of the project to run, as a Git commit reference for Git projects.",
1334
1346
  )
1347
+ @click.option(
1348
+ "--build-context",
1349
+ metavar="(str)",
1350
+ help="Path to the build context within the source code. Defaults to the "
1351
+ "root of the source code. Compatible only with -u.",
1352
+ )
1353
+ @click.option(
1354
+ "--job-name",
1355
+ "-J",
1356
+ metavar="(str)",
1357
+ default=None,
1358
+ hidden=True,
1359
+ help="Name for the job created if the -u,--uri flag is passed in.",
1360
+ )
1335
1361
  @click.option(
1336
1362
  "--name",
1337
1363
  envvar="WANDB_NAME",
@@ -1456,6 +1482,7 @@ def launch(
1456
1482
  job,
1457
1483
  entry_point,
1458
1484
  git_version,
1485
+ build_context,
1459
1486
  name,
1460
1487
  resource,
1461
1488
  entity,
@@ -1471,6 +1498,7 @@ def launch(
1471
1498
  project_queue,
1472
1499
  dockerfile,
1473
1500
  priority,
1501
+ job_name,
1474
1502
  ):
1475
1503
  """Start a W&B run from the given URI.
1476
1504
 
@@ -1486,6 +1514,8 @@ def launch(
1486
1514
  f"=== Launch called with kwargs {locals()} CLI Version: {wandb.__version__}==="
1487
1515
  )
1488
1516
  from wandb.sdk.launch._launch import _launch
1517
+ from wandb.sdk.launch.create_job import _create_job
1518
+ from wandb.sdk.launch.utils import _is_git_uri
1489
1519
 
1490
1520
  api = _get_cling_api()
1491
1521
  wandb._sentry.configure_scope(process_context="launch_cli")
@@ -1532,6 +1562,36 @@ def launch(
1532
1562
 
1533
1563
  run_id = config.get("run_id")
1534
1564
 
1565
+ # If URI was provided, we need to create a job from it.
1566
+ if uri:
1567
+ if entry_point is None:
1568
+ raise LaunchError(
1569
+ "Cannot provide a uri without an entry point. Please provide an "
1570
+ "entry point with --entry-point or -E."
1571
+ )
1572
+ if job is not None:
1573
+ raise LaunchError("Cannot provide both a uri and a job name.")
1574
+ job_type = (
1575
+ "git" if _is_git_uri(uri) else "code"
1576
+ ) # TODO: Add support for local URIs with git.
1577
+ if entity is None:
1578
+ entity = launch_utils.get_default_entity(api, config)
1579
+ artifact, _, _ = _create_job(
1580
+ api,
1581
+ job_type,
1582
+ uri,
1583
+ entrypoint=" ".join(entry_point),
1584
+ git_hash=git_version,
1585
+ name=job_name,
1586
+ project=project,
1587
+ build_context=build_context,
1588
+ dockerfile=dockerfile,
1589
+ entity=entity,
1590
+ )
1591
+ if artifact is None:
1592
+ raise LaunchError(f"Failed to create job from uri: {uri}")
1593
+ job = f"{entity}/{project}/{artifact.name}"
1594
+
1535
1595
  if dockerfile:
1536
1596
  if "overrides" in config:
1537
1597
  config["overrides"]["dockerfile"] = dockerfile
@@ -1565,7 +1625,6 @@ def launch(
1565
1625
  run = asyncio.run(
1566
1626
  _launch(
1567
1627
  api,
1568
- uri,
1569
1628
  job,
1570
1629
  project=project,
1571
1630
  entity=entity,
@@ -1602,7 +1661,6 @@ def launch(
1602
1661
  try:
1603
1662
  _launch_add(
1604
1663
  api,
1605
- uri,
1606
1664
  job,
1607
1665
  config,
1608
1666
  template_variables,
@@ -1641,13 +1699,6 @@ def launch(
1641
1699
  metavar="<queue(s)>",
1642
1700
  help="The name of a queue for the agent to watch. Multiple -q flags supported.",
1643
1701
  )
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
1702
  @click.option(
1652
1703
  "--entity",
1653
1704
  "-e",
@@ -1684,7 +1735,6 @@ def launch(
1684
1735
  @display_error
1685
1736
  def launch_agent(
1686
1737
  ctx,
1687
- project=None,
1688
1738
  entity=None,
1689
1739
  queues=None,
1690
1740
  max_jobs=None,
@@ -1709,7 +1759,7 @@ def launch_agent(
1709
1759
  api = _get_cling_api()
1710
1760
  wandb._sentry.configure_scope(process_context="launch_agent")
1711
1761
  agent_config, api = _launch.resolve_agent_config(
1712
- entity, project, max_jobs, queues, config, verbose
1762
+ entity, max_jobs, queues, config, verbose
1713
1763
  )
1714
1764
 
1715
1765
  if len(agent_config.get("queues")) == 0:
@@ -1907,14 +1957,16 @@ def describe(job):
1907
1957
  "--entry-point",
1908
1958
  "-E",
1909
1959
  "entrypoint",
1910
- help="Entrypoint to the script, including an executable and an entrypoint file. Required for code or repo jobs",
1960
+ help="Entrypoint to the script, including an executable and an entrypoint "
1961
+ "file. Required for code or repo jobs. If --build-context is provided, "
1962
+ "paths in the entrypoint command will be relative to the build context.",
1911
1963
  )
1912
1964
  @click.option(
1913
1965
  "--git-hash",
1914
1966
  "-g",
1915
1967
  "git_hash",
1916
1968
  type=str,
1917
- help="Hash to a specific git commit.",
1969
+ help="Commit reference to use as the source for git jobs",
1918
1970
  )
1919
1971
  @click.option(
1920
1972
  "--runtime",
@@ -1922,6 +1974,20 @@ def describe(job):
1922
1974
  type=str,
1923
1975
  help="Python runtime to execute the job",
1924
1976
  )
1977
+ @click.option(
1978
+ "--build-context",
1979
+ "-b",
1980
+ type=str,
1981
+ help="Path to the build context from the root of the job source code. If "
1982
+ "provided, this is used as the base path for the Dockerfile and entrypoint.",
1983
+ )
1984
+ @click.option(
1985
+ "--dockerfile",
1986
+ "-D",
1987
+ type=str,
1988
+ help="Path to the Dockerfile for the job. If --build-context is provided, "
1989
+ "the Dockerfile path will be relative to the build context.",
1990
+ )
1925
1991
  @click.argument(
1926
1992
  "job_type",
1927
1993
  type=click.Choice(("git", "code", "image")),
@@ -1938,6 +2004,8 @@ def create(
1938
2004
  entrypoint,
1939
2005
  git_hash,
1940
2006
  runtime,
2007
+ build_context,
2008
+ dockerfile,
1941
2009
  ):
1942
2010
  """Create a job from a source, without a wandb run.
1943
2011
 
@@ -1980,6 +2048,8 @@ def create(
1980
2048
  entrypoint=entrypoint,
1981
2049
  git_hash=git_hash,
1982
2050
  runtime=runtime,
2051
+ build_context=build_context,
2052
+ dockerfile=dockerfile,
1983
2053
  )
1984
2054
  if not artifact:
1985
2055
  wandb.termerror("Job creation failed")
@@ -2188,7 +2258,7 @@ def docker(
2188
2258
  if cmd:
2189
2259
  command.extend(["-e", "WANDB_COMMAND=%s" % cmd])
2190
2260
  command.extend(["-it", image, shell])
2191
- wandb.termlog("Launching docker container \U0001F6A2")
2261
+ wandb.termlog("Launching docker container \U0001f6a2")
2192
2262
  subprocess.call(command)
2193
2263
 
2194
2264
 
@@ -2306,7 +2376,7 @@ def start(ctx, port, env, daemon, upgrade, edge):
2306
2376
  )
2307
2377
  exit(1)
2308
2378
  else:
2309
- wandb.termlog("W&B server started at http://localhost:%s \U0001F680" % port)
2379
+ wandb.termlog("W&B server started at http://localhost:%s \U0001f680" % port)
2310
2380
  wandb.termlog("You can stop the server by running `wandb server stop`")
2311
2381
  if not api.api_key:
2312
2382
  # Let the server start before potentially launching a browser
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 availble for legacy reasons and should not be used.
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. This can be one of the normal python classes, an internal W&B type, or an example objec, like an instance of wandb.Image or wandb.Classes.
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.
@@ -513,9 +516,9 @@ class Table(Media):
513
516
  deserialized = np.load(
514
517
  source_artifact.get_entry(serialization_path["path"]).download()
515
518
  )
516
- np_deserialized_columns[
517
- json_obj["columns"].index(col_name)
518
- ] = deserialized[serialization_path["key"]]
519
+ np_deserialized_columns[json_obj["columns"].index(col_name)] = (
520
+ deserialized[serialization_path["key"]]
521
+ )
519
522
  ndarray_type._clear_serialization_path()
520
523
 
521
524
  for r_ndx, row in enumerate(json_obj["data"]):
@@ -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 homogenous data
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
@@ -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
- """Retreve the image id from the local docker daemon or remote registry."""
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
@@ -13,11 +13,10 @@ these values in many cases.
13
13
  import json
14
14
  import os
15
15
  import sys
16
- from distutils.util import strtobool
17
16
  from pathlib import Path
18
17
  from typing import List, MutableMapping, Optional, Union
19
18
 
20
- import appdirs # type: ignore
19
+ import platformdirs # type: ignore
21
20
 
22
21
  Env = Optional[MutableMapping]
23
22
 
@@ -61,6 +60,8 @@ SAVE_CODE = "WANDB_SAVE_CODE"
61
60
  TAGS = "WANDB_TAGS"
62
61
  IGNORE = "WANDB_IGNORE_GLOBS"
63
62
  ERROR_REPORTING = "WANDB_ERROR_REPORTING"
63
+ CORE_ERROR_REPORTING = "WANDB_CORE_ERROR_REPORTING"
64
+ CORE_DEBUG = "WANDB_CORE_DEBUG"
64
65
  DOCKER = "WANDB_DOCKER"
65
66
  AGENT_REPORT_INTERVAL = "WANDB_AGENT_REPORT_INTERVAL"
66
67
  AGENT_KILL_DELAY = "WANDB_AGENT_KILL_DELAY"
@@ -87,6 +88,7 @@ _EXECUTABLE = "WANDB_EXECUTABLE"
87
88
  LAUNCH_QUEUE_NAME = "WANDB_LAUNCH_QUEUE_NAME"
88
89
  LAUNCH_QUEUE_ENTITY = "WANDB_LAUNCH_QUEUE_ENTITY"
89
90
  LAUNCH_TRACE_ID = "WANDB_LAUNCH_TRACE_ID"
91
+ _REQUIRE_CORE = "WANDB__REQUIRE_CORE"
90
92
 
91
93
  # For testing, to be removed in future version
92
94
  USE_V1_ARTIFACTS = "_WANDB_USE_V1_ARTIFACTS"
@@ -139,11 +141,16 @@ def _env_as_bool(
139
141
  if env is None:
140
142
  env = os.environ
141
143
  val = env.get(var, default)
144
+ if not isinstance(val, str):
145
+ return False
142
146
  try:
143
- val = bool(strtobool(val)) # type: ignore
144
- except (AttributeError, ValueError):
145
- pass
146
- return val if isinstance(val, bool) else False
147
+ return strtobool(val)
148
+ except ValueError:
149
+ return False
150
+
151
+
152
+ def is_require_core(env: Optional[Env] = None) -> bool:
153
+ return _env_as_bool(_REQUIRE_CORE, default="False", env=env)
147
154
 
148
155
 
149
156
  def is_debug(default: Optional[str] = None, env: Optional[Env] = None) -> bool:
@@ -154,6 +161,14 @@ def error_reporting_enabled() -> bool:
154
161
  return _env_as_bool(ERROR_REPORTING, default="True")
155
162
 
156
163
 
164
+ def core_error_reporting_enabled(default: Optional[str] = None) -> bool:
165
+ return _env_as_bool(CORE_ERROR_REPORTING, default=default)
166
+
167
+
168
+ def core_debug(default: Optional[str] = None) -> bool:
169
+ return _env_as_bool(CORE_DEBUG, default=default)
170
+
171
+
157
172
  def ssl_disabled() -> bool:
158
173
  return _env_as_bool(DISABLE_SSL, default="False")
159
174
 
@@ -370,7 +385,7 @@ def get_magic(
370
385
 
371
386
 
372
387
  def get_data_dir(env: Optional[Env] = None) -> str:
373
- default_dir = appdirs.user_data_dir("wandb")
388
+ default_dir = platformdirs.user_data_dir("wandb")
374
389
  if env is None:
375
390
  env = os.environ
376
391
  val = env.get(DATA_DIR, default_dir)
@@ -395,7 +410,7 @@ def get_artifact_fetch_file_url_batch_size(env: Optional[Env] = None) -> int:
395
410
 
396
411
  def get_cache_dir(env: Optional[Env] = None) -> Path:
397
412
  env = env or os.environ
398
- return Path(env.get(CACHE_DIR, appdirs.user_cache_dir("wandb")))
413
+ return Path(env.get(CACHE_DIR, platformdirs.user_cache_dir("wandb")))
399
414
 
400
415
 
401
416
  def get_use_v1_artifacts(env: Optional[Env] = None) -> bool:
@@ -464,3 +479,18 @@ def get_launch_trace_id(env: Optional[Env] = None) -> Optional[str]:
464
479
  env = os.environ
465
480
  val = env.get(LAUNCH_TRACE_ID, None)
466
481
  return val
482
+
483
+
484
+ def strtobool(val: str) -> bool:
485
+ """Convert a string representation of truth to true or false.
486
+
487
+ Copied from distutils. distutils was removed in Python 3.12.
488
+ """
489
+ val = val.lower()
490
+
491
+ if val in ("y", "yes", "t", "true", "on", "1"):
492
+ return True
493
+ elif val in ("n", "no", "f", "false", "off", "0"):
494
+ return False
495
+ else:
496
+ raise ValueError(f"invalid truth value {val!r}")
wandb/errors/__init__.py CHANGED
@@ -4,6 +4,7 @@ __all__ = [
4
4
  "AuthenticationError",
5
5
  "UsageError",
6
6
  "UnsupportedError",
7
+ "WandbCoreNotAvailableError",
7
8
  ]
8
9
 
9
10
  from typing import Optional
@@ -39,3 +40,7 @@ class UsageError(Error):
39
40
 
40
41
  class UnsupportedError(UsageError):
41
42
  """Raised when trying to use a feature that is not supported."""
43
+
44
+
45
+ class WandbCoreNotAvailableError(Error):
46
+ """Raised when wandb core is not available."""
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()