wandb 0.17.3__py3-none-any.whl → 0.17.5__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. wandb/__init__.py +1 -1
  2. wandb/apis/internal.py +4 -0
  3. wandb/cli/cli.py +7 -6
  4. wandb/env.py +16 -0
  5. wandb/filesync/upload_job.py +1 -1
  6. wandb/proto/v3/wandb_internal_pb2.py +339 -328
  7. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  8. wandb/proto/v4/wandb_internal_pb2.py +326 -323
  9. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  10. wandb/proto/v5/wandb_internal_pb2.py +326 -323
  11. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  12. wandb/sdk/artifacts/artifact.py +13 -24
  13. wandb/sdk/artifacts/artifact_file_cache.py +35 -13
  14. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +11 -6
  15. wandb/sdk/interface/interface.py +12 -5
  16. wandb/sdk/interface/interface_shared.py +9 -7
  17. wandb/sdk/internal/handler.py +1 -1
  18. wandb/sdk/internal/internal_api.py +67 -14
  19. wandb/sdk/internal/sender.py +9 -2
  20. wandb/sdk/launch/agent/agent.py +3 -1
  21. wandb/sdk/launch/builder/kaniko_builder.py +30 -9
  22. wandb/sdk/launch/inputs/internal.py +79 -2
  23. wandb/sdk/launch/inputs/manage.py +21 -3
  24. wandb/sdk/launch/sweeps/scheduler.py +2 -0
  25. wandb/sdk/lib/_settings_toposort_generated.py +3 -0
  26. wandb/sdk/lib/credentials.py +141 -0
  27. wandb/sdk/lib/tracelog.py +2 -2
  28. wandb/sdk/wandb_init.py +12 -2
  29. wandb/sdk/wandb_login.py +6 -0
  30. wandb/sdk/wandb_manager.py +34 -21
  31. wandb/sdk/wandb_run.py +100 -75
  32. wandb/sdk/wandb_settings.py +13 -2
  33. wandb/sdk/wandb_setup.py +12 -13
  34. wandb/util.py +29 -11
  35. {wandb-0.17.3.dist-info → wandb-0.17.5.dist-info}/METADATA +1 -1
  36. {wandb-0.17.3.dist-info → wandb-0.17.5.dist-info}/RECORD +39 -38
  37. {wandb-0.17.3.dist-info → wandb-0.17.5.dist-info}/WHEEL +0 -0
  38. {wandb-0.17.3.dist-info → wandb-0.17.5.dist-info}/entry_points.txt +0 -0
  39. {wandb-0.17.3.dist-info → wandb-0.17.5.dist-info}/licenses/LICENSE +0 -0
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
15
15
  from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
16
16
 
