wandb 0.18.2__py3-none-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (827) hide show
  1. package_readme.md +89 -0
  2. wandb/__init__.py +245 -0
  3. wandb/__init__.pyi +1139 -0
  4. wandb/__main__.py +3 -0
  5. wandb/_globals.py +19 -0
  6. wandb/agents/__init__.py +0 -0
  7. wandb/agents/pyagent.py +363 -0
  8. wandb/analytics/__init__.py +3 -0
  9. wandb/analytics/sentry.py +266 -0
  10. wandb/apis/__init__.py +48 -0
  11. wandb/apis/attrs.py +40 -0
  12. wandb/apis/importers/__init__.py +1 -0
  13. wandb/apis/importers/internals/internal.py +385 -0
  14. wandb/apis/importers/internals/protocols.py +99 -0
  15. wandb/apis/importers/internals/util.py +78 -0
  16. wandb/apis/importers/mlflow.py +254 -0
  17. wandb/apis/importers/validation.py +108 -0
  18. wandb/apis/importers/wandb.py +1603 -0
  19. wandb/apis/internal.py +232 -0
  20. wandb/apis/normalize.py +89 -0
  21. wandb/apis/paginator.py +81 -0
  22. wandb/apis/public/__init__.py +34 -0
  23. wandb/apis/public/api.py +1305 -0
  24. wandb/apis/public/artifacts.py +1090 -0
  25. wandb/apis/public/const.py +4 -0
  26. wandb/apis/public/files.py +195 -0
  27. wandb/apis/public/history.py +149 -0
  28. wandb/apis/public/jobs.py +659 -0
  29. wandb/apis/public/projects.py +154 -0
  30. wandb/apis/public/query_generator.py +166 -0
  31. wandb/apis/public/reports.py +469 -0
  32. wandb/apis/public/runs.py +914 -0
  33. wandb/apis/public/sweeps.py +240 -0
  34. wandb/apis/public/teams.py +198 -0
  35. wandb/apis/public/users.py +136 -0
  36. wandb/apis/reports/__init__.py +1 -0
  37. wandb/apis/reports/v1/__init__.py +8 -0
  38. wandb/apis/reports/v2/__init__.py +8 -0
  39. wandb/apis/workspaces/__init__.py +8 -0
  40. wandb/beta/workflows.py +288 -0
  41. wandb/bin/nvidia_gpu_stats +0 -0
  42. wandb/bin/wandb-core +0 -0
  43. wandb/cli/__init__.py +0 -0
  44. wandb/cli/cli.py +3004 -0
  45. wandb/data_types.py +63 -0
  46. wandb/docker/__init__.py +342 -0
  47. wandb/docker/auth.py +436 -0
  48. wandb/docker/wandb-entrypoint.sh +33 -0
  49. wandb/docker/www_authenticate.py +94 -0
  50. wandb/env.py +514 -0
  51. wandb/errors/__init__.py +17 -0
  52. wandb/errors/errors.py +37 -0
  53. wandb/errors/term.py +103 -0
  54. wandb/errors/util.py +57 -0
  55. wandb/errors/warnings.py +2 -0
  56. wandb/filesync/__init__.py +0 -0
  57. wandb/filesync/dir_watcher.py +403 -0
  58. wandb/filesync/stats.py +100 -0
  59. wandb/filesync/step_checksum.py +142 -0
  60. wandb/filesync/step_prepare.py +179 -0
  61. wandb/filesync/step_upload.py +290 -0
  62. wandb/filesync/upload_job.py +142 -0
  63. wandb/integration/__init__.py +0 -0
  64. wandb/integration/catboost/__init__.py +5 -0
  65. wandb/integration/catboost/catboost.py +178 -0
  66. wandb/integration/cohere/__init__.py +3 -0
  67. wandb/integration/cohere/cohere.py +21 -0
  68. wandb/integration/cohere/resolver.py +347 -0
  69. wandb/integration/diffusers/__init__.py +3 -0
  70. wandb/integration/diffusers/autologger.py +76 -0
  71. wandb/integration/diffusers/pipeline_resolver.py +50 -0
  72. wandb/integration/diffusers/resolvers/__init__.py +9 -0
  73. wandb/integration/diffusers/resolvers/multimodal.py +882 -0
  74. wandb/integration/diffusers/resolvers/utils.py +102 -0
  75. wandb/integration/fastai/__init__.py +249 -0
  76. wandb/integration/gym/__init__.py +105 -0
  77. wandb/integration/huggingface/__init__.py +3 -0
  78. wandb/integration/huggingface/huggingface.py +18 -0
  79. wandb/integration/huggingface/resolver.py +213 -0
  80. wandb/integration/keras/__init__.py +11 -0
  81. wandb/integration/keras/callbacks/__init__.py +5 -0
  82. wandb/integration/keras/callbacks/metrics_logger.py +136 -0
  83. wandb/integration/keras/callbacks/model_checkpoint.py +195 -0
  84. wandb/integration/keras/callbacks/tables_builder.py +226 -0
  85. wandb/integration/keras/keras.py +1091 -0
  86. wandb/integration/kfp/__init__.py +6 -0
  87. wandb/integration/kfp/helpers.py +28 -0
  88. wandb/integration/kfp/kfp_patch.py +324 -0
  89. wandb/integration/kfp/wandb_logging.py +182 -0
  90. wandb/integration/langchain/__init__.py +3 -0
  91. wandb/integration/langchain/wandb_tracer.py +48 -0
  92. wandb/integration/lightgbm/__init__.py +239 -0
  93. wandb/integration/lightning/__init__.py +0 -0
  94. wandb/integration/lightning/fabric/__init__.py +3 -0
  95. wandb/integration/lightning/fabric/logger.py +762 -0
  96. wandb/integration/magic.py +556 -0
  97. wandb/integration/metaflow/__init__.py +3 -0
  98. wandb/integration/metaflow/metaflow.py +383 -0
  99. wandb/integration/openai/__init__.py +3 -0
  100. wandb/integration/openai/fine_tuning.py +480 -0
  101. wandb/integration/openai/openai.py +22 -0
  102. wandb/integration/openai/resolver.py +240 -0
  103. wandb/integration/prodigy/__init__.py +3 -0
  104. wandb/integration/prodigy/prodigy.py +299 -0
  105. wandb/integration/sacred/__init__.py +117 -0
  106. wandb/integration/sagemaker/__init__.py +12 -0
  107. wandb/integration/sagemaker/auth.py +28 -0
  108. wandb/integration/sagemaker/config.py +49 -0
  109. wandb/integration/sagemaker/files.py +3 -0
  110. wandb/integration/sagemaker/resources.py +34 -0
  111. wandb/integration/sb3/__init__.py +3 -0
  112. wandb/integration/sb3/sb3.py +153 -0
  113. wandb/integration/sklearn/__init__.py +37 -0
  114. wandb/integration/sklearn/calculate/__init__.py +32 -0
  115. wandb/integration/sklearn/calculate/calibration_curves.py +125 -0
  116. wandb/integration/sklearn/calculate/class_proportions.py +68 -0
  117. wandb/integration/sklearn/calculate/confusion_matrix.py +93 -0
  118. wandb/integration/sklearn/calculate/decision_boundaries.py +40 -0
  119. wandb/integration/sklearn/calculate/elbow_curve.py +55 -0
  120. wandb/integration/sklearn/calculate/feature_importances.py +67 -0
  121. wandb/integration/sklearn/calculate/learning_curve.py +64 -0
  122. wandb/integration/sklearn/calculate/outlier_candidates.py +69 -0
  123. wandb/integration/sklearn/calculate/residuals.py +86 -0
  124. wandb/integration/sklearn/calculate/silhouette.py +118 -0
  125. wandb/integration/sklearn/calculate/summary_metrics.py +62 -0
  126. wandb/integration/sklearn/plot/__init__.py +35 -0
  127. wandb/integration/sklearn/plot/classifier.py +329 -0
  128. wandb/integration/sklearn/plot/clusterer.py +146 -0
  129. wandb/integration/sklearn/plot/regressor.py +121 -0
  130. wandb/integration/sklearn/plot/shared.py +91 -0
  131. wandb/integration/sklearn/utils.py +183 -0
  132. wandb/integration/tensorboard/__init__.py +10 -0
  133. wandb/integration/tensorboard/log.py +355 -0
  134. wandb/integration/tensorboard/monkeypatch.py +185 -0
  135. wandb/integration/tensorflow/__init__.py +5 -0
  136. wandb/integration/tensorflow/estimator_hook.py +54 -0
  137. wandb/integration/torch/__init__.py +0 -0
  138. wandb/integration/torch/wandb_torch.py +554 -0
  139. wandb/integration/ultralytics/__init__.py +11 -0
  140. wandb/integration/ultralytics/bbox_utils.py +208 -0
  141. wandb/integration/ultralytics/callback.py +524 -0
  142. wandb/integration/ultralytics/classification_utils.py +83 -0
  143. wandb/integration/ultralytics/mask_utils.py +202 -0
  144. wandb/integration/ultralytics/pose_utils.py +103 -0
  145. wandb/integration/xgboost/__init__.py +11 -0
  146. wandb/integration/xgboost/xgboost.py +189 -0
  147. wandb/integration/yolov8/__init__.py +0 -0
  148. wandb/integration/yolov8/yolov8.py +284 -0
  149. wandb/jupyter.py +515 -0
  150. wandb/magic.py +3 -0
  151. wandb/mpmain/__init__.py +0 -0
  152. wandb/mpmain/__main__.py +1 -0
  153. wandb/old/__init__.py +0 -0
  154. wandb/old/core.py +53 -0
  155. wandb/old/settings.py +173 -0
  156. wandb/old/summary.py +440 -0
  157. wandb/plot/__init__.py +19 -0
  158. wandb/plot/bar.py +45 -0
  159. wandb/plot/confusion_matrix.py +100 -0
  160. wandb/plot/histogram.py +39 -0
  161. wandb/plot/line.py +43 -0
  162. wandb/plot/line_series.py +88 -0
  163. wandb/plot/pr_curve.py +136 -0
  164. wandb/plot/roc_curve.py +118 -0
  165. wandb/plot/scatter.py +32 -0
  166. wandb/plot/utils.py +183 -0
  167. wandb/plot/viz.py +123 -0
  168. wandb/proto/__init__.py +0 -0
  169. wandb/proto/v3/__init__.py +0 -0
  170. wandb/proto/v3/wandb_base_pb2.py +55 -0
  171. wandb/proto/v3/wandb_internal_pb2.py +1608 -0
  172. wandb/proto/v3/wandb_server_pb2.py +208 -0
  173. wandb/proto/v3/wandb_settings_pb2.py +112 -0
  174. wandb/proto/v3/wandb_telemetry_pb2.py +106 -0
  175. wandb/proto/v4/__init__.py +0 -0
  176. wandb/proto/v4/wandb_base_pb2.py +30 -0
  177. wandb/proto/v4/wandb_internal_pb2.py +360 -0
  178. wandb/proto/v4/wandb_server_pb2.py +63 -0
  179. wandb/proto/v4/wandb_settings_pb2.py +45 -0
  180. wandb/proto/v4/wandb_telemetry_pb2.py +41 -0
  181. wandb/proto/v5/wandb_base_pb2.py +31 -0
  182. wandb/proto/v5/wandb_internal_pb2.py +361 -0
  183. wandb/proto/v5/wandb_server_pb2.py +64 -0
  184. wandb/proto/v5/wandb_settings_pb2.py +46 -0
  185. wandb/proto/v5/wandb_telemetry_pb2.py +42 -0
  186. wandb/proto/wandb_base_pb2.py +10 -0
  187. wandb/proto/wandb_deprecated.py +53 -0
  188. wandb/proto/wandb_generate_deprecated.py +34 -0
  189. wandb/proto/wandb_generate_proto.py +49 -0
  190. wandb/proto/wandb_internal_pb2.py +16 -0
  191. wandb/proto/wandb_server_pb2.py +10 -0
  192. wandb/proto/wandb_settings_pb2.py +10 -0
  193. wandb/proto/wandb_telemetry_pb2.py +10 -0
  194. wandb/py.typed +0 -0
  195. wandb/sdk/__init__.py +37 -0
  196. wandb/sdk/artifacts/__init__.py +0 -0
  197. wandb/sdk/artifacts/_validators.py +90 -0
  198. wandb/sdk/artifacts/artifact.py +2389 -0
  199. wandb/sdk/artifacts/artifact_download_logger.py +43 -0
  200. wandb/sdk/artifacts/artifact_file_cache.py +253 -0
  201. wandb/sdk/artifacts/artifact_instance_cache.py +17 -0
  202. wandb/sdk/artifacts/artifact_manifest.py +74 -0
  203. wandb/sdk/artifacts/artifact_manifest_entry.py +249 -0
  204. wandb/sdk/artifacts/artifact_manifests/__init__.py +0 -0
  205. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +92 -0
  206. wandb/sdk/artifacts/artifact_saver.py +269 -0
  207. wandb/sdk/artifacts/artifact_state.py +11 -0
  208. wandb/sdk/artifacts/artifact_ttl.py +7 -0
  209. wandb/sdk/artifacts/exceptions.py +57 -0
  210. wandb/sdk/artifacts/staging.py +25 -0
  211. wandb/sdk/artifacts/storage_handler.py +62 -0
  212. wandb/sdk/artifacts/storage_handlers/__init__.py +0 -0
  213. wandb/sdk/artifacts/storage_handlers/azure_handler.py +208 -0
  214. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +228 -0
  215. wandb/sdk/artifacts/storage_handlers/http_handler.py +114 -0
  216. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +141 -0
  217. wandb/sdk/artifacts/storage_handlers/multi_handler.py +56 -0
  218. wandb/sdk/artifacts/storage_handlers/s3_handler.py +300 -0
  219. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +72 -0
  220. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +135 -0
  221. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +74 -0
  222. wandb/sdk/artifacts/storage_layout.py +6 -0
  223. wandb/sdk/artifacts/storage_policies/__init__.py +4 -0
  224. wandb/sdk/artifacts/storage_policies/register.py +1 -0
  225. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +378 -0
  226. wandb/sdk/artifacts/storage_policy.py +72 -0
  227. wandb/sdk/backend/__init__.py +0 -0
  228. wandb/sdk/backend/backend.py +222 -0
  229. wandb/sdk/data_types/__init__.py +0 -0
  230. wandb/sdk/data_types/_dtypes.py +914 -0
  231. wandb/sdk/data_types/_private.py +10 -0
  232. wandb/sdk/data_types/audio.py +165 -0
  233. wandb/sdk/data_types/base_types/__init__.py +0 -0
  234. wandb/sdk/data_types/base_types/json_metadata.py +55 -0
  235. wandb/sdk/data_types/base_types/media.py +315 -0
  236. wandb/sdk/data_types/base_types/wb_value.py +272 -0
  237. wandb/sdk/data_types/bokeh.py +70 -0
  238. wandb/sdk/data_types/graph.py +405 -0
  239. wandb/sdk/data_types/helper_types/__init__.py +0 -0
  240. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +295 -0
  241. wandb/sdk/data_types/helper_types/classes.py +159 -0
  242. wandb/sdk/data_types/helper_types/image_mask.py +235 -0
  243. wandb/sdk/data_types/histogram.py +96 -0
  244. wandb/sdk/data_types/html.py +115 -0
  245. wandb/sdk/data_types/image.py +845 -0
  246. wandb/sdk/data_types/molecule.py +241 -0
  247. wandb/sdk/data_types/object_3d.py +474 -0
  248. wandb/sdk/data_types/plotly.py +82 -0
  249. wandb/sdk/data_types/saved_model.py +446 -0
  250. wandb/sdk/data_types/table.py +1204 -0
  251. wandb/sdk/data_types/trace_tree.py +438 -0
  252. wandb/sdk/data_types/utils.py +229 -0
  253. wandb/sdk/data_types/video.py +247 -0
  254. wandb/sdk/integration_utils/__init__.py +0 -0
  255. wandb/sdk/integration_utils/auto_logging.py +239 -0
  256. wandb/sdk/integration_utils/data_logging.py +475 -0
  257. wandb/sdk/interface/__init__.py +0 -0
  258. wandb/sdk/interface/constants.py +4 -0
  259. wandb/sdk/interface/interface.py +972 -0
  260. wandb/sdk/interface/interface_queue.py +59 -0
  261. wandb/sdk/interface/interface_relay.py +53 -0
  262. wandb/sdk/interface/interface_shared.py +537 -0
  263. wandb/sdk/interface/interface_sock.py +61 -0
  264. wandb/sdk/interface/message_future.py +27 -0
  265. wandb/sdk/interface/message_future_poll.py +50 -0
  266. wandb/sdk/interface/router.py +118 -0
  267. wandb/sdk/interface/router_queue.py +44 -0
  268. wandb/sdk/interface/router_relay.py +39 -0
  269. wandb/sdk/interface/router_sock.py +36 -0
  270. wandb/sdk/interface/summary_record.py +67 -0
  271. wandb/sdk/internal/__init__.py +0 -0
  272. wandb/sdk/internal/context.py +89 -0
  273. wandb/sdk/internal/datastore.py +297 -0
  274. wandb/sdk/internal/file_pusher.py +181 -0
  275. wandb/sdk/internal/file_stream.py +695 -0
  276. wandb/sdk/internal/flow_control.py +263 -0
  277. wandb/sdk/internal/handler.py +901 -0
  278. wandb/sdk/internal/internal.py +417 -0
  279. wandb/sdk/internal/internal_api.py +4358 -0
  280. wandb/sdk/internal/internal_util.py +100 -0
  281. wandb/sdk/internal/job_builder.py +629 -0
  282. wandb/sdk/internal/profiler.py +78 -0
  283. wandb/sdk/internal/progress.py +83 -0
  284. wandb/sdk/internal/run.py +25 -0
  285. wandb/sdk/internal/sample.py +70 -0
  286. wandb/sdk/internal/sender.py +1686 -0
  287. wandb/sdk/internal/sender_config.py +197 -0
  288. wandb/sdk/internal/settings_static.py +90 -0
  289. wandb/sdk/internal/system/__init__.py +0 -0
  290. wandb/sdk/internal/system/assets/__init__.py +27 -0
  291. wandb/sdk/internal/system/assets/aggregators.py +37 -0
  292. wandb/sdk/internal/system/assets/asset_registry.py +20 -0
  293. wandb/sdk/internal/system/assets/cpu.py +163 -0
  294. wandb/sdk/internal/system/assets/disk.py +210 -0
  295. wandb/sdk/internal/system/assets/gpu.py +416 -0
  296. wandb/sdk/internal/system/assets/gpu_amd.py +239 -0
  297. wandb/sdk/internal/system/assets/gpu_apple.py +177 -0
  298. wandb/sdk/internal/system/assets/interfaces.py +207 -0
  299. wandb/sdk/internal/system/assets/ipu.py +177 -0
  300. wandb/sdk/internal/system/assets/memory.py +166 -0
  301. wandb/sdk/internal/system/assets/network.py +125 -0
  302. wandb/sdk/internal/system/assets/open_metrics.py +299 -0
  303. wandb/sdk/internal/system/assets/tpu.py +154 -0
  304. wandb/sdk/internal/system/assets/trainium.py +399 -0
  305. wandb/sdk/internal/system/env_probe_helpers.py +13 -0
  306. wandb/sdk/internal/system/system_info.py +249 -0
  307. wandb/sdk/internal/system/system_monitor.py +229 -0
  308. wandb/sdk/internal/tb_watcher.py +518 -0
  309. wandb/sdk/internal/thread_local_settings.py +18 -0
  310. wandb/sdk/internal/writer.py +206 -0
  311. wandb/sdk/launch/__init__.py +14 -0
  312. wandb/sdk/launch/_launch.py +330 -0
  313. wandb/sdk/launch/_launch_add.py +255 -0
  314. wandb/sdk/launch/_project_spec.py +566 -0
  315. wandb/sdk/launch/agent/__init__.py +5 -0
  316. wandb/sdk/launch/agent/agent.py +924 -0
  317. wandb/sdk/launch/agent/config.py +296 -0
  318. wandb/sdk/launch/agent/job_status_tracker.py +53 -0
  319. wandb/sdk/launch/agent/run_queue_item_file_saver.py +45 -0
  320. wandb/sdk/launch/builder/__init__.py +0 -0
  321. wandb/sdk/launch/builder/abstract.py +156 -0
  322. wandb/sdk/launch/builder/build.py +297 -0
  323. wandb/sdk/launch/builder/context_manager.py +235 -0
  324. wandb/sdk/launch/builder/docker_builder.py +177 -0
  325. wandb/sdk/launch/builder/kaniko_builder.py +595 -0
  326. wandb/sdk/launch/builder/noop.py +58 -0
  327. wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +188 -0
  328. wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
  329. wandb/sdk/launch/create_job.py +528 -0
  330. wandb/sdk/launch/environment/abstract.py +29 -0
  331. wandb/sdk/launch/environment/aws_environment.py +322 -0
  332. wandb/sdk/launch/environment/azure_environment.py +105 -0
  333. wandb/sdk/launch/environment/gcp_environment.py +335 -0
  334. wandb/sdk/launch/environment/local_environment.py +66 -0
  335. wandb/sdk/launch/errors.py +19 -0
  336. wandb/sdk/launch/git_reference.py +109 -0
  337. wandb/sdk/launch/inputs/files.py +148 -0
  338. wandb/sdk/launch/inputs/internal.py +315 -0
  339. wandb/sdk/launch/inputs/manage.py +113 -0
  340. wandb/sdk/launch/inputs/schema.py +39 -0
  341. wandb/sdk/launch/loader.py +249 -0
  342. wandb/sdk/launch/registry/abstract.py +48 -0
  343. wandb/sdk/launch/registry/anon.py +29 -0
  344. wandb/sdk/launch/registry/azure_container_registry.py +124 -0
  345. wandb/sdk/launch/registry/elastic_container_registry.py +192 -0
  346. wandb/sdk/launch/registry/google_artifact_registry.py +219 -0
  347. wandb/sdk/launch/registry/local_registry.py +67 -0
  348. wandb/sdk/launch/runner/__init__.py +0 -0
  349. wandb/sdk/launch/runner/abstract.py +195 -0
  350. wandb/sdk/launch/runner/kubernetes_monitor.py +474 -0
  351. wandb/sdk/launch/runner/kubernetes_runner.py +963 -0
  352. wandb/sdk/launch/runner/local_container.py +301 -0
  353. wandb/sdk/launch/runner/local_process.py +78 -0
  354. wandb/sdk/launch/runner/sagemaker_runner.py +426 -0
  355. wandb/sdk/launch/runner/vertex_runner.py +230 -0
  356. wandb/sdk/launch/sweeps/__init__.py +39 -0
  357. wandb/sdk/launch/sweeps/scheduler.py +742 -0
  358. wandb/sdk/launch/sweeps/scheduler_sweep.py +91 -0
  359. wandb/sdk/launch/sweeps/utils.py +316 -0
  360. wandb/sdk/launch/utils.py +746 -0
  361. wandb/sdk/launch/wandb_reference.py +138 -0
  362. wandb/sdk/lib/__init__.py +5 -0
  363. wandb/sdk/lib/_settings_toposort_generate.py +159 -0
  364. wandb/sdk/lib/_settings_toposort_generated.py +250 -0
  365. wandb/sdk/lib/_wburls_generate.py +25 -0
  366. wandb/sdk/lib/_wburls_generated.py +22 -0
  367. wandb/sdk/lib/apikey.py +273 -0
  368. wandb/sdk/lib/capped_dict.py +26 -0
  369. wandb/sdk/lib/config_util.py +101 -0
  370. wandb/sdk/lib/credentials.py +141 -0
  371. wandb/sdk/lib/deprecate.py +42 -0
  372. wandb/sdk/lib/disabled.py +29 -0
  373. wandb/sdk/lib/exit_hooks.py +54 -0
  374. wandb/sdk/lib/file_stream_utils.py +118 -0
  375. wandb/sdk/lib/filenames.py +64 -0
  376. wandb/sdk/lib/filesystem.py +372 -0
  377. wandb/sdk/lib/fsm.py +174 -0
  378. wandb/sdk/lib/gitlib.py +239 -0
  379. wandb/sdk/lib/gql_request.py +65 -0
  380. wandb/sdk/lib/handler_util.py +21 -0
  381. wandb/sdk/lib/hashutil.py +84 -0
  382. wandb/sdk/lib/import_hooks.py +275 -0
  383. wandb/sdk/lib/ipython.py +146 -0
  384. wandb/sdk/lib/json_util.py +80 -0
  385. wandb/sdk/lib/lazyloader.py +63 -0
  386. wandb/sdk/lib/mailbox.py +460 -0
  387. wandb/sdk/lib/module.py +69 -0
  388. wandb/sdk/lib/paths.py +106 -0
  389. wandb/sdk/lib/preinit.py +42 -0
  390. wandb/sdk/lib/printer.py +313 -0
  391. wandb/sdk/lib/proto_util.py +90 -0
  392. wandb/sdk/lib/redirect.py +845 -0
  393. wandb/sdk/lib/reporting.py +99 -0
  394. wandb/sdk/lib/retry.py +289 -0
  395. wandb/sdk/lib/run_moment.py +78 -0
  396. wandb/sdk/lib/runid.py +12 -0
  397. wandb/sdk/lib/server.py +52 -0
  398. wandb/sdk/lib/service_connection.py +216 -0
  399. wandb/sdk/lib/service_token.py +94 -0
  400. wandb/sdk/lib/sock_client.py +295 -0
  401. wandb/sdk/lib/sparkline.py +45 -0
  402. wandb/sdk/lib/telemetry.py +100 -0
  403. wandb/sdk/lib/timed_input.py +133 -0
  404. wandb/sdk/lib/timer.py +19 -0
  405. wandb/sdk/lib/tracelog.py +255 -0
  406. wandb/sdk/lib/wburls.py +46 -0
  407. wandb/sdk/service/__init__.py +0 -0
  408. wandb/sdk/service/_startup_debug.py +22 -0
  409. wandb/sdk/service/port_file.py +53 -0
  410. wandb/sdk/service/server.py +116 -0
  411. wandb/sdk/service/server_sock.py +276 -0
  412. wandb/sdk/service/service.py +242 -0
  413. wandb/sdk/service/streams.py +417 -0
  414. wandb/sdk/verify/__init__.py +0 -0
  415. wandb/sdk/verify/verify.py +501 -0
  416. wandb/sdk/wandb_alerts.py +12 -0
  417. wandb/sdk/wandb_config.py +322 -0
  418. wandb/sdk/wandb_helper.py +54 -0
  419. wandb/sdk/wandb_init.py +1266 -0
  420. wandb/sdk/wandb_login.py +349 -0
  421. wandb/sdk/wandb_metric.py +110 -0
  422. wandb/sdk/wandb_require.py +97 -0
  423. wandb/sdk/wandb_require_helpers.py +44 -0
  424. wandb/sdk/wandb_run.py +4236 -0
  425. wandb/sdk/wandb_settings.py +2001 -0
  426. wandb/sdk/wandb_setup.py +409 -0
  427. wandb/sdk/wandb_summary.py +150 -0
  428. wandb/sdk/wandb_sweep.py +119 -0
  429. wandb/sdk/wandb_sync.py +81 -0
  430. wandb/sdk/wandb_watch.py +144 -0
  431. wandb/sklearn.py +35 -0
  432. wandb/sync/__init__.py +3 -0
  433. wandb/sync/sync.py +443 -0
  434. wandb/trigger.py +29 -0
  435. wandb/util.py +1956 -0
  436. wandb/vendor/__init__.py +0 -0
  437. wandb/vendor/gql-0.2.0/setup.py +40 -0
  438. wandb/vendor/gql-0.2.0/tests/__init__.py +0 -0
  439. wandb/vendor/gql-0.2.0/tests/starwars/__init__.py +0 -0
  440. wandb/vendor/gql-0.2.0/tests/starwars/fixtures.py +96 -0
  441. wandb/vendor/gql-0.2.0/tests/starwars/schema.py +146 -0
  442. wandb/vendor/gql-0.2.0/tests/starwars/test_dsl.py +293 -0
  443. wandb/vendor/gql-0.2.0/tests/starwars/test_query.py +355 -0
  444. wandb/vendor/gql-0.2.0/tests/starwars/test_validation.py +171 -0
  445. wandb/vendor/gql-0.2.0/tests/test_client.py +31 -0
  446. wandb/vendor/gql-0.2.0/tests/test_transport.py +89 -0
  447. wandb/vendor/gql-0.2.0/wandb_gql/__init__.py +4 -0
  448. wandb/vendor/gql-0.2.0/wandb_gql/client.py +75 -0
  449. wandb/vendor/gql-0.2.0/wandb_gql/dsl.py +152 -0
  450. wandb/vendor/gql-0.2.0/wandb_gql/gql.py +10 -0
  451. wandb/vendor/gql-0.2.0/wandb_gql/transport/__init__.py +0 -0
  452. wandb/vendor/gql-0.2.0/wandb_gql/transport/http.py +6 -0
  453. wandb/vendor/gql-0.2.0/wandb_gql/transport/local_schema.py +15 -0
  454. wandb/vendor/gql-0.2.0/wandb_gql/transport/requests.py +46 -0
  455. wandb/vendor/gql-0.2.0/wandb_gql/utils.py +21 -0
  456. wandb/vendor/graphql-core-1.1/setup.py +86 -0
  457. wandb/vendor/graphql-core-1.1/wandb_graphql/__init__.py +287 -0
  458. wandb/vendor/graphql-core-1.1/wandb_graphql/error/__init__.py +6 -0
  459. wandb/vendor/graphql-core-1.1/wandb_graphql/error/base.py +42 -0
  460. wandb/vendor/graphql-core-1.1/wandb_graphql/error/format_error.py +11 -0
  461. wandb/vendor/graphql-core-1.1/wandb_graphql/error/located_error.py +29 -0
  462. wandb/vendor/graphql-core-1.1/wandb_graphql/error/syntax_error.py +36 -0
  463. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/__init__.py +26 -0
  464. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/base.py +311 -0
  465. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executor.py +398 -0
  466. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/__init__.py +0 -0
  467. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/asyncio.py +53 -0
  468. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/gevent.py +22 -0
  469. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/process.py +32 -0
  470. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/sync.py +7 -0
  471. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/thread.py +35 -0
  472. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/utils.py +6 -0
  473. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/__init__.py +0 -0
  474. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/executor.py +66 -0
  475. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/fragment.py +252 -0
  476. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/resolver.py +151 -0
  477. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/utils.py +7 -0
  478. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/middleware.py +57 -0
  479. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/values.py +145 -0
  480. wandb/vendor/graphql-core-1.1/wandb_graphql/graphql.py +60 -0
  481. wandb/vendor/graphql-core-1.1/wandb_graphql/language/__init__.py +0 -0
  482. wandb/vendor/graphql-core-1.1/wandb_graphql/language/ast.py +1349 -0
  483. wandb/vendor/graphql-core-1.1/wandb_graphql/language/base.py +19 -0
  484. wandb/vendor/graphql-core-1.1/wandb_graphql/language/lexer.py +435 -0
  485. wandb/vendor/graphql-core-1.1/wandb_graphql/language/location.py +30 -0
  486. wandb/vendor/graphql-core-1.1/wandb_graphql/language/parser.py +779 -0
  487. wandb/vendor/graphql-core-1.1/wandb_graphql/language/printer.py +193 -0
  488. wandb/vendor/graphql-core-1.1/wandb_graphql/language/source.py +18 -0
  489. wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor.py +222 -0
  490. wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor_meta.py +82 -0
  491. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/__init__.py +0 -0
  492. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/cached_property.py +17 -0
  493. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/contain_subset.py +28 -0
  494. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/default_ordered_dict.py +40 -0
  495. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/ordereddict.py +8 -0
  496. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/pair_set.py +43 -0
  497. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/version.py +78 -0
  498. wandb/vendor/graphql-core-1.1/wandb_graphql/type/__init__.py +67 -0
  499. wandb/vendor/graphql-core-1.1/wandb_graphql/type/definition.py +619 -0
  500. wandb/vendor/graphql-core-1.1/wandb_graphql/type/directives.py +132 -0
  501. wandb/vendor/graphql-core-1.1/wandb_graphql/type/introspection.py +440 -0
  502. wandb/vendor/graphql-core-1.1/wandb_graphql/type/scalars.py +131 -0
  503. wandb/vendor/graphql-core-1.1/wandb_graphql/type/schema.py +100 -0
  504. wandb/vendor/graphql-core-1.1/wandb_graphql/type/typemap.py +145 -0
  505. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/__init__.py +0 -0
  506. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/assert_valid_name.py +9 -0
  507. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_from_value.py +65 -0
  508. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_code.py +49 -0
  509. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_dict.py +24 -0
  510. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/base.py +75 -0
  511. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_ast_schema.py +291 -0
  512. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_client_schema.py +250 -0
  513. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/concat_ast.py +9 -0
  514. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/extend_schema.py +357 -0
  515. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_field_def.py +27 -0
  516. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_operation_ast.py +21 -0
  517. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/introspection_query.py +90 -0
  518. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_literal_value.py +67 -0
  519. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_value.py +66 -0
  520. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/quoted_or_list.py +21 -0
  521. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/schema_printer.py +168 -0
  522. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/suggestion_list.py +56 -0
  523. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_comparators.py +69 -0
  524. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_from_ast.py +21 -0
  525. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_info.py +149 -0
  526. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/value_from_ast.py +69 -0
  527. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/__init__.py +4 -0
  528. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/__init__.py +79 -0
  529. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/arguments_of_correct_type.py +24 -0
  530. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/base.py +8 -0
  531. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/default_values_of_correct_type.py +44 -0
  532. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fields_on_correct_type.py +113 -0
  533. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fragments_on_composite_types.py +33 -0
  534. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_argument_names.py +70 -0
  535. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_directives.py +97 -0
  536. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_fragment_names.py +19 -0
  537. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_type_names.py +43 -0
  538. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/lone_anonymous_operation.py +23 -0
  539. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_fragment_cycles.py +59 -0
  540. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_undefined_variables.py +36 -0
  541. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_fragments.py +38 -0
  542. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_variables.py +37 -0
  543. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/overlapping_fields_can_be_merged.py +529 -0
  544. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/possible_fragment_spreads.py +44 -0
  545. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/provided_non_null_arguments.py +46 -0
  546. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/scalar_leafs.py +33 -0
  547. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_argument_names.py +32 -0
  548. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_fragment_names.py +28 -0
  549. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_input_field_names.py +33 -0
  550. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_operation_names.py +31 -0
  551. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_variable_names.py +27 -0
  552. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_are_input_types.py +21 -0
  553. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_in_allowed_position.py +53 -0
  554. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/validation.py +158 -0
  555. wandb/vendor/promise-2.3.0/conftest.py +30 -0
  556. wandb/vendor/promise-2.3.0/setup.py +64 -0
  557. wandb/vendor/promise-2.3.0/tests/__init__.py +0 -0
  558. wandb/vendor/promise-2.3.0/tests/conftest.py +8 -0
  559. wandb/vendor/promise-2.3.0/tests/test_awaitable.py +32 -0
  560. wandb/vendor/promise-2.3.0/tests/test_awaitable_35.py +47 -0
  561. wandb/vendor/promise-2.3.0/tests/test_benchmark.py +116 -0
  562. wandb/vendor/promise-2.3.0/tests/test_complex_threads.py +23 -0
  563. wandb/vendor/promise-2.3.0/tests/test_dataloader.py +452 -0
  564. wandb/vendor/promise-2.3.0/tests/test_dataloader_awaitable_35.py +99 -0
  565. wandb/vendor/promise-2.3.0/tests/test_dataloader_extra.py +65 -0
  566. wandb/vendor/promise-2.3.0/tests/test_extra.py +670 -0
  567. wandb/vendor/promise-2.3.0/tests/test_issues.py +132 -0
  568. wandb/vendor/promise-2.3.0/tests/test_promise_list.py +70 -0
  569. wandb/vendor/promise-2.3.0/tests/test_spec.py +584 -0
  570. wandb/vendor/promise-2.3.0/tests/test_thread_safety.py +115 -0
  571. wandb/vendor/promise-2.3.0/tests/utils.py +3 -0
  572. wandb/vendor/promise-2.3.0/wandb_promise/__init__.py +38 -0
  573. wandb/vendor/promise-2.3.0/wandb_promise/async_.py +135 -0
  574. wandb/vendor/promise-2.3.0/wandb_promise/compat.py +32 -0
  575. wandb/vendor/promise-2.3.0/wandb_promise/dataloader.py +326 -0
  576. wandb/vendor/promise-2.3.0/wandb_promise/iterate_promise.py +12 -0
  577. wandb/vendor/promise-2.3.0/wandb_promise/promise.py +848 -0
  578. wandb/vendor/promise-2.3.0/wandb_promise/promise_list.py +151 -0
  579. wandb/vendor/promise-2.3.0/wandb_promise/pyutils/__init__.py +0 -0
  580. wandb/vendor/promise-2.3.0/wandb_promise/pyutils/version.py +83 -0
  581. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/__init__.py +0 -0
  582. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/asyncio.py +22 -0
  583. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/gevent.py +21 -0
  584. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/immediate.py +27 -0
  585. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/thread.py +18 -0
  586. wandb/vendor/promise-2.3.0/wandb_promise/utils.py +56 -0
  587. wandb/vendor/pygments/__init__.py +90 -0
  588. wandb/vendor/pygments/cmdline.py +568 -0
  589. wandb/vendor/pygments/console.py +74 -0
  590. wandb/vendor/pygments/filter.py +74 -0
  591. wandb/vendor/pygments/filters/__init__.py +350 -0
  592. wandb/vendor/pygments/formatter.py +95 -0
  593. wandb/vendor/pygments/formatters/__init__.py +153 -0
  594. wandb/vendor/pygments/formatters/_mapping.py +85 -0
  595. wandb/vendor/pygments/formatters/bbcode.py +109 -0
  596. wandb/vendor/pygments/formatters/html.py +851 -0
  597. wandb/vendor/pygments/formatters/img.py +600 -0
  598. wandb/vendor/pygments/formatters/irc.py +182 -0
  599. wandb/vendor/pygments/formatters/latex.py +482 -0
  600. wandb/vendor/pygments/formatters/other.py +160 -0
  601. wandb/vendor/pygments/formatters/rtf.py +147 -0
  602. wandb/vendor/pygments/formatters/svg.py +153 -0
  603. wandb/vendor/pygments/formatters/terminal.py +136 -0
  604. wandb/vendor/pygments/formatters/terminal256.py +309 -0
  605. wandb/vendor/pygments/lexer.py +871 -0
  606. wandb/vendor/pygments/lexers/__init__.py +329 -0
  607. wandb/vendor/pygments/lexers/_asy_builtins.py +1645 -0
  608. wandb/vendor/pygments/lexers/_cl_builtins.py +232 -0
  609. wandb/vendor/pygments/lexers/_cocoa_builtins.py +72 -0
  610. wandb/vendor/pygments/lexers/_csound_builtins.py +1346 -0
  611. wandb/vendor/pygments/lexers/_lasso_builtins.py +5327 -0
  612. wandb/vendor/pygments/lexers/_lua_builtins.py +295 -0
  613. wandb/vendor/pygments/lexers/_mapping.py +500 -0
  614. wandb/vendor/pygments/lexers/_mql_builtins.py +1172 -0
  615. wandb/vendor/pygments/lexers/_openedge_builtins.py +2547 -0
  616. wandb/vendor/pygments/lexers/_php_builtins.py +4756 -0
  617. wandb/vendor/pygments/lexers/_postgres_builtins.py +621 -0
  618. wandb/vendor/pygments/lexers/_scilab_builtins.py +3094 -0
  619. wandb/vendor/pygments/lexers/_sourcemod_builtins.py +1163 -0
  620. wandb/vendor/pygments/lexers/_stan_builtins.py +532 -0
  621. wandb/vendor/pygments/lexers/_stata_builtins.py +419 -0
  622. wandb/vendor/pygments/lexers/_tsql_builtins.py +1004 -0
  623. wandb/vendor/pygments/lexers/_vim_builtins.py +1939 -0
  624. wandb/vendor/pygments/lexers/actionscript.py +240 -0
  625. wandb/vendor/pygments/lexers/agile.py +24 -0
  626. wandb/vendor/pygments/lexers/algebra.py +221 -0
  627. wandb/vendor/pygments/lexers/ambient.py +76 -0
  628. wandb/vendor/pygments/lexers/ampl.py +87 -0
  629. wandb/vendor/pygments/lexers/apl.py +101 -0
  630. wandb/vendor/pygments/lexers/archetype.py +318 -0
  631. wandb/vendor/pygments/lexers/asm.py +641 -0
  632. wandb/vendor/pygments/lexers/automation.py +374 -0
  633. wandb/vendor/pygments/lexers/basic.py +500 -0
  634. wandb/vendor/pygments/lexers/bibtex.py +160 -0
  635. wandb/vendor/pygments/lexers/business.py +612 -0
  636. wandb/vendor/pygments/lexers/c_cpp.py +252 -0
  637. wandb/vendor/pygments/lexers/c_like.py +541 -0
  638. wandb/vendor/pygments/lexers/capnproto.py +78 -0
  639. wandb/vendor/pygments/lexers/chapel.py +102 -0
  640. wandb/vendor/pygments/lexers/clean.py +288 -0
  641. wandb/vendor/pygments/lexers/compiled.py +34 -0
  642. wandb/vendor/pygments/lexers/configs.py +833 -0
  643. wandb/vendor/pygments/lexers/console.py +114 -0
  644. wandb/vendor/pygments/lexers/crystal.py +393 -0
  645. wandb/vendor/pygments/lexers/csound.py +366 -0
  646. wandb/vendor/pygments/lexers/css.py +689 -0
  647. wandb/vendor/pygments/lexers/d.py +251 -0
  648. wandb/vendor/pygments/lexers/dalvik.py +125 -0
  649. wandb/vendor/pygments/lexers/data.py +555 -0
  650. wandb/vendor/pygments/lexers/diff.py +165 -0
  651. wandb/vendor/pygments/lexers/dotnet.py +691 -0
  652. wandb/vendor/pygments/lexers/dsls.py +878 -0
  653. wandb/vendor/pygments/lexers/dylan.py +289 -0
  654. wandb/vendor/pygments/lexers/ecl.py +125 -0
  655. wandb/vendor/pygments/lexers/eiffel.py +65 -0
  656. wandb/vendor/pygments/lexers/elm.py +121 -0
  657. wandb/vendor/pygments/lexers/erlang.py +533 -0
  658. wandb/vendor/pygments/lexers/esoteric.py +277 -0
  659. wandb/vendor/pygments/lexers/ezhil.py +69 -0
  660. wandb/vendor/pygments/lexers/factor.py +344 -0
  661. wandb/vendor/pygments/lexers/fantom.py +250 -0
  662. wandb/vendor/pygments/lexers/felix.py +273 -0
  663. wandb/vendor/pygments/lexers/forth.py +177 -0
  664. wandb/vendor/pygments/lexers/fortran.py +205 -0
  665. wandb/vendor/pygments/lexers/foxpro.py +428 -0
  666. wandb/vendor/pygments/lexers/functional.py +21 -0
  667. wandb/vendor/pygments/lexers/go.py +101 -0
  668. wandb/vendor/pygments/lexers/grammar_notation.py +213 -0
  669. wandb/vendor/pygments/lexers/graph.py +80 -0
  670. wandb/vendor/pygments/lexers/graphics.py +553 -0
  671. wandb/vendor/pygments/lexers/haskell.py +843 -0
  672. wandb/vendor/pygments/lexers/haxe.py +936 -0
  673. wandb/vendor/pygments/lexers/hdl.py +382 -0
  674. wandb/vendor/pygments/lexers/hexdump.py +103 -0
  675. wandb/vendor/pygments/lexers/html.py +602 -0
  676. wandb/vendor/pygments/lexers/idl.py +270 -0
  677. wandb/vendor/pygments/lexers/igor.py +288 -0
  678. wandb/vendor/pygments/lexers/inferno.py +96 -0
  679. wandb/vendor/pygments/lexers/installers.py +322 -0
  680. wandb/vendor/pygments/lexers/int_fiction.py +1343 -0
  681. wandb/vendor/pygments/lexers/iolang.py +63 -0
  682. wandb/vendor/pygments/lexers/j.py +146 -0
  683. wandb/vendor/pygments/lexers/javascript.py +1525 -0
  684. wandb/vendor/pygments/lexers/julia.py +333 -0
  685. wandb/vendor/pygments/lexers/jvm.py +1573 -0
  686. wandb/vendor/pygments/lexers/lisp.py +2621 -0
  687. wandb/vendor/pygments/lexers/make.py +202 -0
  688. wandb/vendor/pygments/lexers/markup.py +595 -0
  689. wandb/vendor/pygments/lexers/math.py +21 -0
  690. wandb/vendor/pygments/lexers/matlab.py +663 -0
  691. wandb/vendor/pygments/lexers/ml.py +769 -0
  692. wandb/vendor/pygments/lexers/modeling.py +358 -0
  693. wandb/vendor/pygments/lexers/modula2.py +1561 -0
  694. wandb/vendor/pygments/lexers/monte.py +204 -0
  695. wandb/vendor/pygments/lexers/ncl.py +894 -0
  696. wandb/vendor/pygments/lexers/nimrod.py +159 -0
  697. wandb/vendor/pygments/lexers/nit.py +64 -0
  698. wandb/vendor/pygments/lexers/nix.py +136 -0
  699. wandb/vendor/pygments/lexers/oberon.py +105 -0
  700. wandb/vendor/pygments/lexers/objective.py +504 -0
  701. wandb/vendor/pygments/lexers/ooc.py +85 -0
  702. wandb/vendor/pygments/lexers/other.py +41 -0
  703. wandb/vendor/pygments/lexers/parasail.py +79 -0
  704. wandb/vendor/pygments/lexers/parsers.py +835 -0
  705. wandb/vendor/pygments/lexers/pascal.py +644 -0
  706. wandb/vendor/pygments/lexers/pawn.py +199 -0
  707. wandb/vendor/pygments/lexers/perl.py +620 -0
  708. wandb/vendor/pygments/lexers/php.py +267 -0
  709. wandb/vendor/pygments/lexers/praat.py +294 -0
  710. wandb/vendor/pygments/lexers/prolog.py +306 -0
  711. wandb/vendor/pygments/lexers/python.py +939 -0
  712. wandb/vendor/pygments/lexers/qvt.py +152 -0
  713. wandb/vendor/pygments/lexers/r.py +453 -0
  714. wandb/vendor/pygments/lexers/rdf.py +270 -0
  715. wandb/vendor/pygments/lexers/rebol.py +431 -0
  716. wandb/vendor/pygments/lexers/resource.py +85 -0
  717. wandb/vendor/pygments/lexers/rnc.py +67 -0
  718. wandb/vendor/pygments/lexers/roboconf.py +82 -0
  719. wandb/vendor/pygments/lexers/robotframework.py +560 -0
  720. wandb/vendor/pygments/lexers/ruby.py +519 -0
  721. wandb/vendor/pygments/lexers/rust.py +220 -0
  722. wandb/vendor/pygments/lexers/sas.py +228 -0
  723. wandb/vendor/pygments/lexers/scripting.py +1222 -0
  724. wandb/vendor/pygments/lexers/shell.py +794 -0
  725. wandb/vendor/pygments/lexers/smalltalk.py +195 -0
  726. wandb/vendor/pygments/lexers/smv.py +79 -0
  727. wandb/vendor/pygments/lexers/snobol.py +83 -0
  728. wandb/vendor/pygments/lexers/special.py +103 -0
  729. wandb/vendor/pygments/lexers/sql.py +681 -0
  730. wandb/vendor/pygments/lexers/stata.py +108 -0
  731. wandb/vendor/pygments/lexers/supercollider.py +90 -0
  732. wandb/vendor/pygments/lexers/tcl.py +145 -0
  733. wandb/vendor/pygments/lexers/templates.py +2283 -0
  734. wandb/vendor/pygments/lexers/testing.py +207 -0
  735. wandb/vendor/pygments/lexers/text.py +25 -0
  736. wandb/vendor/pygments/lexers/textedit.py +169 -0
  737. wandb/vendor/pygments/lexers/textfmts.py +297 -0
  738. wandb/vendor/pygments/lexers/theorem.py +458 -0
  739. wandb/vendor/pygments/lexers/trafficscript.py +54 -0
  740. wandb/vendor/pygments/lexers/typoscript.py +226 -0
  741. wandb/vendor/pygments/lexers/urbi.py +133 -0
  742. wandb/vendor/pygments/lexers/varnish.py +190 -0
  743. wandb/vendor/pygments/lexers/verification.py +111 -0
  744. wandb/vendor/pygments/lexers/web.py +24 -0
  745. wandb/vendor/pygments/lexers/webmisc.py +988 -0
  746. wandb/vendor/pygments/lexers/whiley.py +116 -0
  747. wandb/vendor/pygments/lexers/x10.py +69 -0
  748. wandb/vendor/pygments/modeline.py +44 -0
  749. wandb/vendor/pygments/plugin.py +68 -0
  750. wandb/vendor/pygments/regexopt.py +92 -0
  751. wandb/vendor/pygments/scanner.py +105 -0
  752. wandb/vendor/pygments/sphinxext.py +158 -0
  753. wandb/vendor/pygments/style.py +155 -0
  754. wandb/vendor/pygments/styles/__init__.py +80 -0
  755. wandb/vendor/pygments/styles/abap.py +29 -0
  756. wandb/vendor/pygments/styles/algol.py +63 -0
  757. wandb/vendor/pygments/styles/algol_nu.py +63 -0
  758. wandb/vendor/pygments/styles/arduino.py +98 -0
  759. wandb/vendor/pygments/styles/autumn.py +65 -0
  760. wandb/vendor/pygments/styles/borland.py +51 -0
  761. wandb/vendor/pygments/styles/bw.py +49 -0
  762. wandb/vendor/pygments/styles/colorful.py +81 -0
  763. wandb/vendor/pygments/styles/default.py +73 -0
  764. wandb/vendor/pygments/styles/emacs.py +72 -0
  765. wandb/vendor/pygments/styles/friendly.py +72 -0
  766. wandb/vendor/pygments/styles/fruity.py +42 -0
  767. wandb/vendor/pygments/styles/igor.py +29 -0
  768. wandb/vendor/pygments/styles/lovelace.py +97 -0
  769. wandb/vendor/pygments/styles/manni.py +75 -0
  770. wandb/vendor/pygments/styles/monokai.py +106 -0
  771. wandb/vendor/pygments/styles/murphy.py +80 -0
  772. wandb/vendor/pygments/styles/native.py +65 -0
  773. wandb/vendor/pygments/styles/paraiso_dark.py +125 -0
  774. wandb/vendor/pygments/styles/paraiso_light.py +125 -0
  775. wandb/vendor/pygments/styles/pastie.py +75 -0
  776. wandb/vendor/pygments/styles/perldoc.py +69 -0
  777. wandb/vendor/pygments/styles/rainbow_dash.py +89 -0
  778. wandb/vendor/pygments/styles/rrt.py +33 -0
  779. wandb/vendor/pygments/styles/sas.py +44 -0
  780. wandb/vendor/pygments/styles/stata.py +40 -0
  781. wandb/vendor/pygments/styles/tango.py +141 -0
  782. wandb/vendor/pygments/styles/trac.py +63 -0
  783. wandb/vendor/pygments/styles/vim.py +63 -0
  784. wandb/vendor/pygments/styles/vs.py +38 -0
  785. wandb/vendor/pygments/styles/xcode.py +51 -0
  786. wandb/vendor/pygments/token.py +213 -0
  787. wandb/vendor/pygments/unistring.py +217 -0
  788. wandb/vendor/pygments/util.py +388 -0
  789. wandb/vendor/pynvml/__init__.py +0 -0
  790. wandb/vendor/pynvml/pynvml.py +4779 -0
  791. wandb/vendor/watchdog_0_9_0/wandb_watchdog/__init__.py +17 -0
  792. wandb/vendor/watchdog_0_9_0/wandb_watchdog/events.py +615 -0
  793. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/__init__.py +98 -0
  794. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/api.py +369 -0
  795. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents.py +172 -0
  796. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents2.py +239 -0
  797. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify.py +218 -0
  798. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_buffer.py +81 -0
  799. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_c.py +575 -0
  800. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/kqueue.py +730 -0
  801. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/polling.py +145 -0
  802. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/read_directory_changes.py +133 -0
  803. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/winapi.py +348 -0
  804. wandb/vendor/watchdog_0_9_0/wandb_watchdog/patterns.py +265 -0
  805. wandb/vendor/watchdog_0_9_0/wandb_watchdog/tricks/__init__.py +174 -0
  806. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/__init__.py +151 -0
  807. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/bricks.py +249 -0
  808. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/compat.py +29 -0
  809. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/decorators.py +198 -0
  810. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/delayed_queue.py +88 -0
  811. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/dirsnapshot.py +293 -0
  812. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/echo.py +157 -0
  813. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/event_backport.py +41 -0
  814. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/importlib2.py +40 -0
  815. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/platform.py +57 -0
  816. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/unicode_paths.py +64 -0
  817. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/win32stat.py +123 -0
  818. wandb/vendor/watchdog_0_9_0/wandb_watchdog/version.py +28 -0
  819. wandb/vendor/watchdog_0_9_0/wandb_watchdog/watchmedo.py +577 -0
  820. wandb/wandb_agent.py +588 -0
  821. wandb/wandb_controller.py +721 -0
  822. wandb/wandb_run.py +9 -0
  823. wandb-0.18.2.dist-info/METADATA +213 -0
  824. wandb-0.18.2.dist-info/RECORD +827 -0
  825. wandb-0.18.2.dist-info/WHEEL +5 -0
  826. wandb-0.18.2.dist-info/entry_points.txt +3 -0
  827. wandb-0.18.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,2001 @@
