wandb 0.21.2__py3-none-macosx_12_0_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 (904) hide show
  1. package_readme.md +97 -0
  2. wandb/__init__.py +248 -0
  3. wandb/__init__.pyi +1230 -0
  4. wandb/__main__.py +3 -0
  5. wandb/_iterutils.py +65 -0
  6. wandb/_pydantic/__init__.py +30 -0
  7. wandb/_pydantic/base.py +128 -0
  8. wandb/_pydantic/utils.py +80 -0
  9. wandb/_pydantic/v1_compat.py +284 -0
  10. wandb/agents/__init__.py +0 -0
  11. wandb/agents/pyagent.py +386 -0
  12. wandb/analytics/__init__.py +3 -0
  13. wandb/analytics/sentry.py +267 -0
  14. wandb/apis/__init__.py +48 -0
  15. wandb/apis/attrs.py +50 -0
  16. wandb/apis/importers/__init__.py +1 -0
  17. wandb/apis/importers/internals/internal.py +382 -0
  18. wandb/apis/importers/internals/protocols.py +103 -0
  19. wandb/apis/importers/internals/util.py +78 -0
  20. wandb/apis/importers/mlflow.py +254 -0
  21. wandb/apis/importers/validation.py +108 -0
  22. wandb/apis/importers/wandb.py +1608 -0
  23. wandb/apis/internal.py +239 -0
  24. wandb/apis/normalize.py +81 -0
  25. wandb/apis/paginator.py +138 -0
  26. wandb/apis/public/__init__.py +35 -0
  27. wandb/apis/public/api.py +2449 -0
  28. wandb/apis/public/artifacts.py +1046 -0
  29. wandb/apis/public/automations.py +85 -0
  30. wandb/apis/public/const.py +4 -0
  31. wandb/apis/public/files.py +402 -0
  32. wandb/apis/public/history.py +201 -0
  33. wandb/apis/public/integrations.py +203 -0
  34. wandb/apis/public/jobs.py +742 -0
  35. wandb/apis/public/projects.py +276 -0
  36. wandb/apis/public/query_generator.py +176 -0
  37. wandb/apis/public/registries/__init__.py +0 -0
  38. wandb/apis/public/registries/_freezable_list.py +179 -0
  39. wandb/apis/public/registries/_utils.py +138 -0
  40. wandb/apis/public/registries/registries_search.py +347 -0
  41. wandb/apis/public/registries/registry.py +358 -0
  42. wandb/apis/public/reports.py +595 -0
  43. wandb/apis/public/runs.py +1216 -0
  44. wandb/apis/public/sweeps.py +440 -0
  45. wandb/apis/public/teams.py +235 -0
  46. wandb/apis/public/users.py +177 -0
  47. wandb/apis/public/utils.py +210 -0
  48. wandb/apis/reports/__init__.py +1 -0
  49. wandb/apis/reports/v1/__init__.py +8 -0
  50. wandb/apis/reports/v2/__init__.py +8 -0
  51. wandb/apis/workspaces/__init__.py +8 -0
  52. wandb/automations/__init__.py +73 -0
  53. wandb/automations/_filters/__init__.py +40 -0
  54. wandb/automations/_filters/expressions.py +181 -0
  55. wandb/automations/_filters/operators.py +258 -0
  56. wandb/automations/_filters/run_metrics.py +330 -0
  57. wandb/automations/_generated/__init__.py +177 -0
  58. wandb/automations/_generated/create_automation.py +17 -0
  59. wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
  60. wandb/automations/_generated/delete_automation.py +15 -0
  61. wandb/automations/_generated/enums.py +35 -0
  62. wandb/automations/_generated/fragments.py +358 -0
  63. wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
  64. wandb/automations/_generated/get_automations.py +24 -0
  65. wandb/automations/_generated/get_automations_by_entity.py +26 -0
  66. wandb/automations/_generated/input_types.py +104 -0
  67. wandb/automations/_generated/integrations_by_entity.py +22 -0
  68. wandb/automations/_generated/operations.py +647 -0
  69. wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
  70. wandb/automations/_generated/update_automation.py +17 -0
  71. wandb/automations/_utils.py +235 -0
  72. wandb/automations/_validators.py +165 -0
  73. wandb/automations/actions.py +218 -0
  74. wandb/automations/automations.py +85 -0
  75. wandb/automations/events.py +285 -0
  76. wandb/automations/integrations.py +45 -0
  77. wandb/automations/scopes.py +78 -0
  78. wandb/beta/workflows.py +324 -0
  79. wandb/bin/gpu_stats +0 -0
  80. wandb/bin/wandb-core +0 -0
  81. wandb/cli/__init__.py +0 -0
  82. wandb/cli/beta.py +175 -0
  83. wandb/cli/cli.py +2883 -0
  84. wandb/data_types.py +66 -0
  85. wandb/docker/__init__.py +290 -0
  86. wandb/docker/names.py +40 -0
  87. wandb/docker/wandb-entrypoint.sh +33 -0
  88. wandb/env.py +535 -0
  89. wandb/errors/__init__.py +17 -0
  90. wandb/errors/errors.py +40 -0
  91. wandb/errors/links.py +73 -0
  92. wandb/errors/term.py +415 -0
  93. wandb/errors/util.py +57 -0
  94. wandb/errors/warnings.py +2 -0
  95. wandb/filesync/__init__.py +0 -0
  96. wandb/filesync/dir_watcher.py +404 -0
  97. wandb/filesync/stats.py +100 -0
  98. wandb/filesync/step_checksum.py +142 -0
  99. wandb/filesync/step_prepare.py +179 -0
  100. wandb/filesync/step_upload.py +287 -0
  101. wandb/filesync/upload_job.py +142 -0
  102. wandb/integration/__init__.py +0 -0
  103. wandb/integration/catboost/__init__.py +5 -0
  104. wandb/integration/catboost/catboost.py +182 -0
  105. wandb/integration/cohere/__init__.py +3 -0
  106. wandb/integration/cohere/cohere.py +21 -0
  107. wandb/integration/cohere/resolver.py +347 -0
  108. wandb/integration/diffusers/__init__.py +3 -0
  109. wandb/integration/diffusers/autologger.py +76 -0
  110. wandb/integration/diffusers/pipeline_resolver.py +50 -0
  111. wandb/integration/diffusers/resolvers/__init__.py +9 -0
  112. wandb/integration/diffusers/resolvers/multimodal.py +881 -0
  113. wandb/integration/diffusers/resolvers/utils.py +102 -0
  114. wandb/integration/fastai/__init__.py +243 -0
  115. wandb/integration/gym/__init__.py +98 -0
  116. wandb/integration/huggingface/__init__.py +3 -0
  117. wandb/integration/huggingface/huggingface.py +18 -0
  118. wandb/integration/huggingface/resolver.py +213 -0
  119. wandb/integration/keras/__init__.py +11 -0
  120. wandb/integration/keras/callbacks/__init__.py +5 -0
  121. wandb/integration/keras/callbacks/metrics_logger.py +129 -0
  122. wandb/integration/keras/callbacks/model_checkpoint.py +188 -0
  123. wandb/integration/keras/callbacks/tables_builder.py +228 -0
  124. wandb/integration/keras/keras.py +1086 -0
  125. wandb/integration/kfp/__init__.py +6 -0
  126. wandb/integration/kfp/helpers.py +28 -0
  127. wandb/integration/kfp/kfp_patch.py +335 -0
  128. wandb/integration/kfp/wandb_logging.py +182 -0
  129. wandb/integration/langchain/__init__.py +3 -0
  130. wandb/integration/langchain/wandb_tracer.py +49 -0
  131. wandb/integration/lightgbm/__init__.py +239 -0
  132. wandb/integration/lightning/__init__.py +0 -0
  133. wandb/integration/lightning/fabric/__init__.py +3 -0
  134. wandb/integration/lightning/fabric/logger.py +763 -0
  135. wandb/integration/metaflow/__init__.py +9 -0
  136. wandb/integration/metaflow/data_pandas.py +74 -0
  137. wandb/integration/metaflow/data_pytorch.py +75 -0
  138. wandb/integration/metaflow/data_sklearn.py +76 -0
  139. wandb/integration/metaflow/errors.py +13 -0
  140. wandb/integration/metaflow/metaflow.py +327 -0
  141. wandb/integration/openai/__init__.py +3 -0
  142. wandb/integration/openai/fine_tuning.py +480 -0
  143. wandb/integration/openai/openai.py +22 -0
  144. wandb/integration/openai/resolver.py +240 -0
  145. wandb/integration/prodigy/__init__.py +3 -0
  146. wandb/integration/prodigy/prodigy.py +291 -0
  147. wandb/integration/sacred/__init__.py +117 -0
  148. wandb/integration/sagemaker/__init__.py +14 -0
  149. wandb/integration/sagemaker/auth.py +29 -0
  150. wandb/integration/sagemaker/config.py +58 -0
  151. wandb/integration/sagemaker/files.py +2 -0
  152. wandb/integration/sagemaker/resources.py +63 -0
  153. wandb/integration/sb3/__init__.py +3 -0
  154. wandb/integration/sb3/sb3.py +147 -0
  155. wandb/integration/sklearn/__init__.py +37 -0
  156. wandb/integration/sklearn/calculate/__init__.py +32 -0
  157. wandb/integration/sklearn/calculate/calibration_curves.py +125 -0
  158. wandb/integration/sklearn/calculate/class_proportions.py +68 -0
  159. wandb/integration/sklearn/calculate/confusion_matrix.py +93 -0
  160. wandb/integration/sklearn/calculate/decision_boundaries.py +40 -0
  161. wandb/integration/sklearn/calculate/elbow_curve.py +55 -0
  162. wandb/integration/sklearn/calculate/feature_importances.py +67 -0
  163. wandb/integration/sklearn/calculate/learning_curve.py +64 -0
  164. wandb/integration/sklearn/calculate/outlier_candidates.py +69 -0
  165. wandb/integration/sklearn/calculate/residuals.py +86 -0
  166. wandb/integration/sklearn/calculate/silhouette.py +118 -0
  167. wandb/integration/sklearn/calculate/summary_metrics.py +62 -0
  168. wandb/integration/sklearn/plot/__init__.py +35 -0
  169. wandb/integration/sklearn/plot/classifier.py +329 -0
  170. wandb/integration/sklearn/plot/clusterer.py +146 -0
  171. wandb/integration/sklearn/plot/regressor.py +121 -0
  172. wandb/integration/sklearn/plot/shared.py +91 -0
  173. wandb/integration/sklearn/utils.py +184 -0
  174. wandb/integration/tensorboard/__init__.py +10 -0
  175. wandb/integration/tensorboard/log.py +351 -0
  176. wandb/integration/tensorboard/monkeypatch.py +186 -0
  177. wandb/integration/tensorflow/__init__.py +5 -0
  178. wandb/integration/tensorflow/estimator_hook.py +54 -0
  179. wandb/integration/torch/__init__.py +0 -0
  180. wandb/integration/torch/wandb_torch.py +554 -0
  181. wandb/integration/ultralytics/__init__.py +11 -0
  182. wandb/integration/ultralytics/bbox_utils.py +215 -0
  183. wandb/integration/ultralytics/callback.py +528 -0
  184. wandb/integration/ultralytics/classification_utils.py +83 -0
  185. wandb/integration/ultralytics/mask_utils.py +202 -0
  186. wandb/integration/ultralytics/pose_utils.py +103 -0
  187. wandb/integration/weave/__init__.py +6 -0
  188. wandb/integration/weave/interface.py +49 -0
  189. wandb/integration/weave/weave.py +63 -0
  190. wandb/integration/xgboost/__init__.py +11 -0
  191. wandb/integration/xgboost/xgboost.py +189 -0
  192. wandb/integration/yolov8/__init__.py +0 -0
  193. wandb/integration/yolov8/yolov8.py +284 -0
  194. wandb/jupyter.py +538 -0
  195. wandb/mpmain/__init__.py +0 -0
  196. wandb/mpmain/__main__.py +1 -0
  197. wandb/old/__init__.py +0 -0
  198. wandb/old/core.py +53 -0
  199. wandb/old/settings.py +176 -0
  200. wandb/old/summary.py +438 -0
  201. wandb/plot/__init__.py +30 -0
  202. wandb/plot/bar.py +71 -0
  203. wandb/plot/confusion_matrix.py +185 -0
  204. wandb/plot/custom_chart.py +147 -0
  205. wandb/plot/histogram.py +66 -0
  206. wandb/plot/line.py +75 -0
  207. wandb/plot/line_series.py +173 -0
  208. wandb/plot/pr_curve.py +186 -0
  209. wandb/plot/roc_curve.py +163 -0
  210. wandb/plot/scatter.py +66 -0
  211. wandb/plot/utils.py +184 -0
  212. wandb/plot/viz.py +41 -0
  213. wandb/proto/__init__.py +0 -0
  214. wandb/proto/v3/__init__.py +0 -0
  215. wandb/proto/v3/wandb_base_pb2.py +55 -0
  216. wandb/proto/v3/wandb_internal_pb2.py +1728 -0
  217. wandb/proto/v3/wandb_server_pb2.py +228 -0
  218. wandb/proto/v3/wandb_settings_pb2.py +122 -0
  219. wandb/proto/v3/wandb_telemetry_pb2.py +106 -0
  220. wandb/proto/v4/__init__.py +0 -0
  221. wandb/proto/v4/wandb_base_pb2.py +30 -0
  222. wandb/proto/v4/wandb_internal_pb2.py +382 -0
  223. wandb/proto/v4/wandb_server_pb2.py +67 -0
  224. wandb/proto/v4/wandb_settings_pb2.py +47 -0
  225. wandb/proto/v4/wandb_telemetry_pb2.py +41 -0
  226. wandb/proto/v5/wandb_base_pb2.py +31 -0
  227. wandb/proto/v5/wandb_internal_pb2.py +383 -0
  228. wandb/proto/v5/wandb_server_pb2.py +68 -0
  229. wandb/proto/v5/wandb_settings_pb2.py +48 -0
  230. wandb/proto/v5/wandb_telemetry_pb2.py +42 -0
  231. wandb/proto/v6/wandb_base_pb2.py +41 -0
  232. wandb/proto/v6/wandb_internal_pb2.py +393 -0
  233. wandb/proto/v6/wandb_server_pb2.py +78 -0
  234. wandb/proto/v6/wandb_settings_pb2.py +58 -0
  235. wandb/proto/v6/wandb_telemetry_pb2.py +52 -0
  236. wandb/proto/wandb_base_pb2.py +12 -0
  237. wandb/proto/wandb_deprecated.py +59 -0
  238. wandb/proto/wandb_generate_deprecated.py +30 -0
  239. wandb/proto/wandb_generate_proto.py +49 -0
  240. wandb/proto/wandb_internal_pb2.py +18 -0
  241. wandb/proto/wandb_server_pb2.py +12 -0
  242. wandb/proto/wandb_settings_pb2.py +12 -0
  243. wandb/proto/wandb_telemetry_pb2.py +12 -0
  244. wandb/py.typed +0 -0
  245. wandb/sdk/__init__.py +37 -0
  246. wandb/sdk/artifacts/__init__.py +0 -0
  247. wandb/sdk/artifacts/_factories.py +17 -0
  248. wandb/sdk/artifacts/_generated/__init__.py +508 -0
  249. wandb/sdk/artifacts/_generated/add_aliases.py +21 -0
  250. wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
  251. wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
  252. wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
  253. wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +43 -0
  254. wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
  255. wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
  256. wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
  257. wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
  258. wandb/sdk/artifacts/_generated/artifact_version_files.py +36 -0
  259. wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
  260. wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +36 -0
  261. wandb/sdk/artifacts/_generated/delete_aliases.py +21 -0
  262. wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
  263. wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +25 -0
  264. wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +35 -0
  265. wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +35 -0
  266. wandb/sdk/artifacts/_generated/enums.py +22 -0
  267. wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
  268. wandb/sdk/artifacts/_generated/fetch_linked_artifacts.py +67 -0
  269. wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
  270. wandb/sdk/artifacts/_generated/fragments.py +459 -0
  271. wandb/sdk/artifacts/_generated/input_types.py +46 -0
  272. wandb/sdk/artifacts/_generated/link_artifact.py +27 -0
  273. wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
  274. wandb/sdk/artifacts/_generated/operations.py +1223 -0
  275. wandb/sdk/artifacts/_generated/project_artifact_collection.py +101 -0
  276. wandb/sdk/artifacts/_generated/project_artifact_collections.py +33 -0
  277. wandb/sdk/artifacts/_generated/project_artifact_type.py +24 -0
  278. wandb/sdk/artifacts/_generated/project_artifact_types.py +24 -0
  279. wandb/sdk/artifacts/_generated/project_artifacts.py +42 -0
  280. wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
  281. wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
  282. wandb/sdk/artifacts/_generated/run_input_artifacts.py +51 -0
  283. wandb/sdk/artifacts/_generated/run_output_artifacts.py +51 -0
  284. wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
  285. wandb/sdk/artifacts/_generated/update_artifact.py +26 -0
  286. wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +35 -0
  287. wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
  288. wandb/sdk/artifacts/_graphql_fragments.py +19 -0
  289. wandb/sdk/artifacts/_internal_artifact.py +54 -0
  290. wandb/sdk/artifacts/_validators.py +309 -0
  291. wandb/sdk/artifacts/artifact.py +2702 -0
  292. wandb/sdk/artifacts/artifact_download_logger.py +45 -0
  293. wandb/sdk/artifacts/artifact_file_cache.py +251 -0
  294. wandb/sdk/artifacts/artifact_instance_cache.py +17 -0
  295. wandb/sdk/artifacts/artifact_manifest.py +76 -0
  296. wandb/sdk/artifacts/artifact_manifest_entry.py +258 -0
  297. wandb/sdk/artifacts/artifact_manifests/__init__.py +0 -0
  298. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +94 -0
  299. wandb/sdk/artifacts/artifact_saver.py +277 -0
  300. wandb/sdk/artifacts/artifact_state.py +13 -0
  301. wandb/sdk/artifacts/artifact_ttl.py +9 -0
  302. wandb/sdk/artifacts/exceptions.py +71 -0
  303. wandb/sdk/artifacts/staging.py +27 -0
  304. wandb/sdk/artifacts/storage_handler.py +62 -0
  305. wandb/sdk/artifacts/storage_handlers/__init__.py +0 -0
  306. wandb/sdk/artifacts/storage_handlers/azure_handler.py +214 -0
  307. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +224 -0
  308. wandb/sdk/artifacts/storage_handlers/http_handler.py +114 -0
  309. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +142 -0
  310. wandb/sdk/artifacts/storage_handlers/multi_handler.py +56 -0
  311. wandb/sdk/artifacts/storage_handlers/s3_handler.py +339 -0
  312. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +68 -0
  313. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +131 -0
  314. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +74 -0
  315. wandb/sdk/artifacts/storage_layout.py +8 -0
  316. wandb/sdk/artifacts/storage_policies/__init__.py +4 -0
  317. wandb/sdk/artifacts/storage_policies/register.py +1 -0
  318. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +580 -0
  319. wandb/sdk/artifacts/storage_policy.py +75 -0
  320. wandb/sdk/backend/__init__.py +0 -0
  321. wandb/sdk/backend/backend.py +57 -0
  322. wandb/sdk/data_types/__init__.py +0 -0
  323. wandb/sdk/data_types/_dtypes.py +914 -0
  324. wandb/sdk/data_types/_private.py +10 -0
  325. wandb/sdk/data_types/audio.py +208 -0
  326. wandb/sdk/data_types/base_types/__init__.py +0 -0
  327. wandb/sdk/data_types/base_types/json_metadata.py +55 -0
  328. wandb/sdk/data_types/base_types/media.py +339 -0
  329. wandb/sdk/data_types/base_types/wb_value.py +295 -0
  330. wandb/sdk/data_types/bokeh.py +87 -0
  331. wandb/sdk/data_types/graph.py +439 -0
  332. wandb/sdk/data_types/helper_types/__init__.py +0 -0
  333. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +327 -0
  334. wandb/sdk/data_types/helper_types/classes.py +159 -0
  335. wandb/sdk/data_types/helper_types/image_mask.py +251 -0
  336. wandb/sdk/data_types/histogram.py +107 -0
  337. wandb/sdk/data_types/html.py +165 -0
  338. wandb/sdk/data_types/image.py +974 -0
  339. wandb/sdk/data_types/molecule.py +250 -0
  340. wandb/sdk/data_types/object_3d.py +495 -0
  341. wandb/sdk/data_types/plotly.py +95 -0
  342. wandb/sdk/data_types/saved_model.py +435 -0
  343. wandb/sdk/data_types/table.py +1468 -0
  344. wandb/sdk/data_types/table_decorators.py +108 -0
  345. wandb/sdk/data_types/trace_tree.py +440 -0
  346. wandb/sdk/data_types/utils.py +260 -0
  347. wandb/sdk/data_types/video.py +303 -0
  348. wandb/sdk/integration_utils/__init__.py +0 -0
  349. wandb/sdk/integration_utils/auto_logging.py +232 -0
  350. wandb/sdk/integration_utils/data_logging.py +475 -0
  351. wandb/sdk/interface/__init__.py +0 -0
  352. wandb/sdk/interface/constants.py +4 -0
  353. wandb/sdk/interface/interface.py +1056 -0
  354. wandb/sdk/interface/interface_queue.py +40 -0
  355. wandb/sdk/interface/interface_shared.py +471 -0
  356. wandb/sdk/interface/interface_sock.py +49 -0
  357. wandb/sdk/interface/summary_record.py +67 -0
  358. wandb/sdk/internal/__init__.py +0 -0
  359. wandb/sdk/internal/_generated/__init__.py +15 -0
  360. wandb/sdk/internal/_generated/enums.py +4 -0
  361. wandb/sdk/internal/_generated/input_types.py +4 -0
  362. wandb/sdk/internal/_generated/operations.py +15 -0
  363. wandb/sdk/internal/_generated/server_features_query.py +27 -0
  364. wandb/sdk/internal/context.py +89 -0
  365. wandb/sdk/internal/datastore.py +293 -0
  366. wandb/sdk/internal/file_pusher.py +177 -0
  367. wandb/sdk/internal/file_stream.py +686 -0
  368. wandb/sdk/internal/handler.py +854 -0
  369. wandb/sdk/internal/incremental_table_util.py +53 -0
  370. wandb/sdk/internal/internal_api.py +4723 -0
  371. wandb/sdk/internal/job_builder.py +639 -0
  372. wandb/sdk/internal/profiler.py +79 -0
  373. wandb/sdk/internal/progress.py +77 -0
  374. wandb/sdk/internal/run.py +27 -0
  375. wandb/sdk/internal/sample.py +70 -0
  376. wandb/sdk/internal/sender.py +1692 -0
  377. wandb/sdk/internal/sender_config.py +203 -0
  378. wandb/sdk/internal/settings_static.py +120 -0
  379. wandb/sdk/internal/tb_watcher.py +519 -0
  380. wandb/sdk/internal/thread_local_settings.py +18 -0
  381. wandb/sdk/launch/__init__.py +15 -0
  382. wandb/sdk/launch/_launch.py +331 -0
  383. wandb/sdk/launch/_launch_add.py +255 -0
  384. wandb/sdk/launch/_project_spec.py +565 -0
  385. wandb/sdk/launch/agent/__init__.py +5 -0
  386. wandb/sdk/launch/agent/agent.py +931 -0
  387. wandb/sdk/launch/agent/config.py +296 -0
  388. wandb/sdk/launch/agent/job_status_tracker.py +55 -0
  389. wandb/sdk/launch/agent/run_queue_item_file_saver.py +39 -0
  390. wandb/sdk/launch/builder/__init__.py +0 -0
  391. wandb/sdk/launch/builder/abstract.py +156 -0
  392. wandb/sdk/launch/builder/build.py +296 -0
  393. wandb/sdk/launch/builder/context_manager.py +235 -0
  394. wandb/sdk/launch/builder/docker_builder.py +177 -0
  395. wandb/sdk/launch/builder/kaniko_builder.py +595 -0
  396. wandb/sdk/launch/builder/noop.py +58 -0
  397. wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +188 -0
  398. wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
  399. wandb/sdk/launch/create_job.py +541 -0
  400. wandb/sdk/launch/environment/abstract.py +29 -0
  401. wandb/sdk/launch/environment/aws_environment.py +322 -0
  402. wandb/sdk/launch/environment/azure_environment.py +105 -0
  403. wandb/sdk/launch/environment/gcp_environment.py +334 -0
  404. wandb/sdk/launch/environment/local_environment.py +65 -0
  405. wandb/sdk/launch/errors.py +13 -0
  406. wandb/sdk/launch/git_reference.py +109 -0
  407. wandb/sdk/launch/inputs/files.py +148 -0
  408. wandb/sdk/launch/inputs/internal.py +314 -0
  409. wandb/sdk/launch/inputs/manage.py +113 -0
  410. wandb/sdk/launch/inputs/schema.py +40 -0
  411. wandb/sdk/launch/loader.py +249 -0
  412. wandb/sdk/launch/registry/abstract.py +48 -0
  413. wandb/sdk/launch/registry/anon.py +29 -0
  414. wandb/sdk/launch/registry/azure_container_registry.py +124 -0
  415. wandb/sdk/launch/registry/elastic_container_registry.py +192 -0
  416. wandb/sdk/launch/registry/google_artifact_registry.py +219 -0
  417. wandb/sdk/launch/registry/local_registry.py +65 -0
  418. wandb/sdk/launch/runner/__init__.py +0 -0
  419. wandb/sdk/launch/runner/abstract.py +185 -0
  420. wandb/sdk/launch/runner/kubernetes_monitor.py +473 -0
  421. wandb/sdk/launch/runner/kubernetes_runner.py +1285 -0
  422. wandb/sdk/launch/runner/local_container.py +301 -0
  423. wandb/sdk/launch/runner/local_process.py +78 -0
  424. wandb/sdk/launch/runner/sagemaker_runner.py +424 -0
  425. wandb/sdk/launch/runner/vertex_runner.py +225 -0
  426. wandb/sdk/launch/sweeps/__init__.py +37 -0
  427. wandb/sdk/launch/sweeps/scheduler.py +739 -0
  428. wandb/sdk/launch/sweeps/scheduler_sweep.py +90 -0
  429. wandb/sdk/launch/sweeps/utils.py +324 -0
  430. wandb/sdk/launch/utils.py +746 -0
  431. wandb/sdk/launch/wandb_reference.py +138 -0
  432. wandb/sdk/lib/__init__.py +5 -0
  433. wandb/sdk/lib/apikey.py +334 -0
  434. wandb/sdk/lib/asyncio_compat.py +213 -0
  435. wandb/sdk/lib/asyncio_manager.py +252 -0
  436. wandb/sdk/lib/capped_dict.py +26 -0
  437. wandb/sdk/lib/config_util.py +101 -0
  438. wandb/sdk/lib/console_capture.py +219 -0
  439. wandb/sdk/lib/credentials.py +141 -0
  440. wandb/sdk/lib/deprecate.py +27 -0
  441. wandb/sdk/lib/disabled.py +30 -0
  442. wandb/sdk/lib/exit_hooks.py +54 -0
  443. wandb/sdk/lib/file_stream_utils.py +118 -0
  444. wandb/sdk/lib/filenames.py +64 -0
  445. wandb/sdk/lib/filesystem.py +372 -0
  446. wandb/sdk/lib/fsm.py +165 -0
  447. wandb/sdk/lib/gitlib.py +240 -0
  448. wandb/sdk/lib/gql_request.py +65 -0
  449. wandb/sdk/lib/handler_util.py +21 -0
  450. wandb/sdk/lib/hashutil.py +106 -0
  451. wandb/sdk/lib/import_hooks.py +275 -0
  452. wandb/sdk/lib/interrupt.py +37 -0
  453. wandb/sdk/lib/ipython.py +126 -0
  454. wandb/sdk/lib/json_util.py +75 -0
  455. wandb/sdk/lib/lazyloader.py +63 -0
  456. wandb/sdk/lib/module.py +72 -0
  457. wandb/sdk/lib/paths.py +106 -0
  458. wandb/sdk/lib/preinit.py +42 -0
  459. wandb/sdk/lib/printer.py +571 -0
  460. wandb/sdk/lib/printer_asyncio.py +48 -0
  461. wandb/sdk/lib/progress.py +320 -0
  462. wandb/sdk/lib/proto_util.py +90 -0
  463. wandb/sdk/lib/redirect.py +876 -0
  464. wandb/sdk/lib/retry.py +395 -0
  465. wandb/sdk/lib/run_moment.py +82 -0
  466. wandb/sdk/lib/runid.py +12 -0
  467. wandb/sdk/lib/server.py +58 -0
  468. wandb/sdk/lib/service/ipc_support.py +13 -0
  469. wandb/sdk/lib/service/service_client.py +106 -0
  470. wandb/sdk/lib/service/service_connection.py +192 -0
  471. wandb/sdk/lib/service/service_port_file.py +105 -0
  472. wandb/sdk/lib/service/service_process.py +111 -0
  473. wandb/sdk/lib/service/service_token.py +181 -0
  474. wandb/sdk/lib/sparkline.py +44 -0
  475. wandb/sdk/lib/telemetry.py +100 -0
  476. wandb/sdk/lib/timed_input.py +133 -0
  477. wandb/sdk/lib/timer.py +19 -0
  478. wandb/sdk/lib/wb_logging.py +161 -0
  479. wandb/sdk/mailbox/__init__.py +23 -0
  480. wandb/sdk/mailbox/mailbox.py +143 -0
  481. wandb/sdk/mailbox/mailbox_handle.py +132 -0
  482. wandb/sdk/mailbox/response_handle.py +99 -0
  483. wandb/sdk/mailbox/wait_with_progress.py +100 -0
  484. wandb/sdk/projects/_generated/__init__.py +47 -0
  485. wandb/sdk/projects/_generated/delete_project.py +22 -0
  486. wandb/sdk/projects/_generated/enums.py +4 -0
  487. wandb/sdk/projects/_generated/fetch_registry.py +22 -0
  488. wandb/sdk/projects/_generated/fragments.py +41 -0
  489. wandb/sdk/projects/_generated/input_types.py +13 -0
  490. wandb/sdk/projects/_generated/operations.py +88 -0
  491. wandb/sdk/projects/_generated/rename_project.py +27 -0
  492. wandb/sdk/projects/_generated/upsert_registry_project.py +27 -0
  493. wandb/sdk/verify/__init__.py +0 -0
  494. wandb/sdk/verify/verify.py +555 -0
  495. wandb/sdk/wandb_alerts.py +12 -0
  496. wandb/sdk/wandb_config.py +323 -0
  497. wandb/sdk/wandb_helper.py +54 -0
  498. wandb/sdk/wandb_init.py +1581 -0
  499. wandb/sdk/wandb_login.py +332 -0
  500. wandb/sdk/wandb_metric.py +112 -0
  501. wandb/sdk/wandb_require.py +88 -0
  502. wandb/sdk/wandb_require_helpers.py +44 -0
  503. wandb/sdk/wandb_run.py +4088 -0
  504. wandb/sdk/wandb_settings.py +2105 -0
  505. wandb/sdk/wandb_setup.py +560 -0
  506. wandb/sdk/wandb_summary.py +150 -0
  507. wandb/sdk/wandb_sweep.py +120 -0
  508. wandb/sdk/wandb_sync.py +71 -0
  509. wandb/sdk/wandb_watch.py +146 -0
  510. wandb/sklearn.py +35 -0
  511. wandb/sync/__init__.py +3 -0
  512. wandb/sync/sync.py +452 -0
  513. wandb/trigger.py +29 -0
  514. wandb/util.py +2040 -0
  515. wandb/vendor/__init__.py +0 -0
  516. wandb/vendor/gql-0.2.0/setup.py +40 -0
  517. wandb/vendor/gql-0.2.0/tests/__init__.py +0 -0
  518. wandb/vendor/gql-0.2.0/tests/starwars/__init__.py +0 -0
  519. wandb/vendor/gql-0.2.0/tests/starwars/fixtures.py +96 -0
  520. wandb/vendor/gql-0.2.0/tests/starwars/schema.py +146 -0
  521. wandb/vendor/gql-0.2.0/tests/starwars/test_dsl.py +293 -0
  522. wandb/vendor/gql-0.2.0/tests/starwars/test_query.py +355 -0
  523. wandb/vendor/gql-0.2.0/tests/starwars/test_validation.py +171 -0
  524. wandb/vendor/gql-0.2.0/tests/test_client.py +31 -0
  525. wandb/vendor/gql-0.2.0/tests/test_transport.py +89 -0
  526. wandb/vendor/gql-0.2.0/wandb_gql/__init__.py +4 -0
  527. wandb/vendor/gql-0.2.0/wandb_gql/client.py +75 -0
  528. wandb/vendor/gql-0.2.0/wandb_gql/dsl.py +152 -0
  529. wandb/vendor/gql-0.2.0/wandb_gql/gql.py +10 -0
  530. wandb/vendor/gql-0.2.0/wandb_gql/transport/__init__.py +0 -0
  531. wandb/vendor/gql-0.2.0/wandb_gql/transport/http.py +6 -0
  532. wandb/vendor/gql-0.2.0/wandb_gql/transport/local_schema.py +15 -0
  533. wandb/vendor/gql-0.2.0/wandb_gql/transport/requests.py +46 -0
  534. wandb/vendor/gql-0.2.0/wandb_gql/utils.py +21 -0
  535. wandb/vendor/graphql-core-1.1/setup.py +86 -0
  536. wandb/vendor/graphql-core-1.1/wandb_graphql/__init__.py +287 -0
  537. wandb/vendor/graphql-core-1.1/wandb_graphql/error/__init__.py +6 -0
  538. wandb/vendor/graphql-core-1.1/wandb_graphql/error/base.py +42 -0
  539. wandb/vendor/graphql-core-1.1/wandb_graphql/error/format_error.py +11 -0
  540. wandb/vendor/graphql-core-1.1/wandb_graphql/error/located_error.py +29 -0
  541. wandb/vendor/graphql-core-1.1/wandb_graphql/error/syntax_error.py +36 -0
  542. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/__init__.py +26 -0
  543. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/base.py +311 -0
  544. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executor.py +398 -0
  545. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/__init__.py +0 -0
  546. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/asyncio.py +53 -0
  547. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/gevent.py +22 -0
  548. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/process.py +32 -0
  549. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/sync.py +7 -0
  550. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/thread.py +35 -0
  551. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/utils.py +6 -0
  552. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/__init__.py +0 -0
  553. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/executor.py +66 -0
  554. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/fragment.py +252 -0
  555. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/resolver.py +151 -0
  556. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/utils.py +7 -0
  557. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/middleware.py +57 -0
  558. wandb/vendor/graphql-core-1.1/wandb_graphql/execution/values.py +145 -0
  559. wandb/vendor/graphql-core-1.1/wandb_graphql/graphql.py +60 -0
  560. wandb/vendor/graphql-core-1.1/wandb_graphql/language/__init__.py +0 -0
  561. wandb/vendor/graphql-core-1.1/wandb_graphql/language/ast.py +1349 -0
  562. wandb/vendor/graphql-core-1.1/wandb_graphql/language/base.py +19 -0
  563. wandb/vendor/graphql-core-1.1/wandb_graphql/language/lexer.py +435 -0
  564. wandb/vendor/graphql-core-1.1/wandb_graphql/language/location.py +30 -0
  565. wandb/vendor/graphql-core-1.1/wandb_graphql/language/parser.py +779 -0
  566. wandb/vendor/graphql-core-1.1/wandb_graphql/language/printer.py +193 -0
  567. wandb/vendor/graphql-core-1.1/wandb_graphql/language/source.py +18 -0
  568. wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor.py +222 -0
  569. wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor_meta.py +82 -0
  570. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/__init__.py +0 -0
  571. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/cached_property.py +17 -0
  572. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/contain_subset.py +28 -0
  573. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/default_ordered_dict.py +40 -0
  574. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/ordereddict.py +8 -0
  575. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/pair_set.py +43 -0
  576. wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/version.py +78 -0
  577. wandb/vendor/graphql-core-1.1/wandb_graphql/type/__init__.py +67 -0
  578. wandb/vendor/graphql-core-1.1/wandb_graphql/type/definition.py +619 -0
  579. wandb/vendor/graphql-core-1.1/wandb_graphql/type/directives.py +132 -0
  580. wandb/vendor/graphql-core-1.1/wandb_graphql/type/introspection.py +440 -0
  581. wandb/vendor/graphql-core-1.1/wandb_graphql/type/scalars.py +131 -0
  582. wandb/vendor/graphql-core-1.1/wandb_graphql/type/schema.py +100 -0
  583. wandb/vendor/graphql-core-1.1/wandb_graphql/type/typemap.py +145 -0
  584. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/__init__.py +0 -0
  585. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/assert_valid_name.py +9 -0
  586. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_from_value.py +65 -0
  587. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_code.py +49 -0
  588. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_dict.py +24 -0
  589. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/base.py +75 -0
  590. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_ast_schema.py +291 -0
  591. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_client_schema.py +250 -0
  592. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/concat_ast.py +9 -0
  593. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/extend_schema.py +357 -0
  594. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_field_def.py +27 -0
  595. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_operation_ast.py +21 -0
  596. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/introspection_query.py +90 -0
  597. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_literal_value.py +67 -0
  598. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_value.py +66 -0
  599. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/quoted_or_list.py +21 -0
  600. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/schema_printer.py +168 -0
  601. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/suggestion_list.py +56 -0
  602. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_comparators.py +69 -0
  603. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_from_ast.py +21 -0
  604. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_info.py +149 -0
  605. wandb/vendor/graphql-core-1.1/wandb_graphql/utils/value_from_ast.py +69 -0
  606. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/__init__.py +4 -0
  607. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/__init__.py +79 -0
  608. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/arguments_of_correct_type.py +24 -0
  609. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/base.py +8 -0
  610. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/default_values_of_correct_type.py +44 -0
  611. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fields_on_correct_type.py +113 -0
  612. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fragments_on_composite_types.py +33 -0
  613. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_argument_names.py +70 -0
  614. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_directives.py +97 -0
  615. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_fragment_names.py +19 -0
  616. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_type_names.py +43 -0
  617. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/lone_anonymous_operation.py +23 -0
  618. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_fragment_cycles.py +59 -0
  619. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_undefined_variables.py +36 -0
  620. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_fragments.py +38 -0
  621. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_variables.py +37 -0
  622. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/overlapping_fields_can_be_merged.py +529 -0
  623. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/possible_fragment_spreads.py +44 -0
  624. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/provided_non_null_arguments.py +46 -0
  625. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/scalar_leafs.py +33 -0
  626. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_argument_names.py +32 -0
  627. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_fragment_names.py +28 -0
  628. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_input_field_names.py +33 -0
  629. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_operation_names.py +31 -0
  630. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_variable_names.py +27 -0
  631. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_are_input_types.py +21 -0
  632. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_in_allowed_position.py +53 -0
  633. wandb/vendor/graphql-core-1.1/wandb_graphql/validation/validation.py +158 -0
  634. wandb/vendor/promise-2.3.0/conftest.py +30 -0
  635. wandb/vendor/promise-2.3.0/setup.py +64 -0
  636. wandb/vendor/promise-2.3.0/tests/__init__.py +0 -0
  637. wandb/vendor/promise-2.3.0/tests/conftest.py +8 -0
  638. wandb/vendor/promise-2.3.0/tests/test_awaitable.py +32 -0
  639. wandb/vendor/promise-2.3.0/tests/test_awaitable_35.py +47 -0
  640. wandb/vendor/promise-2.3.0/tests/test_benchmark.py +116 -0
  641. wandb/vendor/promise-2.3.0/tests/test_complex_threads.py +23 -0
  642. wandb/vendor/promise-2.3.0/tests/test_dataloader.py +452 -0
  643. wandb/vendor/promise-2.3.0/tests/test_dataloader_awaitable_35.py +99 -0
  644. wandb/vendor/promise-2.3.0/tests/test_dataloader_extra.py +65 -0
  645. wandb/vendor/promise-2.3.0/tests/test_extra.py +670 -0
  646. wandb/vendor/promise-2.3.0/tests/test_issues.py +132 -0
  647. wandb/vendor/promise-2.3.0/tests/test_promise_list.py +70 -0
  648. wandb/vendor/promise-2.3.0/tests/test_spec.py +584 -0
  649. wandb/vendor/promise-2.3.0/tests/test_thread_safety.py +115 -0
  650. wandb/vendor/promise-2.3.0/tests/utils.py +3 -0
  651. wandb/vendor/promise-2.3.0/wandb_promise/__init__.py +38 -0
  652. wandb/vendor/promise-2.3.0/wandb_promise/async_.py +135 -0
  653. wandb/vendor/promise-2.3.0/wandb_promise/compat.py +32 -0
  654. wandb/vendor/promise-2.3.0/wandb_promise/dataloader.py +326 -0
  655. wandb/vendor/promise-2.3.0/wandb_promise/iterate_promise.py +12 -0
  656. wandb/vendor/promise-2.3.0/wandb_promise/promise.py +848 -0
  657. wandb/vendor/promise-2.3.0/wandb_promise/promise_list.py +151 -0
  658. wandb/vendor/promise-2.3.0/wandb_promise/pyutils/__init__.py +0 -0
  659. wandb/vendor/promise-2.3.0/wandb_promise/pyutils/version.py +83 -0
  660. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/__init__.py +0 -0
  661. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/asyncio.py +22 -0
  662. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/gevent.py +21 -0
  663. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/immediate.py +27 -0
  664. wandb/vendor/promise-2.3.0/wandb_promise/schedulers/thread.py +18 -0
  665. wandb/vendor/promise-2.3.0/wandb_promise/utils.py +56 -0
  666. wandb/vendor/pygments/__init__.py +90 -0
  667. wandb/vendor/pygments/cmdline.py +568 -0
  668. wandb/vendor/pygments/console.py +74 -0
  669. wandb/vendor/pygments/filter.py +74 -0
  670. wandb/vendor/pygments/filters/__init__.py +350 -0
  671. wandb/vendor/pygments/formatter.py +95 -0
  672. wandb/vendor/pygments/formatters/__init__.py +153 -0
  673. wandb/vendor/pygments/formatters/_mapping.py +85 -0
  674. wandb/vendor/pygments/formatters/bbcode.py +109 -0
  675. wandb/vendor/pygments/formatters/html.py +851 -0
  676. wandb/vendor/pygments/formatters/img.py +600 -0
  677. wandb/vendor/pygments/formatters/irc.py +182 -0
  678. wandb/vendor/pygments/formatters/latex.py +482 -0
  679. wandb/vendor/pygments/formatters/other.py +160 -0
  680. wandb/vendor/pygments/formatters/rtf.py +147 -0
  681. wandb/vendor/pygments/formatters/svg.py +153 -0
  682. wandb/vendor/pygments/formatters/terminal.py +136 -0
  683. wandb/vendor/pygments/formatters/terminal256.py +309 -0
  684. wandb/vendor/pygments/lexer.py +871 -0
  685. wandb/vendor/pygments/lexers/__init__.py +329 -0
  686. wandb/vendor/pygments/lexers/_asy_builtins.py +1645 -0
  687. wandb/vendor/pygments/lexers/_cl_builtins.py +232 -0
  688. wandb/vendor/pygments/lexers/_cocoa_builtins.py +72 -0
  689. wandb/vendor/pygments/lexers/_csound_builtins.py +1346 -0
  690. wandb/vendor/pygments/lexers/_lasso_builtins.py +5327 -0
  691. wandb/vendor/pygments/lexers/_lua_builtins.py +295 -0
  692. wandb/vendor/pygments/lexers/_mapping.py +500 -0
  693. wandb/vendor/pygments/lexers/_mql_builtins.py +1172 -0
  694. wandb/vendor/pygments/lexers/_openedge_builtins.py +2547 -0
  695. wandb/vendor/pygments/lexers/_php_builtins.py +4756 -0
  696. wandb/vendor/pygments/lexers/_postgres_builtins.py +621 -0
  697. wandb/vendor/pygments/lexers/_scilab_builtins.py +3094 -0
  698. wandb/vendor/pygments/lexers/_sourcemod_builtins.py +1163 -0
  699. wandb/vendor/pygments/lexers/_stan_builtins.py +532 -0
  700. wandb/vendor/pygments/lexers/_stata_builtins.py +419 -0
  701. wandb/vendor/pygments/lexers/_tsql_builtins.py +1004 -0
  702. wandb/vendor/pygments/lexers/_vim_builtins.py +1939 -0
  703. wandb/vendor/pygments/lexers/actionscript.py +240 -0
  704. wandb/vendor/pygments/lexers/agile.py +24 -0
  705. wandb/vendor/pygments/lexers/algebra.py +221 -0
  706. wandb/vendor/pygments/lexers/ambient.py +76 -0
  707. wandb/vendor/pygments/lexers/ampl.py +87 -0
  708. wandb/vendor/pygments/lexers/apl.py +101 -0
  709. wandb/vendor/pygments/lexers/archetype.py +318 -0
  710. wandb/vendor/pygments/lexers/asm.py +641 -0
  711. wandb/vendor/pygments/lexers/automation.py +374 -0
  712. wandb/vendor/pygments/lexers/basic.py +500 -0
  713. wandb/vendor/pygments/lexers/bibtex.py +160 -0
  714. wandb/vendor/pygments/lexers/business.py +612 -0
  715. wandb/vendor/pygments/lexers/c_cpp.py +252 -0
  716. wandb/vendor/pygments/lexers/c_like.py +541 -0
  717. wandb/vendor/pygments/lexers/capnproto.py +78 -0
  718. wandb/vendor/pygments/lexers/chapel.py +102 -0
  719. wandb/vendor/pygments/lexers/clean.py +288 -0
  720. wandb/vendor/pygments/lexers/compiled.py +34 -0
  721. wandb/vendor/pygments/lexers/configs.py +833 -0
  722. wandb/vendor/pygments/lexers/console.py +114 -0
  723. wandb/vendor/pygments/lexers/crystal.py +393 -0
  724. wandb/vendor/pygments/lexers/csound.py +366 -0
  725. wandb/vendor/pygments/lexers/css.py +689 -0
  726. wandb/vendor/pygments/lexers/d.py +251 -0
  727. wandb/vendor/pygments/lexers/dalvik.py +125 -0
  728. wandb/vendor/pygments/lexers/data.py +555 -0
  729. wandb/vendor/pygments/lexers/diff.py +165 -0
  730. wandb/vendor/pygments/lexers/dotnet.py +691 -0
  731. wandb/vendor/pygments/lexers/dsls.py +878 -0
  732. wandb/vendor/pygments/lexers/dylan.py +289 -0
  733. wandb/vendor/pygments/lexers/ecl.py +125 -0
  734. wandb/vendor/pygments/lexers/eiffel.py +65 -0
  735. wandb/vendor/pygments/lexers/elm.py +121 -0
  736. wandb/vendor/pygments/lexers/erlang.py +533 -0
  737. wandb/vendor/pygments/lexers/esoteric.py +277 -0
  738. wandb/vendor/pygments/lexers/ezhil.py +69 -0
  739. wandb/vendor/pygments/lexers/factor.py +344 -0
  740. wandb/vendor/pygments/lexers/fantom.py +250 -0
  741. wandb/vendor/pygments/lexers/felix.py +273 -0
  742. wandb/vendor/pygments/lexers/forth.py +177 -0
  743. wandb/vendor/pygments/lexers/fortran.py +205 -0
  744. wandb/vendor/pygments/lexers/foxpro.py +428 -0
  745. wandb/vendor/pygments/lexers/functional.py +21 -0
  746. wandb/vendor/pygments/lexers/go.py +101 -0
  747. wandb/vendor/pygments/lexers/grammar_notation.py +213 -0
  748. wandb/vendor/pygments/lexers/graph.py +80 -0
  749. wandb/vendor/pygments/lexers/graphics.py +553 -0
  750. wandb/vendor/pygments/lexers/haskell.py +843 -0
  751. wandb/vendor/pygments/lexers/haxe.py +936 -0
  752. wandb/vendor/pygments/lexers/hdl.py +382 -0
  753. wandb/vendor/pygments/lexers/hexdump.py +103 -0
  754. wandb/vendor/pygments/lexers/html.py +602 -0
  755. wandb/vendor/pygments/lexers/idl.py +270 -0
  756. wandb/vendor/pygments/lexers/igor.py +288 -0
  757. wandb/vendor/pygments/lexers/inferno.py +96 -0
  758. wandb/vendor/pygments/lexers/installers.py +322 -0
  759. wandb/vendor/pygments/lexers/int_fiction.py +1343 -0
  760. wandb/vendor/pygments/lexers/iolang.py +63 -0
  761. wandb/vendor/pygments/lexers/j.py +146 -0
  762. wandb/vendor/pygments/lexers/javascript.py +1525 -0
  763. wandb/vendor/pygments/lexers/julia.py +333 -0
  764. wandb/vendor/pygments/lexers/jvm.py +1573 -0
  765. wandb/vendor/pygments/lexers/lisp.py +2621 -0
  766. wandb/vendor/pygments/lexers/make.py +202 -0
  767. wandb/vendor/pygments/lexers/markup.py +595 -0
  768. wandb/vendor/pygments/lexers/math.py +21 -0
  769. wandb/vendor/pygments/lexers/matlab.py +663 -0
  770. wandb/vendor/pygments/lexers/ml.py +769 -0
  771. wandb/vendor/pygments/lexers/modeling.py +358 -0
  772. wandb/vendor/pygments/lexers/modula2.py +1561 -0
  773. wandb/vendor/pygments/lexers/monte.py +204 -0
  774. wandb/vendor/pygments/lexers/ncl.py +894 -0
  775. wandb/vendor/pygments/lexers/nimrod.py +159 -0
  776. wandb/vendor/pygments/lexers/nit.py +64 -0
  777. wandb/vendor/pygments/lexers/nix.py +136 -0
  778. wandb/vendor/pygments/lexers/oberon.py +105 -0
  779. wandb/vendor/pygments/lexers/objective.py +504 -0
  780. wandb/vendor/pygments/lexers/ooc.py +85 -0
  781. wandb/vendor/pygments/lexers/other.py +41 -0
  782. wandb/vendor/pygments/lexers/parasail.py +79 -0
  783. wandb/vendor/pygments/lexers/parsers.py +835 -0
  784. wandb/vendor/pygments/lexers/pascal.py +644 -0
  785. wandb/vendor/pygments/lexers/pawn.py +199 -0
  786. wandb/vendor/pygments/lexers/perl.py +620 -0
  787. wandb/vendor/pygments/lexers/php.py +267 -0
  788. wandb/vendor/pygments/lexers/praat.py +294 -0
  789. wandb/vendor/pygments/lexers/prolog.py +306 -0
  790. wandb/vendor/pygments/lexers/python.py +939 -0
  791. wandb/vendor/pygments/lexers/qvt.py +152 -0
  792. wandb/vendor/pygments/lexers/r.py +453 -0
  793. wandb/vendor/pygments/lexers/rdf.py +270 -0
  794. wandb/vendor/pygments/lexers/rebol.py +431 -0
  795. wandb/vendor/pygments/lexers/resource.py +85 -0
  796. wandb/vendor/pygments/lexers/rnc.py +67 -0
  797. wandb/vendor/pygments/lexers/roboconf.py +82 -0
  798. wandb/vendor/pygments/lexers/robotframework.py +560 -0
  799. wandb/vendor/pygments/lexers/ruby.py +519 -0
  800. wandb/vendor/pygments/lexers/rust.py +220 -0
  801. wandb/vendor/pygments/lexers/sas.py +228 -0
  802. wandb/vendor/pygments/lexers/scripting.py +1222 -0
  803. wandb/vendor/pygments/lexers/shell.py +794 -0
  804. wandb/vendor/pygments/lexers/smalltalk.py +195 -0
  805. wandb/vendor/pygments/lexers/smv.py +79 -0
  806. wandb/vendor/pygments/lexers/snobol.py +83 -0
  807. wandb/vendor/pygments/lexers/special.py +103 -0
  808. wandb/vendor/pygments/lexers/sql.py +681 -0
  809. wandb/vendor/pygments/lexers/stata.py +108 -0
  810. wandb/vendor/pygments/lexers/supercollider.py +90 -0
  811. wandb/vendor/pygments/lexers/tcl.py +145 -0
  812. wandb/vendor/pygments/lexers/templates.py +2283 -0
  813. wandb/vendor/pygments/lexers/testing.py +207 -0
  814. wandb/vendor/pygments/lexers/text.py +25 -0
  815. wandb/vendor/pygments/lexers/textedit.py +169 -0
  816. wandb/vendor/pygments/lexers/textfmts.py +297 -0
  817. wandb/vendor/pygments/lexers/theorem.py +458 -0
  818. wandb/vendor/pygments/lexers/trafficscript.py +54 -0
  819. wandb/vendor/pygments/lexers/typoscript.py +226 -0
  820. wandb/vendor/pygments/lexers/urbi.py +133 -0
  821. wandb/vendor/pygments/lexers/varnish.py +190 -0
  822. wandb/vendor/pygments/lexers/verification.py +111 -0
  823. wandb/vendor/pygments/lexers/web.py +24 -0
  824. wandb/vendor/pygments/lexers/webmisc.py +988 -0
  825. wandb/vendor/pygments/lexers/whiley.py +116 -0
  826. wandb/vendor/pygments/lexers/x10.py +69 -0
  827. wandb/vendor/pygments/modeline.py +44 -0
  828. wandb/vendor/pygments/plugin.py +68 -0
  829. wandb/vendor/pygments/regexopt.py +92 -0
  830. wandb/vendor/pygments/scanner.py +105 -0
  831. wandb/vendor/pygments/sphinxext.py +158 -0
  832. wandb/vendor/pygments/style.py +155 -0
  833. wandb/vendor/pygments/styles/__init__.py +80 -0
  834. wandb/vendor/pygments/styles/abap.py +29 -0
  835. wandb/vendor/pygments/styles/algol.py +63 -0
  836. wandb/vendor/pygments/styles/algol_nu.py +63 -0
  837. wandb/vendor/pygments/styles/arduino.py +98 -0
  838. wandb/vendor/pygments/styles/autumn.py +65 -0
  839. wandb/vendor/pygments/styles/borland.py +51 -0
  840. wandb/vendor/pygments/styles/bw.py +49 -0
  841. wandb/vendor/pygments/styles/colorful.py +81 -0
  842. wandb/vendor/pygments/styles/default.py +73 -0
  843. wandb/vendor/pygments/styles/emacs.py +72 -0
  844. wandb/vendor/pygments/styles/friendly.py +72 -0
  845. wandb/vendor/pygments/styles/fruity.py +42 -0
  846. wandb/vendor/pygments/styles/igor.py +29 -0
  847. wandb/vendor/pygments/styles/lovelace.py +97 -0
  848. wandb/vendor/pygments/styles/manni.py +75 -0
  849. wandb/vendor/pygments/styles/monokai.py +106 -0
  850. wandb/vendor/pygments/styles/murphy.py +80 -0
  851. wandb/vendor/pygments/styles/native.py +65 -0
  852. wandb/vendor/pygments/styles/paraiso_dark.py +125 -0
  853. wandb/vendor/pygments/styles/paraiso_light.py +125 -0
  854. wandb/vendor/pygments/styles/pastie.py +75 -0
  855. wandb/vendor/pygments/styles/perldoc.py +69 -0
  856. wandb/vendor/pygments/styles/rainbow_dash.py +89 -0
  857. wandb/vendor/pygments/styles/rrt.py +33 -0
  858. wandb/vendor/pygments/styles/sas.py +44 -0
  859. wandb/vendor/pygments/styles/stata.py +40 -0
  860. wandb/vendor/pygments/styles/tango.py +141 -0
  861. wandb/vendor/pygments/styles/trac.py +63 -0
  862. wandb/vendor/pygments/styles/vim.py +63 -0
  863. wandb/vendor/pygments/styles/vs.py +38 -0
  864. wandb/vendor/pygments/styles/xcode.py +51 -0
  865. wandb/vendor/pygments/token.py +213 -0
  866. wandb/vendor/pygments/unistring.py +217 -0
  867. wandb/vendor/pygments/util.py +388 -0
  868. wandb/vendor/watchdog_0_9_0/wandb_watchdog/__init__.py +17 -0
  869. wandb/vendor/watchdog_0_9_0/wandb_watchdog/events.py +615 -0
  870. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/__init__.py +98 -0
  871. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/api.py +369 -0
  872. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents.py +172 -0
  873. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents2.py +239 -0
  874. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify.py +218 -0
  875. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_buffer.py +81 -0
  876. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_c.py +575 -0
  877. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/kqueue.py +730 -0
  878. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/polling.py +145 -0
  879. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/read_directory_changes.py +133 -0
  880. wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/winapi.py +348 -0
  881. wandb/vendor/watchdog_0_9_0/wandb_watchdog/patterns.py +265 -0
  882. wandb/vendor/watchdog_0_9_0/wandb_watchdog/tricks/__init__.py +174 -0
  883. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/__init__.py +151 -0
  884. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/bricks.py +249 -0
  885. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/compat.py +29 -0
  886. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/decorators.py +198 -0
  887. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/delayed_queue.py +88 -0
  888. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/dirsnapshot.py +293 -0
  889. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/echo.py +157 -0
  890. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/event_backport.py +41 -0
  891. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/importlib2.py +40 -0
  892. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/platform.py +57 -0
  893. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/unicode_paths.py +64 -0
  894. wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/win32stat.py +123 -0
  895. wandb/vendor/watchdog_0_9_0/wandb_watchdog/version.py +28 -0
  896. wandb/vendor/watchdog_0_9_0/wandb_watchdog/watchmedo.py +577 -0
  897. wandb/wandb_agent.py +580 -0
  898. wandb/wandb_controller.py +719 -0
  899. wandb/wandb_run.py +8 -0
  900. wandb-0.21.2.dist-info/METADATA +223 -0
  901. wandb-0.21.2.dist-info/RECORD +904 -0
  902. wandb-0.21.2.dist-info/WHEEL +4 -0
  903. wandb-0.21.2.dist-info/entry_points.txt +3 -0
  904. wandb-0.21.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,974 @@