17
17
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n wandb/proto/wandb_settings.proto\x12\x0ewandb_internal\x1a\x1egoogle/protobuf/wrappers.proto\" \n\x0fListStringValue\x12\r\n\x05value\x18\x01 \x03(\t\"\x8a\x01\n\x17MapStringKeyStringValue\x12\x41\n\x05value\x18\x01 \x03(\x0b\x32\x32.wandb_internal.MapStringKeyStringValue.ValueEntry\x1a,\n\nValueEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xcb\x01\n#MapStringKeyMapStringKeyStringValue\x12M\n\x05value\x18\x01 \x03(\x0b\x32>.wandb_internal.MapStringKeyMapStringKeyStringValue.ValueEntry\x1aU\n\nValueEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue:\x02\x38\x01\"\x9a\x01\n\x12OpenMetricsFilters\x12\x33\n\x08sequence\x18\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValueH\x00\x12\x46\n\x07mapping\x18\x02 \x01(\x0b\x32\x33.wandb_internal.MapStringKeyMapStringKeyStringValueH\x00\x42\x07\n\x05value\"7\n\tRunMoment\x12\x0b\n\x03run\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x01\x12\x0e\n\x06metric\x18\x03 \x01(\t\"\xba\x45\n\x08Settings\x12-\n\x07\x61pi_key\x18\x37 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x08_offline\x18\x1e \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06run_id\x18k \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07run_url\x18q \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07project\x18\x61 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06\x65ntity\x18\x45 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x0b_start_time\x18) \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12-\n\x07log_dir\x18U \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0clog_internal\x18V \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\tfiles_dir\x18\x46 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0cignore_globs\x18N \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12:\n\x15_disable_update_check\x18\xa5\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\r_require_core\x18$ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12.\n\x05_args\x18\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12/\n\x0b_aws_lambda\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0e_cli_only_mode\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06_colab\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x05_cuda\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\r_disable_meta\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x34\n\x10_disable_service\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x39\n\x15_disable_setproctitle\x18\t \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0e_disable_stats\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\x0f_disable_viewer\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\x0b_executable\x18\r \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x44\n\x13_extra_http_headers\x18\x0e \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12\x42\n\x1c_file_stream_timeout_seconds\x18\x0f \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x38\n\x14_flow_control_custom\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12:\n\x16_flow_control_disabled\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12=\n\x17_internal_check_process\x18\x12 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12=\n\x17_internal_queue_timeout\x18\x13 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12,\n\x08_ipython\x18\x14 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x08_jupyter\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\r_jupyter_root\x18\x16 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x07_kaggle\x18\x17 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12<\n\x17_live_policy_rate_limit\x18\x18 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12;\n\x16_live_policy_wait_time\x18\x19 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12/\n\n_log_level\x18\x1a \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x34\n\x0f_network_buffer\x18\x1b \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12)\n\x05_noop\x18\x1c \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\t_notebook\x18\x1d \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12)\n\x05_sync\x18\x1f \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12)\n\x03_os\x18 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\t_platform\x18! \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07_python\x18\" \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x37\n\x11_runqueue_item_id\x18# \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x12_save_requirements\x18% \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x12_service_transport\x18& \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\r_service_wait\x18\' \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x35\n\x0f_start_datetime\x18( \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\n_stats_pid\x18* \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12@\n\x1a_stats_sample_rate_seconds\x18+ \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12>\n\x19_stats_samples_to_average\x18, \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x36\n\x12_stats_join_assets\x18- \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12G\n!_stats_neuron_monitor_config_path\x18. \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12N\n\x1d_stats_open_metrics_endpoints\x18/ \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12G\n\x1b_stats_open_metrics_filters\x18\x30 \x01(\x0b\x32\".wandb_internal.OpenMetricsFilters\x12\x33\n\r_tmp_code_dir\x18\x31 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\t_tracelog\x18\x32 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\r_unsaved_keys\x18\x33 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12,\n\x08_windows\x18\x34 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x34\n\x10\x61llow_val_change\x18\x35 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\tanonymous\x18\x36 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12P\n\x1f\x61zure_account_url_to_access_key\x18\x38 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12.\n\x08\x62\x61se_url\x18\x39 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08\x63ode_dir\x18: \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0c\x63onfig_paths\x18; \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12-\n\x07\x63onsole\x18< \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\ndeployment\x18= \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\x0c\x64isable_code\x18> \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x0b\x64isable_git\x18? \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\rdisable_hints\x18@ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x14\x64isable_job_creation\x18\x41 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x08\x64isabled\x18\x42 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06\x64ocker\x18\x43 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05\x65mail\x18\x44 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x05\x66orce\x18G \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\ngit_commit\x18H \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\ngit_remote\x18I \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\x0egit_remote_url\x18J \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08git_root\x18K \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x11heartbeat_seconds\x18L \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12*\n\x04host\x18M \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0cinit_timeout\x18O \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12,\n\x08is_local\x18P \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\njob_source\x18Q \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\rlabel_disable\x18R \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06launch\x18S \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x12launch_config_path\x18T \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x14log_symlink_internal\x18W \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x10log_symlink_user\x18X \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08log_user\x18Y \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rlogin_timeout\x18Z \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12*\n\x04mode\x18\\ \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rnotebook_name\x18] \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07program\x18_ \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0fprogram_relpath\x18` \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x0bproject_url\x18\x62 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x05quiet\x18\x63 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06reinit\x18\x64 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07relogin\x18\x65 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06resume\x18\x66 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0cresume_fname\x18g \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x07resumed\x18h \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tfork_from\x18\xa4\x01 \x01(\x0b\x32\x19.wandb_internal.RunMoment\x12/\n\x0bresume_from\x18\xa7\x01 \x01(\x0b\x32\x19.wandb_internal.RunMoment\x12.\n\x08root_dir\x18i \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\trun_group\x18j \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0crun_job_type\x18l \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08run_mode\x18m \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08run_name\x18n \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\trun_notes\x18o \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x08run_tags\x18p \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12\x35\n\x11sagemaker_disable\x18r \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tsave_code\x18s \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x35\n\x0fsettings_system\x18t \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x38\n\x12settings_workspace\x18u \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x0bshow_colors\x18v \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12.\n\nshow_emoji\x18w \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x0bshow_errors\x18x \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tshow_info\x18y \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\rshow_warnings\x18z \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06silent\x18{ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0cstart_method\x18| \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12*\n\x06strict\x18} \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\x0esummary_errors\x18~ \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x34\n\x0fsummary_timeout\x18\x7f \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x36\n\x10summary_warnings\x18\x80\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12/\n\x08sweep_id\x18\x81\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x37\n\x10sweep_param_path\x18\x82\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tsweep_url\x18\x83\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x07symlink\x18\x84\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x08sync_dir\x18\x85\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tsync_file\x18\x86\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x13sync_symlink_latest\x18\x87\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rsystem_sample\x18\x88\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12;\n\x15system_sample_seconds\x18\x89\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12J\n%table_raise_on_max_row_limit_exceeded\x18\x8a\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x08timespec\x18\x8b\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x07tmp_dir\x18\x8c\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x08username\x18\x8d\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\twandb_dir\x18\x8e\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\r_jupyter_name\x18\x8f\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\r_jupyter_path\x18\x90\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x08job_name\x18\x91\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12;\n\x11_stats_disk_paths\x18\x92\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12<\n\x16_file_stream_retry_max\x18\x93\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12J\n#_file_stream_retry_wait_min_seconds\x18\x94\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12J\n#_file_stream_retry_wait_max_seconds\x18\x95\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12>\n\x18_file_transfer_retry_max\x18\x96\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12L\n%_file_transfer_retry_wait_min_seconds\x18\x97\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12L\n%_file_transfer_retry_wait_max_seconds\x18\x98\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x45\n\x1e_file_transfer_timeout_seconds\x18\x99\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x38\n\x12_graphql_retry_max\x18\x9a\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x46\n\x1f_graphql_retry_wait_min_seconds\x18\x9b\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x46\n\x1f_graphql_retry_wait_max_seconds\x18\x9c\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12?\n\x18_graphql_timeout_seconds\x18\x9d\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12:\n\x15_disable_machine_info\x18\x9e\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x36\n\x0fprogram_abspath\x18\x9f\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tcolab_url\x18\xa0\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x38\n\x12_stats_buffer_size\x18\xa1\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12,\n\x07_shared\x18\xa2\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x37\n\x10_code_path_local\x18\xa3\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x11\x63onsole_multipart\x18\xa6\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\nhttp_proxy\x18\xa8\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0bhttps_proxy\x18\xa9\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x08_proxies\x18\xc8\x01 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValueJ\x04\x08\x0c\x10\rJ\x04\x08^\x10_b\x06proto3')
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n wandb/proto/wandb_settings.proto\x12\x0ewandb_internal\x1a\x1egoogle/protobuf/wrappers.proto\" \n\x0fListStringValue\x12\r\n\x05value\x18\x01 \x03(\t\"\x8a\x01\n\x17MapStringKeyStringValue\x12\x41\n\x05value\x18\x01 \x03(\x0b\x32\x32.wandb_internal.MapStringKeyStringValue.ValueEntry\x1a,\n\nValueEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xcb\x01\n#MapStringKeyMapStringKeyStringValue\x12M\n\x05value\x18\x01 \x03(\x0b\x32>.wandb_internal.MapStringKeyMapStringKeyStringValue.ValueEntry\x1aU\n\nValueEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue:\x02\x38\x01\"\x9a\x01\n\x12OpenMetricsFilters\x12\x33\n\x08sequence\x18\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValueH\x00\x12\x46\n\x07mapping\x18\x02 \x01(\x0b\x32\x33.wandb_internal.MapStringKeyMapStringKeyStringValueH\x00\x42\x07\n\x05value\"7\n\tRunMoment\x12\x0b\n\x03run\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x01\x12\x0e\n\x06metric\x18\x03 \x01(\t\"\xed\x46\n\x08Settings\x12-\n\x07\x61pi_key\x18\x37 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x08_offline\x18\x1e \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06run_id\x18k \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07run_url\x18q \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07project\x18\x61 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06\x65ntity\x18\x45 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x0b_start_time\x18) \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12-\n\x07log_dir\x18U \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0clog_internal\x18V \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\tfiles_dir\x18\x46 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0cignore_globs\x18N \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12:\n\x15_disable_update_check\x18\xa5\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\r_require_core\x18$ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12:\n\x13identity_token_file\x18\xaa\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x37\n\x10\x63redentials_file\x18\xab\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12<\n\x16_file_stream_max_bytes\x18\xac\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12.\n\x05_args\x18\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12/\n\x0b_aws_lambda\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0e_cli_only_mode\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06_colab\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x05_cuda\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\r_disable_meta\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x34\n\x10_disable_service\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x39\n\x15_disable_setproctitle\x18\t \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0e_disable_stats\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\x0f_disable_viewer\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\x0b_executable\x18\r \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x44\n\x13_extra_http_headers\x18\x0e \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12\x42\n\x1c_file_stream_timeout_seconds\x18\x0f \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x38\n\x14_flow_control_custom\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12:\n\x16_flow_control_disabled\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12=\n\x17_internal_check_process\x18\x12 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12=\n\x17_internal_queue_timeout\x18\x13 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12,\n\x08_ipython\x18\x14 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x08_jupyter\x18\x15 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\r_jupyter_root\x18\x16 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x07_kaggle\x18\x17 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12<\n\x17_live_policy_rate_limit\x18\x18 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12;\n\x16_live_policy_wait_time\x18\x19 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12/\n\n_log_level\x18\x1a \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x34\n\x0f_network_buffer\x18\x1b \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12)\n\x05_noop\x18\x1c \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\t_notebook\x18\x1d \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12)\n\x05_sync\x18\x1f \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12)\n\x03_os\x18 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\t_platform\x18! \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07_python\x18\" \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x37\n\x11_runqueue_item_id\x18# \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x12_save_requirements\x18% \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x12_service_transport\x18& \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\r_service_wait\x18\' \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x35\n\x0f_start_datetime\x18( \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\n_stats_pid\x18* \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12@\n\x1a_stats_sample_rate_seconds\x18+ \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12>\n\x19_stats_samples_to_average\x18, \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x36\n\x12_stats_join_assets\x18- \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12G\n!_stats_neuron_monitor_config_path\x18. \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12N\n\x1d_stats_open_metrics_endpoints\x18/ \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12G\n\x1b_stats_open_metrics_filters\x18\x30 \x01(\x0b\x32\".wandb_internal.OpenMetricsFilters\x12\x33\n\r_tmp_code_dir\x18\x31 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\t_tracelog\x18\x32 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\r_unsaved_keys\x18\x33 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12,\n\x08_windows\x18\x34 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x34\n\x10\x61llow_val_change\x18\x35 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\tanonymous\x18\x36 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12P\n\x1f\x61zure_account_url_to_access_key\x18\x38 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValue\x12.\n\x08\x62\x61se_url\x18\x39 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08\x63ode_dir\x18: \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0c\x63onfig_paths\x18; \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12-\n\x07\x63onsole\x18< \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\ndeployment\x18= \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\x0c\x64isable_code\x18> \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x0b\x64isable_git\x18? \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\rdisable_hints\x18@ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x14\x64isable_job_creation\x18\x41 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x08\x64isabled\x18\x42 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06\x64ocker\x18\x43 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05\x65mail\x18\x44 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x05\x66orce\x18G \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\ngit_commit\x18H \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\ngit_remote\x18I \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\x0egit_remote_url\x18J \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08git_root\x18K \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x11heartbeat_seconds\x18L \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12*\n\x04host\x18M \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0cinit_timeout\x18O \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12,\n\x08is_local\x18P \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\njob_source\x18Q \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\rlabel_disable\x18R \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06launch\x18S \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x38\n\x12launch_config_path\x18T \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x14log_symlink_internal\x18W \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x10log_symlink_user\x18X \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08log_user\x18Y \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rlogin_timeout\x18Z \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12*\n\x04mode\x18\\ \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rnotebook_name\x18] \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07program\x18_ \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0fprogram_relpath\x18` \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x0bproject_url\x18\x62 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x05quiet\x18\x63 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06reinit\x18\x64 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07relogin\x18\x65 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12,\n\x06resume\x18\x66 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0cresume_fname\x18g \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x07resumed\x18h \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tfork_from\x18\xa4\x01 \x01(\x0b\x32\x19.wandb_internal.RunMoment\x12/\n\x0bresume_from\x18\xa7\x01 \x01(\x0b\x32\x19.wandb_internal.RunMoment\x12.\n\x08root_dir\x18i \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\trun_group\x18j \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0crun_job_type\x18l \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08run_mode\x18m \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x08run_name\x18n \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\trun_notes\x18o \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x31\n\x08run_tags\x18p \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12\x35\n\x11sagemaker_disable\x18r \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tsave_code\x18s \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x35\n\x0fsettings_system\x18t \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x38\n\x12settings_workspace\x18u \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x0bshow_colors\x18v \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12.\n\nshow_emoji\x18w \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x0bshow_errors\x18x \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12-\n\tshow_info\x18y \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\rshow_warnings\x18z \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06silent\x18{ \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x32\n\x0cstart_method\x18| \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12*\n\x06strict\x18} \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x33\n\x0esummary_errors\x18~ \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x34\n\x0fsummary_timeout\x18\x7f \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x36\n\x10summary_warnings\x18\x80\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12/\n\x08sweep_id\x18\x81\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x37\n\x10sweep_param_path\x18\x82\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tsweep_url\x18\x83\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x07symlink\x18\x84\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x08sync_dir\x18\x85\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tsync_file\x18\x86\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x13sync_symlink_latest\x18\x87\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x33\n\rsystem_sample\x18\x88\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12;\n\x15system_sample_seconds\x18\x89\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12J\n%table_raise_on_max_row_limit_exceeded\x18\x8a\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12/\n\x08timespec\x18\x8b\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x07tmp_dir\x18\x8c\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x08username\x18\x8d\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\twandb_dir\x18\x8e\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\r_jupyter_name\x18\x8f\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x34\n\r_jupyter_path\x18\x90\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12/\n\x08job_name\x18\x91\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12;\n\x11_stats_disk_paths\x18\x92\x01 \x01(\x0b\x32\x1f.wandb_internal.ListStringValue\x12<\n\x16_file_stream_retry_max\x18\x93\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12J\n#_file_stream_retry_wait_min_seconds\x18\x94\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12J\n#_file_stream_retry_wait_max_seconds\x18\x95\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12>\n\x18_file_transfer_retry_max\x18\x96\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12L\n%_file_transfer_retry_wait_min_seconds\x18\x97\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12L\n%_file_transfer_retry_wait_max_seconds\x18\x98\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x45\n\x1e_file_transfer_timeout_seconds\x18\x99\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x38\n\x12_graphql_retry_max\x18\x9a\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x46\n\x1f_graphql_retry_wait_min_seconds\x18\x9b\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x46\n\x1f_graphql_retry_wait_max_seconds\x18\x9c\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12?\n\x18_graphql_timeout_seconds\x18\x9d\x01 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12:\n\x15_disable_machine_info\x18\x9e\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x36\n\x0fprogram_abspath\x18\x9f\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\tcolab_url\x18\xa0\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x38\n\x12_stats_buffer_size\x18\xa1\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12,\n\x07_shared\x18\xa2\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x37\n\x10_code_path_local\x18\xa3\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x11\x63onsole_multipart\x18\xa6\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x31\n\nhttp_proxy\x18\xa8\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0bhttps_proxy\x18\xa9\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12:\n\x08_proxies\x18\xc8\x01 \x01(\x0b\x32\'.wandb_internal.MapStringKeyStringValueJ\x04\x08\x0c\x10\rJ\x04\x08^\x10_b\x06proto3')
19
19
 
