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,1204 @@
1
+ import base64
2
+ import binascii
3
+ import codecs
4
+ import datetime
5
+ import logging
6
+ import os
7
+
8
+ import wandb
9
+ from wandb import util
10
+ from wandb.sdk.lib import runid
11
+
12
+ from . import _dtypes
13
+ from ._private import MEDIA_TMP
14
+ from .base_types.media import Media, _numpy_arrays_to_lists
15
+ from .base_types.wb_value import WBValue
16
+ from .utils import _json_helper
17
+
18
+
19
+ class _TableLinkMixin:
20
+ def set_table(self, table):
21
+ self._table = table
22
+
23
+
24
+ class _TableKey(str, _TableLinkMixin):
25
+ def set_table(self, table, col_name):
26
+ assert col_name in table.columns
27
+ self._table = table
28
+ self._col_name = col_name
29
+
30
+
31
+ class _TableIndex(int, _TableLinkMixin):
32
+ def get_row(self):
33
+ row = {}
34
+ if self._table:
35
+ row = {
36
+ c: self._table.data[self][i] for i, c in enumerate(self._table.columns)
37
+ }
38
+
39
+ return row
40
+
41
+
42
+ class _PrimaryKeyType(_dtypes.Type):
43
+ name = "primaryKey"
44
+ legacy_names = ["wandb.TablePrimaryKey"]
45
+
46
+ def assign_type(self, wb_type=None):
47
+ if isinstance(wb_type, _dtypes.StringType) or isinstance(
48
+ wb_type, _PrimaryKeyType
49
+ ):
50
+ return self
51
+ return _dtypes.InvalidType()
52
+
53
+ @classmethod
54
+ def from_obj(cls, py_obj):
55
+ if not isinstance(py_obj, _TableKey):
56
+ raise TypeError("py_obj must be a wandb.Table")
57
+ else:
58
+ return cls()
59
+
60
+
61
+ class _ForeignKeyType(_dtypes.Type):
62
+ name = "foreignKey"
63
+ legacy_names = ["wandb.TableForeignKey"]
64
+ types = [_TableKey]
65
+
66
+ def __init__(self, table, col_name):
67
+ assert isinstance(table, Table)
68
+ assert isinstance(col_name, str)
69
+ assert col_name in table.columns
70
+ self.params.update({"table": table, "col_name": col_name})
71
+
72
+ def assign_type(self, wb_type=None):
73
+ if isinstance(wb_type, _dtypes.StringType):
74
+ return self
75
+ elif (
76
+ isinstance(wb_type, _ForeignKeyType)
77
+ and id(self.params["table"]) == id(wb_type.params["table"])
78
+ and self.params["col_name"] == wb_type.params["col_name"]
79
+ ):
80
+ return self
81
+
82
+ return _dtypes.InvalidType()
83
+
84
+ @classmethod
85
+ def from_obj(cls, py_obj):
86
+ if not isinstance(py_obj, _TableKey):
87
+ raise TypeError("py_obj must be a _TableKey")
88
+ else:
89
+ return cls(py_obj._table, py_obj._col_name)
90
+
91
+ def to_json(self, artifact=None):
92
+ res = super().to_json(artifact)
93
+ if artifact is not None:
94
+ table_name = f"media/tables/t_{runid.generate_id()}"
95
+ entry = artifact.add(self.params["table"], table_name)
96
+ res["params"]["table"] = entry.path
97
+ else:
98
+ raise AssertionError(
99
+ "_ForeignKeyType does not support serialization without an artifact"
100
+ )
101
+ return res
102
+
103
+ @classmethod
104
+ def from_json(
105
+ cls,
106
+ json_dict,
107
+ artifact,
108
+ ):
109
+ table = None
110
+ col_name = None
111
+ if artifact is None:
112
+ raise AssertionError(
113
+ "_ForeignKeyType does not support deserialization without an artifact"
114
+ )
115
+ else:
116
+ table = artifact.get(json_dict["params"]["table"])
117
+ col_name = json_dict["params"]["col_name"]
118
+
119
+ if table is None:
120
+ raise AssertionError("Unable to deserialize referenced table")
121
+
122
+ return cls(table, col_name)
123
+
124
+
125
+ class _ForeignIndexType(_dtypes.Type):
126
+ name = "foreignIndex"
127
+ legacy_names = ["wandb.TableForeignIndex"]
128
+ types = [_TableIndex]
129
+
130
+ def __init__(self, table):
131
+ assert isinstance(table, Table)
132
+ self.params.update({"table": table})
133
+
134
+ def assign_type(self, wb_type=None):
135
+ if isinstance(wb_type, _dtypes.NumberType):
136
+ return self
137
+ elif isinstance(wb_type, _ForeignIndexType) and id(self.params["table"]) == id(
138
+ wb_type.params["table"]
139
+ ):
140
+ return self
141
+
142
+ return _dtypes.InvalidType()
143
+
144
+ @classmethod
145
+ def from_obj(cls, py_obj):
146
+ if not isinstance(py_obj, _TableIndex):
147
+ raise TypeError("py_obj must be a _TableIndex")
148
+ else:
149
+ return cls(py_obj._table)
150
+
151
+ def to_json(self, artifact=None):
152
+ res = super().to_json(artifact)
153
+ if artifact is not None:
154
+ table_name = f"media/tables/t_{runid.generate_id()}"
155
+ entry = artifact.add(self.params["table"], table_name)
156
+ res["params"]["table"] = entry.path
157
+ else:
158
+ raise AssertionError(
159
+ "_ForeignIndexType does not support serialization without an artifact"
160
+ )
161
+ return res
162
+
163
+ @classmethod
164
+ def from_json(
165
+ cls,
166
+ json_dict,
167
+ artifact,
168
+ ):
169
+ table = None
170
+ if artifact is None:
171
+ raise AssertionError(
172
+ "_ForeignIndexType does not support deserialization without an artifact"
173
+ )
174
+ else:
175
+ table = artifact.get(json_dict["params"]["table"])
176
+
177
+ if table is None:
178
+ raise AssertionError("Unable to deserialize referenced table")
179
+
180
+ return cls(table)
181
+
182
+
183
+ class Table(Media):
184
+ """The Table class used to display and analyze tabular data.
185
+
186
+ Unlike traditional spreadsheets, Tables support numerous types of data:
187
+ scalar values, strings, numpy arrays, and most subclasses of `wandb.data_types.Media`.
188
+ This means you can embed `Images`, `Video`, `Audio`, and other sorts of rich, annotated media
189
+ directly in Tables, alongside other traditional scalar values.
190
+
191
+ This class is the primary class used to generate the Table Visualizer
192
+ in the UI: https://docs.wandb.ai/guides/data-vis/tables.
193
+
194
+ Arguments:
195
+ columns: (List[str]) Names of the columns in the table.
196
+ Defaults to ["Input", "Output", "Expected"].
197
+ data: (List[List[any]]) 2D row-oriented array of values.
198
+ dataframe: (pandas.DataFrame) DataFrame object used to create the table.
199
+ When set, `data` and `columns` arguments are ignored.
200
+ optional: (Union[bool,List[bool]]) Determines if `None` values are allowed. Default to True
201
+ - If a singular bool value, then the optionality is enforced for all
202
+ columns specified at construction time
203
+ - If a list of bool values, then the optionality is applied to each
204
+ column - should be the same length as `columns`
205
+ applies to all columns. A list of bool values applies to each respective column.
206
+ allow_mixed_types: (bool) Determines if columns are allowed to have mixed types
207
+ (disables type validation). Defaults to False
208
+ """
209
+
210
+ MAX_ROWS = 10000
211
+ MAX_ARTIFACT_ROWS = 200000
212
+ _MAX_EMBEDDING_DIMENSIONS = 150
213
+ _log_type = "table"
214
+
215
+ def __init__(
216
+ self,
217
+ columns=None,
218
+ data=None,
219
+ rows=None,
220
+ dataframe=None,
221
+ dtype=None,
222
+ optional=True,
223
+ allow_mixed_types=False,
224
+ ):
225
+ """Initializes a Table object.
226
+
227
+ The rows is available for legacy reasons and should not be used.
228
+ The Table class uses data to mimic the Pandas API.
229
+ """
230
+ super().__init__()
231
+ self._pk_col = None
232
+ self._fk_cols = set()
233
+ if allow_mixed_types:
234
+ dtype = _dtypes.AnyType
235
+
236
+ # This is kept for legacy reasons (tss: personally, I think we should remove this)
237
+ if columns is None:
238
+ columns = ["Input", "Output", "Expected"]
239
+
240
+ # Explicit dataframe option
241
+ if dataframe is not None:
242
+ self._init_from_dataframe(dataframe, columns, optional, dtype)
243
+ else:
244
+ # Expected pattern
245
+ if data is not None:
246
+ if util.is_numpy_array(data):
247
+ self._init_from_ndarray(data, columns, optional, dtype)
248
+ elif util.is_pandas_data_frame(data):
249
+ self._init_from_dataframe(data, columns, optional, dtype)
250
+ else:
251
+ self._init_from_list(data, columns, optional, dtype)
252
+
253
+ # legacy
254
+ elif rows is not None:
255
+ self._init_from_list(rows, columns, optional, dtype)
256
+
257
+ # Default empty case
258
+ else:
259
+ self._init_from_list([], columns, optional, dtype)
260
+
261
+ @staticmethod
262
+ def _assert_valid_columns(columns):
263
+ valid_col_types = [str, int]
264
+ assert isinstance(columns, list), "columns argument expects a `list` object"
265
+ assert len(columns) == 0 or all(
266
+ [type(col) in valid_col_types for col in columns]
267
+ ), "columns argument expects list of strings or ints"
268
+
269
+ def _init_from_list(self, data, columns, optional=True, dtype=None):
270
+ assert isinstance(data, list), "data argument expects a `list` object"
271
+ self.data = []
272
+ self._assert_valid_columns(columns)
273
+ self.columns = columns
274
+ self._make_column_types(dtype, optional)
275
+ for row in data:
276
+ self.add_data(*row)
277
+
278
+ def _init_from_ndarray(self, ndarray, columns, optional=True, dtype=None):
279
+ assert util.is_numpy_array(
280
+ ndarray
281
+ ), "ndarray argument expects a `numpy.ndarray` object"
282
+ self.data = []
283
+ self._assert_valid_columns(columns)
284
+ self.columns = columns
285
+ self._make_column_types(dtype, optional)
286
+ for row in ndarray:
287
+ self.add_data(*row)
288
+
289
+ def _init_from_dataframe(self, dataframe, columns, optional=True, dtype=None):
290
+ assert util.is_pandas_data_frame(
291
+ dataframe
292
+ ), "dataframe argument expects a `pandas.core.frame.DataFrame` object"
293
+ self.data = []
294
+ columns = list(dataframe.columns)
295
+ self._assert_valid_columns(columns)
296
+ self.columns = columns
297
+ self._make_column_types(dtype, optional)
298
+ for row in range(len(dataframe)):
299
+ self.add_data(*tuple(dataframe[col].values[row] for col in self.columns))
300
+
301
+ def _make_column_types(self, dtype=None, optional=True):
302
+ if dtype is None:
303
+ dtype = _dtypes.UnknownType()
304
+
305
+ if optional.__class__ is not list:
306
+ optional = [optional for _ in range(len(self.columns))]
307
+
308
+ if dtype.__class__ is not list:
309
+ dtype = [dtype for _ in range(len(self.columns))]
310
+
311
+ self._column_types = _dtypes.TypedDictType({})
312
+ for col_name, opt, dt in zip(self.columns, optional, dtype):
313
+ self.cast(col_name, dt, opt)
314
+
315
+ def cast(self, col_name, dtype, optional=False):
316
+ """Casts a column to a specific data type.
317
+
318
+ This can be one of the normal python classes, an internal W&B type, or an
319
+ example object, like an instance of wandb.Image or wandb.Classes.
320
+
321
+ Arguments:
322
+ col_name: (str) - The name of the column to cast.
323
+ dtype: (class, wandb.wandb_sdk.interface._dtypes.Type, any) - The target dtype.
324
+ optional: (bool) - If the column should allow Nones.
325
+ """
326
+ assert col_name in self.columns
327
+
328
+ wbtype = _dtypes.TypeRegistry.type_from_dtype(dtype)
329
+
330
+ if optional:
331
+ wbtype = _dtypes.OptionalType(wbtype)
332
+
333
+ # Cast each value in the row, raising an error if there are invalid entries.
334
+ col_ndx = self.columns.index(col_name)
335
+ for row in self.data:
336
+ result_type = wbtype.assign(row[col_ndx])
337
+ if isinstance(result_type, _dtypes.InvalidType):
338
+ raise TypeError(
339
+ "Existing data {}, of type {} cannot be cast to {}".format(
340
+ row[col_ndx],
341
+ _dtypes.TypeRegistry.type_of(row[col_ndx]),
342
+ wbtype,
343
+ )
344
+ )
345
+ wbtype = result_type
346
+
347
+ # Assert valid options
348
+ is_pk = isinstance(wbtype, _PrimaryKeyType)
349
+ is_fk = isinstance(wbtype, _ForeignKeyType)
350
+ is_fi = isinstance(wbtype, _ForeignIndexType)
351
+ if is_pk or is_fk or is_fi:
352
+ assert (
353
+ not optional
354
+ ), "Primary keys, foreign keys, and foreign indexes cannot be optional."
355
+
356
+ if (is_fk or is_fk) and id(wbtype.params["table"]) == id(self):
357
+ raise AssertionError("Cannot set a foreign table reference to same table.")
358
+
359
+ if is_pk:
360
+ assert (
361
+ self._pk_col is None
362
+ ), "Cannot have multiple primary keys - {} is already set as the primary key.".format(
363
+ self._pk_col
364
+ )
365
+
366
+ # Update the column type
367
+ self._column_types.params["type_map"][col_name] = wbtype
368
+
369
+ # Wrap the data if needed
370
+ self._update_keys()
371
+ return wbtype
372
+
373
+ def __ne__(self, other):
374
+ return not self.__eq__(other)
375
+
376
+ def _eq_debug(self, other, should_assert=False):
377
+ eq = isinstance(other, Table)
378
+ assert not should_assert or eq, "Found type {}, expected {}".format(
379
+ other.__class__, Table
380
+ )
381
+ eq = eq and len(self.data) == len(other.data)
382
+ assert not should_assert or eq, "Found {} rows, expected {}".format(
383
+ len(other.data), len(self.data)
384
+ )
385
+ eq = eq and self.columns == other.columns
386
+ assert not should_assert or eq, "Found columns {}, expected {}".format(
387
+ other.columns, self.columns
388
+ )
389
+ eq = eq and self._column_types == other._column_types
390
+ assert (
391
+ not should_assert or eq
392
+ ), "Found column type {}, expected column type {}".format(
393
+ other._column_types, self._column_types
394
+ )
395
+ if eq:
396
+ for row_ndx in range(len(self.data)):
397
+ for col_ndx in range(len(self.data[row_ndx])):
398
+ _eq = self.data[row_ndx][col_ndx] == other.data[row_ndx][col_ndx]
399
+ # equal if all are equal
400
+ if util.is_numpy_array(_eq):
401
+ _eq = ((_eq * -1) + 1).sum() == 0
402
+ eq = eq and _eq
403
+ assert (
404
+ not should_assert or eq
405
+ ), "Unequal data at row_ndx {} col_ndx {}: found {}, expected {}".format(
406
+ row_ndx,
407
+ col_ndx,
408
+ other.data[row_ndx][col_ndx],
409
+ self.data[row_ndx][col_ndx],
410
+ )
411
+ if not eq:
412
+ return eq
413
+ return eq
414
+
415
+ def __eq__(self, other):
416
+ return self._eq_debug(other)
417
+
418
+ def add_row(self, *row):
419
+ """Deprecated; use add_data instead."""
420
+ logging.warning("add_row is deprecated, use add_data")
421
+ self.add_data(*row)
422
+
423
+ def add_data(self, *data):
424
+ """Adds a new row of data to the table. The maximum amount of rows in a table is determined by `wandb.Table.MAX_ARTIFACT_ROWS`.
425
+
426
+ The length of the data should match the length of the table column.
427
+ """
428
+ if len(data) != len(self.columns):
429
+ raise ValueError(
430
+ "This table expects {} columns: {}, found {}".format(
431
+ len(self.columns), self.columns, len(data)
432
+ )
433
+ )
434
+
435
+ # Special case to pre-emptively cast a column as a key.
436
+ # Needed as String.assign(Key) is invalid
437
+ for ndx, item in enumerate(data):
438
+ if isinstance(item, _TableLinkMixin):
439
+ self.cast(
440
+ self.columns[ndx],
441
+ _dtypes.TypeRegistry.type_of(item),
442
+ optional=False,
443
+ )
444
+
445
+ # Update the table's column types
446
+ result_type = self._get_updated_result_type(data)
447
+ self._column_types = result_type
448
+
449
+ # rows need to be mutable
450
+ if isinstance(data, tuple):
451
+ data = list(data)
452
+ # Add the new data
453
+ self.data.append(data)
454
+
455
+ # Update the wrapper values if needed
456
+ self._update_keys(force_last=True)
457
+
458
+ def _get_updated_result_type(self, row):
459
+ """Returns the updated result type based on the inputted row.
460
+
461
+ Raises:
462
+ TypeError: if the assignment is invalid.
463
+ """
464
+ incoming_row_dict = {
465
+ col_key: row[ndx] for ndx, col_key in enumerate(self.columns)
466
+ }
467
+ current_type = self._column_types
468
+ result_type = current_type.assign(incoming_row_dict)
469
+ if isinstance(result_type, _dtypes.InvalidType):
470
+ raise TypeError(
471
+ "Data row contained incompatible types:\n{}".format(
472
+ current_type.explain(incoming_row_dict)
473
+ )
474
+ )
475
+ return result_type
476
+
477
+ def _to_table_json(self, max_rows=None, warn=True):
478
+ # separate this method for easier testing
479
+ if max_rows is None:
480
+ max_rows = Table.MAX_ROWS
481
+ n_rows = len(self.data)
482
+ if n_rows > max_rows and warn:
483
+ if wandb.run and (
484
+ wandb.run.settings.table_raise_on_max_row_limit_exceeded
485
+ or wandb.run.settings.strict
486
+ ):
487
+ raise ValueError(
488
+ f"Table row limit exceeded: table has {n_rows} rows, limit is {max_rows}. "
489
+ f"To increase the maximum number of allowed rows in a wandb.Table, override "
490
+ f"the limit with `wandb.Table.MAX_ARTIFACT_ROWS = X` and try again. Note: "
491
+ f"this may cause slower queries in the W&B UI."
492
+ )
493
+ logging.warning("Truncating wandb.Table object to %i rows." % max_rows)
494
+ return {"columns": self.columns, "data": self.data[:max_rows]}
495
+
496
+ def bind_to_run(self, *args, **kwargs):
497
+ # We set `warn=False` since Tables will now always be logged to both
498
+ # files and artifacts. The file limit will never practically matter and
499
+ # this code path will be ultimately removed. The 10k limit warning confuses
500
+ # users given that we publicly say 200k is the limit.
501
+ data = self._to_table_json(warn=False)
502
+ tmp_path = os.path.join(MEDIA_TMP.name, runid.generate_id() + ".table.json")
503
+ data = _numpy_arrays_to_lists(data)
504
+ with codecs.open(tmp_path, "w", encoding="utf-8") as fp:
505
+ util.json_dump_safer(data, fp)
506
+ self._set_file(tmp_path, is_tmp=True, extension=".table.json")
507
+ super().bind_to_run(*args, **kwargs)
508
+
509
+ @classmethod
510
+ def get_media_subdir(cls):
511
+ return os.path.join("media", "table")
512
+
513
+ @classmethod
514
+ def from_json(cls, json_obj, source_artifact):
515
+ data = []
516
+ column_types = None
517
+ np_deserialized_columns = {}
518
+ timestamp_column_indices = set()
519
+ if json_obj.get("column_types") is not None:
520
+ column_types = _dtypes.TypeRegistry.type_from_dict(
521
+ json_obj["column_types"], source_artifact
522
+ )
523
+ for col_name in column_types.params["type_map"]:
524
+ col_type = column_types.params["type_map"][col_name]
525
+ ndarray_type = None
526
+ if isinstance(col_type, _dtypes.NDArrayType):
527
+ ndarray_type = col_type
528
+ elif isinstance(col_type, _dtypes.UnionType):
529
+ for t in col_type.params["allowed_types"]:
530
+ if isinstance(t, _dtypes.NDArrayType):
531
+ ndarray_type = t
532
+ elif isinstance(t, _dtypes.TimestampType):
533
+ timestamp_column_indices.add(
534
+ json_obj["columns"].index(col_name)
535
+ )
536
+
537
+ elif isinstance(col_type, _dtypes.TimestampType):
538
+ timestamp_column_indices.add(json_obj["columns"].index(col_name))
539
+
540
+ if (
541
+ ndarray_type is not None
542
+ and ndarray_type._get_serialization_path() is not None
543
+ ):
544
+ serialization_path = ndarray_type._get_serialization_path()
545
+ np = util.get_module(
546
+ "numpy",
547
+ required="Deserializing NumPy columns requires NumPy to be installed.",
548
+ )
549
+ deserialized = np.load(
550
+ source_artifact.get_entry(serialization_path["path"]).download()
551
+ )
552
+ np_deserialized_columns[json_obj["columns"].index(col_name)] = (
553
+ deserialized[serialization_path["key"]]
554
+ )
555
+ ndarray_type._clear_serialization_path()
556
+
557
+ for r_ndx, row in enumerate(json_obj["data"]):
558
+ row_data = []
559
+ for c_ndx, item in enumerate(row):
560
+ cell = item
561
+ if c_ndx in timestamp_column_indices and isinstance(item, (int, float)):
562
+ cell = datetime.datetime.fromtimestamp(
563
+ item / 1000, tz=datetime.timezone.utc
564
+ )
565
+ elif c_ndx in np_deserialized_columns:
566
+ cell = np_deserialized_columns[c_ndx][r_ndx]
567
+ elif isinstance(item, dict) and "_type" in item:
568
+ obj = WBValue.init_from_json(item, source_artifact)
569
+ if obj is not None:
570
+ cell = obj
571
+ row_data.append(cell)
572
+ data.append(row_data)
573
+
574
+ # construct Table with dtypes for each column if type information exists
575
+ dtypes = None
576
+ if column_types is not None:
577
+ dtypes = [
578
+ column_types.params["type_map"][str(col)] for col in json_obj["columns"]
579
+ ]
580
+
581
+ new_obj = cls(columns=json_obj["columns"], data=data, dtype=dtypes)
582
+
583
+ if column_types is not None:
584
+ new_obj._column_types = column_types
585
+
586
+ new_obj._update_keys()
587
+ return new_obj
588
+
589
+ def to_json(self, run_or_artifact):
590
+ json_dict = super().to_json(run_or_artifact)
591
+
592
+ if isinstance(run_or_artifact, wandb.wandb_sdk.wandb_run.Run):
593
+ json_dict.update(
594
+ {
595
+ "_type": "table-file",
596
+ "ncols": len(self.columns),
597
+ "nrows": len(self.data),
598
+ }
599
+ )
600
+
601
+ elif isinstance(run_or_artifact, wandb.Artifact):
602
+ artifact = run_or_artifact
603
+ mapped_data = []
604
+ data = self._to_table_json(Table.MAX_ARTIFACT_ROWS)["data"]
605
+
606
+ ndarray_col_ndxs = set()
607
+ for col_ndx, col_name in enumerate(self.columns):
608
+ col_type = self._column_types.params["type_map"][col_name]
609
+ ndarray_type = None
610
+ if isinstance(col_type, _dtypes.NDArrayType):
611
+ ndarray_type = col_type
612
+ elif isinstance(col_type, _dtypes.UnionType):
613
+ for t in col_type.params["allowed_types"]:
614
+ if isinstance(t, _dtypes.NDArrayType):
615
+ ndarray_type = t
616
+
617
+ # Do not serialize 1d arrays - these are likely embeddings and
618
+ # will not have the same cost as higher dimensional arrays
619
+ is_1d_array = (
620
+ ndarray_type is not None
621
+ and "shape" in ndarray_type._params
622
+ and isinstance(ndarray_type._params["shape"], list)
623
+ and len(ndarray_type._params["shape"]) == 1
624
+ and ndarray_type._params["shape"][0]
625
+ <= self._MAX_EMBEDDING_DIMENSIONS
626
+ )
627
+ if is_1d_array:
628
+ self._column_types.params["type_map"][col_name] = _dtypes.ListType(
629
+ _dtypes.NumberType, ndarray_type._params["shape"][0]
630
+ )
631
+ elif ndarray_type is not None:
632
+ np = util.get_module(
633
+ "numpy",
634
+ required="Serializing NumPy requires NumPy to be installed.",
635
+ )
636
+ file_name = f"{str(col_name)}_{runid.generate_id()}.npz"
637
+ npz_file_name = os.path.join(MEDIA_TMP.name, file_name)
638
+ np.savez_compressed(
639
+ npz_file_name,
640
+ **{
641
+ str(col_name): self.get_column(col_name, convert_to="numpy")
642
+ },
643
+ )
644
+ entry = artifact.add_file(
645
+ npz_file_name, "media/serialized_data/" + file_name, is_tmp=True
646
+ )
647
+ ndarray_type._set_serialization_path(entry.path, str(col_name))
648
+ ndarray_col_ndxs.add(col_ndx)
649
+
650
+ for row in data:
651
+ mapped_row = []
652
+ for ndx, v in enumerate(row):
653
+ if ndx in ndarray_col_ndxs:
654
+ mapped_row.append(None)
655
+ else:
656
+ mapped_row.append(_json_helper(v, artifact))
657
+ mapped_data.append(mapped_row)
658
+
659
+ json_dict.update(
660
+ {
661
+ "_type": Table._log_type,
662
+ "columns": self.columns,
663
+ "data": mapped_data,
664
+ "ncols": len(self.columns),
665
+ "nrows": len(mapped_data),
666
+ "column_types": self._column_types.to_json(artifact),
667
+ }
668
+ )
669
+ else:
670
+ raise ValueError("to_json accepts wandb_run.Run or wandb_artifact.Artifact")
671
+
672
+ return json_dict
673
+
674
+ def iterrows(self):
675
+ """Returns the table data by row, showing the index of the row and the relevant data.
676
+
677
+ Yields:
678
+ ------
679
+ index : int
680
+ The index of the row. Using this value in other W&B tables
681
+ will automatically build a relationship between the tables
682
+ row : List[any]
683
+ The data of the row.
684
+ """
685
+ for ndx in range(len(self.data)):
686
+ index = _TableIndex(ndx)
687
+ index.set_table(self)
688
+ yield index, self.data[ndx]
689
+
690
+ def set_pk(self, col_name):
691
+ # TODO: Docs
692
+ assert col_name in self.columns
693
+ self.cast(col_name, _PrimaryKeyType())
694
+
695
+ def set_fk(self, col_name, table, table_col):
696
+ # TODO: Docs
697
+ assert col_name in self.columns
698
+ assert col_name != self._pk_col
699
+ self.cast(col_name, _ForeignKeyType(table, table_col))
700
+
701
+ def _update_keys(self, force_last=False):
702
+ """Updates the known key-like columns based on current column types.
703
+
704
+ If the state has been updated since the last update, wraps the data
705
+ appropriately in the Key classes.
706
+
707
+ Arguments:
708
+ force_last: (bool) Wraps the last column of data even if there
709
+ are no key updates.
710
+ """
711
+ _pk_col = None
712
+ _fk_cols = set()
713
+
714
+ # Buildup the known keys from column types
715
+ c_types = self._column_types.params["type_map"]
716
+ for t in c_types:
717
+ if isinstance(c_types[t], _PrimaryKeyType):
718
+ _pk_col = t
719
+ elif isinstance(c_types[t], _ForeignKeyType) or isinstance(
720
+ c_types[t], _ForeignIndexType
721
+ ):
722
+ _fk_cols.add(t)
723
+
724
+ # If there are updates to perform, safely update them
725
+ has_update = _pk_col != self._pk_col or _fk_cols != self._fk_cols
726
+ if has_update:
727
+ # If we removed the PK
728
+ if _pk_col is None and self._pk_col is not None:
729
+ raise AssertionError(
730
+ f"Cannot unset primary key (column {self._pk_col})"
731
+ )
732
+ # If there is a removed FK
733
+ if len(self._fk_cols - _fk_cols) > 0:
734
+ raise AssertionError(
735
+ "Cannot unset foreign key. Attempted to unset ({})".format(
736
+ self._fk_cols - _fk_cols
737
+ )
738
+ )
739
+
740
+ self._pk_col = _pk_col
741
+ self._fk_cols = _fk_cols
742
+
743
+ # Apply updates to data only if there are update or the caller
744
+ # requested the final row to be updated
745
+ if has_update or force_last:
746
+ self._apply_key_updates(not has_update)
747
+
748
+ def _apply_key_updates(self, only_last=False):
749
+ """Appropriately wraps the underlying data in special Key classes.
750
+
751
+ Arguments:
752
+ only_last: only apply the updates to the last row (used for performance when
753
+ the caller knows that the only new data is the last row and no updates were
754
+ applied to the column types)
755
+ """
756
+ c_types = self._column_types.params["type_map"]
757
+
758
+ # Define a helper function which will wrap the data of a single row
759
+ # in the appropriate class wrapper.
760
+ def update_row(row_ndx):
761
+ for fk_col in self._fk_cols:
762
+ col_ndx = self.columns.index(fk_col)
763
+
764
+ # Wrap the Foreign Keys
765
+ if isinstance(c_types[fk_col], _ForeignKeyType) and not isinstance(
766
+ self.data[row_ndx][col_ndx], _TableKey
767
+ ):
768
+ self.data[row_ndx][col_ndx] = _TableKey(self.data[row_ndx][col_ndx])
769
+ self.data[row_ndx][col_ndx].set_table(
770
+ c_types[fk_col].params["table"],
771
+ c_types[fk_col].params["col_name"],
772
+ )
773
+
774
+ # Wrap the Foreign Indexes
775
+ elif isinstance(c_types[fk_col], _ForeignIndexType) and not isinstance(
776
+ self.data[row_ndx][col_ndx], _TableIndex
777
+ ):
778
+ self.data[row_ndx][col_ndx] = _TableIndex(
779
+ self.data[row_ndx][col_ndx]
780
+ )
781
+ self.data[row_ndx][col_ndx].set_table(
782
+ c_types[fk_col].params["table"]
783
+ )
784
+
785
+ # Wrap the Primary Key
786
+ if self._pk_col is not None:
787
+ col_ndx = self.columns.index(self._pk_col)
788
+ self.data[row_ndx][col_ndx] = _TableKey(self.data[row_ndx][col_ndx])
789
+ self.data[row_ndx][col_ndx].set_table(self, self._pk_col)
790
+
791
+ if only_last:
792
+ update_row(len(self.data) - 1)
793
+ else:
794
+ for row_ndx in range(len(self.data)):
795
+ update_row(row_ndx)
796
+
797
+ def add_column(self, name, data, optional=False):
798
+ """Adds a column of data to the table.
799
+
800
+ Arguments:
801
+ name: (str) - the unique name of the column
802
+ data: (list | np.array) - a column of homogeneous data
803
+ optional: (bool) - if null-like values are permitted
804
+ """
805
+ assert isinstance(name, str) and name not in self.columns
806
+ is_np = util.is_numpy_array(data)
807
+ assert isinstance(data, list) or is_np
808
+ assert isinstance(optional, bool)
809
+ is_first_col = len(self.columns) == 0
810
+ assert is_first_col or len(data) == len(
811
+ self.data
812
+ ), f"Expected length {len(self.data)}, found {len(data)}"
813
+
814
+ # Add the new data
815
+ for ndx in range(max(len(data), len(self.data))):
816
+ if is_first_col:
817
+ self.data.append([])
818
+ if is_np:
819
+ self.data[ndx].append(data[ndx])
820
+ else:
821
+ self.data[ndx].append(data[ndx])
822
+ # add the column
823
+ self.columns.append(name)
824
+
825
+ try:
826
+ self.cast(name, _dtypes.UnknownType(), optional=optional)
827
+ except TypeError as err:
828
+ # Undo the changes
829
+ if is_first_col:
830
+ self.data = []
831
+ self.columns = []
832
+ else:
833
+ for ndx in range(len(self.data)):
834
+ self.data[ndx] = self.data[ndx][:-1]
835
+ self.columns = self.columns[:-1]
836
+ raise err
837
+
838
+ def get_column(self, name, convert_to=None):
839
+ """Retrieves a column from the table and optionally converts it to a NumPy object.
840
+
841
+ Arguments:
842
+ name: (str) - the name of the column
843
+ convert_to: (str, optional)
844
+ - "numpy": will convert the underlying data to numpy object
845
+ """
846
+ assert name in self.columns
847
+ assert convert_to is None or convert_to == "numpy"
848
+ if convert_to == "numpy":
849
+ np = util.get_module(
850
+ "numpy", required="Converting to NumPy requires installing NumPy"
851
+ )
852
+ col = []
853
+ col_ndx = self.columns.index(name)
854
+ for row in self.data:
855
+ item = row[col_ndx]
856
+ if convert_to is not None and isinstance(item, WBValue):
857
+ item = item.to_data_array()
858
+ col.append(item)
859
+ if convert_to == "numpy":
860
+ col = np.array(col)
861
+ return col
862
+
863
+ def get_index(self):
864
+ """Returns an array of row indexes for use in other tables to create links."""
865
+ ndxs = []
866
+ for ndx in range(len(self.data)):
867
+ index = _TableIndex(ndx)
868
+ index.set_table(self)
869
+ ndxs.append(index)
870
+ return ndxs
871
+
872
+ def get_dataframe(self):
873
+ """Returns a `pandas.DataFrame` of the table."""
874
+ pd = util.get_module(
875
+ "pandas",
876
+ required="Converting to pandas.DataFrame requires installing pandas",
877
+ )
878
+ return pd.DataFrame.from_records(self.data, columns=self.columns)
879
+
880
+ def index_ref(self, index):
881
+ """Gets a reference of the index of a row in the table."""
882
+ assert index < len(self.data)
883
+ _index = _TableIndex(index)
884
+ _index.set_table(self)
885
+ return _index
886
+
887
+ def add_computed_columns(self, fn):
888
+ """Adds one or more computed columns based on existing data.
889
+
890
+ Args:
891
+ fn: A function which accepts one or two parameters, ndx (int) and row (dict),
892
+ which is expected to return a dict representing new columns for that row, keyed
893
+ by the new column names.
894
+
895
+ `ndx` is an integer representing the index of the row. Only included if `include_ndx`
896
+ is set to `True`.
897
+
898
+ `row` is a dictionary keyed by existing columns
899
+ """
900
+ new_columns = {}
901
+ for ndx, row in self.iterrows():
902
+ row_dict = {self.columns[i]: row[i] for i in range(len(self.columns))}
903
+ new_row_dict = fn(ndx, row_dict)
904
+ assert isinstance(new_row_dict, dict)
905
+ for key in new_row_dict:
906
+ new_columns[key] = new_columns.get(key, [])
907
+ new_columns[key].append(new_row_dict[key])
908
+ for new_col_name in new_columns:
909
+ self.add_column(new_col_name, new_columns[new_col_name])
910
+
911
+
912
+ class _PartitionTablePartEntry:
913
+ """Helper class for PartitionTable to track its parts."""
914
+
915
+ def __init__(self, entry, source_artifact):
916
+ self.entry = entry
917
+ self.source_artifact = source_artifact
918
+ self._part = None
919
+
920
+ def get_part(self):
921
+ if self._part is None:
922
+ self._part = self.source_artifact.get(self.entry.path)
923
+ return self._part
924
+
925
+ def free(self):
926
+ self._part = None
927
+
928
+
929
+ class PartitionedTable(Media):
930
+ """A table which is composed of multiple sub-tables.
931
+
932
+ Currently, PartitionedTable is designed to point to a directory within an artifact.
933
+ """
934
+
935
+ _log_type = "partitioned-table"
936
+
937
+ def __init__(self, parts_path):
938
+ """Initialize a PartitionedTable.
939
+
940
+ Args:
941
+ parts_path (str): path to a directory of tables in the artifact.
942
+ """
943
+ super().__init__()
944
+ self.parts_path = parts_path
945
+ self._loaded_part_entries = {}
946
+
947
+ def to_json(self, artifact_or_run):
948
+ json_obj = {
949
+ "_type": PartitionedTable._log_type,
950
+ }
951
+ if isinstance(artifact_or_run, wandb.wandb_sdk.wandb_run.Run):
952
+ artifact_entry_url = self._get_artifact_entry_ref_url()
953
+ if artifact_entry_url is None:
954
+ raise ValueError(
955
+ "PartitionedTables must first be added to an Artifact before logging to a Run"
956
+ )
957
+ json_obj["artifact_path"] = artifact_entry_url
958
+ else:
959
+ json_obj["parts_path"] = self.parts_path
960
+ return json_obj
961
+
962
+ @classmethod
963
+ def from_json(cls, json_obj, source_artifact):
964
+ instance = cls(json_obj["parts_path"])
965
+ entries = source_artifact.manifest.get_entries_in_directory(
966
+ json_obj["parts_path"]
967
+ )
968
+ for entry in entries:
969
+ instance._add_part_entry(entry, source_artifact)
970
+ return instance
971
+
972
+ def iterrows(self):
973
+ """Iterate over rows as (ndx, row).
974
+
975
+ Yields:
976
+ ------
977
+ index : int
978
+ The index of the row.
979
+ row : List[any]
980
+ The data of the row.
981
+ """
982
+ columns = None
983
+ ndx = 0
984
+ for entry_path in self._loaded_part_entries:
985
+ part = self._loaded_part_entries[entry_path].get_part()
986
+ if columns is None:
987
+ columns = part.columns
988
+ elif columns != part.columns:
989
+ raise ValueError(
990
+ "Table parts have non-matching columns. {} != {}".format(
991
+ columns, part.columns
992
+ )
993
+ )
994
+ for _, row in part.iterrows():
995
+ yield ndx, row
996
+ ndx += 1
997
+
998
+ self._loaded_part_entries[entry_path].free()
999
+
1000
+ def _add_part_entry(self, entry, source_artifact):
1001
+ self._loaded_part_entries[entry.path] = _PartitionTablePartEntry(
1002
+ entry, source_artifact
1003
+ )
1004
+
1005
+ def __ne__(self, other):
1006
+ return not self.__eq__(other)
1007
+
1008
+ def __eq__(self, other):
1009
+ return isinstance(other, self.__class__) and self.parts_path == other.parts_path
1010
+
1011
+ def bind_to_run(self, *args, **kwargs):
1012
+ raise ValueError("PartitionedTables cannot be bound to runs")
1013
+
1014
+
1015
+ class JoinedTable(Media):
1016
+ """Join two tables for visualization in the Artifact UI.
1017
+
1018
+ Arguments:
1019
+ table1 (str, wandb.Table, ArtifactManifestEntry):
1020
+ the path to a wandb.Table in an artifact, the table object, or ArtifactManifestEntry
1021
+ table2 (str, wandb.Table):
1022
+ the path to a wandb.Table in an artifact, the table object, or ArtifactManifestEntry
1023
+ join_key (str, [str, str]):
1024
+ key or keys to perform the join
1025
+ """
1026
+
1027
+ _log_type = "joined-table"
1028
+
1029
+ def __init__(self, table1, table2, join_key):
1030
+ super().__init__()
1031
+
1032
+ if not isinstance(join_key, str) and (
1033
+ not isinstance(join_key, list) or len(join_key) != 2
1034
+ ):
1035
+ raise ValueError(
1036
+ "JoinedTable join_key should be a string or a list of two strings"
1037
+ )
1038
+
1039
+ if not self._validate_table_input(table1):
1040
+ raise ValueError(
1041
+ "JoinedTable table1 should be an artifact path to a table or wandb.Table object"
1042
+ )
1043
+
1044
+ if not self._validate_table_input(table2):
1045
+ raise ValueError(
1046
+ "JoinedTable table2 should be an artifact path to a table or wandb.Table object"
1047
+ )
1048
+
1049
+ self._table1 = table1
1050
+ self._table2 = table2
1051
+ self._join_key = join_key
1052
+
1053
+ @classmethod
1054
+ def from_json(cls, json_obj, source_artifact):
1055
+ t1 = source_artifact.get(json_obj["table1"])
1056
+ if t1 is None:
1057
+ t1 = json_obj["table1"]
1058
+
1059
+ t2 = source_artifact.get(json_obj["table2"])
1060
+ if t2 is None:
1061
+ t2 = json_obj["table2"]
1062
+
1063
+ return cls(
1064
+ t1,
1065
+ t2,
1066
+ json_obj["join_key"],
1067
+ )
1068
+
1069
+ @staticmethod
1070
+ def _validate_table_input(table):
1071
+ """Helper method to validate that the table input is one of the 3 supported types."""
1072
+ return (
1073
+ (isinstance(table, str) and table.endswith(".table.json"))
1074
+ or isinstance(table, Table)
1075
+ or isinstance(table, PartitionedTable)
1076
+ or (hasattr(table, "ref_url") and table.ref_url().endswith(".table.json"))
1077
+ )
1078
+
1079
+ def _ensure_table_in_artifact(self, table, artifact, table_ndx):
1080
+ """Helper method to add the table to the incoming artifact. Returns the path."""
1081
+ if isinstance(table, Table) or isinstance(table, PartitionedTable):
1082
+ table_name = f"t{table_ndx}_{str(id(self))}"
1083
+ if (
1084
+ table._artifact_source is not None
1085
+ and table._artifact_source.name is not None
1086
+ ):
1087
+ table_name = os.path.basename(table._artifact_source.name)
1088
+ entry = artifact.add(table, table_name)
1089
+ table = entry.path
1090
+ # Check if this is an ArtifactManifestEntry
1091
+ elif hasattr(table, "ref_url"):
1092
+ # Give the new object a unique, yet deterministic name
1093
+ name = binascii.hexlify(base64.standard_b64decode(table.digest)).decode(
1094
+ "ascii"
1095
+ )[:20]
1096
+ entry = artifact.add_reference(
1097
+ table.ref_url(), "{}.{}.json".format(name, table.name.split(".")[-2])
1098
+ )[0]
1099
+ table = entry.path
1100
+
1101
+ err_str = "JoinedTable table:{} not found in artifact. Add a table to the artifact using Artifact#add(<table>, {}) before adding this JoinedTable"
1102
+ if table not in artifact._manifest.entries:
1103
+ raise ValueError(err_str.format(table, table))
1104
+
1105
+ return table
1106
+
1107
+ def to_json(self, artifact_or_run):
1108
+ json_obj = {
1109
+ "_type": JoinedTable._log_type,
1110
+ }
1111
+ if isinstance(artifact_or_run, wandb.wandb_sdk.wandb_run.Run):
1112
+ artifact_entry_url = self._get_artifact_entry_ref_url()
1113
+ if artifact_entry_url is None:
1114
+ raise ValueError(
1115
+ "JoinedTables must first be added to an Artifact before logging to a Run"
1116
+ )
1117
+ json_obj["artifact_path"] = artifact_entry_url
1118
+ else:
1119
+ table1 = self._ensure_table_in_artifact(self._table1, artifact_or_run, 1)
1120
+ table2 = self._ensure_table_in_artifact(self._table2, artifact_or_run, 2)
1121
+ json_obj.update(
1122
+ {
1123
+ "table1": table1,
1124
+ "table2": table2,
1125
+ "join_key": self._join_key,
1126
+ }
1127
+ )
1128
+ return json_obj
1129
+
1130
+ def __ne__(self, other):
1131
+ return not self.__eq__(other)
1132
+
1133
+ def _eq_debug(self, other, should_assert=False):
1134
+ eq = isinstance(other, JoinedTable)
1135
+ assert not should_assert or eq, "Found type {}, expected {}".format(
1136
+ other.__class__, JoinedTable
1137
+ )
1138
+ eq = eq and self._join_key == other._join_key
1139
+ assert not should_assert or eq, "Found {} join key, expected {}".format(
1140
+ other._join_key, self._join_key
1141
+ )
1142
+ eq = eq and self._table1._eq_debug(other._table1, should_assert)
1143
+ eq = eq and self._table2._eq_debug(other._table2, should_assert)
1144
+ return eq
1145
+
1146
+ def __eq__(self, other):
1147
+ return self._eq_debug(other, False)
1148
+
1149
+ def bind_to_run(self, *args, **kwargs):
1150
+ raise ValueError("JoinedTables cannot be bound to runs")
1151
+
1152
+
1153
+ class _TableType(_dtypes.Type):
1154
+ name = "table"
1155
+ legacy_names = ["wandb.Table"]
1156
+ types = [Table]
1157
+
1158
+ def __init__(self, column_types=None):
1159
+ if column_types is None:
1160
+ column_types = _dtypes.UnknownType()
1161
+ if isinstance(column_types, dict):
1162
+ column_types = _dtypes.TypedDictType(column_types)
1163
+ elif not (
1164
+ isinstance(column_types, _dtypes.TypedDictType)
1165
+ or isinstance(column_types, _dtypes.UnknownType)
1166
+ ):
1167
+ raise TypeError("column_types must be a dict or TypedDictType")
1168
+
1169
+ self.params.update({"column_types": column_types})
1170
+
1171
+ def assign_type(self, wb_type=None):
1172
+ if isinstance(wb_type, _TableType):
1173
+ column_types = self.params["column_types"].assign_type(
1174
+ wb_type.params["column_types"]
1175
+ )
1176
+ if not isinstance(column_types, _dtypes.InvalidType):
1177
+ return _TableType(column_types)
1178
+
1179
+ return _dtypes.InvalidType()
1180
+
1181
+ @classmethod
1182
+ def from_obj(cls, py_obj):
1183
+ if not isinstance(py_obj, Table):
1184
+ raise TypeError("py_obj must be a wandb.Table")
1185
+ else:
1186
+ return cls(py_obj._column_types)
1187
+
1188
+
1189
+ class _JoinedTableType(_dtypes.Type):
1190
+ name = "joined-table"
1191
+ types = [JoinedTable]
1192
+
1193
+
1194
+ class _PartitionedTableType(_dtypes.Type):
1195
+ name = "partitioned-table"
1196
+ types = [PartitionedTable]
1197
+
1198
+
1199
+ _dtypes.TypeRegistry.add(_TableType)
1200
+ _dtypes.TypeRegistry.add(_JoinedTableType)
1201
+ _dtypes.TypeRegistry.add(_PartitionedTableType)
1202
+ _dtypes.TypeRegistry.add(_ForeignKeyType)
1203
+ _dtypes.TypeRegistry.add(_PrimaryKeyType)
1204
+ _dtypes.TypeRegistry.add(_ForeignIndexType)