1
+ import collections.abc
2
+ import configparser
3
+ import enum
4
+ import getpass
5
+ import json
6
+ import logging
7
+ import multiprocessing
8
+ import os
9
+ import platform
10
+ import re
11
+ import shutil
12
+ import socket
13
+ import sys
14
+ import tempfile
15
+ import time
16
+ from dataclasses import dataclass
17
+ from datetime import datetime
18
+ from distutils.util import strtobool
19
+ from functools import reduce
20
+ from typing import (
21
+ Any,
22
+ Callable,
23
+ Dict,
24
+ FrozenSet,
25
+ ItemsView,
26
+ Iterable,
27
+ Mapping,
28
+ Optional,
29
+ Sequence,
30
+ Set,
31
+ Tuple,
32
+ Union,
33
+ no_type_check,
34
+ )
35
+ from urllib.parse import quote, unquote, urlencode, urlparse, urlsplit
36
+
37
+ from google.protobuf.wrappers_pb2 import BoolValue, DoubleValue, Int32Value, StringValue
38
+
39
+ import wandb
40
+ import wandb.env
41
+ from wandb import util
42
+ from wandb.apis.internal import Api
43
+ from wandb.errors import UsageError
44
+ from wandb.proto import wandb_settings_pb2
45
+ from wandb.sdk.internal.system.env_probe_helpers import is_aws_lambda
46
+ from wandb.sdk.lib import credentials, filesystem
47
+ from wandb.sdk.lib._settings_toposort_generated import SETTINGS_TOPOLOGICALLY_SORTED
48
+ from wandb.sdk.lib.run_moment import RunMoment
49
+ from wandb.sdk.wandb_setup import _EarlyLogger
50
+
51
+ from .lib import apikey
52
+ from .lib.gitlib import GitRepo
53
+ from .lib.ipython import _get_python_type
54
+ from .lib.runid import generate_id
55
+
56
+ if sys.version_info >= (3, 8):
57
+ from typing import get_args, get_origin, get_type_hints
58
+ else:
59
+ from typing_extensions import get_args, get_origin, get_type_hints
60
+
61
+
62
+ class SettingsPreprocessingError(UsageError):
63
+ """Raised when the value supplied to a wandb.Settings() setting does not pass preprocessing."""
64
+
65
+
66
+ class SettingsValidationError(UsageError):
67
+ """Raised when the value supplied to a wandb.Settings() setting does not pass validation."""
68
+
69
+
70
+ class SettingsUnexpectedArgsError(UsageError):
71
+ """Raised when unexpected arguments are passed to wandb.Settings()."""
72
+
73
+
74
+ def _get_wandb_dir(root_dir: str) -> str:
75
+ """Get the full path to the wandb directory.
76
+
77
+ The setting exposed to users as `dir=` or `WANDB_DIR` is the `root_dir`.
78
+ We add the `__stage_dir__` to it to get the full `wandb_dir`
79
+ """
80
+ # We use the hidden version if it already exists, otherwise non-hidden.
81
+ if os.path.exists(os.path.join(root_dir, ".wandb")):
82
+ __stage_dir__ = ".wandb" + os.sep
83
+ else:
84
+ __stage_dir__ = "wandb" + os.sep
85
+
86
+ path = os.path.join(root_dir, __stage_dir__)
87
+ if not os.access(root_dir or ".", os.W_OK):
88
+ wandb.termwarn(
89
+ f"Path {path} wasn't writable, using system temp directory.",
90
+ repeat=False,
91
+ )
92
+ path = os.path.join(tempfile.gettempdir(), __stage_dir__ or ("wandb" + os.sep))
93
+
94
+ return os.path.expanduser(path)
95
+
96
+
97
+ def _str_as_bool(val: Union[str, bool]) -> bool:
98
+ """Parse a string as a bool."""
99
+ if isinstance(val, bool):
100
+ return val
101
+ try:
102
+ ret_val = bool(strtobool(str(val)))
103
+ return ret_val
104
+ except (AttributeError, ValueError):
105
+ pass
106
+
107
+ raise UsageError(f"Could not parse value {val} as a bool.")
108
+
109
+
110
+ def _str_as_json(val: Union[str, Dict[str, Any]]) -> Any:
111
+ """Parse a string as a json object."""
112
+ if not isinstance(val, str):
113
+ return val
114
+ try:
115
+ return json.loads(val)
116
+ except (AttributeError, ValueError):
117
+ pass
118
+
119
+ raise UsageError(f"Could not parse value {val} as JSON.")
120
+
121
+
122
+ def _str_as_tuple(val: Union[str, Sequence[str]]) -> Tuple[str, ...]:
123
+ """Parse a (potentially comma-separated) string as a tuple."""
124
+ if isinstance(val, str):
125
+ return tuple(val.split(","))
126
+ return tuple(val)
127
+
128
+
129
+ def _datetime_as_str(val: Union[datetime, str]) -> str:
130
+ """Parse a datetime object as a string."""
131
+ if isinstance(val, datetime):
132
+ return datetime.strftime(val, "%Y%m%d_%H%M%S")
133
+ return val
134
+
135
+
136
+ def _redact_dict(
137
+ d: Dict[str, Any],
138
+ unsafe_keys: Union[Set[str], FrozenSet[str]] = frozenset({"api_key"}),
139
+ redact_str: str = "***REDACTED***",
140
+ ) -> Dict[str, Any]:
141
+ """Redact a dict of unsafe values specified by their key."""
142
+ if not d or unsafe_keys.isdisjoint(d):
143
+ return d
144
+ safe_dict = d.copy()
145
+ safe_dict.update({k: redact_str for k in unsafe_keys.intersection(d)})
146
+ return safe_dict
147
+
148
+
149
+ def _get_program() -> Optional[str]:
150
+ program = os.getenv(wandb.env.PROGRAM)
151
+ if program is not None:
152
+ return program
153
+ try:
154
+ import __main__
155
+
156
+ if __main__.__spec__ is None:
157
+ return __main__.__file__
158
+ # likely run as `python -m ...`
159
+ return f"-m {__main__.__spec__.name}"
160
+ except (ImportError, AttributeError):
161
+ return None
162
+
163
+
164
+ def _runmoment_preprocessor(val: Any) -> Optional[RunMoment]:
165
+ if isinstance(val, RunMoment) or val is None:
166
+ return val
167
+ elif isinstance(val, str):
168
+ return RunMoment.from_uri(val)
169
+ raise UsageError(f"Could not parse value {val} as a RunMoment.")
170
+
171
+
172
+ def _get_program_relpath(
173
+ program: str, root: Optional[str] = None, _logger: Optional[_EarlyLogger] = None
174
+ ) -> Optional[str]:
175
+ if not program:
176
+ if _logger is not None:
177
+ _logger.warning("Empty program passed to get_program_relpath")
178
+ return None
179
+
180
+ root = root or os.getcwd()
181
+ if not root:
182
+ return None
183
+
184
+ full_path_to_program = os.path.join(
185
+ root, os.path.relpath(os.getcwd(), root), program
186
+ )
187
+ if os.path.exists(full_path_to_program):
188
+ relative_path = os.path.relpath(full_path_to_program, start=root)
189
+ if "../" in relative_path:
190
+ if _logger is not None:
191
+ _logger.warning(f"Could not save program above cwd: {program}")
192
+ return None
193
+ return relative_path
194
+
195
+ if _logger is not None:
196
+ _logger.warning(f"Could not find program at {program}")
197
+ return None
198
+
199
+
200
+ def is_instance_recursive(obj: Any, type_hint: Any) -> bool: # noqa: C901
201
+ if type_hint is Any:
202
+ return True
203
+
204
+ origin = get_origin(type_hint)
205
+ args = get_args(type_hint)
206
+
207
+ if origin is None:
208
+ return isinstance(obj, type_hint)
209
+
210
+ if origin is Union:
211
+ return any(is_instance_recursive(obj, arg) for arg in args)
212
+
213
+ if issubclass(origin, collections.abc.Mapping):
214
+ if not isinstance(obj, collections.abc.Mapping):
215
+ return False
216
+ key_type, value_type = args
217
+
218
+ for key, value in obj.items():
219
+ if not is_instance_recursive(key, key_type) or not is_instance_recursive(
220
+ value, value_type
221
+ ):
222
+ return False
223
+
224
+ return True
225
+
226
+ if issubclass(origin, collections.abc.Sequence):
227
+ if not isinstance(obj, collections.abc.Sequence) or isinstance(
228
+ obj, (str, bytes, bytearray)
229
+ ):
230
+ return False
231
+
232
+ if len(args) == 1 and args[0] != ...:
233
+ (item_type,) = args
234
+ for item in obj:
235
+ if not is_instance_recursive(item, item_type):
236
+ return False
237
+ elif len(args) == 2 and args[-1] == ...:
238
+ item_type = args[0]
239
+ for item in obj:
240
+ if not is_instance_recursive(item, item_type):
241
+ return False
242
+ elif len(args) == len(obj):
243
+ for item, item_type in zip(obj, args):
244
+ if not is_instance_recursive(item, item_type):
245
+ return False
246
+ else:
247
+ return False
248
+
249
+ return True
250
+
251
+ if issubclass(origin, collections.abc.Set):
252
+ if not isinstance(obj, collections.abc.Set):
253
+ return False
254
+
255
+ (item_type,) = args
256
+ for item in obj:
257
+ if not is_instance_recursive(item, item_type):
258
+ return False
259
+
260
+ return True
261
+
262
+ return False
263
+
264
+
265
+ @enum.unique
266
+ class Source(enum.IntEnum):
267
+ OVERRIDE: int = 0
268
+ BASE: int = 1 # todo: audit this
269
+ ORG: int = 2
270
+ ENTITY: int = 3
271
+ PROJECT: int = 4
272
+ USER: int = 5
273
+ SYSTEM: int = 6
274
+ WORKSPACE: int = 7
275
+ ENV: int = 8
276
+ SETUP: int = 9
277
+ LOGIN: int = 10
278
+ INIT: int = 11
279
+ SETTINGS: int = 12
280
+ ARGS: int = 13
281
+ RUN: int = 14
282
+
283
+
284
+ ConsoleValue = {
285
+ "auto",
286
+ "off",
287
+ "wrap",
288
+ "redirect",
289
+ # internal console states
290
+ "wrap_raw",
291
+ "wrap_emu",
292
+ }
293
+
294
+
295
+ @dataclass()
296
+ class SettingsData:
297
+ """Settings for the W&B SDK."""
298
+
299
+ _args: Sequence[str]
300
+ _aws_lambda: bool
301
+ _cli_only_mode: bool # Avoid running any code specific for runs
302
+ _code_path_local: str
303
+ _colab: bool
304
+ # _config_dict: Config
305
+ _cuda: str
306
+ _disable_meta: bool # Do not collect system metadata
307
+ _disable_service: (
308
+ bool # Disable wandb-service, spin up internal process the old way
309
+ )
310
+ _disable_setproctitle: bool # Do not use setproctitle on internal process
311
+ _disable_stats: bool # Do not collect system metrics
312
+ _disable_update_check: bool # Disable version check
313
+ _disable_viewer: bool # Prevent early viewer query
314
+ _disable_machine_info: bool # Disable automatic machine info collection
315
+ _executable: str
316
+ _extra_http_headers: Mapping[str, str]
317
+ _file_stream_max_bytes: int # max size for filestream requests in core
318
+ _file_stream_transmit_interval: float # tx interval for filestream requests in core
319
+ # file stream retry client configuration
320
+ _file_stream_retry_max: int # max number of retries
321
+ _file_stream_retry_wait_min_seconds: float # min wait time between retries
322
+ _file_stream_retry_wait_max_seconds: float # max wait time between retries
323
+ _file_stream_timeout_seconds: float # timeout for individual HTTP requests
324
+ # file transfer retry client configuration
325
+ _file_transfer_retry_max: int
326
+ _file_transfer_retry_wait_min_seconds: float
327
+ _file_transfer_retry_wait_max_seconds: float
328
+ _file_transfer_timeout_seconds: float
329
+ _flow_control_custom: bool
330
+ _flow_control_disabled: bool
331
+ # graphql retry client configuration
332
+ _graphql_retry_max: int
333
+ _graphql_retry_wait_min_seconds: float
334
+ _graphql_retry_wait_max_seconds: float
335
+ _graphql_timeout_seconds: float
336
+ _internal_check_process: float
337
+ _internal_queue_timeout: float
338
+ _ipython: bool
339
+ _jupyter: bool
340
+ _jupyter_name: str
341
+ _jupyter_path: str
342
+ _jupyter_root: str
343
+ _kaggle: bool
344
+ _live_policy_rate_limit: int
345
+ _live_policy_wait_time: int
346
+ _log_level: int
347
+ _network_buffer: int
348
+ _noop: bool
349
+ _notebook: bool
350
+ _offline: bool
351
+ _sync: bool
352
+ _os: str
353
+ _platform: str
354
+ _proxies: Mapping[
355
+ str, str
356
+ ] # custom proxy servers for the requests to W&B [scheme -> url]
357
+ _python: str
358
+ _runqueue_item_id: str
359
+ _require_legacy_service: bool
360
+ _save_requirements: bool
361
+ _service_transport: str
362
+ _service_wait: float
363
+ _shared: bool
364
+ _start_datetime: str
365
+ _start_time: float
366
+ _stats_pid: int # (internal) base pid for system stats
367
+ _stats_sampling_interval: float # sampling interval for system stats
368
+ _stats_sample_rate_seconds: float # badly-named sampling interval, deprecated
369
+ _stats_samples_to_average: (
370
+ int # number of samples to average before reporting, deprecated
371
+ )
372
+ _stats_join_assets: (
373
+ bool # join metrics from different assets before sending to backend
374
+ )
375
+ _stats_neuron_monitor_config_path: (
376
+ str # path to place config file for neuron-monitor (AWS Trainium)
377
+ )
378
+ _stats_open_metrics_endpoints: Mapping[str, str] # open metrics endpoint names/urls
379
+ # open metrics filters in one of the two formats:
380
+ # - {"metric regex pattern, including endpoint name as prefix": {"label": "label value regex pattern"}}
381
+ # - ("metric regex pattern 1", "metric regex pattern 2", ...)
382
+ _stats_open_metrics_filters: Union[Sequence[str], Mapping[str, Mapping[str, str]]]
383
+ _stats_disk_paths: Sequence[str] # paths to monitor disk usage
384
+ _stats_buffer_size: int # number of consolidated samples to buffer before flushing, available in run obj
385
+ _tmp_code_dir: str
386
+ _tracelog: str
387
+ _unsaved_keys: Sequence[str]
388
+ _windows: bool
389
+ allow_val_change: bool
390
+ anonymous: str
391
+ api_key: str
392
+ azure_account_url_to_access_key: Dict[str, str]
393
+ base_url: str # The base url for the wandb api
394
+ code_dir: str
395
+ colab_url: str
396
+ config_paths: Sequence[str]
397
+ console: str
398
+ console_multipart: bool # whether to produce multipart console log files
399
+ credentials_file: str # file path to write access tokens
400
+ deployment: str
401
+ disable_code: bool
402
+ disable_git: bool
403
+ disable_hints: bool
404
+ disable_job_creation: bool
405
+ disabled: bool # Alias for mode=dryrun, not supported yet
406
+ docker: str
407
+ email: str
408
+ entity: str
409
+ files_dir: str
410
+ force: bool
411
+ fork_from: RunMoment
412
+ resume_from: RunMoment
413
+ git_commit: str
414
+ git_remote: str
415
+ git_remote_url: str
416
+ git_root: str
417
+ heartbeat_seconds: int
418
+ host: str
419
+ http_proxy: str # proxy server for the http requests to W&B
420
+ https_proxy: str # proxy server for the https requests to W&B
421
+ identity_token_file: str # file path to supply a jwt for authentication
422
+ ignore_globs: Tuple[str]
423
+ init_timeout: float
424
+ is_local: bool
425
+ job_name: str
426
+ job_source: str
427
+ label_disable: bool
428
+ launch: bool
429
+ launch_config_path: str
430
+ log_dir: str
431
+ log_internal: str
432
+ log_symlink_internal: str
433
+ log_symlink_user: str
434
+ log_user: str
435
+ login_timeout: float
436
+ # magic: Union[str, bool, dict] # never used in code, deprecated
437
+ mode: str
438
+ notebook_name: str
439
+ program: str
440
+ program_abspath: str
441
+ program_relpath: str
442
+ project: str
443
+ project_url: str
444
+ quiet: bool
445
+ reinit: bool
446
+ relogin: bool
447
+ # todo: add a preprocessing step to convert this to string
448
+ resume: Union[str, bool]
449
+ resume_fname: str
450
+ resumed: bool # indication from the server about the state of the run (different from resume - user provided flag)
451
+ root_dir: str
452
+ run_group: str
453
+ run_id: str
454
+ run_job_type: str
455
+ run_mode: str
456
+ run_name: str
457
+ run_notes: str
458
+ run_tags: Tuple[str]
459
+ run_url: str
460
+ sagemaker_disable: bool
461
+ save_code: bool
462
+ settings_system: str
463
+ settings_workspace: str
464
+ show_colors: bool
465
+ show_emoji: bool
466
+ show_errors: bool
467
+ show_info: bool
468
+ show_warnings: bool
469
+ silent: bool
470
+ start_method: str
471
+ strict: bool
472
+ summary_errors: int
473
+ summary_timeout: int
474
+ summary_warnings: int
475
+ sweep_id: str
476
+ sweep_param_path: str
477
+ sweep_url: str
478
+ symlink: bool
479
+ sync_dir: str
480
+ sync_file: str
481
+ sync_symlink_latest: str
482
+ table_raise_on_max_row_limit_exceeded: bool
483
+ timespec: str
484
+ tmp_dir: str
485
+ username: str
486
+ wandb_dir: str
487
+
488
+
489
+ class Property:
490
+ """A class to represent attributes (individual settings) of the Settings object.
491
+
492
+ - Encapsulates the logic of how to preprocess and validate values of settings
493
+ throughout the lifetime of a class instance.
494
+ - Allows for runtime modification of settings with hooks, e.g. in the case when
495
+ a setting depends on another setting.
496
+ - The update() method is used to update the value of a setting.
497
+ - The `is_policy` attribute determines the source priority when updating the property value.
498
+ E.g. if `is_policy` is True, the smallest `Source` value takes precedence.
499
+ """
500
+
501
+ def __init__( # pylint: disable=unused-argument
502
+ self,
503
+ name: str,
504
+ value: Optional[Any] = None,
505
+ preprocessor: Union[Callable, Sequence[Callable], None] = None,
506
+ # validators allow programming by contract
507
+ validator: Union[Callable, Sequence[Callable], None] = None,
508
+ # runtime converter (hook): properties can be e.g. tied to other properties
509
+ hook: Union[Callable, Sequence[Callable], None] = None,
510
+ # always apply hook even if value is None. can be used to replace @property's
511
+ auto_hook: bool = False,
512
+ is_policy: bool = False,
513
+ frozen: bool = False,
514
+ source: int = Source.BASE,
515
+ **kwargs: Any,
516
+ ):
517
+ self.name = name
518
+ self._preprocessor = preprocessor
519
+ self._validator = validator
520
+ self._hook = hook
521
+ self._auto_hook = auto_hook
522
+ self._is_policy = is_policy
523
+ self._source = source
524
+
525
+ # preprocess and validate value
526
+ self._value = self._validate(self._preprocess(value))
527
+
528
+ self.__frozen = frozen
529
+
530
+ @property
531
+ def value(self) -> Any:
532
+ """Apply the runtime modifier(s) (if any) and return the value."""
533
+ _value = self._value
534
+ if (_value is not None or self._auto_hook) and self._hook is not None:
535
+ _hook = [self._hook] if callable(self._hook) else self._hook
536
+ for h in _hook:
537
+ _value = h(_value)
538
+ return _value
539
+
540
+ @property
541
+ def is_policy(self) -> bool:
542
+ return self._is_policy
543
+
544
+ @property
545
+ def source(self) -> int:
546
+ return self._source
547
+
548
+ def _preprocess(self, value: Any) -> Any:
549
+ if value is not None and self._preprocessor is not None:
550
+ _preprocessor = (
551
+ [self._preprocessor]
552
+ if callable(self._preprocessor)
553
+ else self._preprocessor
554
+ )
555
+ for p in _preprocessor:
556
+ try:
557
+ value = p(value)
558
+ except Exception:
559
+ raise SettingsPreprocessingError(
560
+ f"Unable to preprocess value for property {self.name}: {value}."
561
+ )
562
+ return value
563
+
564
+ def _validate(self, value: Any) -> Any:
565
+ if value is not None and self._validator is not None:
566
+ _validator = (
567
+ [self._validator] if callable(self._validator) else self._validator
568
+ )
569
+ for v in _validator:
570
+ if not v(value):
571
+ # failed validation will likely cause a downstream error
572
+ # when trying to convert to protobuf, so we raise a hard error
573
+ raise SettingsValidationError(
574
+ f"Invalid value for property {self.name}: {value}."
575
+ )
576
+ return value
577
+
578
+ def update(self, value: Any, source: int = Source.OVERRIDE) -> None:
579
+ """Update the value of the property."""
580
+ if self.__frozen:
581
+ raise TypeError("Property object is frozen")
582
+ # - always update value if source == Source.OVERRIDE
583
+ # - if not previously overridden:
584
+ # - update value if source is lower than or equal to current source and property is policy
585
+ # - update value if source is higher than or equal to current source and property is not policy
586
+ if (
587
+ (source == Source.OVERRIDE)
588
+ or (
589
+ self._is_policy
590
+ and self._source != Source.OVERRIDE
591
+ and source <= self._source
592
+ )
593
+ or (
594
+ not self._is_policy
595
+ and self._source != Source.OVERRIDE
596
+ and source >= self._source
597
+ )
598
+ ):
599
+ # self.__dict__["_value"] = self._validate(self._preprocess(value))
600
+ self._value = self._validate(self._preprocess(value))
601
+ self._source = source
602
+
603
+ def __setattr__(self, key: str, value: Any) -> None:
604
+ if "_Property__frozen" in self.__dict__ and self.__frozen:
605
+ raise TypeError(f"Property object {self.name} is frozen")
606
+ if key == "value":
607
+ raise AttributeError("Use update() to update property value")
608
+ self.__dict__[key] = value
609
+
610
+ def __str__(self) -> str:
611
+ return f"{self.value!r}" if isinstance(self.value, str) else f"{self.value}"
612
+
613
+ def __repr__(self) -> str:
614
+ return (
615
+ f"<Property {self.name}: value={self.value} "
616
+ f"_value={self._value} source={self._source} is_policy={self._is_policy}>"
617
+ )
618
+ # return f"<Property {self.name}: value={self.value}>"
619
+ # return self.__dict__.__repr__()
620
+
621
+
622
+ class Settings(SettingsData):
623
+ """Settings for the W&B SDK."""
624
+
625
+ def _default_props(self) -> Dict[str, Dict[str, Any]]:
626
+ """Initialize instance attributes (individual settings) as Property objects.
627
+
628
+ Helper method that is used in `__init__` together with the class attributes.
629
+ Note that key names must be the same as the class attribute names.
630
+ """
631
+ props: Dict[str, Dict[str, Any]] = dict(
632
+ _aws_lambda={
633
+ "hook": lambda _: is_aws_lambda(),
634
+ "auto_hook": True,
635
+ },
636
+ _code_path_local={
637
+ "hook": lambda _: _get_program_relpath(self.program),
638
+ "auto_hook": True,
639
+ },
640
+ _colab={
641
+ "hook": lambda _: "google.colab" in sys.modules,
642
+ "auto_hook": True,
643
+ },
644
+ _disable_machine_info={
645
+ "value": False,
646
+ "preprocessor": _str_as_bool,
647
+ },
648
+ _disable_meta={
649
+ "value": False,
650
+ "preprocessor": _str_as_bool,
651
+ "hook": lambda x: self._disable_machine_info or x,
652
+ },
653
+ _disable_service={
654
+ "value": False,
655
+ "preprocessor": self._process_disable_service,
656
+ "is_policy": True,
657
+ },
658
+ _disable_setproctitle={"value": False, "preprocessor": _str_as_bool},
659
+ _disable_stats={
660
+ "value": False,
661
+ "preprocessor": _str_as_bool,
662
+ "hook": lambda x: self._disable_machine_info or x,
663
+ },
664
+ _disable_update_check={"preprocessor": _str_as_bool},
665
+ _disable_viewer={"preprocessor": _str_as_bool},
666
+ _extra_http_headers={"preprocessor": _str_as_json},
667
+ _file_stream_max_bytes={"preprocessor": int},
668
+ _file_stream_transmit_interval={"preprocessor": float},
669
+ _file_stream_retry_max={"preprocessor": int},
670
+ _file_stream_retry_wait_min_seconds={"preprocessor": float},
671
+ _file_stream_retry_wait_max_seconds={"preprocessor": float},
672
+ _file_stream_timeout_seconds={"preprocessor": float},
673
+ _file_transfer_retry_max={"preprocessor": int},
674
+ _file_transfer_retry_wait_min_seconds={"preprocessor": float},
675
+ _file_transfer_retry_wait_max_seconds={"preprocessor": float},
676
+ _file_transfer_timeout_seconds={"preprocessor": float},
677
+ _flow_control_disabled={
678
+ "hook": lambda _: self._network_buffer == 0,
679
+ "auto_hook": True,
680
+ },
681
+ _flow_control_custom={
682
+ "hook": lambda _: bool(self._network_buffer),
683
+ "auto_hook": True,
684
+ },
685
+ _graphql_retry_max={"preprocessor": int},
686
+ _graphql_retry_wait_min_seconds={"preprocessor": float},
687
+ _graphql_retry_wait_max_seconds={"preprocessor": float},
688
+ _graphql_timeout_seconds={"preprocessor": float},
689
+ _internal_check_process={"value": 8, "preprocessor": float},
690
+ _internal_queue_timeout={"value": 2, "preprocessor": float},
691
+ _ipython={
692
+ "hook": lambda _: _get_python_type() == "ipython",
693
+ "auto_hook": True,
694
+ },
695
+ _jupyter={
696
+ "hook": lambda _: _get_python_type() == "jupyter",
697
+ "auto_hook": True,
698
+ },
699
+ _kaggle={"hook": lambda _: util._is_likely_kaggle(), "auto_hook": True},
700
+ _log_level={"value": logging.DEBUG},
701
+ _network_buffer={"preprocessor": int},
702
+ _noop={"hook": lambda _: self.mode == "disabled", "auto_hook": True},
703
+ _notebook={
704
+ "hook": lambda _: self._ipython
705
+ or self._jupyter
706
+ or self._colab
707
+ or self._kaggle,
708
+ "auto_hook": True,
709
+ },
710
+ _offline={
711
+ "hook": (
712
+ lambda _: True
713
+ if self.disabled or (self.mode in ("dryrun", "offline"))
714
+ else False
715
+ ),
716
+ "auto_hook": True,
717
+ },
718
+ _platform={"value": util.get_platform_name()},
719
+ _proxies={
720
+ # TODO: deprecate and ask the user to use http_proxy and https_proxy instead
721
+ "preprocessor": _str_as_json,
722
+ },
723
+ _require_legacy_service={"value": False, "preprocessor": _str_as_bool},
724
+ _save_requirements={"value": True, "preprocessor": _str_as_bool},
725
+ _service_wait={
726
+ "value": 30,
727
+ "preprocessor": float,
728
+ "validator": self._validate__service_wait,
729
+ },
730
+ _shared={
731
+ "hook": lambda _: self.mode == "shared",
732
+ "auto_hook": True,
733
+ },
734
+ _start_datetime={"preprocessor": _datetime_as_str},
735
+ _stats_sampling_interval={
736
+ "value": 10.0,
737
+ "preprocessor": float,
738
+ "validator": self._validate__stats_sampling_interval,
739
+ },
740
+ _stats_sample_rate_seconds={
741
+ "value": 2.0,
742
+ "preprocessor": float,
743
+ "validator": self._validate__stats_sample_rate_seconds,
744
+ },
745
+ _stats_samples_to_average={
746
+ "value": 15,
747
+ "preprocessor": int,
748
+ "validator": self._validate__stats_samples_to_average,
749
+ },
750
+ _stats_join_assets={"value": True, "preprocessor": _str_as_bool},
751
+ _stats_neuron_monitor_config_path={
752
+ "hook": lambda x: self._path_convert(x),
753
+ },
754
+ _stats_open_metrics_endpoints={
755
+ "preprocessor": _str_as_json,
756
+ },
757
+ _stats_open_metrics_filters={
758
+ # capture all metrics on all endpoints by default
759
+ "value": (".*",),
760
+ "preprocessor": _str_as_json,
761
+ },
762
+ _stats_disk_paths={
763
+ "value": ("/",),
764
+ "preprocessor": _str_as_json,
765
+ },
766
+ _stats_buffer_size={
767
+ "value": 0,
768
+ "preprocessor": int,
769
+ },
770
+ _sync={"value": False},
771
+ _tmp_code_dir={
772
+ "value": "code",
773
+ "hook": lambda x: self._path_convert(self.tmp_dir, x),
774
+ },
775
+ _windows={
776
+ "hook": lambda _: platform.system() == "Windows",
777
+ "auto_hook": True,
778
+ },
779
+ anonymous={"validator": self._validate_anonymous},
780
+ api_key={"validator": self._validate_api_key},
781
+ base_url={
782
+ "value": "https://api.wandb.ai",
783
+ "preprocessor": lambda x: str(x).strip().rstrip("/"),
784
+ "validator": self._validate_base_url,
785
+ },
786
+ colab_url={
787
+ "hook": lambda _: self._get_colab_url(),
788
+ "auto_hook": True,
789
+ },
790
+ config_paths={"preprocessor": _str_as_tuple},
791
+ console={
792
+ "value": "auto",
793
+ "validator": self._validate_console,
794
+ "hook": lambda x: self._convert_console(x),
795
+ "auto_hook": True,
796
+ },
797
+ console_multipart={"value": False, "preprocessor": _str_as_bool},
798
+ credentials_file={
799
+ "value": str(credentials.DEFAULT_WANDB_CREDENTIALS_FILE),
800
+ "preprocessor": str,
801
+ },
802
+ deployment={
803
+ "hook": lambda _: "local" if self.is_local else "cloud",
804
+ "auto_hook": True,
805
+ },
806
+ disable_code={
807
+ "value": False,
808
+ "preprocessor": _str_as_bool,
809
+ "hook": lambda x: self._disable_machine_info or x,
810
+ },
811
+ disable_hints={"preprocessor": _str_as_bool},
812
+ disable_git={
813
+ "value": False,
814
+ "preprocessor": _str_as_bool,
815
+ "hook": lambda x: self._disable_machine_info or x,
816
+ },
817
+ disable_job_creation={
818
+ "value": False,
819
+ "preprocessor": _str_as_bool,
820
+ "hook": lambda x: self._disable_machine_info or x,
821
+ },
822
+ disabled={"value": False, "preprocessor": _str_as_bool},
823
+ files_dir={
824
+ "value": "files",
825
+ "hook": lambda x: self._path_convert(
826
+ self.wandb_dir, f"{self.run_mode}-{self.timespec}-{self.run_id}", x
827
+ ),
828
+ },
829
+ force={"preprocessor": _str_as_bool},
830
+ fork_from={
831
+ "value": None,
832
+ "preprocessor": _runmoment_preprocessor,
833
+ },
834
+ resume_from={
835
+ "value": None,
836
+ "preprocessor": _runmoment_preprocessor,
837
+ },
838
+ git_remote={"value": "origin"},
839
+ heartbeat_seconds={"value": 30},
840
+ http_proxy={
841
+ "hook": lambda x: self._proxies and self._proxies.get("http") or x,
842
+ "auto_hook": True,
843
+ },
844
+ https_proxy={
845
+ "hook": lambda x: self._proxies and self._proxies.get("https") or x,
846
+ "auto_hook": True,
847
+ },
848
+ identity_token_file={"value": None, "preprocessor": str},
849
+ ignore_globs={
850
+ "value": tuple(),
851
+ "preprocessor": lambda x: tuple(x) if not isinstance(x, tuple) else x,
852
+ },
853
+ init_timeout={"value": 90, "preprocessor": lambda x: float(x)},
854
+ is_local={
855
+ "hook": (
856
+ lambda _: self.base_url != "https://api.wandb.ai"
857
+ if self.base_url is not None
858
+ else False
859
+ ),
860
+ "auto_hook": True,
861
+ },
862
+ job_name={"preprocessor": str},
863
+ job_source={"validator": self._validate_job_source},
864
+ label_disable={"preprocessor": _str_as_bool},
865
+ launch={"preprocessor": _str_as_bool},
866
+ log_dir={
867
+ "value": "logs",
868
+ "hook": lambda x: self._path_convert(
869
+ self.wandb_dir, f"{self.run_mode}-{self.timespec}-{self.run_id}", x
870
+ ),
871
+ },
872
+ log_internal={
873
+ "value": "debug-internal.log",
874
+ "hook": lambda x: self._path_convert(self.log_dir, x),
875
+ },
876
+ log_symlink_internal={
877
+ "value": "debug-internal.log",
878
+ "hook": lambda x: self._path_convert(self.wandb_dir, x),
879
+ },
880
+ log_symlink_user={
881
+ "value": "debug.log",
882
+ "hook": lambda x: self._path_convert(self.wandb_dir, x),
883
+ },
884
+ log_user={
885
+ "value": "debug.log",
886
+ "hook": lambda x: self._path_convert(self.log_dir, x),
887
+ },
888
+ login_timeout={"preprocessor": lambda x: float(x)},
889
+ mode={"value": "online", "validator": self._validate_mode},
890
+ program={
891
+ "hook": lambda x: self._get_program(x),
892
+ },
893
+ project={
894
+ "validator": self._validate_project,
895
+ },
896
+ project_url={"hook": lambda _: self._project_url(), "auto_hook": True},
897
+ quiet={"preprocessor": _str_as_bool},
898
+ reinit={"preprocessor": _str_as_bool},
899
+ relogin={"preprocessor": _str_as_bool},
900
+ # todo: hack to make to_proto() always happy
901
+ resume={"preprocessor": lambda x: None if x is False else x},
902
+ resume_fname={
903
+ "value": "wandb-resume.json",
904
+ "hook": lambda x: self._path_convert(self.wandb_dir, x),
905
+ },
906
+ resumed={"value": "False", "preprocessor": _str_as_bool},
907
+ root_dir={
908
+ "preprocessor": lambda x: str(x),
909
+ "value": os.path.abspath(os.getcwd()),
910
+ },
911
+ run_id={
912
+ "validator": self._validate_run_id,
913
+ },
914
+ run_mode={
915
+ "hook": lambda _: "offline-run" if self._offline else "run",
916
+ "auto_hook": True,
917
+ },
918
+ run_tags={
919
+ "preprocessor": lambda x: tuple(x) if not isinstance(x, tuple) else x,
920
+ },
921
+ run_url={"hook": lambda _: self._run_url(), "auto_hook": True},
922
+ sagemaker_disable={"preprocessor": _str_as_bool},
923
+ save_code={"preprocessor": _str_as_bool},
924
+ settings_system={
925
+ "value": os.path.join("~", ".config", "wandb", "settings"),
926
+ "hook": lambda x: self._path_convert(x),
927
+ },
928
+ settings_workspace={
929
+ "value": "settings",
930
+ "hook": lambda x: self._path_convert(self.wandb_dir, x),
931
+ },
932
+ show_colors={"preprocessor": _str_as_bool},
933
+ show_emoji={"preprocessor": _str_as_bool},
934
+ show_errors={"value": "True", "preprocessor": _str_as_bool},
935
+ show_info={"value": "True", "preprocessor": _str_as_bool},
936
+ show_warnings={"value": "True", "preprocessor": _str_as_bool},
937
+ silent={"value": "False", "preprocessor": _str_as_bool},
938
+ start_method={"validator": self._validate_start_method},
939
+ strict={"preprocessor": _str_as_bool},
940
+ summary_timeout={"value": 60, "preprocessor": lambda x: int(x)},
941
+ summary_warnings={
942
+ "value": 5,
943
+ "preprocessor": lambda x: int(x),
944
+ "is_policy": True,
945
+ },
946
+ sweep_url={"hook": lambda _: self._sweep_url(), "auto_hook": True},
947
+ symlink={"preprocessor": _str_as_bool},
948
+ sync_dir={
949
+ "hook": [
950
+ lambda _: self._path_convert(
951
+ self.wandb_dir, f"{self.run_mode}-{self.timespec}-{self.run_id}"
952
+ )
953
+ ],
954
+ "auto_hook": True,
955
+ },
956
+ sync_file={
957
+ "hook": lambda _: self._path_convert(
958
+ self.sync_dir, f"run-{self.run_id}.wandb"
959
+ ),
960
+ "auto_hook": True,
961
+ },
962
+ sync_symlink_latest={
963
+ "value": "latest-run",
964
+ "hook": lambda x: self._path_convert(self.wandb_dir, x),
965
+ },
966
+ table_raise_on_max_row_limit_exceeded={
967
+ "value": False,
968
+ "preprocessor": _str_as_bool,
969
+ },
970
+ timespec={
971
+ "hook": lambda _: self._start_datetime,
972
+ "auto_hook": True,
973
+ },
974
+ tmp_dir={
975
+ "value": "tmp",
976
+ "hook": lambda x: (
977
+ self._path_convert(
978
+ self.wandb_dir,
979
+ f"{self.run_mode}-{self.timespec}-{self.run_id}",
980
+ x,
981
+ )
982
+ or tempfile.gettempdir()
983
+ ),
984
+ },
985
+ wandb_dir={
986
+ "hook": lambda _: _get_wandb_dir(self.root_dir or ""),
987
+ "auto_hook": True,
988
+ },
989
+ )
990
+ return props
991
+
992
+ # helper methods for validating values
993
+ @staticmethod
994
+ def _validator_factory(hint: Any) -> Callable[[Any], bool]: # noqa: C901
995
+ """Return a factory for setting type validators."""
996
+
997
+ def helper(value: Any) -> bool:
998
+ try:
999
+ is_valid = is_instance_recursive(value, hint)
1000
+ except Exception:
1001
+ # instance check failed, but let's not crash and only print a warning
1002
+ is_valid = False
1003
+
1004
+ return is_valid
1005
+
1006
+ return helper
1007
+
1008
+ @staticmethod
1009
+ def _validate_mode(value: str) -> bool:
1010
+ choices: Set[str] = {"dryrun", "run", "offline", "online", "disabled", "shared"}
1011
+ if value not in choices:
1012
+ raise UsageError(f"Settings field `mode`: {value!r} not in {choices}")
1013
+ return True
1014
+
1015
+ @staticmethod
1016
+ def _validate_project(value: Optional[str]) -> bool:
1017
+ invalid_chars_list = list("/\\#?%:")
1018
+ if value is not None:
1019
+ if len(value) > 128:
1020
+ raise UsageError(
1021
+ f"Invalid project name {value!r}: exceeded 128 characters"
1022
+ )
1023
+ invalid_chars = {char for char in invalid_chars_list if char in value}
1024
+ if invalid_chars:
1025
+ raise UsageError(
1026
+ f"Invalid project name {value!r}: "
1027
+ f"cannot contain characters {','.join(invalid_chars_list)!r}, "
1028
+ f"found {','.join(invalid_chars)!r}"
1029
+ )
1030
+ return True
1031
+
1032
+ @staticmethod
1033
+ def _validate_start_method(value: str) -> bool:
1034
+ available_methods = ["thread"]
1035
+ if hasattr(multiprocessing, "get_all_start_methods"):
1036
+ available_methods += multiprocessing.get_all_start_methods()
1037
+ if value not in available_methods:
1038
+ raise UsageError(
1039
+ f"Settings field `start_method`: {value!r} not in {available_methods}"
1040
+ )
1041
+ return True
1042
+
1043
+ @staticmethod
1044
+ def _validate_console(value: str) -> bool:
1045
+ choices = ConsoleValue
1046
+ if value not in choices:
1047
+ # do not advertise internal console states
1048
+ choices -= {"wrap_emu", "wrap_raw"}
1049
+ raise UsageError(f"Settings field `console`: {value!r} not in {choices}")
1050
+ return True
1051
+
1052
+ @staticmethod
1053
+ def _validate_anonymous(value: str) -> bool:
1054
+ choices: Set[str] = {"allow", "must", "never", "false", "true"}
1055
+ if value not in choices:
1056
+ raise UsageError(f"Settings field `anonymous`: {value!r} not in {choices}")
1057
+ return True
1058
+
1059
+ @staticmethod
1060
+ def _validate_run_id(value: str) -> bool:
1061
+ # if len(value) > len(value.strip()):
1062
+ # raise UsageError("Run ID cannot start or end with whitespace")
1063
+ return bool(value.strip())
1064
+
1065
+ @staticmethod
1066
+ def _validate_api_key(value: str) -> bool:
1067
+ if len(value) > len(value.strip()):
1068
+ raise UsageError("API key cannot start or end with whitespace")
1069
+
1070
+ # todo: move this check to the post-init validation step
1071
+ # if value.startswith("local") and not self.is_local:
1072
+ # raise UsageError(
1073
+ # "Attempting to use a local API key to connect to https://api.wandb.ai"
1074
+ # )
1075
+ # todo: move here the logic from sdk/lib/apikey.py
1076
+
1077
+ return True
1078
+
1079
+ @staticmethod
1080
+ def _validate_base_url(value: Optional[str]) -> bool:
1081
+ """Validate the base url of the wandb server.
1082
+
1083
+ param value: URL to validate
1084
+
1085
+ Based on the Django URLValidator, but with a few additional checks.
1086
+
1087
+ Copyright (c) Django Software Foundation and individual contributors.
1088
+ All rights reserved.
1089
+
1090
+ Redistribution and use in source and binary forms, with or without modification,
1091
+ are permitted provided that the following conditions are met:
1092
+
1093
+ 1. Redistributions of source code must retain the above copyright notice,
1094
+ this list of conditions and the following disclaimer.
1095
+
1096
+ 2. Redistributions in binary form must reproduce the above copyright
1097
+ notice, this list of conditions and the following disclaimer in the
1098
+ documentation and/or other materials provided with the distribution.
1099
+
1100
+ 3. Neither the name of Django nor the names of its contributors may be used
1101
+ to endorse or promote products derived from this software without
1102
+ specific prior written permission.
1103
+
1104
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1105
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1106
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1107
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
1108
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1109
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1110
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1111
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1112
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1113
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1114
+ """
1115
+ if value is None:
1116
+ return True
1117
+
1118
+ ul = "\u00a1-\uffff" # Unicode letters range (must not be a raw string).
1119
+
1120
+ # IP patterns
1121
+ ipv4_re = (
1122
+ r"(?:0|25[0-5]|2[0-4][0-9]|1[0-9]?[0-9]?|[1-9][0-9]?)"
1123
+ r"(?:\.(?:0|25[0-5]|2[0-4][0-9]|1[0-9]?[0-9]?|[1-9][0-9]?)){3}"
1124
+ )
1125
+ ipv6_re = r"\[[0-9a-f:.]+\]" # (simple regex, validated later)
1126
+
1127
+ # Host patterns
1128
+ hostname_re = (
1129
+ r"[a-z" + ul + r"0-9](?:[a-z" + ul + r"0-9-]{0,61}[a-z" + ul + r"0-9])?"
1130
+ )
1131
+ # Max length for domain name labels is 63 characters per RFC 1034 sec. 3.1
1132
+ domain_re = r"(?:\.(?!-)[a-z" + ul + r"0-9-]{1,63}(?<!-))*"
1133
+ tld_re = (
1134
+ r"\." # dot
1135
+ r"(?!-)" # can't start with a dash
1136
+ r"(?:[a-z" + ul + "-]{2,63}" # domain label
1137
+ r"|xn--[a-z0-9]{1,59})" # or punycode label
1138
+ r"(?<!-)" # can't end with a dash
1139
+ r"\.?" # may have a trailing dot
1140
+ )
1141
+ # host_re = "(" + hostname_re + domain_re + tld_re + "|localhost)"
1142
+ # todo?: allow hostname to be just a hostname (no tld)?
1143
+ host_re = "(" + hostname_re + domain_re + f"({tld_re})?" + "|localhost)"
1144
+
1145
+ regex = re.compile(
1146
+ r"^(?:[a-z0-9.+-]*)://" # scheme is validated separately
1147
+ r"(?:[^\s:@/]+(?::[^\s:@/]*)?@)?" # user:pass authentication
1148
+ r"(?:" + ipv4_re + "|" + ipv6_re + "|" + host_re + ")"
1149
+ r"(?::[0-9]{1,5})?" # port
1150
+ r"(?:[/?#][^\s]*)?" # resource path
1151
+ r"\Z",
1152
+ re.IGNORECASE,
1153
+ )
1154
+ schemes = {"http", "https"}
1155
+ unsafe_chars = frozenset("\t\r\n")
1156
+
1157
+ scheme = value.split("://")[0].lower()
1158
+ split_url = urlsplit(value)
1159
+ parsed_url = urlparse(value)
1160
+
1161
+ if re.match(r".*wandb\.ai[^\.]*$", value) and "api." not in value:
1162
+ # user might guess app.wandb.ai or wandb.ai is the default cloud server
1163
+ raise UsageError(
1164
+ f"{value} is not a valid server address, did you mean https://api.wandb.ai?"
1165
+ )
1166
+ elif re.match(r".*wandb\.ai[^\.]*$", value) and scheme != "https":
1167
+ raise UsageError("http is not secure, please use https://api.wandb.ai")
1168
+ elif parsed_url.netloc == "":
1169
+ raise UsageError(f"Invalid URL: {value}")
1170
+ elif unsafe_chars.intersection(value):
1171
+ raise UsageError("URL cannot contain unsafe characters")
1172
+ elif scheme not in schemes:
1173
+ raise UsageError("URL must start with `http(s)://`")
1174
+ elif not regex.search(value):
1175
+ raise UsageError(f"{value} is not a valid server address")
1176
+ elif split_url.hostname is None or len(split_url.hostname) > 253:
1177
+ raise UsageError("hostname is invalid")
1178
+
1179
+ return True
1180
+
1181
+ @staticmethod
1182
+ def _process_disable_service(value: Union[str, bool]) -> bool:
1183
+ value = _str_as_bool(value)
1184
+ if value:
1185
+ wandb.termwarn(
1186
+ "Disabling the wandb service is deprecated as of version 0.18.0 and will be removed in future versions. ",
1187
+ repeat=False,
1188
+ )
1189
+ return value
1190
+
1191
+ @staticmethod
1192
+ def _validate__service_wait(value: float) -> bool:
1193
+ if value <= 0:
1194
+ raise UsageError("_service_wait must be a positive number")
1195
+ return True
1196
+
1197
+ @staticmethod
1198
+ def _validate__stats_sampling_interval(value: float) -> bool:
1199
+ if value < 0.1:
1200
+ raise UsageError("sampling interval must be >= 0.1 seconds")
1201
+ return True
1202
+
1203
+ @staticmethod
1204
+ def _validate__stats_sample_rate_seconds(value: float) -> bool:
1205
+ if value < 0.1:
1206
+ raise UsageError("_stats_sample_rate_seconds must be >= 0.1")
1207
+ return True
1208
+
1209
+ @staticmethod
1210
+ def _validate__stats_samples_to_average(value: int) -> bool:
1211
+ if value < 1 or value > 30:
1212
+ raise UsageError("_stats_samples_to_average must be between 1 and 30")
1213
+ return True
1214
+
1215
+ @staticmethod
1216
+ def _validate_job_source(value: str) -> bool:
1217
+ valid_sources = ["repo", "artifact", "image"]
1218
+ if value not in valid_sources:
1219
+ raise UsageError(
1220
+ f"Settings field `job_source`: {value!r} not in {valid_sources}"
1221
+ )
1222
+ return True
1223
+
1224
+ # other helper methods
1225
+ @staticmethod
1226
+ def _path_convert(*args: str) -> str:
1227
+ """Join path and apply os.path.expanduser to it."""
1228
+ return os.path.expanduser(os.path.join(*args))
1229
+
1230
+ def _convert_console(self, console: str) -> str:
1231
+ if console == "auto":
1232
+ if (
1233
+ self._jupyter
1234
+ or (self.start_method == "thread")
1235
+ or not self._disable_service
1236
+ or self._windows
1237
+ ):
1238
+ console = "wrap"
1239
+ else:
1240
+ console = "redirect"
1241
+ return console
1242
+
1243
+ def _get_colab_url(self) -> Optional[str]:
1244
+ if not self._colab:
1245
+ return None
1246
+ if self._jupyter_path and self._jupyter_path.startswith("fileId="):
1247
+ unescaped = unquote(self._jupyter_path)
1248
+ return "https://colab.research.google.com/notebook#" + unescaped
1249
+ return None
1250
+
1251
+ def _get_program(self, program: Optional[str]) -> Optional[str]:
1252
+ if program is not None and program != "<python with no main file>":
1253
+ return program
1254
+
1255
+ if not self._jupyter:
1256
+ return program
1257
+
1258
+ if self.notebook_name:
1259
+ return self.notebook_name
1260
+
1261
+ if not self._jupyter_path:
1262
+ return program
1263
+
1264
+ if self._jupyter_path.startswith("fileId="):
1265
+ return self._jupyter_name
1266
+ else:
1267
+ return self._jupyter_path
1268
+
1269
+ def _get_url_query_string(self) -> str:
1270
+ # TODO(settings) use `wandb_setting` (if self.anonymous != "true":)
1271
+ if Api().settings().get("anonymous") != "true":
1272
+ return ""
1273
+
1274
+ api_key = apikey.api_key(settings=self)
1275
+
1276
+ return f"?{urlencode({'apiKey': api_key})}"
1277
+
1278
+ def _project_url_base(self) -> str:
1279
+ if not all([self.entity, self.project]):
1280
+ return ""
1281
+
1282
+ app_url = wandb.util.app_url(self.base_url)
1283
+ return f"{app_url}/{quote(self.entity)}/{quote(self.project)}"
1284
+
1285
+ def _project_url(self) -> str:
1286
+ project_url = self._project_url_base()
1287
+ if not project_url:
1288
+ return ""
1289
+
1290
+ query = self._get_url_query_string()
1291
+
1292
+ return f"{project_url}{query}"
1293
+
1294
+ def _run_url(self) -> str:
1295
+ """Return the run url."""
1296
+ project_url = self._project_url_base()
1297
+ if not all([project_url, self.run_id]):
1298
+ return ""
1299
+
1300
+ query = self._get_url_query_string()
1301
+ return f"{project_url}/runs/{quote(self.run_id)}{query}"
1302
+
1303
+ def _set_run_start_time(self, source: int = Source.BASE) -> None:
1304
+ """Set the time stamps for the settings.
1305
+
1306
+ Called once the run is initialized.
1307
+ """
1308
+ time_stamp: float = time.time()
1309
+ datetime_now: datetime = datetime.fromtimestamp(time_stamp)
1310
+ datetime_now_str = _datetime_as_str(datetime_now)
1311
+ object.__setattr__(self, "_Settings_start_datetime", datetime_now_str)
1312
+ object.__setattr__(self, "_Settings_start_time", time_stamp)
1313
+ self.update(
1314
+ _start_datetime=datetime_now_str,
1315
+ _start_time=time_stamp,
1316
+ source=source,
1317
+ )
1318
+
1319
+ def _sweep_url(self) -> str:
1320
+ """Return the sweep url."""
1321
+ project_url = self._project_url_base()
1322
+ if not all([project_url, self.sweep_id]):
1323
+ return ""
1324
+
1325
+ query = self._get_url_query_string()
1326
+ return f"{project_url}/sweeps/{quote(self.sweep_id)}{query}"
1327
+
1328
+ def __init__(self, **kwargs: Any) -> None:
1329
+ self.__frozen: bool = False
1330
+ self.__initialized: bool = False
1331
+
1332
+ self.__modification_order = SETTINGS_TOPOLOGICALLY_SORTED
1333
+
1334
+ # Set default settings values
1335
+ # We start off with the class attributes and `default_props` dicts
1336
+ # and then create Property objects.
1337
+ # Once initialized, attributes are to only be updated using the `update` method
1338
+ default_props = self._default_props()
1339
+
1340
+ # Init instance attributes as Property objects.
1341
+ # Type hints of class attributes are used to generate a type validator function
1342
+ # for runtime checks for each attribute.
1343
+ # These are defaults, using Source.BASE for non-policy attributes and Source.RUN for policies.
1344
+ for prop, type_hint in get_type_hints(SettingsData).items():
1345
+ validators = [self._validator_factory(type_hint)]
1346
+
1347
+ if prop in default_props:
1348
+ validator = default_props[prop].pop("validator", [])
1349
+ # Property validator could be either Callable or Sequence[Callable]
1350
+ if callable(validator):
1351
+ validators.append(validator)
1352
+ elif isinstance(validator, Sequence):
1353
+ validators.extend(list(validator))
1354
+ object.__setattr__(
1355
+ self,
1356
+ prop,
1357
+ Property(
1358
+ name=prop,
1359
+ **default_props[prop],
1360
+ validator=validators,
1361
+ # todo: double-check this logic:
1362
+ source=Source.RUN
1363
+ if default_props[prop].get("is_policy", False)
1364
+ else Source.BASE,
1365
+ ),
1366
+ )
1367
+ else:
1368
+ object.__setattr__(
1369
+ self,
1370
+ prop,
1371
+ Property(
1372
+ name=prop,
1373
+ validator=validators,
1374
+ source=Source.BASE,
1375
+ ),
1376
+ )
1377
+
1378
+ # update overridden defaults from kwargs
1379
+ unexpected_arguments = [k for k in kwargs.keys() if k not in self.__dict__]
1380
+ # allow only explicitly defined arguments
1381
+ if unexpected_arguments:
1382
+ raise SettingsUnexpectedArgsError(
1383
+ f"Got unexpected arguments: {unexpected_arguments}. "
1384
+ )
1385
+
1386
+ # automatically inspect setting validators and runtime hooks and topologically sort them
1387
+ # so that we can safely update them. throw error if there are cycles.
1388
+ for prop in self.__modification_order:
1389
+ if prop in kwargs:
1390
+ source = Source.RUN if self.__dict__[prop].is_policy else Source.BASE
1391
+ self.update({prop: kwargs[prop]}, source=source)
1392
+ kwargs.pop(prop)
1393
+
1394
+ for k, v in kwargs.items():
1395
+ # todo: double-check this logic:
1396
+ source = Source.RUN if self.__dict__[k].is_policy else Source.BASE
1397
+ self.update({k: v}, source=source)
1398
+
1399
+ # setup private attributes
1400
+ object.__setattr__(self, "_Settings_start_datetime", None)
1401
+ object.__setattr__(self, "_Settings_start_time", None)
1402
+
1403
+ # done with init, use self.update() to update attributes from now on
1404
+ self.__initialized = True
1405
+
1406
+ # todo? freeze settings to prevent accidental changes
1407
+ # self.freeze()
1408
+
1409
+ def __str__(self) -> str:
1410
+ # get attributes that are instances of the Property class:
1411
+ representation = {
1412
+ k: v.value for k, v in self.__dict__.items() if isinstance(v, Property)
1413
+ }
1414
+ return f"<Settings {_redact_dict(representation)}>"
1415
+
1416
+ def __repr__(self) -> str:
1417
+ # private attributes
1418
+ private = {k: v for k, v in self.__dict__.items() if k.startswith("_Settings")}
1419
+ # get attributes that are instances of the Property class:
1420
+ attributes = {
1421
+ k: f"<Property value={v.value} source={v.source}>"
1422
+ for k, v in self.__dict__.items()
1423
+ if isinstance(v, Property)
1424
+ }
1425
+ representation = {**private, **attributes}
1426
+ return f"<Settings {representation}>"
1427
+
1428
+ def __copy__(self) -> "Settings":
1429
+ """Ensure that a copy of the settings object is a truly deep copy.
1430
+
1431
+ Note that the copied object will not be frozen todo? why is this needed?
1432
+ """
1433
+ # get attributes that are instances of the Property class:
1434
+ attributes = {k: v for k, v in self.__dict__.items() if isinstance(v, Property)}
1435
+ new = Settings()
1436
+ # update properties that have deps or are dependent on in the topologically-sorted order
1437
+ for prop in self.__modification_order:
1438
+ new.update({prop: attributes[prop]._value}, source=attributes[prop].source)
1439
+ attributes.pop(prop)
1440
+
1441
+ # update the remaining attributes
1442
+ for k, v in attributes.items():
1443
+ # make sure to use the raw property value (v._value),
1444
+ # not the potential result of runtime hooks applied to it (v.value)
1445
+ new.update({k: v._value}, source=v.source)
1446
+ new.unfreeze()
1447
+
1448
+ return new
1449
+
1450
+ def __deepcopy__(self, memo: dict) -> "Settings":
1451
+ return self.__copy__()
1452
+
1453
+ # attribute access methods
1454
+ @no_type_check # this is a hack to make mypy happy
1455
+ def __getattribute__(self, name: str) -> Any:
1456
+ """Expose `attribute.value` if `attribute` is a Property."""
1457
+ item = object.__getattribute__(self, name)
1458
+ if isinstance(item, Property):
1459
+ return item.value
1460
+ return item
1461
+
1462
+ def __setattr__(self, key: str, value: Any) -> None:
1463
+ if "_Settings__initialized" in self.__dict__ and self.__initialized:
1464
+ raise TypeError(f"Please use update() to update attribute `{key}` value")
1465
+ object.__setattr__(self, key, value)
1466
+
1467
+ def __iter__(self) -> Iterable:
1468
+ return iter(self.to_dict())
1469
+
1470
+ def copy(self) -> "Settings":
1471
+ return self.__copy__()
1472
+
1473
+ # implement the Mapping interface
1474
+ def keys(self) -> Iterable[str]:
1475
+ return self.to_dict().keys()
1476
+
1477
+ @no_type_check # this is a hack to make mypy happy
1478
+ def __getitem__(self, name: str) -> Any:
1479
+ """Expose attribute.value if attribute is a Property."""
1480
+ item = object.__getattribute__(self, name)
1481
+ if isinstance(item, Property):
1482
+ return item.value
1483
+ return item
1484
+
1485
+ def update(
1486
+ self,
1487
+ settings: Optional[Union[Dict[str, Any], "Settings"]] = None,
1488
+ source: int = Source.OVERRIDE,
1489
+ **kwargs: Any,
1490
+ ) -> None:
1491
+ """Update individual settings."""
1492
+ if "_Settings__frozen" in self.__dict__ and self.__frozen:
1493
+ raise TypeError("Settings object is frozen")
1494
+
1495
+ if isinstance(settings, Settings):
1496
+ # If a Settings object is passed, detect the settings that differ
1497
+ # from defaults, collect them into a dict, and apply them using `source`.
1498
+ # This comes up in `wandb.init(settings=wandb.Settings(...))` and
1499
+ # seems like the behavior that the user would expect when calling init that way.
1500
+ defaults = Settings()
1501
+ settings_dict = dict()
1502
+ for k, v in settings.__dict__.items():
1503
+ if isinstance(v, Property):
1504
+ if v._value != defaults.__dict__[k]._value:
1505
+ settings_dict[k] = v._value
1506
+ # replace with the generated dict
1507
+ settings = settings_dict
1508
+
1509
+ # add kwargs to settings
1510
+ settings = settings or dict()
1511
+ # explicit kwargs take precedence over settings
1512
+ settings = {**settings, **kwargs}
1513
+ unknown_properties = []
1514
+ for key in settings.keys():
1515
+ # only allow updating known Properties
1516
+ if key not in self.__dict__ or not isinstance(self.__dict__[key], Property):
1517
+ unknown_properties.append(key)
1518
+ if unknown_properties:
1519
+ raise KeyError(f"Unknown settings: {unknown_properties}")
1520
+ # only if all keys are valid, update them
1521
+
1522
+ # store settings to be updated in a dict to preserve stats on preprocessing and validation errors
1523
+ settings.copy()
1524
+
1525
+ # update properties that have deps or are dependent on in the topologically-sorted order
1526
+ for key in self.__modification_order:
1527
+ if key in settings:
1528
+ self.__dict__[key].update(settings.pop(key), source=source)
1529
+
1530
+ # update the remaining properties
1531
+ for key, value in settings.items():
1532
+ self.__dict__[key].update(value, source)
1533
+
1534
+ def items(self) -> ItemsView[str, Any]:
1535
+ return self.to_dict().items()
1536
+
1537
+ def get(self, key: str, default: Optional[Any] = None) -> Any:
1538
+ return self.to_dict().get(key, default)
1539
+
1540
+ def freeze(self) -> None:
1541
+ object.__setattr__(self, "_Settings__frozen", True)
1542
+
1543
+ def unfreeze(self) -> None:
1544
+ object.__setattr__(self, "_Settings__frozen", False)
1545
+
1546
+ def is_frozen(self) -> bool:
1547
+ return self.__frozen
1548
+
1549
+ def to_dict(self) -> Dict[str, Any]:
1550
+ """Return a dict representation of the settings."""
1551
+ # get attributes that are instances of the Property class:
1552
+ attributes = {
1553
+ k: v.value for k, v in self.__dict__.items() if isinstance(v, Property)
1554
+ }
1555
+ return attributes
1556
+
1557
+ def to_proto(self) -> wandb_settings_pb2.Settings:
1558
+ """Generate a protobuf representation of the settings."""
1559
+ from dataclasses import fields
1560
+
1561
+ settings = wandb_settings_pb2.Settings()
1562
+ for field in fields(SettingsData):
1563
+ k = field.name
1564
+ v = getattr(self, k)
1565
+ # special case for _stats_open_metrics_filters
1566
+ if k == "_stats_open_metrics_filters":
1567
+ if isinstance(v, (list, set, tuple)):
1568
+ setting = getattr(settings, k)
1569
+ setting.sequence.value.extend(v)
1570
+ elif isinstance(v, dict):
1571
+ setting = getattr(settings, k)
1572
+ for key, value in v.items():
1573
+ for kk, vv in value.items():
1574
+ setting.mapping.value[key].value[kk] = vv
1575
+ else:
1576
+ raise TypeError(f"Unsupported type {type(v)} for setting {k}")
1577
+ continue
1578
+
1579
+ if isinstance(v, bool):
1580
+ getattr(settings, k).CopyFrom(BoolValue(value=v))
1581
+ elif isinstance(v, int):
1582
+ getattr(settings, k).CopyFrom(Int32Value(value=v))
1583
+ elif isinstance(v, float):
1584
+ getattr(settings, k).CopyFrom(DoubleValue(value=v))
1585
+ elif isinstance(v, str):
1586
+ getattr(settings, k).CopyFrom(StringValue(value=v))
1587
+ elif isinstance(v, (list, set, tuple)):
1588
+ # we only support sequences of strings for now
1589
+ sequence = getattr(settings, k)
1590
+ sequence.value.extend(v)
1591
+ elif isinstance(v, dict):
1592
+ mapping = getattr(settings, k)
1593
+ for key, value in v.items():
1594
+ # we only support dicts with string values for now
1595
+ mapping.value[key] = value
1596
+ elif isinstance(v, RunMoment):
1597
+ getattr(settings, k).CopyFrom(
1598
+ wandb_settings_pb2.RunMoment(
1599
+ run=v.run,
1600
+ value=v.value,
1601
+ metric=v.metric,
1602
+ )
1603
+ )
1604
+ elif v is None:
1605
+ # None is the default value for all settings, so we don't need to set it,
1606
+ # i.e. None means that the value was not set.
1607
+ pass
1608
+ else:
1609
+ raise TypeError(f"Unsupported type {type(v)} for setting {k}")
1610
+ # TODO: store property sources in the protobuf so that we can reconstruct the
1611
+ # settings object from the protobuf
1612
+ return settings
1613
+
1614
+ # apply settings from different sources
1615
+ # TODO(dd): think about doing some|all of that at init
1616
+ def _apply_settings(
1617
+ self,
1618
+ settings: "Settings",
1619
+ _logger: Optional[_EarlyLogger] = None,
1620
+ ) -> None:
1621
+ """Apply settings from a Settings object."""
1622
+ if _logger is not None:
1623
+ _logger.info(f"Applying settings from {settings}")
1624
+ attributes = {
1625
+ k: v for k, v in settings.__dict__.items() if isinstance(v, Property)
1626
+ }
1627
+ # update properties that have deps or are dependent on in the topologically-sorted order
1628
+ for prop in self.__modification_order:
1629
+ self.update({prop: attributes[prop]._value}, source=attributes[prop].source)
1630
+ attributes.pop(prop)
1631
+ # update the remaining properties
1632
+ for k, v in attributes.items():
1633
+ # note that only the same/higher priority settings are propagated
1634
+ self.update({k: v._value}, source=v.source)
1635
+
1636
+ @staticmethod
1637
+ def _load_config_file(file_name: str, section: str = "default") -> dict:
1638
+ parser = configparser.ConfigParser()
1639
+ parser.add_section(section)
1640
+ parser.read(file_name)
1641
+ config: Dict[str, Any] = dict()
1642
+ for k in parser[section]:
1643
+ config[k] = parser[section][k]
1644
+ # TODO (cvp): we didn't do this in the old cli, but it seems necessary
1645
+ if k == "ignore_globs":
1646
+ config[k] = config[k].split(",")
1647
+ return config
1648
+
1649
+ def _apply_base(self, pid: int, _logger: Optional[_EarlyLogger] = None) -> None:
1650
+ if _logger is not None:
1651
+ _logger.info(f"Current SDK version is {wandb.__version__}")
1652
+ _logger.info(f"Configure stats pid to {pid}")
1653
+ self.update({"_stats_pid": pid}, source=Source.SETUP)
1654
+
1655
+ def _apply_config_files(self, _logger: Optional[_EarlyLogger] = None) -> None:
1656
+ # TODO(jhr): permit setting of config in system and workspace
1657
+ if self.settings_system is not None:
1658
+ if _logger is not None:
1659
+ _logger.info(f"Loading settings from {self.settings_system}")
1660
+ self.update(
1661
+ self._load_config_file(self.settings_system),
1662
+ source=Source.SYSTEM,
1663
+ )
1664
+ if self.settings_workspace is not None:
1665
+ if _logger is not None:
1666
+ _logger.info(f"Loading settings from {self.settings_workspace}")
1667
+ self.update(
1668
+ self._load_config_file(self.settings_workspace),
1669
+ source=Source.WORKSPACE,
1670
+ )
1671
+
1672
+ def _apply_env_vars(
1673
+ self,
1674
+ environ: Mapping[str, Any],
1675
+ _logger: Optional[_EarlyLogger] = None,
1676
+ ) -> None:
1677
+ env_prefix: str = "WANDB_"
1678
+ special_env_var_names = {
1679
+ "WANDB_TRACELOG": "_tracelog",
1680
+ "WANDB_DISABLE_SERVICE": "_disable_service",
1681
+ "WANDB_SERVICE_TRANSPORT": "_service_transport",
1682
+ "WANDB_DIR": "root_dir",
1683
+ "WANDB_NAME": "run_name",
1684
+ "WANDB_NOTES": "run_notes",
1685
+ "WANDB_TAGS": "run_tags",
1686
+ "WANDB_JOB_TYPE": "run_job_type",
1687
+ "WANDB_HTTP_TIMEOUT": "_graphql_timeout_seconds",
1688
+ "WANDB_FILE_PUSHER_TIMEOUT": "_file_transfer_timeout_seconds",
1689
+ "WANDB_USER_EMAIL": "email",
1690
+ }
1691
+ env = dict()
1692
+ for setting, value in environ.items():
1693
+ if not setting.startswith(env_prefix):
1694
+ continue
1695
+
1696
+ if setting in special_env_var_names:
1697
+ key = special_env_var_names[setting]
1698
+ else:
1699
+ # otherwise, strip the prefix and convert to lowercase
1700
+ key = setting[len(env_prefix) :].lower()
1701
+
1702
+ if key in self.__dict__:
1703
+ if key in ("ignore_globs", "run_tags"):
1704
+ value = value.split(",")
1705
+ env[key] = value
1706
+ elif _logger is not None:
1707
+ _logger.warning(f"Unknown environment variable: {setting}")
1708
+
1709
+ if _logger is not None:
1710
+ _logger.info(
1711
+ f"Loading settings from environment variables: {_redact_dict(env)}"
1712
+ )
1713
+ self.update(env, source=Source.ENV)
1714
+
1715
+ def _infer_settings_from_environment(
1716
+ self, _logger: Optional[_EarlyLogger] = None
1717
+ ) -> None:
1718
+ """Modify settings based on environment (for runs and cli)."""
1719
+ settings: Dict[str, Union[bool, str, Sequence, None]] = dict()
1720
+ # disable symlinks if on windows (requires admin or developer setup)
1721
+ settings["symlink"] = True
1722
+ if self._windows:
1723
+ settings["symlink"] = False
1724
+
1725
+ # TODO(jhr): this needs to be moved last in setting up settings ?
1726
+ # (dd): loading order does not matter as long as source is set correctly
1727
+
1728
+ # For code saving, only allow env var override if value from server is true, or
1729
+ # if no preference was specified.
1730
+ if (self.save_code is True or self.save_code is None) and (
1731
+ os.getenv(wandb.env.SAVE_CODE) is not None
1732
+ or os.getenv(wandb.env.DISABLE_CODE) is not None
1733
+ ):
1734
+ settings["save_code"] = wandb.env.should_save_code()
1735
+
1736
+ settings["disable_git"] = wandb.env.disable_git()
1737
+
1738
+ # Attempt to get notebook information if not already set by the user
1739
+ if self._jupyter and (self.notebook_name is None or self.notebook_name == ""):
1740
+ meta = wandb.jupyter.notebook_metadata(self.silent) # type: ignore
1741
+ settings["_jupyter_path"] = meta.get("path")
1742
+ settings["_jupyter_name"] = meta.get("name")
1743
+ settings["_jupyter_root"] = meta.get("root")
1744
+ elif (
1745
+ self._jupyter
1746
+ and self.notebook_name is not None
1747
+ and os.path.exists(self.notebook_name)
1748
+ ):
1749
+ settings["_jupyter_path"] = self.notebook_name
1750
+ settings["_jupyter_name"] = self.notebook_name
1751
+ settings["_jupyter_root"] = os.getcwd()
1752
+ elif self._jupyter:
1753
+ wandb.termwarn(
1754
+ "WANDB_NOTEBOOK_NAME should be a path to a notebook file, "
1755
+ f"couldn't find {self.notebook_name}.",
1756
+ )
1757
+
1758
+ # host and username are populated by apply_env_vars if corresponding env
1759
+ # vars exist -- but if they don't, we'll fill them in here
1760
+ if self.host is None:
1761
+ settings["host"] = socket.gethostname() # type: ignore
1762
+
1763
+ if self.username is None:
1764
+ try: # type: ignore
1765
+ settings["username"] = getpass.getuser()
1766
+ except KeyError:
1767
+ # getuser() could raise KeyError in restricted environments like
1768
+ # chroot jails or docker containers. Return user id in these cases.
1769
+ settings["username"] = str(os.getuid())
1770
+
1771
+ _executable = (
1772
+ self._executable
1773
+ or os.environ.get(wandb.env._EXECUTABLE)
1774
+ or sys.executable
1775
+ or shutil.which("python3")
1776
+ or "python3"
1777
+ )
1778
+ settings["_executable"] = _executable
1779
+
1780
+ settings["docker"] = wandb.env.get_docker(wandb.util.image_id_from_k8s())
1781
+
1782
+ # TODO: we should use the cuda library to collect this
1783
+ if os.path.exists("/usr/local/cuda/version.txt"):
1784
+ with open("/usr/local/cuda/version.txt") as f:
1785
+ settings["_cuda"] = f.read().split(" ")[-1].strip()
1786
+ if not self._jupyter:
1787
+ settings["_args"] = sys.argv[1:]
1788
+ settings["_os"] = platform.platform(aliased=True)
1789
+ settings["_python"] = platform.python_version()
1790
+
1791
+ if _logger is not None:
1792
+ _logger.info(
1793
+ f"Inferring settings from compute environment: {_redact_dict(settings)}"
1794
+ )
1795
+
1796
+ self.update(settings, source=Source.ENV)
1797
+
1798
+ def _infer_run_settings_from_environment(
1799
+ self,
1800
+ _logger: Optional[_EarlyLogger] = None,
1801
+ ) -> None:
1802
+ """Modify settings based on environment (for runs only)."""
1803
+ # If there's not already a program file, infer it now.
1804
+ settings: Dict[str, Union[bool, str, None]] = dict()
1805
+ program = self.program or _get_program()
1806
+ if program is not None:
1807
+ repo = GitRepo()
1808
+ root = repo.root or os.getcwd()
1809
+
1810
+ program_relpath = self.program_relpath or _get_program_relpath(
1811
+ program, repo.root, _logger=_logger
1812
+ )
1813
+ settings["program_relpath"] = program_relpath
1814
+ program_abspath = os.path.abspath(
1815
+ os.path.join(root, os.path.relpath(os.getcwd(), root), program)
1816
+ )
1817
+ if os.path.exists(program_abspath):
1818
+ settings["program_abspath"] = program_abspath
1819
+ else:
1820
+ program = "<python with no main file>"
1821
+
1822
+ settings["program"] = program
1823
+
1824
+ if _logger is not None:
1825
+ _logger.info(
1826
+ f"Inferring run settings from compute environment: {_redact_dict(settings)}"
1827
+ )
1828
+
1829
+ self.update(settings, source=Source.ENV)
1830
+
1831
+ def _apply_setup(
1832
+ self, setup_settings: Dict[str, Any], _logger: Optional[_EarlyLogger] = None
1833
+ ) -> None:
1834
+ if _logger:
1835
+ _logger.info(f"Applying setup settings: {_redact_dict(setup_settings)}")
1836
+ self.update(setup_settings, source=Source.SETUP)
1837
+
1838
+ def _apply_user(
1839
+ self, user_settings: Dict[str, Any], _logger: Optional[_EarlyLogger] = None
1840
+ ) -> None:
1841
+ if _logger:
1842
+ _logger.info(f"Applying user settings: {_redact_dict(user_settings)}")
1843
+ self.update(user_settings, source=Source.USER)
1844
+
1845
+ def _apply_init(self, init_settings: Dict[str, Union[str, int, None]]) -> None:
1846
+ # pop magic from init settings
1847
+ init_settings.pop("magic", None)
1848
+
1849
+ # prevent setting project, entity if in sweep
1850
+ # TODO(jhr): these should be locked elements in the future
1851
+ if self.sweep_id:
1852
+ for key in ("project", "entity", "id"):
1853
+ val = init_settings.pop(key, None)
1854
+ if val:
1855
+ wandb.termwarn(
1856
+ f"Ignored wandb.init() arg {key} when running a sweep."
1857
+ )
1858
+ if self.launch:
1859
+ if self.project is not None and init_settings.pop("project", None):
1860
+ wandb.termwarn(
1861
+ "Project is ignored when running from wandb launch context. "
1862
+ "Ignored wandb.init() arg project when running running from launch.",
1863
+ )
1864
+ for key in ("entity", "id"):
1865
+ # Init settings cannot override launch settings.
1866
+ if init_settings.pop(key, None):
1867
+ wandb.termwarn(
1868
+ "Project, entity and id are ignored when running from wandb launch context. "
1869
+ f"Ignored wandb.init() arg {key} when running running from launch.",
1870
+ )
1871
+
1872
+ # strip out items where value is None
1873
+ param_map = dict(
1874
+ name="run_name",
1875
+ id="run_id",
1876
+ tags="run_tags",
1877
+ group="run_group",
1878
+ job_type="run_job_type",
1879
+ notes="run_notes",
1880
+ dir="root_dir",
1881
+ sweep_id="sweep_id",
1882
+ )
1883
+ init_settings = {
1884
+ param_map.get(k, k): v for k, v in init_settings.items() if v is not None
1885
+ }
1886
+ # fun logic to convert the resume init arg
1887
+ if init_settings.get("resume"):
1888
+ if isinstance(init_settings["resume"], str):
1889
+ if init_settings["resume"] not in ("allow", "must", "never", "auto"):
1890
+ if init_settings.get("run_id") is None:
1891
+ # TODO: deprecate or don't support
1892
+ init_settings["run_id"] = init_settings["resume"]
1893
+ init_settings["resume"] = "allow"
1894
+ elif init_settings["resume"] is True:
1895
+ # todo: add deprecation warning, switch to literal strings for resume
1896
+ init_settings["resume"] = "auto"
1897
+
1898
+ # update settings
1899
+ self.update(init_settings, source=Source.INIT)
1900
+ self._handle_fork_logic()
1901
+ self._handle_rewind_logic()
1902
+ self._handle_resume_logic()
1903
+
1904
+ def _handle_fork_logic(self) -> None:
1905
+ if self.fork_from is None:
1906
+ return
1907
+
1908
+ if self.run_id is not None and (self.fork_from.run == self.run_id):
1909
+ raise ValueError(
1910
+ "Provided `run_id` is the same as the run to `fork_from`. "
1911
+ "Please provide a different `run_id` or remove the `run_id` argument. "
1912
+ "If you want to rewind the current run, please use `resume_from` instead."
1913
+ )
1914
+
1915
+ def _handle_rewind_logic(self) -> None:
1916
+ if self.resume_from is None:
1917
+ return
1918
+
1919
+ if self.run_id is not None and (self.resume_from.run != self.run_id):
1920
+ wandb.termwarn(
1921
+ "Both `run_id` and `resume_from` have been specified with different ids. "
1922
+ "`run_id` will be ignored."
1923
+ )
1924
+ self.update({"run_id": self.resume_from.run}, source=Source.INIT)
1925
+
1926
+ def _handle_resume_logic(self) -> None:
1927
+ # handle auto resume logic
1928
+ if self.resume == "auto":
1929
+ if os.path.exists(self.resume_fname):
1930
+ with open(self.resume_fname) as f:
1931
+ resume_run_id = json.load(f)["run_id"]
1932
+ if self.run_id is None:
1933
+ self.update({"run_id": resume_run_id}, source=Source.INIT) # type: ignore
1934
+ elif self.run_id != resume_run_id:
1935
+ wandb.termwarn(
1936
+ "Tried to auto resume run with "
1937
+ f"id {resume_run_id} but id {self.run_id} is set.",
1938
+ )
1939
+
1940
+ self.update({"run_id": self.run_id or generate_id()}, source=Source.INIT)
1941
+ # persist our run id in case of failure
1942
+ # check None for mypy
1943
+ if self.resume == "auto" and self.resume_fname is not None:
1944
+ filesystem.mkdir_exists_ok(self.wandb_dir)
1945
+ with open(self.resume_fname, "w") as f:
1946
+ f.write(json.dumps({"run_id": self.run_id}))
1947
+
1948
+ def _apply_login(
1949
+ self,
1950
+ login_settings: Dict[str, Any],
1951
+ _logger: Optional[_EarlyLogger] = None,
1952
+ ) -> None:
1953
+ key_map = {
1954
+ "key": "api_key",
1955
+ "host": "base_url",
1956
+ "timeout": "login_timeout",
1957
+ }
1958
+
1959
+ # Rename keys and keep only the non-None values.
1960
+ #
1961
+ # The input keys are parameters to wandb.login(), but we use different
1962
+ # names for some of them in Settings.
1963
+ login_settings = {
1964
+ key_map.get(key, key): value
1965
+ for key, value in login_settings.items()
1966
+ if value is not None
1967
+ }
1968
+
1969
+ if _logger:
1970
+ _logger.info(f"Applying login settings: {_redact_dict(login_settings)}")
1971
+
1972
+ self.update(
1973
+ login_settings,
1974
+ source=Source.LOGIN,
1975
+ )
1976
+
1977
+ def _apply_run_start(self, run_start_settings: Dict[str, Any]) -> None:
1978
+ # This dictionary maps from the "run message dict" to relevant fields in settings
1979
+ # Note: that config is missing
1980
+ param_map = {
1981
+ "run_id": "run_id",
1982
+ "entity": "entity",
1983
+ "project": "project",
1984
+ "run_group": "run_group",
1985
+ "job_type": "run_job_type",
1986
+ "display_name": "run_name",
1987
+ "notes": "run_notes",
1988
+ "tags": "run_tags",
1989
+ "sweep_id": "sweep_id",
1990
+ "host": "host",
1991
+ "resumed": "resumed",
1992
+ "git.remote_url": "git_remote_url",
1993
+ "git.commit": "git_commit",
1994
+ }
1995
+ run_settings = {
1996
+ name: reduce(lambda d, k: d.get(k, {}), attr.split("."), run_start_settings)
1997
+ for attr, name in param_map.items()
1998
+ }
1999
+ run_settings = {key: value for key, value in run_settings.items() if value}
2000
+ if run_settings:
2001
+ self.update(run_settings, source=Source.RUN)