20
20
  _globals = globals()
21
21
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -41,5 +41,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
41
41
  _globals['_RUNMOMENT']._serialized_start=622
42
42
  _globals['_RUNMOMENT']._serialized_end=677
43
43
  _globals['_SETTINGS']._serialized_start=680
44
- _globals['_SETTINGS']._serialized_end=9570
44
+ _globals['_SETTINGS']._serialized_end=9749
45
45
  # @@protoc_insertion_point(module_scope)
@@ -1300,7 +1300,8 @@ class Artifact:
1300
1300
  automatic integrity validation. Disabling checksumming will speed up
1301
1301
  artifact creation but reference directories will not iterated through so the
1302
1302
  objects in the directory will not be saved to the artifact. We recommend
1303
- adding reference objects in the case checksumming is false.
1303
+ setting `checksum=False` when adding reference objects, in which case
1304
+ a new version will only be created if the reference URI changes.
1304
1305
  max_objects: The maximum number of objects to consider when adding a
1305
1306
  reference that points to directory or bucket store prefix. By default,
1306
1307
  the maximum number of objects allowed for Amazon S3,
@@ -1627,16 +1628,19 @@ class Artifact:
1627
1628
  ) -> FilePathStr:
1628
1629
  """Download the contents of the artifact to the specified root directory.
1629
1630
 
1630
- Existing files located within `root` are not modified. Explicitly delete
1631
- `root` before you call `download` if you want the contents of `root` to exactly
1632
- match the artifact.
1631
+ Existing files located within `root` are not modified. Explicitly delete `root`
1632
+ before you call `download` if you want the contents of `root` to exactly match
1633
+ the artifact.
1633
1634
 
1634
1635
  Arguments:
1635
1636
  root: The directory W&B stores the artifact's files.
1636
1637
  allow_missing_references: If set to `True`, any invalid reference paths
1637
1638
  will be ignored while downloading referenced files.
1638
- skip_cache: If set to `True`, the artifact cache will be skipped when downloading
1639
- and W&B will download each file into the default root or specified download directory.
1639
+ skip_cache: If set to `True`, the artifact cache will be skipped when
1640
+ downloading and W&B will download each file into the default root or
1641
+ specified download directory.
1642
+ path_prefix: If specified, only files with a path that starts with the given
1643
+ prefix will be downloaded. Uses unix format (forward slashes).
1640
1644
 
1641
1645
  Returns:
1642
1646
  The path to the downloaded contents.
@@ -1653,6 +1657,8 @@ class Artifact:
1653
1657
  return self._download_using_core(
1654
1658
  root=root,
1655
1659
  allow_missing_references=allow_missing_references,
1660
+ skip_cache=bool(skip_cache),
1661
+ path_prefix=path_prefix,
1656
1662
  )
1657
1663
  return self._download(
1658
1664
  root=root,
@@ -1661,23 +1667,6 @@ class Artifact:
1661
1667
  path_prefix=path_prefix,
1662
1668
  )
1663
1669
 
1664
- @classmethod
1665
- def path_contains_dir_prefix(cls, path: StrPath, dir_path: StrPath) -> bool:
1666
- """Returns true if `path` contains `dir_path` as a prefix."""
1667
- if not dir_path:
1668
- return True
1669
- path_parts = PurePosixPath(path).parts
1670
- dir_parts = PurePosixPath(dir_path).parts
1671
- return path_parts[: len(dir_parts)] == dir_parts
1672
-
1673
- @classmethod
1674
- def should_download_entry(
1675
- cls, entry: ArtifactManifestEntry, prefix: Optional[StrPath]
1676
- ) -> bool:
1677
- if prefix is None:
1678
- return True
1679
- return cls.path_contains_dir_prefix(entry.path, prefix)
1680
-
1681
1670
  def _download_using_core(
1682
1671
  self,
1683
1672
  root: str,
@@ -1814,7 +1803,7 @@ class Artifact:
1814
1803
  # Handled by core
1815
1804
  continue
1816
1805
  entry._download_url = edge["node"]["directUrl"]
1817
- if self.should_download_entry(entry, prefix=path_prefix):
1806
+ if (not path_prefix) or entry.path.startswith(str(path_prefix)):
1818
1807
  active_futures.add(executor.submit(download_entry, entry))
1819
1808
  # Wait for download threads to catch up.
1820
1809
  max_backlog = fetch_url_batch_size
@@ -9,7 +9,7 @@ import subprocess
9
9
  import sys
10
10
  from pathlib import Path
11
11
  from tempfile import NamedTemporaryFile
12
- from typing import IO, TYPE_CHECKING, ContextManager, Generator, Optional, Tuple
12
+ from typing import IO, TYPE_CHECKING, ContextManager, Iterator, Optional, Tuple
13
13
 
14
14
  import wandb
15
15
  from wandb import env, util
@@ -29,6 +29,15 @@ if TYPE_CHECKING:
29
29
  pass
30
30
 
31
31
 
32
+ def _get_sys_umask_threadsafe() -> int:
33
+ # Workaround to get the current system umask, since
34
+ # - `os.umask()` isn't thread-safe
35
+ # - we don't want to inadvertently change the umask of the current process
36
+ # See: https://stackoverflow.com/questions/53227072/reading-umask-thread-safe
37
+ umask_cmd = (sys.executable, "-c", "import os; print(os.umask(22))")
38
+ return int(subprocess.check_output(umask_cmd))
39
+
40
+
32
41
  class ArtifactFileCache:
33
42
  def __init__(self, cache_dir: StrPath) -> None:
34
43
  self._cache_dir = Path(cache_dir)
@@ -38,21 +47,22 @@ class ArtifactFileCache:
38
47
 
39
48
  # NamedTemporaryFile sets the file mode to 600 [1], we reset to the default.
40
49
  # [1] https://stackoverflow.com/questions/10541760/can-i-set-the-umask-for-tempfile-namedtemporaryfile-in-python
41
- umask_cmd = (sys.executable, "-c", "import os; print(os.umask(22))")
42
- umask = int(subprocess.check_output(umask_cmd))
43
- self._sys_umask = umask
50
+ self._sys_umask = _get_sys_umask_threadsafe()
44
51
 
45
52
  self._override_cache_path: Optional[StrPath] = None
46
53
 
47
54
  def check_md5_obj_path(
48
55
  self, b64_md5: B64MD5, size: int
49
56
  ) -> Tuple[FilePathStr, bool, "Opener"]:
57
+ # Check if we're using vs skipping the cache
50
58
  if self._override_cache_path is not None:
59
+ skip_cache = True
51
60
  path = Path(self._override_cache_path)
52
61
  else:
62
+ skip_cache = False
53
63
  hex_md5 = b64_to_hex_id(b64_md5)
54
64
  path = self._obj_dir / "md5" / hex_md5[:2] / hex_md5[2:]
55
- return self._check_or_create(path, size)
65
+ return self._check_or_create(path, size, skip_cache=skip_cache)
56
66
 
57
67
  # TODO(spencerpearson): this method at least needs its signature changed.
58
68
  # An ETag is not (necessarily) a checksum.
@@ -62,20 +72,23 @@ class ArtifactFileCache:
62
72
  etag: ETag,
63
73
  size: int,
64
74
  ) -> Tuple[FilePathStr, bool, "Opener"]:
75
+ # Check if we're using vs skipping the cache
65
76
  if self._override_cache_path is not None:
77
+ skip_cache = True
66
78
  path = Path(self._override_cache_path)
67
79
  else:
80
+ skip_cache = False
68
81
  hexhash = hashlib.sha256(
69
82
  hashlib.sha256(url.encode("utf-8")).digest()
70
83
  + hashlib.sha256(etag.encode("utf-8")).digest()
71
84
  ).hexdigest()
72
85
  path = self._obj_dir / "etag" / hexhash[:2] / hexhash[2:]
73
- return self._check_or_create(path, size)
86
+ return self._check_or_create(path, size, skip_cache=skip_cache)
74
87
 
75
88
  def _check_or_create(
76
- self, path: Path, size: int
89
+ self, path: Path, size: int, skip_cache: bool = False
77
90
  ) -> Tuple[FilePathStr, bool, "Opener"]:
78
- opener = self._cache_opener(path, size)
91
+ opener = self._opener(path, size, skip_cache=skip_cache)
79
92
  hit = path.is_file() and path.stat().st_size == size
80
93
  return FilePathStr(str(path)), hit, opener
81
94
 
@@ -185,14 +198,23 @@ class ArtifactFileCache:
185
198
  if size > self._free_space():
186
199
  raise OSError(errno.ENOSPC, f"Insufficient free space in {self._cache_dir}")
187
200
 
188
- def _cache_opener(self, path: Path, size: int) -> "Opener":
201
+ def _opener(self, path: Path, size: int, skip_cache: bool = False) -> "Opener":
189
202
  @contextlib.contextmanager
190
- def helper(mode: str = "w") -> Generator[IO, None, None]:
203
+ def atomic_open(mode: str = "w") -> Iterator[IO]:
191
204
  if "a" in mode:
192
205
  raise ValueError("Appending to cache files is not supported")
193
206
 
194
- self._reserve_space(size)
195
- temp_file = NamedTemporaryFile(dir=self._temp_dir, mode=mode, delete=False)
207
+ if skip_cache:
208
+ # We skip the cache, but we'll still need an intermediate, temporary file to ensure atomicity.
209
+ # Put the temp file in the same root as the destination file in an attempt to avoid moving/copying
210
+ # across filesystems.
211
+ temp_dir = path.parent
212
+ else:
213
+ self._reserve_space(size)
214
+ temp_dir = self._temp_dir
215
+
216
+ temp_dir.mkdir(parents=True, exist_ok=True)
217
+ temp_file = NamedTemporaryFile(dir=temp_dir, mode=mode, delete=False)
196
218
  try:
197
219
  yield temp_file
198
220
  temp_file.close()
@@ -203,7 +225,7 @@ class ArtifactFileCache:
203
225
  os.remove(temp_file.name)
204
226
  raise
205
227
 
206
- return helper
228
+ return atomic_open
207
229
 
208
230
  def _ensure_write_permissions(self) -> None:
209
231
  """Raise an error if we cannot write to the cache directory."""
@@ -118,7 +118,9 @@ class WandbStoragePolicy(StoragePolicy):
118
118
  manifest_entry: "ArtifactManifestEntry",
119
119
  dest_path: Optional[str] = None,
120
120
  ) -> FilePathStr:
121
- self._cache._override_cache_path = dest_path
121
+ if dest_path is not None:
122
+ self._cache._override_cache_path = dest_path
123
+
122
124
  path, hit, cache_open = self._cache.check_md5_obj_path(
123
125
  B64MD5(manifest_entry.digest), # TODO(spencerpearson): unsafe cast
124
126
  manifest_entry.size if manifest_entry.size is not None else 0,
@@ -135,14 +137,17 @@ class WandbStoragePolicy(StoragePolicy):
135
137
  manifest_entry._download_url = None
136
138
  if manifest_entry._download_url is None:
137
139
  auth = None
138
- if not _thread_local_api_settings.cookies:
139
- assert self._api.api_key is not None
140
- auth = ("api", self._api.api_key)
140
+ http_headers = _thread_local_api_settings.headers or {}
141
+ if self._api.access_token is not None:
142
+ http_headers["Authorization"] = f"Bearer {self._api.access_token}"
143
+ elif _thread_local_api_settings.cookies is None:
144
+ auth = ("api", self._api.api_key or "")
145
+
141
146
  response = self._session.get(
142
147
  self._file_url(self._api, artifact.entity, manifest_entry),
143
148
  auth=auth,
144
149
  cookies=_thread_local_api_settings.cookies,
145
- headers=_thread_local_api_settings.headers,
150
+ headers=http_headers,
146
151
  stream=True,
147
152
  )
148
153
  response.raise_for_status()
@@ -172,7 +177,7 @@ class WandbStoragePolicy(StoragePolicy):
172
177
  ) -> Union[FilePathStr, URIStr]:
173
178
  assert manifest_entry.ref is not None
174
179
  used_handler = self._handler._get_handler(manifest_entry.ref)
175
- if hasattr(used_handler, "_cache"):
180
+ if hasattr(used_handler, "_cache") and (dest_path is not None):
176
181
  used_handler._cache._override_cache_path = dest_path
177
182
  return self._handler.load_path(manifest_entry, local)
178
183
 
@@ -358,7 +358,7 @@ class InterfaceBase:
358
358
  proto_extra.value_json = json.dumps(v)
359
359
  return proto_manifest
360
360
 
361
- def publish_link_artifact(
361
+ def deliver_link_artifact(
362
362
  self,
363
363
  run: "Run",
364
364
  artifact: "Artifact",
@@ -366,8 +366,8 @@ class InterfaceBase:
366
366
  aliases: Iterable[str],
367
367
  entity: Optional[str] = None,
368
368
  project: Optional[str] = None,
369
- ) -> None:
370
- link_artifact = pb.LinkArtifactRecord()
369
+ ) -> MailboxHandle:
370
+ link_artifact = pb.LinkArtifactRequest()
371
371
  if artifact.is_draft():
372
372
  link_artifact.client_id = artifact._client_id
373
373
  else:
@@ -377,10 +377,12 @@ class InterfaceBase:
377
377
  link_artifact.portfolio_project = project or run.project
378
378
  link_artifact.portfolio_aliases.extend(aliases)
379
379
 
380
- self._publish_link_artifact(link_artifact)
380
+ return self._deliver_link_artifact(link_artifact)
381
381
 
382
382
  @abstractmethod
383
- def _publish_link_artifact(self, link_artifact: pb.LinkArtifactRecord) -> None:
383
+ def _deliver_link_artifact(
384
+ self, link_artifact: pb.LinkArtifactRequest
385
+ ) -> MailboxHandle:
384
386
  raise NotImplementedError
385
387
 
386
388
  @staticmethod
@@ -749,6 +751,7 @@ class InterfaceBase:
749
751
  self,
750
752
  include_paths: List[List[str]],
751
753
  exclude_paths: List[List[str]],
754
+ input_schema: Optional[dict],
752
755
  run_config: bool = False,
753
756
  file_path: str = "",
754
757
  ):
@@ -766,6 +769,8 @@ class InterfaceBase:
766
769
  Args:
767
770
  include_paths: paths within config to include as job inputs.
768
771
  exclude_paths: paths within config to exclude as job inputs.
772
+ input_schema: A JSON Schema describing which attributes will be
773
+ editable from the Launch drawer.
769
774
  run_config: bool indicating whether wandb.config is the input source.
770
775
  file_path: path to file to include as a job input.
771
776
  """