1
+ import hashlib
2
+ import logging
3
+ import os
4
+ import pathlib
5
+ from io import BytesIO
6
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Type, Union, cast
7
+ from urllib import parse
8
+
9
+ from packaging.version import parse as parse_version
10
+
11
+ import wandb
12
+ from wandb import util
13
+ from wandb.sdk.lib import hashutil, runid
14
+ from wandb.sdk.lib.paths import LogicalPath
15
+
16
+ from . import _dtypes
17
+ from ._private import MEDIA_TMP
18
+ from .base_types.media import BatchableMedia, Media
19
+ from .helper_types.bounding_boxes_2d import BoundingBoxes2D
20
+ from .helper_types.classes import Classes
21
+ from .helper_types.image_mask import ImageMask
22
+
23
+ if TYPE_CHECKING: # pragma: no cover
24
+ import matplotlib # type: ignore
25
+ import numpy as np
26
+ import torch # type: ignore
27
+ from PIL.Image import Image as PILImage
28
+
29
+ from wandb.sdk.artifacts.artifact import Artifact
30
+
31
+ ImageDataType = Union[
32
+ "matplotlib.artist.Artist", "PILImage", "TorchTensorType", "np.ndarray"
33
+ ]
34
+ ImageDataOrPathType = Union[str, pathlib.Path, "Image", ImageDataType]
35
+ TorchTensorType = Union["torch.Tensor", "torch.Variable"]
36
+
37
+
38
+ def _warn_on_invalid_data_range(
39
+ data: "np.ndarray",
40
+ normalize: bool = True,
41
+ ) -> None:
42
+ if not normalize:
43
+ return
44
+
45
+ np = util.get_module(
46
+ "numpy",
47
+ required="wandb.Image requires numpy if not supplying PIL Images: pip install numpy",
48
+ )
49
+
50
+ if np.min(data) < 0 or np.max(data) > 255:
51
+ wandb.termwarn(
52
+ "Data passed to `wandb.Image` should consist of values in the range [0, 255], "
53
+ "image data will be normalized to this range, "
54
+ "but behavior will be removed in a future version of wandb.",
55
+ repeat=False,
56
+ )
57
+
58
+
59
+ def _guess_and_rescale_to_0_255(data: "np.ndarray") -> "np.ndarray":
60
+ """Guess the image's format and rescale its values to the range [0, 255].
61
+
62
+ This is an unfortunate design flaw carried forward for backward
63
+ compatibility. A better design would have been to document the expected
64
+ data format and not mangle the data provided by the user.
65
+
66
+ If given data in the range [0, 1], we multiply all values by 255
67
+ and round down to get integers.
68
+
69
+ If given data in the range [-1, 1], we rescale it by mapping -1 to 0 and
70
+ 1 to 255, then round down to get integers.
71
+
72
+ We clip and round all other data.
73
+ """
74
+ try:
75
+ import numpy as np
76
+ except ImportError:
77
+ raise wandb.Error(
78
+ "wandb.Image requires numpy if not supplying PIL images: pip install numpy"
79
+ ) from None
80
+
81
+ data_min: float = data.min()
82
+ data_max: float = data.max()
83
+
84
+ if 0 <= data_min and data_max <= 1:
85
+ return (data * 255).astype(np.uint8)
86
+
87
+ elif -1 <= data_min and data_max <= 1:
88
+ return (255 * 0.5 * (data + 1)).astype(np.uint8)
89
+
90
+ else:
91
+ return data.clip(0, 255).astype(np.uint8)
92
+
93
+
94
+ def _convert_to_uint8(data: "np.ndarray") -> "np.ndarray":
95
+ np = util.get_module(
96
+ "numpy",
97
+ required="wandb.Image requires numpy if not supplying PIL Images: pip install numpy",
98
+ )
99
+ return data.astype(np.uint8)
100
+
101
+
102
+ def _server_accepts_image_filenames(run: "wandb.Run") -> bool:
103
+ if run.offline:
104
+ return True
105
+
106
+ # Newer versions of wandb accept large image filenames arrays
107
+ # but older versions would have issues with this.
108
+ max_cli_version = util._get_max_cli_version()
109
+ if max_cli_version is None:
110
+ return False
111
+
112
+ accepts_image_filenames: bool = parse_version(max_cli_version) >= parse_version(
113
+ "0.12.10"
114
+ )
115
+ return accepts_image_filenames
116
+
117
+
118
+ def _server_accepts_artifact_path(run: "wandb.Run") -> bool:
119
+ if run.offline:
120
+ return False
121
+
122
+ max_cli_version = util._get_max_cli_version()
123
+ if max_cli_version is None:
124
+ return False
125
+
126
+ return parse_version(max_cli_version) >= parse_version("0.12.14")
127
+
128
+
129
+ class Image(BatchableMedia):
130
+ """A class for logging images to W&B."""
131
+
132
+ MAX_ITEMS = 108
133
+
134
+ # PIL limit
135
+ MAX_DIMENSION = 65500
136
+
137
+ _log_type = "image-file"
138
+
139
+ format: Optional[str]
140
+ _grouping: Optional[int]
141
+ _caption: Optional[str]
142
+ _width: Optional[int]
143
+ _height: Optional[int]
144
+ _image: Optional["PILImage"]
145
+ _classes: Optional["Classes"]
146
+ _boxes: Optional[Dict[str, "BoundingBoxes2D"]]
147
+ _masks: Optional[Dict[str, "ImageMask"]]
148
+ _file_type: Optional[str]
149
+
150
+ def __init__(
151
+ self,
152
+ data_or_path: "ImageDataOrPathType",
153
+ mode: Optional[str] = None,
154
+ caption: Optional[str] = None,
155
+ grouping: Optional[int] = None,
156
+ classes: Optional[Union["Classes", Sequence[dict]]] = None,
157
+ boxes: Optional[Union[Dict[str, "BoundingBoxes2D"], Dict[str, dict]]] = None,
158
+ masks: Optional[Union[Dict[str, "ImageMask"], Dict[str, dict]]] = None,
159
+ file_type: Optional[str] = None,
160
+ normalize: bool = True,
161
+ ) -> None:
162
+ """Initialize a `wandb.Image` object.
163
+
164
+ Args:
165
+ data_or_path: Accepts NumPy array/pytorch tensor of image data,
166
+ a PIL image object, or a path to an image file. If a NumPy
167
+ array or pytorch tensor is provided,
168
+ the image data will be saved to the given file type.
169
+ If the values are not in the range [0, 255] or all values are in the range [0, 1],
170
+ the image pixel values will be normalized to the range [0, 255]
171
+ unless `normalize` is set to False.
172
+ - pytorch tensor should be in the format (channel, height, width)
173
+ - NumPy array should be in the format (height, width, channel)
174
+ mode: The PIL mode for an image. Most common are "L", "RGB",
175
+ "RGBA". Full explanation at https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes
176
+ caption: Label for display of image.
177
+ grouping: The grouping number for the image.
178
+ classes: A list of class information for the image,
179
+ used for labeling bounding boxes, and image masks.
180
+ boxes: A dictionary containing bounding box information for the image.
181
+ see: https://docs.wandb.ai/ref/python/data-types/boundingboxes2d/
182
+ masks: A dictionary containing mask information for the image.
183
+ see: https://docs.wandb.ai/ref/python/data-types/imagemask/
184
+ file_type: The file type to save the image as.
185
+ This parameter has no effect if data_or_path is a path to an image file.
186
+ normalize: If True, normalize the image pixel values to fall within the range of [0, 255].
187
+ Normalize is only applied if data_or_path is a numpy array or pytorch tensor.
188
+
189
+ Examples:
190
+ Create a wandb.Image from a numpy array
191
+
192
+ ```python
193
+ import numpy as np
194
+ import wandb
195
+
196
+ with wandb.init() as run:
197
+ examples = []
198
+ for i in range(3):
199
+ pixels = np.random.randint(low=0, high=256, size=(100, 100, 3))
200
+ image = wandb.Image(pixels, caption=f"random field {i}")
201
+ examples.append(image)
202
+ run.log({"examples": examples})
203
+ ```
204
+
205
+ Create a wandb.Image from a PILImage
206
+
207
+ ```python
208
+ import numpy as np
209
+ from PIL import Image as PILImage
210
+ import wandb
211
+
212
+ with wandb.init() as run:
213
+ examples = []
214
+ for i in range(3):
215
+ pixels = np.random.randint(
216
+ low=0, high=256, size=(100, 100, 3), dtype=np.uint8
217
+ )
218
+ pil_image = PILImage.fromarray(pixels, mode="RGB")
219
+ image = wandb.Image(pil_image, caption=f"random field {i}")
220
+ examples.append(image)
221
+ run.log({"examples": examples})
222
+ ```
223
+
224
+ Log .jpg rather than .png (default)
225
+
226
+ ```python
227
+ import numpy as np
228
+ import wandb
229
+
230
+ with wandb.init() as run:
231
+ examples = []
232
+ for i in range(3):
233
+ pixels = np.random.randint(low=0, high=256, size=(100, 100, 3))
234
+ image = wandb.Image(
235
+ pixels, caption=f"random field {i}", file_type="jpg"
236
+ )
237
+ examples.append(image)
238
+ run.log({"examples": examples})
239
+ ```
240
+ """
241
+ super().__init__(caption=caption)
242
+ # TODO: We should remove grouping, it's a terrible name and I don't
243
+ # think anyone uses it.
244
+
245
+ self._grouping = None
246
+ self._width = None
247
+ self._height = None
248
+ self._image = None
249
+ self._classes = None
250
+ self._boxes = None
251
+ self._masks = None
252
+ self._file_type = None
253
+
254
+ # Allows the user to pass an Image object as the first parameter and have a perfect copy,
255
+ # only overriding additional metadata passed in. If this pattern is compelling, we can generalize.
256
+ if isinstance(data_or_path, Image):
257
+ self._initialize_from_wbimage(data_or_path)
258
+ elif isinstance(data_or_path, (str, pathlib.Path)):
259
+ data_or_path = str(data_or_path)
260
+
261
+ if self.path_is_reference(data_or_path):
262
+ self._initialize_from_reference(data_or_path)
263
+ else:
264
+ self._initialize_from_path(data_or_path)
265
+ else:
266
+ self._initialize_from_data(data_or_path, mode, file_type, normalize)
267
+ self._set_initialization_meta(
268
+ grouping, caption, classes, boxes, masks, file_type
269
+ )
270
+
271
+ def _set_initialization_meta(
272
+ self,
273
+ grouping: Optional[int] = None,
274
+ caption: Optional[str] = None,
275
+ classes: Optional[Union["Classes", Sequence[dict]]] = None,
276
+ boxes: Optional[Union[Dict[str, "BoundingBoxes2D"], Dict[str, dict]]] = None,
277
+ masks: Optional[Union[Dict[str, "ImageMask"], Dict[str, dict]]] = None,
278
+ file_type: Optional[str] = None,
279
+ ) -> None:
280
+ if grouping is not None:
281
+ self._grouping = grouping
282
+
283
+ total_classes = {}
284
+
285
+ if boxes:
286
+ if not isinstance(boxes, dict):
287
+ raise ValueError('Images "boxes" argument must be a dictionary')
288
+ boxes_final: Dict[str, BoundingBoxes2D] = {}
289
+ for key in boxes:
290
+ box_item = boxes[key]
291
+ if isinstance(box_item, BoundingBoxes2D):
292
+ boxes_final[key] = box_item
293
+ elif isinstance(box_item, dict):
294
+ # TODO: Consider injecting top-level classes if user-provided is empty
295
+ boxes_final[key] = BoundingBoxes2D(box_item, key)
296
+ total_classes.update(boxes_final[key]._class_labels)
297
+ self._boxes = boxes_final
298
+
299
+ if masks:
300
+ if not isinstance(masks, dict):
301
+ raise ValueError('Images "masks" argument must be a dictionary')
302
+ masks_final: Dict[str, ImageMask] = {}
303
+ for key in masks:
304
+ mask_item = masks[key]
305
+ if isinstance(mask_item, ImageMask):
306
+ masks_final[key] = mask_item
307
+ elif isinstance(mask_item, dict):
308
+ # TODO: Consider injecting top-level classes if user-provided is empty
309
+ masks_final[key] = ImageMask(mask_item, key)
310
+ if hasattr(masks_final[key], "_val"):
311
+ total_classes.update(masks_final[key]._val["class_labels"])
312
+ self._masks = masks_final
313
+
314
+ if classes is not None:
315
+ if isinstance(classes, Classes):
316
+ total_classes.update(
317
+ {val["id"]: val["name"] for val in classes._class_set}
318
+ )
319
+ else:
320
+ total_classes.update({val["id"]: val["name"] for val in classes})
321
+
322
+ if len(total_classes.keys()) > 0:
323
+ self._classes = Classes(
324
+ [
325
+ {"id": key, "name": total_classes[key]}
326
+ for key in total_classes.keys()
327
+ ]
328
+ )
329
+ if self.image is not None:
330
+ self._width, self._height = self.image.size
331
+ self._free_ram()
332
+
333
+ def _initialize_from_wbimage(self, wbimage: "Image") -> None:
334
+ self._grouping = wbimage._grouping
335
+ self._caption = wbimage._caption
336
+ self._width = wbimage._width
337
+ self._height = wbimage._height
338
+ self._image = wbimage._image
339
+ self._classes = wbimage._classes
340
+ self._path = wbimage._path
341
+ self._is_tmp = wbimage._is_tmp
342
+ self._extension = wbimage._extension
343
+ self._sha256 = wbimage._sha256
344
+ self._size = wbimage._size
345
+ self.format = wbimage.format
346
+ self._file_type = wbimage._file_type
347
+ self._artifact_source = wbimage._artifact_source
348
+ self._artifact_target = wbimage._artifact_target
349
+
350
+ # We do not want to implicitly copy boxes or masks, just the image-related data.
351
+ # self._boxes = wbimage._boxes
352
+ # self._masks = wbimage._masks
353
+
354
+ def _initialize_from_path(self, path: str) -> None:
355
+ pil_image = util.get_module(
356
+ "PIL.Image",
357
+ required='wandb.Image needs the PIL package. To get it, run "pip install pillow".',
358
+ )
359
+ self._set_file(path, is_tmp=False)
360
+ self._image = pil_image.open(path)
361
+ assert self._image is not None
362
+ self._image.load()
363
+ ext = os.path.splitext(path)[1][1:]
364
+ self.format = ext
365
+
366
+ def _initialize_from_reference(self, path: str) -> None:
367
+ self._path = path
368
+ self._is_tmp = False
369
+ self._sha256 = hashlib.sha256(path.encode("utf-8")).hexdigest()
370
+ path = parse.urlparse(path).path
371
+ ext = path.split("/")[-1].split(".")[-1]
372
+ self.format = ext
373
+
374
+ def _initialize_from_data(
375
+ self,
376
+ data: "ImageDataType",
377
+ mode: Optional[str] = None,
378
+ file_type: Optional[str] = None,
379
+ normalize: bool = True,
380
+ ) -> None:
381
+ pil_image = util.get_module(
382
+ "PIL.Image",
383
+ required='wandb.Image needs the PIL package. To get it, run "pip install pillow".',
384
+ )
385
+
386
+ accepted_formats = ["png", "jpg", "jpeg", "bmp"]
387
+ self.format = file_type or "png"
388
+
389
+ if self.format not in accepted_formats:
390
+ raise ValueError(f"file_type must be one of {accepted_formats}")
391
+
392
+ tmp_path = os.path.join(MEDIA_TMP.name, runid.generate_id() + "." + self.format)
393
+
394
+ if util.is_matplotlib_typename(util.get_full_typename(data)):
395
+ buf = BytesIO()
396
+ util.ensure_matplotlib_figure(data).savefig(buf, format=self.format)
397
+ self._image = pil_image.open(buf)
398
+ elif isinstance(data, pil_image.Image):
399
+ self._image = data
400
+ elif util.is_pytorch_tensor_typename(util.get_full_typename(data)):
401
+ if hasattr(data, "requires_grad") and data.requires_grad:
402
+ data = data.detach() # type: ignore
403
+ if hasattr(data, "dtype") and str(data.dtype) == "torch.uint8":
404
+ data = data.to(float) # type: ignore [union-attr]
405
+ mode = mode or self.guess_mode(data, file_type)
406
+ data = data.permute(1, 2, 0).cpu().numpy() # type: ignore [union-attr]
407
+
408
+ _warn_on_invalid_data_range(data, normalize)
409
+
410
+ data = _guess_and_rescale_to_0_255(data) if normalize else data # type: ignore [arg-type]
411
+ data = _convert_to_uint8(data)
412
+
413
+ if data.ndim > 2:
414
+ data = data.squeeze()
415
+
416
+ self._image = pil_image.fromarray(
417
+ data,
418
+ mode=mode,
419
+ )
420
+ else:
421
+ if hasattr(data, "numpy"): # TF data eager tensors
422
+ data = data.numpy()
423
+ if data.ndim > 2: # type: ignore [union-attr]
424
+ # get rid of trivial dimensions as a convenience
425
+ data = data.squeeze() # type: ignore [union-attr]
426
+
427
+ _warn_on_invalid_data_range(data, normalize) # type: ignore [arg-type]
428
+
429
+ mode = mode or self.guess_mode(data, file_type)
430
+ data = _guess_and_rescale_to_0_255(data) if normalize else data # type: ignore [arg-type]
431
+ data = _convert_to_uint8(data) # type: ignore [arg-type]
432
+ self._image = pil_image.fromarray(
433
+ data,
434
+ mode=mode,
435
+ )
436
+
437
+ assert self._image is not None
438
+ self._image.save(tmp_path, transparency=None)
439
+ self._set_file(tmp_path, is_tmp=True)
440
+
441
+ @classmethod
442
+ def from_json(
443
+ cls: Type["Image"], json_obj: dict, source_artifact: "Artifact"
444
+ ) -> "Image":
445
+ """Factory method to create an Audio object from a JSON object.
446
+
447
+ "<!-- lazydoc-ignore-classmethod: internal -->
448
+ """
449
+ classes: Optional[Classes] = None
450
+ if json_obj.get("classes") is not None:
451
+ value = source_artifact.get(json_obj["classes"]["path"])
452
+ assert isinstance(value, (type(None), Classes))
453
+ classes = value
454
+
455
+ masks = json_obj.get("masks")
456
+ _masks: Optional[Dict[str, ImageMask]] = None
457
+ if masks:
458
+ _masks = {}
459
+ for key in masks:
460
+ _masks[key] = ImageMask.from_json(masks[key], source_artifact)
461
+ _masks[key]._set_artifact_source(source_artifact)
462
+ _masks[key]._key = key
463
+
464
+ boxes = json_obj.get("boxes")
465
+ _boxes: Optional[Dict[str, BoundingBoxes2D]] = None
466
+ if boxes:
467
+ _boxes = {}
468
+ for key in boxes:
469
+ _boxes[key] = BoundingBoxes2D.from_json(boxes[key], source_artifact)
470
+ _boxes[key]._key = key
471
+
472
+ return cls(
473
+ source_artifact.get_entry(json_obj["path"]).download(),
474
+ caption=json_obj.get("caption"),
475
+ grouping=json_obj.get("grouping"),
476
+ classes=classes,
477
+ boxes=_boxes,
478
+ masks=_masks,
479
+ )
480
+
481
+ @classmethod
482
+ def get_media_subdir(cls: Type["Image"]) -> str:
483
+ """Get media subdirectory.
484
+
485
+ "<!-- lazydoc-ignore-classmethod: internal -->
486
+ """
487
+ return os.path.join("media", "images")
488
+
489
+ def bind_to_run(
490
+ self,
491
+ run: "wandb.Run",
492
+ key: Union[int, str],
493
+ step: Union[int, str],
494
+ id_: Optional[Union[int, str]] = None,
495
+ ignore_copy_err: Optional[bool] = None,
496
+ ) -> None:
497
+ """Bind this object to a run.
498
+
499
+ <!-- lazydoc-ignore: internal -->
500
+ """
501
+ # For Images, we are going to avoid copying the image file to the run.
502
+ # We should make this common functionality for all media types, but that
503
+ # requires a broader UI refactor. This model can easily be moved to the
504
+ # higher level Media class, but that will require every UI surface area
505
+ # that depends on the `path` to be able to instead consume
506
+ # `artifact_path`. I (Tim) think the media panel makes up most of this
507
+ # space, but there are also custom charts, and maybe others. Let's
508
+ # commit to getting all that fixed up before moving this to the top
509
+ # level Media class.
510
+ if self.path_is_reference(self._path):
511
+ raise ValueError(
512
+ "Image media created by a reference to external storage cannot currently be added to a run"
513
+ )
514
+
515
+ if (
516
+ not _server_accepts_artifact_path(run)
517
+ or self._get_artifact_entry_ref_url() is None
518
+ ):
519
+ super().bind_to_run(run, key, step, id_, ignore_copy_err=ignore_copy_err)
520
+ if self._boxes is not None:
521
+ for i, k in enumerate(self._boxes):
522
+ id_ = f"{id_}{i}" if id_ is not None else None
523
+ self._boxes[k].bind_to_run(
524
+ run, key, step, id_, ignore_copy_err=ignore_copy_err
525
+ )
526
+
527
+ if self._masks is not None:
528
+ for i, k in enumerate(self._masks):
529
+ id_ = f"{id_}{i}" if id_ is not None else None
530
+ self._masks[k].bind_to_run(
531
+ run, key, step, id_, ignore_copy_err=ignore_copy_err
532
+ )
533
+
534
+ def to_json(self, run_or_artifact: Union["wandb.Run", "Artifact"]) -> dict:
535
+ """Returns the JSON representation expected by the backend.
536
+
537
+ <!-- lazydoc-ignore: internal -->
538
+ """
539
+ json_dict = super().to_json(run_or_artifact)
540
+ json_dict["_type"] = Image._log_type
541
+ json_dict["format"] = self.format
542
+
543
+ if self._width is not None:
544
+ json_dict["width"] = self._width
545
+ if self._height is not None:
546
+ json_dict["height"] = self._height
547
+ if self._grouping:
548
+ json_dict["grouping"] = self._grouping
549
+
550
+ if isinstance(run_or_artifact, wandb.Artifact):
551
+ artifact = run_or_artifact
552
+ if (
553
+ self._masks is not None or self._boxes is not None
554
+ ) and self._classes is None:
555
+ raise ValueError(
556
+ "classes must be passed to wandb.Image which have masks or bounding boxes when adding to artifacts"
557
+ )
558
+
559
+ if self._classes is not None:
560
+ class_id = hashutil._md5(
561
+ str(self._classes._class_set).encode("utf-8")
562
+ ).hexdigest()
563
+ class_name = os.path.join(
564
+ "media",
565
+ "classes",
566
+ class_id + "_cls",
567
+ )
568
+ classes_entry = artifact.add(self._classes, class_name)
569
+ json_dict["classes"] = {
570
+ "type": "classes-file",
571
+ "path": classes_entry.path,
572
+ "digest": classes_entry.digest,
573
+ }
574
+
575
+ elif not isinstance(run_or_artifact, wandb.Run):
576
+ raise TypeError("to_json accepts wandb.Run or wandb_artifact.Artifact")
577
+
578
+ if self._boxes:
579
+ json_dict["boxes"] = {
580
+ k: box.to_json(run_or_artifact) for (k, box) in self._boxes.items()
581
+ }
582
+ if self._masks:
583
+ json_dict["masks"] = {
584
+ k: mask.to_json(run_or_artifact) for (k, mask) in self._masks.items()
585
+ }
586
+ return json_dict
587
+
588
+ def guess_mode(
589
+ self,
590
+ data: Union["np.ndarray", "torch.Tensor"],
591
+ file_type: Optional[str] = None,
592
+ ) -> str:
593
+ """Guess what type of image the np.array is representing.
594
+
595
+ <!-- lazydoc-ignore: internal -->
596
+ """
597
+ # TODO: do we want to support dimensions being at the beginning of the array?
598
+ ndims = data.ndim
599
+ if util.is_pytorch_tensor_typename(util.get_full_typename(data)):
600
+ # Torch tenors typically have the channels dimension first
601
+ num_channels = data.shape[0]
602
+ else:
603
+ num_channels = data.shape[-1]
604
+
605
+ if ndims == 2 or num_channels == 1:
606
+ return "L"
607
+ elif num_channels == 3:
608
+ return "RGB"
609
+ elif num_channels == 4:
610
+ if file_type in ["jpg", "jpeg"]:
611
+ wandb.termwarn(
612
+ "JPEG format does not support transparency. "
613
+ "Ignoring alpha channel.",
614
+ repeat=False,
615
+ )
616
+ return "RGB"
617
+ else:
618
+ return "RGBA"
619
+ else:
620
+ raise ValueError(
621
+ f"Un-supported shape for image conversion {list(data.shape)}"
622
+ )
623
+
624
+ @classmethod
625
+ def seq_to_json(
626
+ cls: Type["Image"],
627
+ seq: Sequence["BatchableMedia"],
628
+ run: "wandb.Run",
629
+ key: str,
630
+ step: Union[int, str],
631
+ ) -> dict:
632
+ """Convert a sequence of Image objects to a JSON representation.
633
+
634
+ "<!-- lazydoc-ignore-classmethod: internal -->
635
+ """
636
+ if TYPE_CHECKING:
637
+ seq = cast(Sequence["Image"], seq)
638
+
639
+ jsons = [obj.to_json(run) for obj in seq]
640
+
641
+ media_dir = cls.get_media_subdir()
642
+
643
+ for obj in jsons:
644
+ expected = LogicalPath(media_dir)
645
+ if "path" in obj and not obj["path"].startswith(expected):
646
+ raise ValueError(
647
+ "Files in an array of Image's must be in the {} directory, not {}".format(
648
+ cls.get_media_subdir(), obj["path"]
649
+ )
650
+ )
651
+
652
+ num_images_to_log = len(seq)
653
+ width, height = seq[0].image.size # type: ignore
654
+ format = jsons[0]["format"]
655
+
656
+ def size_equals_image(image: "Image") -> bool:
657
+ img_width, img_height = image.image.size # type: ignore
658
+ return img_width == width and img_height == height
659
+
660
+ sizes_match = all(size_equals_image(img) for img in seq)
661
+ if not sizes_match:
662
+ logging.warning(
663
+ "Images sizes do not match. This will causes images to be display incorrectly in the UI."
664
+ )
665
+
666
+ meta = {
667
+ "_type": "images/separated",
668
+ "width": width,
669
+ "height": height,
670
+ "format": format,
671
+ "count": num_images_to_log,
672
+ }
673
+ if _server_accepts_image_filenames(run):
674
+ meta["filenames"] = [
675
+ obj.get("path", obj.get("artifact_path")) for obj in jsons
676
+ ]
677
+ else:
678
+ wandb.termwarn(
679
+ "Unable to log image array filenames. In some cases, this can prevent images from being "
680
+ "viewed in the UI. Please upgrade your wandb server",
681
+ repeat=False,
682
+ )
683
+
684
+ captions = Image.all_captions(seq)
685
+
686
+ if captions:
687
+ meta["captions"] = captions
688
+
689
+ all_masks = Image.all_masks(seq, run, key, step)
690
+
691
+ if all_masks:
692
+ meta["all_masks"] = all_masks
693
+
694
+ all_boxes = Image.all_boxes(seq, run, key, step)
695
+
696
+ if all_boxes:
697
+ meta["all_boxes"] = all_boxes
698
+
699
+ return meta
700
+
701
+ @classmethod
702
+ def all_masks(
703
+ cls: Type["Image"],
704
+ images: Sequence["Image"],
705
+ run: "wandb.Run",
706
+ run_key: str,
707
+ step: Union[int, str],
708
+ ) -> Union[List[Optional[dict]], bool]:
709
+ """Collect all masks from a list of images.
710
+
711
+ "<!-- lazydoc-ignore-classmethod: internal -->
712
+ """
713
+ all_mask_groups: List[Optional[dict]] = []
714
+ for image in images:
715
+ if image._masks:
716
+ mask_group = {}
717
+ for k in image._masks:
718
+ mask = image._masks[k]
719
+ mask_group[k] = mask.to_json(run)
720
+ all_mask_groups.append(mask_group)
721
+ else:
722
+ all_mask_groups.append(None)
723
+ if all_mask_groups and not all(x is None for x in all_mask_groups):
724
+ return all_mask_groups
725
+ else:
726
+ return False
727
+
728
+ @classmethod
729
+ def all_boxes(
730
+ cls: Type["Image"],
731
+ images: Sequence["Image"],
732
+ run: "wandb.Run",
733
+ run_key: str,
734
+ step: Union[int, str],
735
+ ) -> Union[List[Optional[dict]], bool]:
736
+ """Collect all boxes from a list of images.
737
+
738
+ "<!-- lazydoc-ignore-classmethod: internal -->
739
+ """
740
+ all_box_groups: List[Optional[dict]] = []
741
+ for image in images:
742
+ if image._boxes:
743
+ box_group = {}
744
+ for k in image._boxes:
745
+ box = image._boxes[k]
746
+ box_group[k] = box.to_json(run)
747
+ all_box_groups.append(box_group)
748
+ else:
749
+ all_box_groups.append(None)
750
+ if all_box_groups and not all(x is None for x in all_box_groups):
751
+ return all_box_groups
752
+ else:
753
+ return False
754
+
755
+ @classmethod
756
+ def all_captions(
757
+ cls: Type["Image"], images: Sequence["Media"]
758
+ ) -> Union[bool, Sequence[Optional[str]]]:
759
+ """Get captions from a list of images.
760
+
761
+ "<!-- lazydoc-ignore-classmethod: internal -->
762
+ """
763
+ return cls.captions(images)
764
+
765
+ def __ne__(self, other: object) -> bool:
766
+ return not self.__eq__(other)
767
+
768
+ def __eq__(self, other: object) -> bool:
769
+ if not isinstance(other, Image):
770
+ return False
771
+ else:
772
+ if self.path_is_reference(self._path) and self.path_is_reference(
773
+ other._path
774
+ ):
775
+ return self._path == other._path
776
+ self_image = self.image
777
+ other_image = other.image
778
+ if self_image is not None:
779
+ self_image = list(self_image.getdata()) # type: ignore
780
+ if other_image is not None:
781
+ other_image = list(other_image.getdata()) # type: ignore
782
+
783
+ return (
784
+ self._grouping == other._grouping
785
+ and self._caption == other._caption
786
+ and self._width == other._width
787
+ and self._height == other._height
788
+ and self_image == other_image
789
+ and self._classes == other._classes
790
+ )
791
+
792
+ def to_data_array(self) -> List[Any]:
793
+ """Convert to data array.
794
+
795
+ <!-- lazydoc-ignore: internal -->
796
+ """
797
+ res = []
798
+ if self.image is not None:
799
+ data = list(self.image.getdata())
800
+ for i in range(self.image.height):
801
+ res.append(data[i * self.image.width : (i + 1) * self.image.width])
802
+ self._free_ram()
803
+ return res
804
+
805
+ def _free_ram(self) -> None:
806
+ if self._path is not None:
807
+ self._image = None
808
+
809
+ @property
810
+ def image(self) -> Optional["PILImage"]:
811
+ if self._image is None:
812
+ if self._path is not None and not self.path_is_reference(self._path):
813
+ pil_image = util.get_module(
814
+ "PIL.Image",
815
+ required='wandb.Image needs the PIL package. To get it, run "pip install pillow".',
816
+ )
817
+ self._image = pil_image.open(self._path)
818
+ self._image.load()
819
+ return self._image
820
+
821
+
822
+ # Custom dtypes for typing system
823
+ class _ImageFileType(_dtypes.Type):
824
+ name = "image-file"
825
+ legacy_names = ["wandb.Image"]
826
+ types = [Image]
827
+
828
+ def __init__(
829
+ self,
830
+ box_layers=None,
831
+ box_score_keys=None,
832
+ mask_layers=None,
833
+ class_map=None,
834
+ **kwargs,
835
+ ):
836
+ box_layers = box_layers or {}
837
+ box_score_keys = box_score_keys or []
838
+ mask_layers = mask_layers or {}
839
+ class_map = class_map or {}
840
+
841
+ if isinstance(box_layers, _dtypes.ConstType):
842
+ box_layers = box_layers._params["val"]
843
+ if not isinstance(box_layers, dict):
844
+ raise TypeError("box_layers must be a dict")
845
+ else:
846
+ box_layers = _dtypes.ConstType(
847
+ {layer_key: set(box_layers[layer_key]) for layer_key in box_layers}
848
+ )
849
+
850
+ if isinstance(mask_layers, _dtypes.ConstType):
851
+ mask_layers = mask_layers._params["val"]
852
+ if not isinstance(mask_layers, dict):
853
+ raise TypeError("mask_layers must be a dict")
854
+ else:
855
+ mask_layers = _dtypes.ConstType(
856
+ {layer_key: set(mask_layers[layer_key]) for layer_key in mask_layers}
857
+ )
858
+
859
+ if isinstance(box_score_keys, _dtypes.ConstType):
860
+ box_score_keys = box_score_keys._params["val"]
861
+ if not isinstance(box_score_keys, list) and not isinstance(box_score_keys, set):
862
+ raise TypeError("box_score_keys must be a list or a set")
863
+ else:
864
+ box_score_keys = _dtypes.ConstType(set(box_score_keys))
865
+
866
+ if isinstance(class_map, _dtypes.ConstType):
867
+ class_map = class_map._params["val"]
868
+ if not isinstance(class_map, dict):
869
+ raise TypeError("class_map must be a dict")
870
+ else:
871
+ class_map = _dtypes.ConstType(class_map)
872
+
873
+ self.params.update(
874
+ {
875
+ "box_layers": box_layers,
876
+ "box_score_keys": box_score_keys,
877
+ "mask_layers": mask_layers,
878
+ "class_map": class_map,
879
+ }
880
+ )
881
+
882
+ def assign_type(self, wb_type=None):
883
+ if isinstance(wb_type, _ImageFileType):
884
+ box_layers_self = self.params["box_layers"].params["val"] or {}
885
+ box_score_keys_self = self.params["box_score_keys"].params["val"] or []
886
+ mask_layers_self = self.params["mask_layers"].params["val"] or {}
887
+ class_map_self = self.params["class_map"].params["val"] or {}
888
+
889
+ box_layers_other = wb_type.params["box_layers"].params["val"] or {}
890
+ box_score_keys_other = wb_type.params["box_score_keys"].params["val"] or []
891
+ mask_layers_other = wb_type.params["mask_layers"].params["val"] or {}
892
+ class_map_other = wb_type.params["class_map"].params["val"] or {}
893
+
894
+ # Merge the class_ids from each set of box_layers
895
+ box_layers = {
896
+ str(key): set(
897
+ list(box_layers_self.get(key, []))
898
+ + list(box_layers_other.get(key, []))
899
+ )
900
+ for key in set(
901
+ list(box_layers_self.keys()) + list(box_layers_other.keys())
902
+ )
903
+ }
904
+
905
+ # Merge the class_ids from each set of mask_layers
906
+ mask_layers = {
907
+ str(key): set(
908
+ list(mask_layers_self.get(key, []))
909
+ + list(mask_layers_other.get(key, []))
910
+ )
911
+ for key in set(
912
+ list(mask_layers_self.keys()) + list(mask_layers_other.keys())
913
+ )
914
+ }
915
+
916
+ # Merge the box score keys
917
+ box_score_keys = set(list(box_score_keys_self) + list(box_score_keys_other))
918
+
919
+ # Merge the class_map
920
+ class_map = {
921
+ str(key): class_map_self.get(key, class_map_other.get(key, None))
922
+ for key in set(
923
+ list(class_map_self.keys()) + list(class_map_other.keys())
924
+ )
925
+ }
926
+
927
+ return _ImageFileType(box_layers, box_score_keys, mask_layers, class_map)
928
+
929
+ return _dtypes.InvalidType()
930
+
931
+ @classmethod
932
+ def from_obj(cls, py_obj):
933
+ if not isinstance(py_obj, Image):
934
+ raise TypeError("py_obj must be a wandb.Image")
935
+ else:
936
+ if hasattr(py_obj, "_boxes") and py_obj._boxes:
937
+ box_layers = {
938
+ str(key): set(py_obj._boxes[key]._class_labels.keys())
939
+ for key in py_obj._boxes.keys()
940
+ }
941
+ box_score_keys = {
942
+ key
943
+ for val in py_obj._boxes.values()
944
+ for box in val._val
945
+ for key in box.get("scores", {}).keys()
946
+ }
947
+
948
+ else:
949
+ box_layers = {}
950
+ box_score_keys = set()
951
+
952
+ if hasattr(py_obj, "_masks") and py_obj._masks:
953
+ mask_layers = {
954
+ str(key): set(
955
+ py_obj._masks[key]._val["class_labels"].keys()
956
+ if hasattr(py_obj._masks[key], "_val")
957
+ else []
958
+ )
959
+ for key in py_obj._masks.keys()
960
+ }
961
+ else:
962
+ mask_layers = {}
963
+
964
+ if hasattr(py_obj, "_classes") and py_obj._classes:
965
+ class_set = {
966
+ str(item["id"]): item["name"] for item in py_obj._classes._class_set
967
+ }
968
+ else:
969
+ class_set = {}
970
+
971
+ return cls(box_layers, box_score_keys, mask_layers, class_set)
972
+
973
+
974
+ _dtypes.TypeRegistry.add(_ImageFileType)