@@ -788,6 +793,8 @@ class InterfaceBase:
788
793
  pb.JobInputSource.ConfigFileSource(path=file_path),
789
794
  )
790
795
  request.input_source.CopyFrom(source)
796
+ if input_schema:
797
+ request.input_schema = json_dumps_safer(input_schema)
791
798
 
792
799
  return self._publish_job_input(request)
793
800
 
@@ -137,6 +137,7 @@ class InterfaceShared(InterfaceBase):
137
137
  check_version: Optional[pb.CheckVersionRequest] = None,
138
138
  log_artifact: Optional[pb.LogArtifactRequest] = None,
139
139
  download_artifact: Optional[pb.DownloadArtifactRequest] = None,
140
+ link_artifact: Optional[pb.LinkArtifactRequest] = None,
140
141
  defer: Optional[pb.DeferRequest] = None,
141
142
  attach: Optional[pb.AttachRequest] = None,
142
143
  server_info: Optional[pb.ServerInfoRequest] = None,
@@ -184,6 +185,8 @@ class InterfaceShared(InterfaceBase):
184
185
  request.log_artifact.CopyFrom(log_artifact)
185
186
  elif download_artifact:
186
187
  request.download_artifact.CopyFrom(download_artifact)
188
+ elif link_artifact:
189
+ request.link_artifact.CopyFrom(link_artifact)
187
190
  elif defer:
188
191
  request.defer.CopyFrom(defer)
189
192
  elif attach:
@@ -242,7 +245,6 @@ class InterfaceShared(InterfaceBase):
242
245
  request: Optional[pb.Request] = None,
243
246
  telemetry: Optional[tpb.TelemetryRecord] = None,
244
247
  preempting: Optional[pb.RunPreemptingRecord] = None,
245
- link_artifact: Optional[pb.LinkArtifactRecord] = None,
246
248
  use_artifact: Optional[pb.UseArtifactRecord] = None,
247
249
  output: Optional[pb.OutputRecord] = None,
248
250
  output_raw: Optional[pb.OutputRawRecord] = None,
@@ -282,8 +284,6 @@ class InterfaceShared(InterfaceBase):
282
284
  record.metric.CopyFrom(metric)
283
285
  elif preempting:
284
286
  record.preempting.CopyFrom(preempting)
285
- elif link_artifact:
286
- record.link_artifact.CopyFrom(link_artifact)
287
287
  elif use_artifact:
288
288
  record.use_artifact.CopyFrom(use_artifact)
289
289
  elif output:
@@ -393,10 +393,6 @@ class InterfaceShared(InterfaceBase):
393
393
  rec = self._make_record(files=files)
394
394
  self._publish(rec)
395
395
 
396
- def _publish_link_artifact(self, link_artifact: pb.LinkArtifactRecord) -> Any:
397
- rec = self._make_record(link_artifact=link_artifact)
398
- self._publish(rec)
399
-
400
396
  def _publish_use_artifact(self, use_artifact: pb.UseArtifactRecord) -> Any:
401
397
  rec = self._make_record(use_artifact=use_artifact)
402
398
  self._publish(rec)
@@ -411,6 +407,12 @@ class InterfaceShared(InterfaceBase):
411
407
  rec = self._make_request(download_artifact=download_artifact)
412
408
  return self._deliver_record(rec)
413
409
 
410
+ def _deliver_link_artifact(
411
+ self, link_artifact: pb.LinkArtifactRequest
412
+ ) -> MailboxHandle:
413
+ rec = self._make_request(link_artifact=link_artifact)
414
+ return self._deliver_record(rec)
415
+
414
416
  def _publish_artifact(self, proto_artifact: pb.ArtifactRecord) -> None:
415
417
  rec = self._make_record(artifact=proto_artifact)
416
418
  self._publish(rec)
@@ -230,7 +230,7 @@ class HandleManager:
230
230
  def handle_files(self, record: Record) -> None:
231
231
  self._dispatch_record(record)
232
232
 
233
- def handle_link_artifact(self, record: Record) -> None:
233
+ def handle_request_link_artifact(self, record: Record) -> None:
234
234
  self._dispatch_record(record)
235
235
 
236
236
  def handle_use_artifact(self, record: Record) -> None:
@@ -11,6 +11,7 @@ import socket
11
11
  import sys
12
12
  import threading
13
13
  from copy import deepcopy
14
+ from pathlib import Path
14
15
  from typing import (
15
16
  IO,
16
17
  TYPE_CHECKING,
@@ -37,14 +38,14 @@ from wandb_gql.client import RetryError
37
38
  import wandb
38
39
  from wandb import env, util
39
40
  from wandb.apis.normalize import normalize_exceptions, parse_backend_error_messages
40
- from wandb.errors import CommError, UnsupportedError, UsageError
41
+ from wandb.errors import AuthenticationError, CommError, UnsupportedError, UsageError
41
42
  from wandb.integration.sagemaker import parse_sm_secrets
42
43
  from wandb.old.settings import Settings
43
44
  from wandb.sdk.internal.thread_local_settings import _thread_local_api_settings
44
45
  from wandb.sdk.lib.gql_request import GraphQLSession
45
46
  from wandb.sdk.lib.hashutil import B64MD5, md5_file_b64
46
47
 
47
- from ..lib import retry
48
+ from ..lib import credentials, retry
48
49
  from ..lib.filenames import DIFF_FNAME, METADATA_FNAME
49
50
  from ..lib.gitlib import GitRepo
50
51
  from . import context
@@ -231,24 +232,28 @@ class Api:
231
232
 
232
233
  # todo: remove these hacky hacks after settings refactor is complete
233
234
  # keeping this code here to limit scope and so that it is easy to remove later
234
- extra_http_headers = self.settings("_extra_http_headers") or json.loads(
235
+ self._extra_http_headers = self.settings("_extra_http_headers") or json.loads(
235
236
  self._environ.get("WANDB__EXTRA_HTTP_HEADERS", "{}")
236
237
  )
238
+ self._extra_http_headers.update(_thread_local_api_settings.headers or {})
239
+
240
+ auth = None
241
+ if self.access_token is not None:
242
+ self._extra_http_headers["Authorization"] = f"Bearer {self.access_token}"
243
+ elif _thread_local_api_settings.cookies is None:
244
+ auth = ("api", self.api_key or "")
245
+
237
246
  proxies = self.settings("_proxies") or json.loads(
238
247
  self._environ.get("WANDB__PROXIES", "{}")
239
248
  )
240
249
 
241
- auth = None
242
- if _thread_local_api_settings.cookies is None:
243
- auth = ("api", self.api_key or "")
244
- extra_http_headers.update(_thread_local_api_settings.headers or {})
245
250
  self.client = Client(
246
251
  transport=GraphQLSession(
247
252
  headers={
248
253
  "User-Agent": self.user_agent,
249
254
  "X-WANDB-USERNAME": env.get_username(env=self._environ),
250
255
  "X-WANDB-USER-EMAIL": env.get_user_email(env=self._environ),
251
- **extra_http_headers,
256
+ **self._extra_http_headers,
252
257
  },
253
258
  use_json=True,
254
259
  # this timeout won't apply when the DNS lookup fails. in that case, it will be 60s
@@ -376,6 +381,35 @@ class Api:
376
381
  default_key: Optional[str] = self.default_settings.get("api_key")
377
382
  return env_key or key or sagemaker_key or default_key
378
383
 
384
+ @property
385
+ def access_token(self) -> Optional[str]:
386
+ """Retrieves an access token for authentication.
387
+
388
+ This function attempts to exchange an identity token for a temporary
389
+ access token from the server, and save it to the credentials file.
390
+ It uses the path to the identity token as defined in the environment
391
+ variables. If the environment variable is not set, it returns None.
392
+
393
+ Returns:
394
+ Optional[str]: The access token if available, otherwise None if
395
+ no identity token is supplied.
396
+ Raises:
397
+ AuthenticationError: If the path to the identity token is not found.
398
+ """
399
+ token_file_str = self._environ.get(env.IDENTITY_TOKEN_FILE)
400
+ if not token_file_str:
401
+ return None
402
+
403
+ token_file = Path(token_file_str)
404
+ if not token_file.exists():
405
+ raise AuthenticationError(f"Identity token file not found: {token_file}")
406
+
407
+ base_url = self.settings("base_url")
408
+ credentials_file = env.get_credentials_file(
409
+ str(credentials.DEFAULT_WANDB_CREDENTIALS_FILE), self._environ
410
+ )
411
+ return credentials.access_token(base_url, token_file, credentials_file)
412
+
379
413
  @property
380
414
  def api_url(self) -> str:
381
415
  return self.settings("base_url") # type: ignore
@@ -2674,14 +2708,20 @@ class Api:
2674
2708
  A tuple of the content length and the streaming response
2675
2709
  """
2676
2710
  check_httpclient_logger_handler()
2711
+
2712
+ http_headers = _thread_local_api_settings.headers or {}
2713
+
2677
2714
  auth = None
2678
- if _thread_local_api_settings.cookies is None:
2679
- auth = ("user", self.api_key or "")
2715
+ if self.access_token is not None:
2716
+ http_headers["Authorization"] = f"Bearer {self.access_token}"
2717
+ elif _thread_local_api_settings.cookies is None:
2718
+ auth = ("api", self.api_key or "")
2719
+
2680
2720
  response = requests.get(
2681
2721
  url,
2682
2722
  auth=auth,
2683
2723
  cookies=_thread_local_api_settings.cookies or {},
2684
- headers=_thread_local_api_settings.headers or {},
2724
+ headers=http_headers,
2685
2725
  stream=True,
2686
2726
  )
2687
2727
  response.raise_for_status()
@@ -3039,6 +3079,7 @@ class Api:
3039
3079
  entity: Optional[str] = None,
3040
3080
  state: Optional[str] = None,
3041
3081
  prior_runs: Optional[List[str]] = None,
3082
+ template_variable_values: Optional[Dict[str, Any]] = None,
3042
3083
  ) -> Tuple[str, List[str]]:
3043
3084
  """Upsert a sweep object.
3044
3085
 
@@ -3052,6 +3093,7 @@ class Api:
3052
3093
  entity (str): entity to use
3053
3094
  state (str): state
3054
3095
  prior_runs (list): IDs of existing runs to add to the sweep
3096
+ template_variable_values (dict): template variable values
3055
3097
  """
3056
3098
  project_query = """
3057
3099
  project {
@@ -3096,7 +3138,17 @@ class Api:
3096
3138
  """
3097
3139
  # TODO(jhr): we need protocol versioning to know schema is not supported
3098
3140
  # for now we will just try both new and old query
3099
-
3141
+ mutation_5 = gql(
3142
+ mutation_str.replace(
3143
+ "$controller: JSONString,",
3144
+ "$controller: JSONString,$launchScheduler: JSONString, $templateVariableValues: JSONString,",
3145
+ )
3146
+ .replace(
3147
+ "controller: $controller,",
3148
+ "controller: $controller,launchScheduler: $launchScheduler,templateVariableValues: $templateVariableValues,",
3149
+ )
3150
+ .replace("_PROJECT_QUERY_", project_query)
3151
+ )
3100
3152
  # launchScheduler was introduced in core v0.14.0
3101
3153
  mutation_4 = gql(
3102
3154
  mutation_str.replace(
@@ -3105,7 +3157,7 @@ class Api:
3105
3157
  )
3106
3158
  .replace(
3107
3159
  "controller: $controller,",
3108
- "controller: $controller,launchScheduler: $launchScheduler,",
3160
+ "controller: $controller,launchScheduler: $launchScheduler",
3109
3161
  )
3110
3162
  .replace("_PROJECT_QUERY_", project_query)
3111
3163
  )
@@ -3124,7 +3176,7 @@ class Api:
3124
3176
  )
3125
3177
 
3126
3178
  # TODO(dag): replace this with a query for protocol versioning
3127
- mutations = [mutation_4, mutation_3, mutation_2, mutation_1]
3179
+ mutations = [mutation_5, mutation_4, mutation_3, mutation_2, mutation_1]
3128
3180
 
3129
3181
  config = self._validate_config_and_fill_distribution(config)
3130
3182
 
@@ -3148,6 +3200,7 @@ class Api:
3148
3200
  "projectName": project or self.settings("project"),
3149
3201
  "controller": controller,
3150
3202
  "launchScheduler": launch_scheduler,
3203
+ "templateVariableValues": json.dumps(template_variable_values),
3151
3204
  "scheduler": scheduler,
3152
3205
  "priorRunsFilters": filters,
3153
3206
  }
@@ -1473,8 +1473,13 @@ class SendManager:
1473
1473
  # tbrecord watching threads are handled by handler.py
1474
1474
  pass
1475
1475
 
1476
- def send_link_artifact(self, record: "Record") -> None:
1477
- link = record.link_artifact
1476
+ def send_request_link_artifact(self, record: "Record") -> None:
1477
+ if not (record.control.req_resp or record.control.mailbox_slot):
1478
+ raise ValueError(
1479
+ f"Expected either `req_resp` or `mailbox_slot`, got: {record.control!r}"
1480
+ )
1481
+ result = proto_util._result_from_record(record)
1482
+ link = record.request.link_artifact
1478
1483
  client_id = link.client_id
1479
1484
  server_id = link.server_id
1480
1485
  portfolio_name = link.portfolio_name
@@ -1490,7 +1495,9 @@ class SendManager:
1490
1495
  client_id, server_id, portfolio_name, entity, project, aliases
1491
1496
  )
1492
1497
  except Exception as e:
1498
+ result.response.log_artifact_response.error_message = f'error linking artifact to "{entity}/{project}/{portfolio_name}"; error: {e}'
1493
1499
  logger.warning("Failed to link artifact to portfolio: %s", e)
1500
+ self._respond_result(result)
1494
1501
 
1495
1502
  def send_use_artifact(self, record: "Record") -> None:
1496
1503
  """Pretend to send a used artifact.
@@ -308,7 +308,9 @@ class LaunchAgent:
308
308
  self._wandb_run = None
309
309
 
310
310
  if self.gorilla_supports_agents:
311
- settings = wandb.Settings(silent=True, disable_git=True)
311
+ settings = wandb.Settings(
312
+ silent=True, disable_git=True, disable_job_creation=True
313
+ )
312
314
  self._wandb_run = wandb.init(
313
315
  project=self._project,
314
316
  entity=self._entity,