wandb 0.18.2__py3-none-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package_readme.md +89 -0
- wandb/__init__.py +245 -0
- wandb/__init__.pyi +1139 -0
- wandb/__main__.py +3 -0
- wandb/_globals.py +19 -0
- wandb/agents/__init__.py +0 -0
- wandb/agents/pyagent.py +363 -0
- wandb/analytics/__init__.py +3 -0
- wandb/analytics/sentry.py +266 -0
- wandb/apis/__init__.py +48 -0
- wandb/apis/attrs.py +40 -0
- wandb/apis/importers/__init__.py +1 -0
- wandb/apis/importers/internals/internal.py +385 -0
- wandb/apis/importers/internals/protocols.py +99 -0
- wandb/apis/importers/internals/util.py +78 -0
- wandb/apis/importers/mlflow.py +254 -0
- wandb/apis/importers/validation.py +108 -0
- wandb/apis/importers/wandb.py +1603 -0
- wandb/apis/internal.py +232 -0
- wandb/apis/normalize.py +89 -0
- wandb/apis/paginator.py +81 -0
- wandb/apis/public/__init__.py +34 -0
- wandb/apis/public/api.py +1305 -0
- wandb/apis/public/artifacts.py +1090 -0
- wandb/apis/public/const.py +4 -0
- wandb/apis/public/files.py +195 -0
- wandb/apis/public/history.py +149 -0
- wandb/apis/public/jobs.py +659 -0
- wandb/apis/public/projects.py +154 -0
- wandb/apis/public/query_generator.py +166 -0
- wandb/apis/public/reports.py +469 -0
- wandb/apis/public/runs.py +914 -0
- wandb/apis/public/sweeps.py +240 -0
- wandb/apis/public/teams.py +198 -0
- wandb/apis/public/users.py +136 -0
- wandb/apis/reports/__init__.py +1 -0
- wandb/apis/reports/v1/__init__.py +8 -0
- wandb/apis/reports/v2/__init__.py +8 -0
- wandb/apis/workspaces/__init__.py +8 -0
- wandb/beta/workflows.py +288 -0
- wandb/bin/nvidia_gpu_stats +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/__init__.py +0 -0
- wandb/cli/cli.py +3004 -0
- wandb/data_types.py +63 -0
- wandb/docker/__init__.py +342 -0
- wandb/docker/auth.py +436 -0
- wandb/docker/wandb-entrypoint.sh +33 -0
- wandb/docker/www_authenticate.py +94 -0
- wandb/env.py +514 -0
- wandb/errors/__init__.py +17 -0
- wandb/errors/errors.py +37 -0
- wandb/errors/term.py +103 -0
- wandb/errors/util.py +57 -0
- wandb/errors/warnings.py +2 -0
- wandb/filesync/__init__.py +0 -0
- wandb/filesync/dir_watcher.py +403 -0
- wandb/filesync/stats.py +100 -0
- wandb/filesync/step_checksum.py +142 -0
- wandb/filesync/step_prepare.py +179 -0
- wandb/filesync/step_upload.py +290 -0
- wandb/filesync/upload_job.py +142 -0
- wandb/integration/__init__.py +0 -0
- wandb/integration/catboost/__init__.py +5 -0
- wandb/integration/catboost/catboost.py +178 -0
- wandb/integration/cohere/__init__.py +3 -0
- wandb/integration/cohere/cohere.py +21 -0
- wandb/integration/cohere/resolver.py +347 -0
- wandb/integration/diffusers/__init__.py +3 -0
- wandb/integration/diffusers/autologger.py +76 -0
- wandb/integration/diffusers/pipeline_resolver.py +50 -0
- wandb/integration/diffusers/resolvers/__init__.py +9 -0
- wandb/integration/diffusers/resolvers/multimodal.py +882 -0
- wandb/integration/diffusers/resolvers/utils.py +102 -0
- wandb/integration/fastai/__init__.py +249 -0
- wandb/integration/gym/__init__.py +105 -0
- wandb/integration/huggingface/__init__.py +3 -0
- wandb/integration/huggingface/huggingface.py +18 -0
- wandb/integration/huggingface/resolver.py +213 -0
- wandb/integration/keras/__init__.py +11 -0
- wandb/integration/keras/callbacks/__init__.py +5 -0
- wandb/integration/keras/callbacks/metrics_logger.py +136 -0
- wandb/integration/keras/callbacks/model_checkpoint.py +195 -0
- wandb/integration/keras/callbacks/tables_builder.py +226 -0
- wandb/integration/keras/keras.py +1091 -0
- wandb/integration/kfp/__init__.py +6 -0
- wandb/integration/kfp/helpers.py +28 -0
- wandb/integration/kfp/kfp_patch.py +324 -0
- wandb/integration/kfp/wandb_logging.py +182 -0
- wandb/integration/langchain/__init__.py +3 -0
- wandb/integration/langchain/wandb_tracer.py +48 -0
- wandb/integration/lightgbm/__init__.py +239 -0
- wandb/integration/lightning/__init__.py +0 -0
- wandb/integration/lightning/fabric/__init__.py +3 -0
- wandb/integration/lightning/fabric/logger.py +762 -0
- wandb/integration/magic.py +556 -0
- wandb/integration/metaflow/__init__.py +3 -0
- wandb/integration/metaflow/metaflow.py +383 -0
- wandb/integration/openai/__init__.py +3 -0
- wandb/integration/openai/fine_tuning.py +480 -0
- wandb/integration/openai/openai.py +22 -0
- wandb/integration/openai/resolver.py +240 -0
- wandb/integration/prodigy/__init__.py +3 -0
- wandb/integration/prodigy/prodigy.py +299 -0
- wandb/integration/sacred/__init__.py +117 -0
- wandb/integration/sagemaker/__init__.py +12 -0
- wandb/integration/sagemaker/auth.py +28 -0
- wandb/integration/sagemaker/config.py +49 -0
- wandb/integration/sagemaker/files.py +3 -0
- wandb/integration/sagemaker/resources.py +34 -0
- wandb/integration/sb3/__init__.py +3 -0
- wandb/integration/sb3/sb3.py +153 -0
- wandb/integration/sklearn/__init__.py +37 -0
- wandb/integration/sklearn/calculate/__init__.py +32 -0
- wandb/integration/sklearn/calculate/calibration_curves.py +125 -0
- wandb/integration/sklearn/calculate/class_proportions.py +68 -0
- wandb/integration/sklearn/calculate/confusion_matrix.py +93 -0
- wandb/integration/sklearn/calculate/decision_boundaries.py +40 -0
- wandb/integration/sklearn/calculate/elbow_curve.py +55 -0
- wandb/integration/sklearn/calculate/feature_importances.py +67 -0
- wandb/integration/sklearn/calculate/learning_curve.py +64 -0
- wandb/integration/sklearn/calculate/outlier_candidates.py +69 -0
- wandb/integration/sklearn/calculate/residuals.py +86 -0
- wandb/integration/sklearn/calculate/silhouette.py +118 -0
- wandb/integration/sklearn/calculate/summary_metrics.py +62 -0
- wandb/integration/sklearn/plot/__init__.py +35 -0
- wandb/integration/sklearn/plot/classifier.py +329 -0
- wandb/integration/sklearn/plot/clusterer.py +146 -0
- wandb/integration/sklearn/plot/regressor.py +121 -0
- wandb/integration/sklearn/plot/shared.py +91 -0
- wandb/integration/sklearn/utils.py +183 -0
- wandb/integration/tensorboard/__init__.py +10 -0
- wandb/integration/tensorboard/log.py +355 -0
- wandb/integration/tensorboard/monkeypatch.py +185 -0
- wandb/integration/tensorflow/__init__.py +5 -0
- wandb/integration/tensorflow/estimator_hook.py +54 -0
- wandb/integration/torch/__init__.py +0 -0
- wandb/integration/torch/wandb_torch.py +554 -0
- wandb/integration/ultralytics/__init__.py +11 -0
- wandb/integration/ultralytics/bbox_utils.py +208 -0
- wandb/integration/ultralytics/callback.py +524 -0
- wandb/integration/ultralytics/classification_utils.py +83 -0
- wandb/integration/ultralytics/mask_utils.py +202 -0
- wandb/integration/ultralytics/pose_utils.py +103 -0
- wandb/integration/xgboost/__init__.py +11 -0
- wandb/integration/xgboost/xgboost.py +189 -0
- wandb/integration/yolov8/__init__.py +0 -0
- wandb/integration/yolov8/yolov8.py +284 -0
- wandb/jupyter.py +515 -0
- wandb/magic.py +3 -0
- wandb/mpmain/__init__.py +0 -0
- wandb/mpmain/__main__.py +1 -0
- wandb/old/__init__.py +0 -0
- wandb/old/core.py +53 -0
- wandb/old/settings.py +173 -0
- wandb/old/summary.py +440 -0
- wandb/plot/__init__.py +19 -0
- wandb/plot/bar.py +45 -0
- wandb/plot/confusion_matrix.py +100 -0
- wandb/plot/histogram.py +39 -0
- wandb/plot/line.py +43 -0
- wandb/plot/line_series.py +88 -0
- wandb/plot/pr_curve.py +136 -0
- wandb/plot/roc_curve.py +118 -0
- wandb/plot/scatter.py +32 -0
- wandb/plot/utils.py +183 -0
- wandb/plot/viz.py +123 -0
- wandb/proto/__init__.py +0 -0
- wandb/proto/v3/__init__.py +0 -0
- wandb/proto/v3/wandb_base_pb2.py +55 -0
- wandb/proto/v3/wandb_internal_pb2.py +1608 -0
- wandb/proto/v3/wandb_server_pb2.py +208 -0
- wandb/proto/v3/wandb_settings_pb2.py +112 -0
- wandb/proto/v3/wandb_telemetry_pb2.py +106 -0
- wandb/proto/v4/__init__.py +0 -0
- wandb/proto/v4/wandb_base_pb2.py +30 -0
- wandb/proto/v4/wandb_internal_pb2.py +360 -0
- wandb/proto/v4/wandb_server_pb2.py +63 -0
- wandb/proto/v4/wandb_settings_pb2.py +45 -0
- wandb/proto/v4/wandb_telemetry_pb2.py +41 -0
- wandb/proto/v5/wandb_base_pb2.py +31 -0
- wandb/proto/v5/wandb_internal_pb2.py +361 -0
- wandb/proto/v5/wandb_server_pb2.py +64 -0
- wandb/proto/v5/wandb_settings_pb2.py +46 -0
- wandb/proto/v5/wandb_telemetry_pb2.py +42 -0
- wandb/proto/wandb_base_pb2.py +10 -0
- wandb/proto/wandb_deprecated.py +53 -0
- wandb/proto/wandb_generate_deprecated.py +34 -0
- wandb/proto/wandb_generate_proto.py +49 -0
- wandb/proto/wandb_internal_pb2.py +16 -0
- wandb/proto/wandb_server_pb2.py +10 -0
- wandb/proto/wandb_settings_pb2.py +10 -0
- wandb/proto/wandb_telemetry_pb2.py +10 -0
- wandb/py.typed +0 -0
- wandb/sdk/__init__.py +37 -0
- wandb/sdk/artifacts/__init__.py +0 -0
- wandb/sdk/artifacts/_validators.py +90 -0
- wandb/sdk/artifacts/artifact.py +2389 -0
- wandb/sdk/artifacts/artifact_download_logger.py +43 -0
- wandb/sdk/artifacts/artifact_file_cache.py +253 -0
- wandb/sdk/artifacts/artifact_instance_cache.py +17 -0
- wandb/sdk/artifacts/artifact_manifest.py +74 -0
- wandb/sdk/artifacts/artifact_manifest_entry.py +249 -0
- wandb/sdk/artifacts/artifact_manifests/__init__.py +0 -0
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +92 -0
- wandb/sdk/artifacts/artifact_saver.py +269 -0
- wandb/sdk/artifacts/artifact_state.py +11 -0
- wandb/sdk/artifacts/artifact_ttl.py +7 -0
- wandb/sdk/artifacts/exceptions.py +57 -0
- wandb/sdk/artifacts/staging.py +25 -0
- wandb/sdk/artifacts/storage_handler.py +62 -0
- wandb/sdk/artifacts/storage_handlers/__init__.py +0 -0
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +208 -0
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +228 -0
- wandb/sdk/artifacts/storage_handlers/http_handler.py +114 -0
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +141 -0
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +56 -0
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +300 -0
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +72 -0
- wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +135 -0
- wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +74 -0
- wandb/sdk/artifacts/storage_layout.py +6 -0
- wandb/sdk/artifacts/storage_policies/__init__.py +4 -0
- wandb/sdk/artifacts/storage_policies/register.py +1 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +378 -0
- wandb/sdk/artifacts/storage_policy.py +72 -0
- wandb/sdk/backend/__init__.py +0 -0
- wandb/sdk/backend/backend.py +222 -0
- wandb/sdk/data_types/__init__.py +0 -0
- wandb/sdk/data_types/_dtypes.py +914 -0
- wandb/sdk/data_types/_private.py +10 -0
- wandb/sdk/data_types/audio.py +165 -0
- wandb/sdk/data_types/base_types/__init__.py +0 -0
- wandb/sdk/data_types/base_types/json_metadata.py +55 -0
- wandb/sdk/data_types/base_types/media.py +315 -0
- wandb/sdk/data_types/base_types/wb_value.py +272 -0
- wandb/sdk/data_types/bokeh.py +70 -0
- wandb/sdk/data_types/graph.py +405 -0
- wandb/sdk/data_types/helper_types/__init__.py +0 -0
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +295 -0
- wandb/sdk/data_types/helper_types/classes.py +159 -0
- wandb/sdk/data_types/helper_types/image_mask.py +235 -0
- wandb/sdk/data_types/histogram.py +96 -0
- wandb/sdk/data_types/html.py +115 -0
- wandb/sdk/data_types/image.py +845 -0
- wandb/sdk/data_types/molecule.py +241 -0
- wandb/sdk/data_types/object_3d.py +474 -0
- wandb/sdk/data_types/plotly.py +82 -0
- wandb/sdk/data_types/saved_model.py +446 -0
- wandb/sdk/data_types/table.py +1204 -0
- wandb/sdk/data_types/trace_tree.py +438 -0
- wandb/sdk/data_types/utils.py +229 -0
- wandb/sdk/data_types/video.py +247 -0
- wandb/sdk/integration_utils/__init__.py +0 -0
- wandb/sdk/integration_utils/auto_logging.py +239 -0
- wandb/sdk/integration_utils/data_logging.py +475 -0
- wandb/sdk/interface/__init__.py +0 -0
- wandb/sdk/interface/constants.py +4 -0
- wandb/sdk/interface/interface.py +972 -0
- wandb/sdk/interface/interface_queue.py +59 -0
- wandb/sdk/interface/interface_relay.py +53 -0
- wandb/sdk/interface/interface_shared.py +537 -0
- wandb/sdk/interface/interface_sock.py +61 -0
- wandb/sdk/interface/message_future.py +27 -0
- wandb/sdk/interface/message_future_poll.py +50 -0
- wandb/sdk/interface/router.py +118 -0
- wandb/sdk/interface/router_queue.py +44 -0
- wandb/sdk/interface/router_relay.py +39 -0
- wandb/sdk/interface/router_sock.py +36 -0
- wandb/sdk/interface/summary_record.py +67 -0
- wandb/sdk/internal/__init__.py +0 -0
- wandb/sdk/internal/context.py +89 -0
- wandb/sdk/internal/datastore.py +297 -0
- wandb/sdk/internal/file_pusher.py +181 -0
- wandb/sdk/internal/file_stream.py +695 -0
- wandb/sdk/internal/flow_control.py +263 -0
- wandb/sdk/internal/handler.py +901 -0
- wandb/sdk/internal/internal.py +417 -0
- wandb/sdk/internal/internal_api.py +4358 -0
- wandb/sdk/internal/internal_util.py +100 -0
- wandb/sdk/internal/job_builder.py +629 -0
- wandb/sdk/internal/profiler.py +78 -0
- wandb/sdk/internal/progress.py +83 -0
- wandb/sdk/internal/run.py +25 -0
- wandb/sdk/internal/sample.py +70 -0
- wandb/sdk/internal/sender.py +1686 -0
- wandb/sdk/internal/sender_config.py +197 -0
- wandb/sdk/internal/settings_static.py +90 -0
- wandb/sdk/internal/system/__init__.py +0 -0
- wandb/sdk/internal/system/assets/__init__.py +27 -0
- wandb/sdk/internal/system/assets/aggregators.py +37 -0
- wandb/sdk/internal/system/assets/asset_registry.py +20 -0
- wandb/sdk/internal/system/assets/cpu.py +163 -0
- wandb/sdk/internal/system/assets/disk.py +210 -0
- wandb/sdk/internal/system/assets/gpu.py +416 -0
- wandb/sdk/internal/system/assets/gpu_amd.py +239 -0
- wandb/sdk/internal/system/assets/gpu_apple.py +177 -0
- wandb/sdk/internal/system/assets/interfaces.py +207 -0
- wandb/sdk/internal/system/assets/ipu.py +177 -0
- wandb/sdk/internal/system/assets/memory.py +166 -0
- wandb/sdk/internal/system/assets/network.py +125 -0
- wandb/sdk/internal/system/assets/open_metrics.py +299 -0
- wandb/sdk/internal/system/assets/tpu.py +154 -0
- wandb/sdk/internal/system/assets/trainium.py +399 -0
- wandb/sdk/internal/system/env_probe_helpers.py +13 -0
- wandb/sdk/internal/system/system_info.py +249 -0
- wandb/sdk/internal/system/system_monitor.py +229 -0
- wandb/sdk/internal/tb_watcher.py +518 -0
- wandb/sdk/internal/thread_local_settings.py +18 -0
- wandb/sdk/internal/writer.py +206 -0
- wandb/sdk/launch/__init__.py +14 -0
- wandb/sdk/launch/_launch.py +330 -0
- wandb/sdk/launch/_launch_add.py +255 -0
- wandb/sdk/launch/_project_spec.py +566 -0
- wandb/sdk/launch/agent/__init__.py +5 -0
- wandb/sdk/launch/agent/agent.py +924 -0
- wandb/sdk/launch/agent/config.py +296 -0
- wandb/sdk/launch/agent/job_status_tracker.py +53 -0
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +45 -0
- wandb/sdk/launch/builder/__init__.py +0 -0
- wandb/sdk/launch/builder/abstract.py +156 -0
- wandb/sdk/launch/builder/build.py +297 -0
- wandb/sdk/launch/builder/context_manager.py +235 -0
- wandb/sdk/launch/builder/docker_builder.py +177 -0
- wandb/sdk/launch/builder/kaniko_builder.py +595 -0
- wandb/sdk/launch/builder/noop.py +58 -0
- wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +188 -0
- wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
- wandb/sdk/launch/create_job.py +528 -0
- wandb/sdk/launch/environment/abstract.py +29 -0
- wandb/sdk/launch/environment/aws_environment.py +322 -0
- wandb/sdk/launch/environment/azure_environment.py +105 -0
- wandb/sdk/launch/environment/gcp_environment.py +335 -0
- wandb/sdk/launch/environment/local_environment.py +66 -0
- wandb/sdk/launch/errors.py +19 -0
- wandb/sdk/launch/git_reference.py +109 -0
- wandb/sdk/launch/inputs/files.py +148 -0
- wandb/sdk/launch/inputs/internal.py +315 -0
- wandb/sdk/launch/inputs/manage.py +113 -0
- wandb/sdk/launch/inputs/schema.py +39 -0
- wandb/sdk/launch/loader.py +249 -0
- wandb/sdk/launch/registry/abstract.py +48 -0
- wandb/sdk/launch/registry/anon.py +29 -0
- wandb/sdk/launch/registry/azure_container_registry.py +124 -0
- wandb/sdk/launch/registry/elastic_container_registry.py +192 -0
- wandb/sdk/launch/registry/google_artifact_registry.py +219 -0
- wandb/sdk/launch/registry/local_registry.py +67 -0
- wandb/sdk/launch/runner/__init__.py +0 -0
- wandb/sdk/launch/runner/abstract.py +195 -0
- wandb/sdk/launch/runner/kubernetes_monitor.py +474 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +963 -0
- wandb/sdk/launch/runner/local_container.py +301 -0
- wandb/sdk/launch/runner/local_process.py +78 -0
- wandb/sdk/launch/runner/sagemaker_runner.py +426 -0
- wandb/sdk/launch/runner/vertex_runner.py +230 -0
- wandb/sdk/launch/sweeps/__init__.py +39 -0
- wandb/sdk/launch/sweeps/scheduler.py +742 -0
- wandb/sdk/launch/sweeps/scheduler_sweep.py +91 -0
- wandb/sdk/launch/sweeps/utils.py +316 -0
- wandb/sdk/launch/utils.py +746 -0
- wandb/sdk/launch/wandb_reference.py +138 -0
- wandb/sdk/lib/__init__.py +5 -0
- wandb/sdk/lib/_settings_toposort_generate.py +159 -0
- wandb/sdk/lib/_settings_toposort_generated.py +250 -0
- wandb/sdk/lib/_wburls_generate.py +25 -0
- wandb/sdk/lib/_wburls_generated.py +22 -0
- wandb/sdk/lib/apikey.py +273 -0
- wandb/sdk/lib/capped_dict.py +26 -0
- wandb/sdk/lib/config_util.py +101 -0
- wandb/sdk/lib/credentials.py +141 -0
- wandb/sdk/lib/deprecate.py +42 -0
- wandb/sdk/lib/disabled.py +29 -0
- wandb/sdk/lib/exit_hooks.py +54 -0
- wandb/sdk/lib/file_stream_utils.py +118 -0
- wandb/sdk/lib/filenames.py +64 -0
- wandb/sdk/lib/filesystem.py +372 -0
- wandb/sdk/lib/fsm.py +174 -0
- wandb/sdk/lib/gitlib.py +239 -0
- wandb/sdk/lib/gql_request.py +65 -0
- wandb/sdk/lib/handler_util.py +21 -0
- wandb/sdk/lib/hashutil.py +84 -0
- wandb/sdk/lib/import_hooks.py +275 -0
- wandb/sdk/lib/ipython.py +146 -0
- wandb/sdk/lib/json_util.py +80 -0
- wandb/sdk/lib/lazyloader.py +63 -0
- wandb/sdk/lib/mailbox.py +460 -0
- wandb/sdk/lib/module.py +69 -0
- wandb/sdk/lib/paths.py +106 -0
- wandb/sdk/lib/preinit.py +42 -0
- wandb/sdk/lib/printer.py +313 -0
- wandb/sdk/lib/proto_util.py +90 -0
- wandb/sdk/lib/redirect.py +845 -0
- wandb/sdk/lib/reporting.py +99 -0
- wandb/sdk/lib/retry.py +289 -0
- wandb/sdk/lib/run_moment.py +78 -0
- wandb/sdk/lib/runid.py +12 -0
- wandb/sdk/lib/server.py +52 -0
- wandb/sdk/lib/service_connection.py +216 -0
- wandb/sdk/lib/service_token.py +94 -0
- wandb/sdk/lib/sock_client.py +295 -0
- wandb/sdk/lib/sparkline.py +45 -0
- wandb/sdk/lib/telemetry.py +100 -0
- wandb/sdk/lib/timed_input.py +133 -0
- wandb/sdk/lib/timer.py +19 -0
- wandb/sdk/lib/tracelog.py +255 -0
- wandb/sdk/lib/wburls.py +46 -0
- wandb/sdk/service/__init__.py +0 -0
- wandb/sdk/service/_startup_debug.py +22 -0
- wandb/sdk/service/port_file.py +53 -0
- wandb/sdk/service/server.py +116 -0
- wandb/sdk/service/server_sock.py +276 -0
- wandb/sdk/service/service.py +242 -0
- wandb/sdk/service/streams.py +417 -0
- wandb/sdk/verify/__init__.py +0 -0
- wandb/sdk/verify/verify.py +501 -0
- wandb/sdk/wandb_alerts.py +12 -0
- wandb/sdk/wandb_config.py +322 -0
- wandb/sdk/wandb_helper.py +54 -0
- wandb/sdk/wandb_init.py +1266 -0
- wandb/sdk/wandb_login.py +349 -0
- wandb/sdk/wandb_metric.py +110 -0
- wandb/sdk/wandb_require.py +97 -0
- wandb/sdk/wandb_require_helpers.py +44 -0
- wandb/sdk/wandb_run.py +4236 -0
- wandb/sdk/wandb_settings.py +2001 -0
- wandb/sdk/wandb_setup.py +409 -0
- wandb/sdk/wandb_summary.py +150 -0
- wandb/sdk/wandb_sweep.py +119 -0
- wandb/sdk/wandb_sync.py +81 -0
- wandb/sdk/wandb_watch.py +144 -0
- wandb/sklearn.py +35 -0
- wandb/sync/__init__.py +3 -0
- wandb/sync/sync.py +443 -0
- wandb/trigger.py +29 -0
- wandb/util.py +1956 -0
- wandb/vendor/__init__.py +0 -0
- wandb/vendor/gql-0.2.0/setup.py +40 -0
- wandb/vendor/gql-0.2.0/tests/__init__.py +0 -0
- wandb/vendor/gql-0.2.0/tests/starwars/__init__.py +0 -0
- wandb/vendor/gql-0.2.0/tests/starwars/fixtures.py +96 -0
- wandb/vendor/gql-0.2.0/tests/starwars/schema.py +146 -0
- wandb/vendor/gql-0.2.0/tests/starwars/test_dsl.py +293 -0
- wandb/vendor/gql-0.2.0/tests/starwars/test_query.py +355 -0
- wandb/vendor/gql-0.2.0/tests/starwars/test_validation.py +171 -0
- wandb/vendor/gql-0.2.0/tests/test_client.py +31 -0
- wandb/vendor/gql-0.2.0/tests/test_transport.py +89 -0
- wandb/vendor/gql-0.2.0/wandb_gql/__init__.py +4 -0
- wandb/vendor/gql-0.2.0/wandb_gql/client.py +75 -0
- wandb/vendor/gql-0.2.0/wandb_gql/dsl.py +152 -0
- wandb/vendor/gql-0.2.0/wandb_gql/gql.py +10 -0
- wandb/vendor/gql-0.2.0/wandb_gql/transport/__init__.py +0 -0
- wandb/vendor/gql-0.2.0/wandb_gql/transport/http.py +6 -0
- wandb/vendor/gql-0.2.0/wandb_gql/transport/local_schema.py +15 -0
- wandb/vendor/gql-0.2.0/wandb_gql/transport/requests.py +46 -0
- wandb/vendor/gql-0.2.0/wandb_gql/utils.py +21 -0
- wandb/vendor/graphql-core-1.1/setup.py +86 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/__init__.py +287 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/error/__init__.py +6 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/error/base.py +42 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/error/format_error.py +11 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/error/located_error.py +29 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/error/syntax_error.py +36 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/__init__.py +26 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/base.py +311 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executor.py +398 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/__init__.py +0 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/asyncio.py +53 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/gevent.py +22 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/process.py +32 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/sync.py +7 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/thread.py +35 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/executors/utils.py +6 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/__init__.py +0 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/executor.py +66 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/fragment.py +252 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/resolver.py +151 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/experimental/utils.py +7 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/middleware.py +57 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/execution/values.py +145 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/graphql.py +60 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/__init__.py +0 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/ast.py +1349 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/base.py +19 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/lexer.py +435 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/location.py +30 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/parser.py +779 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/printer.py +193 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/source.py +18 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor.py +222 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/language/visitor_meta.py +82 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/__init__.py +0 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/cached_property.py +17 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/contain_subset.py +28 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/default_ordered_dict.py +40 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/ordereddict.py +8 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/pair_set.py +43 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/pyutils/version.py +78 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/__init__.py +67 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/definition.py +619 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/directives.py +132 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/introspection.py +440 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/scalars.py +131 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/schema.py +100 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/type/typemap.py +145 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/__init__.py +0 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/assert_valid_name.py +9 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_from_value.py +65 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_code.py +49 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/ast_to_dict.py +24 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/base.py +75 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_ast_schema.py +291 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/build_client_schema.py +250 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/concat_ast.py +9 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/extend_schema.py +357 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_field_def.py +27 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/get_operation_ast.py +21 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/introspection_query.py +90 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_literal_value.py +67 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/is_valid_value.py +66 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/quoted_or_list.py +21 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/schema_printer.py +168 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/suggestion_list.py +56 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_comparators.py +69 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_from_ast.py +21 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/type_info.py +149 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/utils/value_from_ast.py +69 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/__init__.py +4 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/__init__.py +79 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/arguments_of_correct_type.py +24 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/base.py +8 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/default_values_of_correct_type.py +44 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fields_on_correct_type.py +113 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/fragments_on_composite_types.py +33 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_argument_names.py +70 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_directives.py +97 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_fragment_names.py +19 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/known_type_names.py +43 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/lone_anonymous_operation.py +23 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_fragment_cycles.py +59 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_undefined_variables.py +36 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_fragments.py +38 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/no_unused_variables.py +37 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/overlapping_fields_can_be_merged.py +529 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/possible_fragment_spreads.py +44 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/provided_non_null_arguments.py +46 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/scalar_leafs.py +33 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_argument_names.py +32 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_fragment_names.py +28 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_input_field_names.py +33 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_operation_names.py +31 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/unique_variable_names.py +27 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_are_input_types.py +21 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/rules/variables_in_allowed_position.py +53 -0
- wandb/vendor/graphql-core-1.1/wandb_graphql/validation/validation.py +158 -0
- wandb/vendor/promise-2.3.0/conftest.py +30 -0
- wandb/vendor/promise-2.3.0/setup.py +64 -0
- wandb/vendor/promise-2.3.0/tests/__init__.py +0 -0
- wandb/vendor/promise-2.3.0/tests/conftest.py +8 -0
- wandb/vendor/promise-2.3.0/tests/test_awaitable.py +32 -0
- wandb/vendor/promise-2.3.0/tests/test_awaitable_35.py +47 -0
- wandb/vendor/promise-2.3.0/tests/test_benchmark.py +116 -0
- wandb/vendor/promise-2.3.0/tests/test_complex_threads.py +23 -0
- wandb/vendor/promise-2.3.0/tests/test_dataloader.py +452 -0
- wandb/vendor/promise-2.3.0/tests/test_dataloader_awaitable_35.py +99 -0
- wandb/vendor/promise-2.3.0/tests/test_dataloader_extra.py +65 -0
- wandb/vendor/promise-2.3.0/tests/test_extra.py +670 -0
- wandb/vendor/promise-2.3.0/tests/test_issues.py +132 -0
- wandb/vendor/promise-2.3.0/tests/test_promise_list.py +70 -0
- wandb/vendor/promise-2.3.0/tests/test_spec.py +584 -0
- wandb/vendor/promise-2.3.0/tests/test_thread_safety.py +115 -0
- wandb/vendor/promise-2.3.0/tests/utils.py +3 -0
- wandb/vendor/promise-2.3.0/wandb_promise/__init__.py +38 -0
- wandb/vendor/promise-2.3.0/wandb_promise/async_.py +135 -0
- wandb/vendor/promise-2.3.0/wandb_promise/compat.py +32 -0
- wandb/vendor/promise-2.3.0/wandb_promise/dataloader.py +326 -0
- wandb/vendor/promise-2.3.0/wandb_promise/iterate_promise.py +12 -0
- wandb/vendor/promise-2.3.0/wandb_promise/promise.py +848 -0
- wandb/vendor/promise-2.3.0/wandb_promise/promise_list.py +151 -0
- wandb/vendor/promise-2.3.0/wandb_promise/pyutils/__init__.py +0 -0
- wandb/vendor/promise-2.3.0/wandb_promise/pyutils/version.py +83 -0
- wandb/vendor/promise-2.3.0/wandb_promise/schedulers/__init__.py +0 -0
- wandb/vendor/promise-2.3.0/wandb_promise/schedulers/asyncio.py +22 -0
- wandb/vendor/promise-2.3.0/wandb_promise/schedulers/gevent.py +21 -0
- wandb/vendor/promise-2.3.0/wandb_promise/schedulers/immediate.py +27 -0
- wandb/vendor/promise-2.3.0/wandb_promise/schedulers/thread.py +18 -0
- wandb/vendor/promise-2.3.0/wandb_promise/utils.py +56 -0
- wandb/vendor/pygments/__init__.py +90 -0
- wandb/vendor/pygments/cmdline.py +568 -0
- wandb/vendor/pygments/console.py +74 -0
- wandb/vendor/pygments/filter.py +74 -0
- wandb/vendor/pygments/filters/__init__.py +350 -0
- wandb/vendor/pygments/formatter.py +95 -0
- wandb/vendor/pygments/formatters/__init__.py +153 -0
- wandb/vendor/pygments/formatters/_mapping.py +85 -0
- wandb/vendor/pygments/formatters/bbcode.py +109 -0
- wandb/vendor/pygments/formatters/html.py +851 -0
- wandb/vendor/pygments/formatters/img.py +600 -0
- wandb/vendor/pygments/formatters/irc.py +182 -0
- wandb/vendor/pygments/formatters/latex.py +482 -0
- wandb/vendor/pygments/formatters/other.py +160 -0
- wandb/vendor/pygments/formatters/rtf.py +147 -0
- wandb/vendor/pygments/formatters/svg.py +153 -0
- wandb/vendor/pygments/formatters/terminal.py +136 -0
- wandb/vendor/pygments/formatters/terminal256.py +309 -0
- wandb/vendor/pygments/lexer.py +871 -0
- wandb/vendor/pygments/lexers/__init__.py +329 -0
- wandb/vendor/pygments/lexers/_asy_builtins.py +1645 -0
- wandb/vendor/pygments/lexers/_cl_builtins.py +232 -0
- wandb/vendor/pygments/lexers/_cocoa_builtins.py +72 -0
- wandb/vendor/pygments/lexers/_csound_builtins.py +1346 -0
- wandb/vendor/pygments/lexers/_lasso_builtins.py +5327 -0
- wandb/vendor/pygments/lexers/_lua_builtins.py +295 -0
- wandb/vendor/pygments/lexers/_mapping.py +500 -0
- wandb/vendor/pygments/lexers/_mql_builtins.py +1172 -0
- wandb/vendor/pygments/lexers/_openedge_builtins.py +2547 -0
- wandb/vendor/pygments/lexers/_php_builtins.py +4756 -0
- wandb/vendor/pygments/lexers/_postgres_builtins.py +621 -0
- wandb/vendor/pygments/lexers/_scilab_builtins.py +3094 -0
- wandb/vendor/pygments/lexers/_sourcemod_builtins.py +1163 -0
- wandb/vendor/pygments/lexers/_stan_builtins.py +532 -0
- wandb/vendor/pygments/lexers/_stata_builtins.py +419 -0
- wandb/vendor/pygments/lexers/_tsql_builtins.py +1004 -0
- wandb/vendor/pygments/lexers/_vim_builtins.py +1939 -0
- wandb/vendor/pygments/lexers/actionscript.py +240 -0
- wandb/vendor/pygments/lexers/agile.py +24 -0
- wandb/vendor/pygments/lexers/algebra.py +221 -0
- wandb/vendor/pygments/lexers/ambient.py +76 -0
- wandb/vendor/pygments/lexers/ampl.py +87 -0
- wandb/vendor/pygments/lexers/apl.py +101 -0
- wandb/vendor/pygments/lexers/archetype.py +318 -0
- wandb/vendor/pygments/lexers/asm.py +641 -0
- wandb/vendor/pygments/lexers/automation.py +374 -0
- wandb/vendor/pygments/lexers/basic.py +500 -0
- wandb/vendor/pygments/lexers/bibtex.py +160 -0
- wandb/vendor/pygments/lexers/business.py +612 -0
- wandb/vendor/pygments/lexers/c_cpp.py +252 -0
- wandb/vendor/pygments/lexers/c_like.py +541 -0
- wandb/vendor/pygments/lexers/capnproto.py +78 -0
- wandb/vendor/pygments/lexers/chapel.py +102 -0
- wandb/vendor/pygments/lexers/clean.py +288 -0
- wandb/vendor/pygments/lexers/compiled.py +34 -0
- wandb/vendor/pygments/lexers/configs.py +833 -0
- wandb/vendor/pygments/lexers/console.py +114 -0
- wandb/vendor/pygments/lexers/crystal.py +393 -0
- wandb/vendor/pygments/lexers/csound.py +366 -0
- wandb/vendor/pygments/lexers/css.py +689 -0
- wandb/vendor/pygments/lexers/d.py +251 -0
- wandb/vendor/pygments/lexers/dalvik.py +125 -0
- wandb/vendor/pygments/lexers/data.py +555 -0
- wandb/vendor/pygments/lexers/diff.py +165 -0
- wandb/vendor/pygments/lexers/dotnet.py +691 -0
- wandb/vendor/pygments/lexers/dsls.py +878 -0
- wandb/vendor/pygments/lexers/dylan.py +289 -0
- wandb/vendor/pygments/lexers/ecl.py +125 -0
- wandb/vendor/pygments/lexers/eiffel.py +65 -0
- wandb/vendor/pygments/lexers/elm.py +121 -0
- wandb/vendor/pygments/lexers/erlang.py +533 -0
- wandb/vendor/pygments/lexers/esoteric.py +277 -0
- wandb/vendor/pygments/lexers/ezhil.py +69 -0
- wandb/vendor/pygments/lexers/factor.py +344 -0
- wandb/vendor/pygments/lexers/fantom.py +250 -0
- wandb/vendor/pygments/lexers/felix.py +273 -0
- wandb/vendor/pygments/lexers/forth.py +177 -0
- wandb/vendor/pygments/lexers/fortran.py +205 -0
- wandb/vendor/pygments/lexers/foxpro.py +428 -0
- wandb/vendor/pygments/lexers/functional.py +21 -0
- wandb/vendor/pygments/lexers/go.py +101 -0
- wandb/vendor/pygments/lexers/grammar_notation.py +213 -0
- wandb/vendor/pygments/lexers/graph.py +80 -0
- wandb/vendor/pygments/lexers/graphics.py +553 -0
- wandb/vendor/pygments/lexers/haskell.py +843 -0
- wandb/vendor/pygments/lexers/haxe.py +936 -0
- wandb/vendor/pygments/lexers/hdl.py +382 -0
- wandb/vendor/pygments/lexers/hexdump.py +103 -0
- wandb/vendor/pygments/lexers/html.py +602 -0
- wandb/vendor/pygments/lexers/idl.py +270 -0
- wandb/vendor/pygments/lexers/igor.py +288 -0
- wandb/vendor/pygments/lexers/inferno.py +96 -0
- wandb/vendor/pygments/lexers/installers.py +322 -0
- wandb/vendor/pygments/lexers/int_fiction.py +1343 -0
- wandb/vendor/pygments/lexers/iolang.py +63 -0
- wandb/vendor/pygments/lexers/j.py +146 -0
- wandb/vendor/pygments/lexers/javascript.py +1525 -0
- wandb/vendor/pygments/lexers/julia.py +333 -0
- wandb/vendor/pygments/lexers/jvm.py +1573 -0
- wandb/vendor/pygments/lexers/lisp.py +2621 -0
- wandb/vendor/pygments/lexers/make.py +202 -0
- wandb/vendor/pygments/lexers/markup.py +595 -0
- wandb/vendor/pygments/lexers/math.py +21 -0
- wandb/vendor/pygments/lexers/matlab.py +663 -0
- wandb/vendor/pygments/lexers/ml.py +769 -0
- wandb/vendor/pygments/lexers/modeling.py +358 -0
- wandb/vendor/pygments/lexers/modula2.py +1561 -0
- wandb/vendor/pygments/lexers/monte.py +204 -0
- wandb/vendor/pygments/lexers/ncl.py +894 -0
- wandb/vendor/pygments/lexers/nimrod.py +159 -0
- wandb/vendor/pygments/lexers/nit.py +64 -0
- wandb/vendor/pygments/lexers/nix.py +136 -0
- wandb/vendor/pygments/lexers/oberon.py +105 -0
- wandb/vendor/pygments/lexers/objective.py +504 -0
- wandb/vendor/pygments/lexers/ooc.py +85 -0
- wandb/vendor/pygments/lexers/other.py +41 -0
- wandb/vendor/pygments/lexers/parasail.py +79 -0
- wandb/vendor/pygments/lexers/parsers.py +835 -0
- wandb/vendor/pygments/lexers/pascal.py +644 -0
- wandb/vendor/pygments/lexers/pawn.py +199 -0
- wandb/vendor/pygments/lexers/perl.py +620 -0
- wandb/vendor/pygments/lexers/php.py +267 -0
- wandb/vendor/pygments/lexers/praat.py +294 -0
- wandb/vendor/pygments/lexers/prolog.py +306 -0
- wandb/vendor/pygments/lexers/python.py +939 -0
- wandb/vendor/pygments/lexers/qvt.py +152 -0
- wandb/vendor/pygments/lexers/r.py +453 -0
- wandb/vendor/pygments/lexers/rdf.py +270 -0
- wandb/vendor/pygments/lexers/rebol.py +431 -0
- wandb/vendor/pygments/lexers/resource.py +85 -0
- wandb/vendor/pygments/lexers/rnc.py +67 -0
- wandb/vendor/pygments/lexers/roboconf.py +82 -0
- wandb/vendor/pygments/lexers/robotframework.py +560 -0
- wandb/vendor/pygments/lexers/ruby.py +519 -0
- wandb/vendor/pygments/lexers/rust.py +220 -0
- wandb/vendor/pygments/lexers/sas.py +228 -0
- wandb/vendor/pygments/lexers/scripting.py +1222 -0
- wandb/vendor/pygments/lexers/shell.py +794 -0
- wandb/vendor/pygments/lexers/smalltalk.py +195 -0
- wandb/vendor/pygments/lexers/smv.py +79 -0
- wandb/vendor/pygments/lexers/snobol.py +83 -0
- wandb/vendor/pygments/lexers/special.py +103 -0
- wandb/vendor/pygments/lexers/sql.py +681 -0
- wandb/vendor/pygments/lexers/stata.py +108 -0
- wandb/vendor/pygments/lexers/supercollider.py +90 -0
- wandb/vendor/pygments/lexers/tcl.py +145 -0
- wandb/vendor/pygments/lexers/templates.py +2283 -0
- wandb/vendor/pygments/lexers/testing.py +207 -0
- wandb/vendor/pygments/lexers/text.py +25 -0
- wandb/vendor/pygments/lexers/textedit.py +169 -0
- wandb/vendor/pygments/lexers/textfmts.py +297 -0
- wandb/vendor/pygments/lexers/theorem.py +458 -0
- wandb/vendor/pygments/lexers/trafficscript.py +54 -0
- wandb/vendor/pygments/lexers/typoscript.py +226 -0
- wandb/vendor/pygments/lexers/urbi.py +133 -0
- wandb/vendor/pygments/lexers/varnish.py +190 -0
- wandb/vendor/pygments/lexers/verification.py +111 -0
- wandb/vendor/pygments/lexers/web.py +24 -0
- wandb/vendor/pygments/lexers/webmisc.py +988 -0
- wandb/vendor/pygments/lexers/whiley.py +116 -0
- wandb/vendor/pygments/lexers/x10.py +69 -0
- wandb/vendor/pygments/modeline.py +44 -0
- wandb/vendor/pygments/plugin.py +68 -0
- wandb/vendor/pygments/regexopt.py +92 -0
- wandb/vendor/pygments/scanner.py +105 -0
- wandb/vendor/pygments/sphinxext.py +158 -0
- wandb/vendor/pygments/style.py +155 -0
- wandb/vendor/pygments/styles/__init__.py +80 -0
- wandb/vendor/pygments/styles/abap.py +29 -0
- wandb/vendor/pygments/styles/algol.py +63 -0
- wandb/vendor/pygments/styles/algol_nu.py +63 -0
- wandb/vendor/pygments/styles/arduino.py +98 -0
- wandb/vendor/pygments/styles/autumn.py +65 -0
- wandb/vendor/pygments/styles/borland.py +51 -0
- wandb/vendor/pygments/styles/bw.py +49 -0
- wandb/vendor/pygments/styles/colorful.py +81 -0
- wandb/vendor/pygments/styles/default.py +73 -0
- wandb/vendor/pygments/styles/emacs.py +72 -0
- wandb/vendor/pygments/styles/friendly.py +72 -0
- wandb/vendor/pygments/styles/fruity.py +42 -0
- wandb/vendor/pygments/styles/igor.py +29 -0
- wandb/vendor/pygments/styles/lovelace.py +97 -0
- wandb/vendor/pygments/styles/manni.py +75 -0
- wandb/vendor/pygments/styles/monokai.py +106 -0
- wandb/vendor/pygments/styles/murphy.py +80 -0
- wandb/vendor/pygments/styles/native.py +65 -0
- wandb/vendor/pygments/styles/paraiso_dark.py +125 -0
- wandb/vendor/pygments/styles/paraiso_light.py +125 -0
- wandb/vendor/pygments/styles/pastie.py +75 -0
- wandb/vendor/pygments/styles/perldoc.py +69 -0
- wandb/vendor/pygments/styles/rainbow_dash.py +89 -0
- wandb/vendor/pygments/styles/rrt.py +33 -0
- wandb/vendor/pygments/styles/sas.py +44 -0
- wandb/vendor/pygments/styles/stata.py +40 -0
- wandb/vendor/pygments/styles/tango.py +141 -0
- wandb/vendor/pygments/styles/trac.py +63 -0
- wandb/vendor/pygments/styles/vim.py +63 -0
- wandb/vendor/pygments/styles/vs.py +38 -0
- wandb/vendor/pygments/styles/xcode.py +51 -0
- wandb/vendor/pygments/token.py +213 -0
- wandb/vendor/pygments/unistring.py +217 -0
- wandb/vendor/pygments/util.py +388 -0
- wandb/vendor/pynvml/__init__.py +0 -0
- wandb/vendor/pynvml/pynvml.py +4779 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/__init__.py +17 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/events.py +615 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/__init__.py +98 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/api.py +369 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents.py +172 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/fsevents2.py +239 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify.py +218 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_buffer.py +81 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/inotify_c.py +575 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/kqueue.py +730 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/polling.py +145 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/read_directory_changes.py +133 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/observers/winapi.py +348 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/patterns.py +265 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/tricks/__init__.py +174 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/__init__.py +151 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/bricks.py +249 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/compat.py +29 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/decorators.py +198 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/delayed_queue.py +88 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/dirsnapshot.py +293 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/echo.py +157 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/event_backport.py +41 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/importlib2.py +40 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/platform.py +57 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/unicode_paths.py +64 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/win32stat.py +123 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/version.py +28 -0
- wandb/vendor/watchdog_0_9_0/wandb_watchdog/watchmedo.py +577 -0
- wandb/wandb_agent.py +588 -0
- wandb/wandb_controller.py +721 -0
- wandb/wandb_run.py +9 -0
- wandb-0.18.2.dist-info/METADATA +213 -0
- wandb-0.18.2.dist-info/RECORD +827 -0
- wandb-0.18.2.dist-info/WHEEL +5 -0
- wandb-0.18.2.dist-info/entry_points.txt +3 -0
- wandb-0.18.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
#
|
2
|
+
from typing import Any, Dict, Iterable
|
3
|
+
|
4
|
+
|
5
|
+
def split_files(
|
6
|
+
files: Dict[str, Any], max_bytes: int = 10 * 1024 * 1024
|
7
|
+
) -> Iterable[Dict[str, Dict]]:
|
8
|
+
"""Split a file's dict (see `files` arg) into smaller dicts.
|
9
|
+
|
10
|
+
Each smaller dict will have at most `MAX_BYTES` size.
|
11
|
+
|
12
|
+
This method is used in `FileStreamAPI._send()` to limit the size of post requests
|
13
|
+
sent to wandb server.
|
14
|
+
|
15
|
+
Arguments:
|
16
|
+
files (dict): `dict` of form {file_name: {'content': ".....", 'offset': 0}}
|
17
|
+
The key `file_name` can also be mapped to a List [{"offset": int, "content": str}]
|
18
|
+
`max_bytes`: max size for chunk in bytes
|
19
|
+
"""
|
20
|
+
current_volume: Dict[str, Dict] = {}
|
21
|
+
current_size = 0
|
22
|
+
|
23
|
+
def _str_size(x):
|
24
|
+
return len(x) if isinstance(x, bytes) else len(x.encode("utf-8"))
|
25
|
+
|
26
|
+
def _file_size(file):
|
27
|
+
size = file.get("_size")
|
28
|
+
if size is None:
|
29
|
+
size = sum(map(_str_size, file["content"]))
|
30
|
+
file["_size"] = size
|
31
|
+
return size
|
32
|
+
|
33
|
+
def _split_file(file, num_lines):
|
34
|
+
offset = file["offset"]
|
35
|
+
content = file["content"]
|
36
|
+
name = file["name"]
|
37
|
+
f1 = {"offset": offset, "content": content[:num_lines], "name": name}
|
38
|
+
f2 = {
|
39
|
+
"offset": offset + num_lines,
|
40
|
+
"content": content[num_lines:],
|
41
|
+
"name": name,
|
42
|
+
}
|
43
|
+
return f1, f2
|
44
|
+
|
45
|
+
def _num_lines_from_num_bytes(file, num_bytes):
|
46
|
+
size = 0
|
47
|
+
num_lines = 0
|
48
|
+
content = file["content"]
|
49
|
+
while num_lines < len(content):
|
50
|
+
size += _str_size(content[num_lines])
|
51
|
+
if size > num_bytes:
|
52
|
+
break
|
53
|
+
num_lines += 1
|
54
|
+
return num_lines
|
55
|
+
|
56
|
+
files_stack = []
|
57
|
+
for k, v in files.items():
|
58
|
+
if isinstance(v, list):
|
59
|
+
for item in v:
|
60
|
+
files_stack.append(
|
61
|
+
{"name": k, "offset": item["offset"], "content": item["content"]}
|
62
|
+
)
|
63
|
+
else:
|
64
|
+
files_stack.append(
|
65
|
+
{"name": k, "offset": v["offset"], "content": v["content"]}
|
66
|
+
)
|
67
|
+
|
68
|
+
while files_stack:
|
69
|
+
f = files_stack.pop()
|
70
|
+
if f["name"] in current_volume:
|
71
|
+
files_stack.append(f)
|
72
|
+
yield current_volume
|
73
|
+
current_volume = {}
|
74
|
+
current_size = 0
|
75
|
+
continue
|
76
|
+
# For each file, we have to do 1 of 4 things:
|
77
|
+
# - Add the file as such to the current volume if possible.
|
78
|
+
# - Split the file and add the first part to the current volume and push the second part back onto the stack.
|
79
|
+
# - If that's not possible, check if current volume is empty:
|
80
|
+
# - If empty, add first line of file to current volume and push rest onto stack (This volume will exceed MAX_MB).
|
81
|
+
# - If not, push file back to stack and yield current volume.
|
82
|
+
fsize = _file_size(f)
|
83
|
+
rem = max_bytes - current_size
|
84
|
+
if fsize <= rem:
|
85
|
+
current_volume[f["name"]] = {
|
86
|
+
"offset": f["offset"],
|
87
|
+
"content": f["content"],
|
88
|
+
}
|
89
|
+
current_size += fsize
|
90
|
+
else:
|
91
|
+
num_lines = _num_lines_from_num_bytes(f, rem)
|
92
|
+
if not num_lines and not current_volume:
|
93
|
+
num_lines = 1
|
94
|
+
if num_lines:
|
95
|
+
f1, f2 = _split_file(f, num_lines)
|
96
|
+
current_volume[f1["name"]] = {
|
97
|
+
"offset": f1["offset"],
|
98
|
+
"content": f1["content"],
|
99
|
+
}
|
100
|
+
files_stack.append(f2)
|
101
|
+
yield current_volume
|
102
|
+
current_volume = {}
|
103
|
+
current_size = 0
|
104
|
+
continue
|
105
|
+
else:
|
106
|
+
files_stack.append(f)
|
107
|
+
yield current_volume
|
108
|
+
current_volume = {}
|
109
|
+
current_size = 0
|
110
|
+
continue
|
111
|
+
if current_size >= max_bytes:
|
112
|
+
yield current_volume
|
113
|
+
current_volume = {}
|
114
|
+
current_size = 0
|
115
|
+
continue
|
116
|
+
|
117
|
+
if current_volume:
|
118
|
+
yield current_volume
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import os
|
2
|
+
from typing import Callable, Generator, Union
|
3
|
+
|
4
|
+
WANDB_DIRS = ("wandb", ".wandb")
|
5
|
+
|
6
|
+
CONFIG_FNAME = "config.yaml"
|
7
|
+
OUTPUT_FNAME = "output.log"
|
8
|
+
DIFF_FNAME = "diff.patch"
|
9
|
+
SUMMARY_FNAME = "wandb-summary.json"
|
10
|
+
METADATA_FNAME = "wandb-metadata.json"
|
11
|
+
REQUIREMENTS_FNAME = "requirements.txt"
|
12
|
+
HISTORY_FNAME = "wandb-history.jsonl"
|
13
|
+
EVENTS_FNAME = "wandb-events.jsonl"
|
14
|
+
JOBSPEC_FNAME = "wandb-jobspec.json"
|
15
|
+
CONDA_ENVIRONMENTS_FNAME = "conda-environment.yaml"
|
16
|
+
|
17
|
+
|
18
|
+
def is_wandb_file(name: str) -> bool:
|
19
|
+
return (
|
20
|
+
name.startswith("wandb")
|
21
|
+
or name == METADATA_FNAME
|
22
|
+
or name == CONFIG_FNAME
|
23
|
+
or name == REQUIREMENTS_FNAME
|
24
|
+
or name == OUTPUT_FNAME
|
25
|
+
or name == DIFF_FNAME
|
26
|
+
or name == CONDA_ENVIRONMENTS_FNAME
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
def filtered_dir(
|
31
|
+
root: str,
|
32
|
+
include_fn: Union[Callable[[str, str], bool], Callable[[str], bool]],
|
33
|
+
exclude_fn: Union[Callable[[str, str], bool], Callable[[str], bool]],
|
34
|
+
) -> Generator[str, None, None]:
|
35
|
+
"""Simple generator to walk a directory."""
|
36
|
+
import inspect
|
37
|
+
|
38
|
+
# compatibility with old API, which didn't pass root
|
39
|
+
def _include_fn(path: str, root: str) -> bool:
|
40
|
+
return (
|
41
|
+
include_fn(path, root) # type: ignore
|
42
|
+
if len(inspect.signature(include_fn).parameters) == 2
|
43
|
+
else include_fn(path) # type: ignore
|
44
|
+
)
|
45
|
+
|
46
|
+
def _exclude_fn(path: str, root: str) -> bool:
|
47
|
+
return (
|
48
|
+
exclude_fn(path, root) # type: ignore
|
49
|
+
if len(inspect.signature(exclude_fn).parameters) == 2
|
50
|
+
else exclude_fn(path) # type: ignore
|
51
|
+
)
|
52
|
+
|
53
|
+
for dirpath, _, files in os.walk(root):
|
54
|
+
for fname in files:
|
55
|
+
file_path = os.path.join(dirpath, fname)
|
56
|
+
if _include_fn(file_path, root) and not _exclude_fn(file_path, root):
|
57
|
+
yield file_path
|
58
|
+
|
59
|
+
|
60
|
+
def exclude_wandb_fn(path: str, root: str) -> bool:
|
61
|
+
return any(
|
62
|
+
os.path.relpath(path, root).startswith(wandb_dir + os.sep)
|
63
|
+
for wandb_dir in WANDB_DIRS
|
64
|
+
)
|
@@ -0,0 +1,372 @@
|
|
1
|
+
import contextlib
|
2
|
+
import ctypes
|
3
|
+
import errno
|
4
|
+
import logging
|
5
|
+
import os
|
6
|
+
import platform
|
7
|
+
import re
|
8
|
+
import shutil
|
9
|
+
import tempfile
|
10
|
+
import threading
|
11
|
+
from pathlib import Path
|
12
|
+
from typing import IO, Any, BinaryIO, Generator, Optional
|
13
|
+
|
14
|
+
from wandb.sdk.lib.paths import StrPath
|
15
|
+
|
16
|
+
logger = logging.getLogger(__name__)
|
17
|
+
|
18
|
+
# https://en.wikipedia.org/wiki/Filename#Comparison_of_filename_limitations
|
19
|
+
PROBLEMATIC_PATH_CHARS = "".join(chr(i) for i in range(0, 32)) + ':"*<>?|'
|
20
|
+
|
21
|
+
|
22
|
+
def mkdir_exists_ok(dir_name: StrPath) -> None:
|
23
|
+
"""Create `dir_name` and any parent directories if they don't exist.
|
24
|
+
|
25
|
+
Raises:
|
26
|
+
FileExistsError: if `dir_name` exists and is not a directory.
|
27
|
+
PermissionError: if `dir_name` is not writable.
|
28
|
+
"""
|
29
|
+
try:
|
30
|
+
os.makedirs(dir_name, exist_ok=True)
|
31
|
+
except FileExistsError as e:
|
32
|
+
raise FileExistsError(f"{dir_name!s} exists and is not a directory") from e
|
33
|
+
except PermissionError as e:
|
34
|
+
raise PermissionError(f"{dir_name!s} is not writable") from e
|
35
|
+
|
36
|
+
|
37
|
+
def path_fallbacks(path: StrPath) -> Generator[str, None, None]:
|
38
|
+
"""Yield variations of `path` that may exist on the filesystem.
|
39
|
+
|
40
|
+
Return a sequence of paths that should be checked in order for existence or
|
41
|
+
create-ability. Essentially, keep replacing "suspect" characters until we run out.
|
42
|
+
"""
|
43
|
+
path = str(path)
|
44
|
+
root, tail = os.path.splitdrive(path)
|
45
|
+
yield os.path.join(root, tail)
|
46
|
+
for char in PROBLEMATIC_PATH_CHARS:
|
47
|
+
if char in tail:
|
48
|
+
tail = tail.replace(char, "-")
|
49
|
+
yield os.path.join(root, tail)
|
50
|
+
|
51
|
+
|
52
|
+
def mkdir_allow_fallback(dir_name: StrPath) -> StrPath:
|
53
|
+
"""Create `dir_name`, removing invalid path characters if necessary.
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
The path to the created directory, which may not be the original path.
|
57
|
+
"""
|
58
|
+
for new_name in path_fallbacks(dir_name):
|
59
|
+
try:
|
60
|
+
os.makedirs(new_name, exist_ok=True)
|
61
|
+
if Path(new_name) != Path(dir_name):
|
62
|
+
logger.warning(f"Creating '{new_name}' instead of '{dir_name}'")
|
63
|
+
return Path(new_name) if isinstance(dir_name, Path) else new_name
|
64
|
+
except (ValueError, NotADirectoryError):
|
65
|
+
pass
|
66
|
+
except OSError as e:
|
67
|
+
if e.errno != 22:
|
68
|
+
raise
|
69
|
+
|
70
|
+
raise OSError(f"Unable to create directory '{dir_name}'")
|
71
|
+
|
72
|
+
|
73
|
+
def files_in(path: StrPath) -> Generator[os.DirEntry, None, None]:
|
74
|
+
"""Yield a directory entry for each file under a given path (recursive)."""
|
75
|
+
if not os.path.isdir(path):
|
76
|
+
return
|
77
|
+
for entry in os.scandir(path):
|
78
|
+
if entry.is_dir():
|
79
|
+
yield from files_in(entry.path)
|
80
|
+
else:
|
81
|
+
yield entry
|
82
|
+
|
83
|
+
|
84
|
+
class WriteSerializingFile:
|
85
|
+
"""Wrapper for a file object that serializes writes."""
|
86
|
+
|
87
|
+
def __init__(self, f: BinaryIO) -> None:
|
88
|
+
self.lock = threading.Lock()
|
89
|
+
self.f = f
|
90
|
+
|
91
|
+
def write(self, *args, **kargs) -> None: # type: ignore
|
92
|
+
self.lock.acquire()
|
93
|
+
try:
|
94
|
+
self.f.write(*args, **kargs)
|
95
|
+
self.f.flush()
|
96
|
+
finally:
|
97
|
+
self.lock.release()
|
98
|
+
|
99
|
+
def close(self) -> None:
|
100
|
+
self.lock.acquire() # wait for pending writes
|
101
|
+
try:
|
102
|
+
self.f.close()
|
103
|
+
finally:
|
104
|
+
self.lock.release()
|
105
|
+
|
106
|
+
|
107
|
+
class CRDedupedFile(WriteSerializingFile):
|
108
|
+
def __init__(self, f: BinaryIO) -> None:
|
109
|
+
super().__init__(f=f)
|
110
|
+
self._buff = b""
|
111
|
+
|
112
|
+
def write(self, data) -> None: # type: ignore
|
113
|
+
lines = re.split(b"\r\n|\n", data)
|
114
|
+
ret = [] # type: ignore
|
115
|
+
for line in lines:
|
116
|
+
if line[:1] == b"\r":
|
117
|
+
if ret:
|
118
|
+
ret.pop()
|
119
|
+
elif self._buff:
|
120
|
+
self._buff = b""
|
121
|
+
line = line.split(b"\r")[-1]
|
122
|
+
if line:
|
123
|
+
ret.append(line)
|
124
|
+
if self._buff:
|
125
|
+
ret.insert(0, self._buff)
|
126
|
+
if ret:
|
127
|
+
self._buff = ret.pop()
|
128
|
+
super().write(b"\n".join(ret) + b"\n")
|
129
|
+
|
130
|
+
def close(self) -> None:
|
131
|
+
if self._buff:
|
132
|
+
super().write(self._buff)
|
133
|
+
super().close()
|
134
|
+
|
135
|
+
|
136
|
+
def copy_or_overwrite_changed(source_path: StrPath, target_path: StrPath) -> StrPath:
|
137
|
+
"""Copy source_path to target_path, unless it already exists with the same mtime.
|
138
|
+
|
139
|
+
We liberally add write permissions to deal with the case of multiple users needing
|
140
|
+
to share the same cache or run directory.
|
141
|
+
|
142
|
+
Args:
|
143
|
+
source_path: The path to the file to copy.
|
144
|
+
target_path: The path to copy the file to.
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
The path to the copied file (which may be different from target_path).
|
148
|
+
"""
|
149
|
+
return_type = type(target_path)
|
150
|
+
|
151
|
+
target_path = system_preferred_path(target_path, warn=True)
|
152
|
+
|
153
|
+
need_copy = (
|
154
|
+
not os.path.isfile(target_path)
|
155
|
+
or os.stat(source_path).st_mtime != os.stat(target_path).st_mtime
|
156
|
+
)
|
157
|
+
|
158
|
+
permissions_plus_write = os.stat(source_path).st_mode
|
159
|
+
if need_copy:
|
160
|
+
dir_name, file_name = os.path.split(target_path)
|
161
|
+
target_path = os.path.join(mkdir_allow_fallback(dir_name), file_name)
|
162
|
+
try:
|
163
|
+
# Use copy2 to preserve file metadata (including modified time).
|
164
|
+
shutil.copy2(source_path, target_path)
|
165
|
+
except PermissionError:
|
166
|
+
# If the file is read-only try to make it writable.
|
167
|
+
try:
|
168
|
+
os.chmod(target_path, permissions_plus_write)
|
169
|
+
shutil.copy2(source_path, target_path)
|
170
|
+
except PermissionError as e:
|
171
|
+
raise PermissionError("Unable to overwrite '{target_path!s}'") from e
|
172
|
+
# Prevent future permissions issues by universal write permissions now.
|
173
|
+
os.chmod(target_path, permissions_plus_write)
|
174
|
+
|
175
|
+
return return_type(target_path) # type: ignore # 'os.PathLike' is abstract.
|
176
|
+
|
177
|
+
|
178
|
+
@contextlib.contextmanager
|
179
|
+
def safe_open(
|
180
|
+
path: StrPath, mode: str = "r", *args: Any, **kwargs: Any
|
181
|
+
) -> Generator[IO, None, None]:
|
182
|
+
"""Open a file, ensuring any changes only apply atomically after close.
|
183
|
+
|
184
|
+
This context manager ensures that even unsuccessful writes will not leave a "dirty"
|
185
|
+
file or overwrite good data, and that all temp data is cleaned up.
|
186
|
+
|
187
|
+
The semantics and behavior are intended to be nearly identical to the built-in
|
188
|
+
open() function. Differences:
|
189
|
+
- It creates any parent directories that don't exist, rather than raising.
|
190
|
+
- In 'x' mode, it checks at the beginning AND end of the write and fails if the
|
191
|
+
file exists either time.
|
192
|
+
"""
|
193
|
+
path = Path(path).resolve()
|
194
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
195
|
+
|
196
|
+
if "x" in mode and path.exists():
|
197
|
+
raise FileExistsError(f"{path!s} already exists")
|
198
|
+
|
199
|
+
if "r" in mode and "+" not in mode:
|
200
|
+
# This is read-only, so we can just open the original file.
|
201
|
+
# TODO (hugh): create a reflink and read from that.
|
202
|
+
with path.open(mode, *args, **kwargs) as f:
|
203
|
+
yield f
|
204
|
+
return
|
205
|
+
|
206
|
+
with tempfile.TemporaryDirectory(dir=path.parent) as tmp_dir:
|
207
|
+
tmp_path = Path(tmp_dir) / path.name
|
208
|
+
|
209
|
+
if ("r" in mode or "a" in mode) and path.exists():
|
210
|
+
# We need to copy the original file in order to support reads and appends.
|
211
|
+
# TODO (hugh): use reflinks to avoid the copy on platforms that support it.
|
212
|
+
shutil.copy2(path, tmp_path)
|
213
|
+
|
214
|
+
with tmp_path.open(mode, *args, **kwargs) as f:
|
215
|
+
yield f
|
216
|
+
f.flush()
|
217
|
+
os.fsync(f.fileno())
|
218
|
+
|
219
|
+
if "x" in mode:
|
220
|
+
# Ensure that if another process has beaten us to writing the file we raise
|
221
|
+
# rather than overwrite. os.link() atomically creates a hard link to the
|
222
|
+
# target file and will raise FileExistsError if the target already exists.
|
223
|
+
os.link(tmp_path, path)
|
224
|
+
os.unlink(tmp_path)
|
225
|
+
else:
|
226
|
+
tmp_path.replace(path)
|
227
|
+
|
228
|
+
|
229
|
+
def safe_copy(source_path: StrPath, target_path: StrPath) -> StrPath:
|
230
|
+
"""Copy a file atomically.
|
231
|
+
|
232
|
+
Copying is not usually atomic, and on operating systems that allow multiple
|
233
|
+
writers to the same file, the result can get corrupted. If two writers copy
|
234
|
+
to the same file, the contents can become interleaved.
|
235
|
+
|
236
|
+
We mitigate the issue somewhat by copying to a temporary file first and
|
237
|
+
then renaming. Renaming is atomic: if process 1 renames file A to X and
|
238
|
+
process 2 renames file B to X, then X will either contain the contents
|
239
|
+
of A or the contents of B, not some mixture of both.
|
240
|
+
"""
|
241
|
+
# TODO (hugh): check that there is enough free space.
|
242
|
+
output_path = Path(target_path).resolve()
|
243
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
244
|
+
with tempfile.TemporaryDirectory(dir=output_path.parent) as tmp_dir:
|
245
|
+
tmp_path = (Path(tmp_dir) / Path(source_path).name).with_suffix(".tmp")
|
246
|
+
shutil.copy2(source_path, tmp_path)
|
247
|
+
tmp_path.replace(output_path)
|
248
|
+
return target_path
|
249
|
+
|
250
|
+
|
251
|
+
def _reflink_linux(existing_path: Path, new_path: Path) -> None:
|
252
|
+
"""Create a reflink to `existing_path` at `new_path` on Linux."""
|
253
|
+
import fcntl
|
254
|
+
|
255
|
+
FICLONE = 0x40049409 # magic number from <linux/fs.h> # noqa: N806
|
256
|
+
with open(existing_path, "rb") as t_f, open(new_path, "wb+") as l_f:
|
257
|
+
fcntl.ioctl(l_f.fileno(), FICLONE, t_f.fileno())
|
258
|
+
|
259
|
+
|
260
|
+
def _reflink_macos(existing_path: Path, new_path: Path) -> None:
|
261
|
+
try:
|
262
|
+
clib = ctypes.CDLL("libc.dylib", use_errno=True)
|
263
|
+
except (FileNotFoundError, OSError) as e:
|
264
|
+
if ctypes.get_errno() != errno.ENOENT and not isinstance(e, FileNotFoundError):
|
265
|
+
raise
|
266
|
+
# Before macOS 11 (<Nov 2020) clib was in libSystem.dylib, so we can try there.
|
267
|
+
clib = ctypes.CDLL("/usr/lib/libSystem.dylib", use_errno=True)
|
268
|
+
|
269
|
+
try:
|
270
|
+
clonefile = clib.clonefile
|
271
|
+
except AttributeError:
|
272
|
+
raise OSError(errno.ENOTSUP, "'clonefile' is not available on this system")
|
273
|
+
|
274
|
+
clonefile.argtypes = (ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int)
|
275
|
+
clonefile.restype = ctypes.c_int
|
276
|
+
|
277
|
+
if clonefile(os.fsencode(existing_path), os.fsencode(new_path), ctypes.c_int(0)):
|
278
|
+
# Anything other than 0 is an error.
|
279
|
+
err = ctypes.get_errno()
|
280
|
+
raise OSError(err, os.strerror(err), existing_path)
|
281
|
+
|
282
|
+
|
283
|
+
def reflink(existing_path: StrPath, new_path: StrPath, overwrite: bool = False) -> None:
|
284
|
+
"""Create a reflink to `existing_path` at `new_path`.
|
285
|
+
|
286
|
+
A reflink (reflective link) is a copy-on-write reference to a file. Once linked, the
|
287
|
+
file and link are both "real" files (not symbolic or hard links) and each can be
|
288
|
+
modified independently without affecting the other; however, they share the same
|
289
|
+
underlying data blocks on disk so until one is modified they are "zero-cost" copies.
|
290
|
+
|
291
|
+
Reflinks have all the functionality of copies, so we should use them wherever they
|
292
|
+
are supported if we would otherwise copy a file. (This is not particularly radical--
|
293
|
+
GNU `cp` defaults to `reflink=auto`, using it whenever available) However, support
|
294
|
+
for them is limited to a small number of filesystems. They should work on:
|
295
|
+
- Linux with a Btrfs or XFS filesystem (NOT ext4)
|
296
|
+
- macOS 10.13 or later with an APFS filesystem (called clone files)
|
297
|
+
|
298
|
+
Reflinks are also supported on Solaris and Windows with ReFSv2, but we haven't
|
299
|
+
implemented support for them.
|
300
|
+
|
301
|
+
Like hard links, a reflink can only be created on the same filesystem as the target.
|
302
|
+
"""
|
303
|
+
if platform.system() == "Linux":
|
304
|
+
link_fn = _reflink_linux
|
305
|
+
elif platform.system() == "Darwin":
|
306
|
+
link_fn = _reflink_macos
|
307
|
+
else:
|
308
|
+
raise OSError(
|
309
|
+
errno.ENOTSUP, f"reflinks are not supported on {platform.system()}"
|
310
|
+
)
|
311
|
+
|
312
|
+
new_path = Path(new_path).resolve()
|
313
|
+
existing_path = Path(existing_path).resolve()
|
314
|
+
if new_path.exists():
|
315
|
+
if not overwrite:
|
316
|
+
raise FileExistsError(f"{new_path} already exists")
|
317
|
+
logger.warning(f"Overwriting existing file {new_path}.")
|
318
|
+
new_path.unlink()
|
319
|
+
|
320
|
+
# Create any missing parent directories.
|
321
|
+
new_path.parent.mkdir(parents=True, exist_ok=True)
|
322
|
+
|
323
|
+
try:
|
324
|
+
link_fn(existing_path, new_path)
|
325
|
+
except OSError as e:
|
326
|
+
base_msg = f"failed to create reflink from {existing_path} to {new_path}."
|
327
|
+
if e.errno in (errno.EPERM, errno.EACCES):
|
328
|
+
raise PermissionError(f"Insufficient permissions; {base_msg}") from e
|
329
|
+
if e.errno == errno.ENOENT:
|
330
|
+
raise FileNotFoundError(f"File not found; {base_msg}") from e
|
331
|
+
if e.errno == errno.EXDEV:
|
332
|
+
raise ValueError(f"Cannot link across filesystems; {base_msg}") from e
|
333
|
+
if e.errno == errno.EISDIR:
|
334
|
+
raise IsADirectoryError(f"Cannot reflink a directory; {base_msg}") from e
|
335
|
+
if e.errno in (errno.EOPNOTSUPP, errno.ENOTSUP):
|
336
|
+
raise OSError(
|
337
|
+
errno.ENOTSUP,
|
338
|
+
f"Filesystem does not support reflinks; {base_msg}",
|
339
|
+
) from e
|
340
|
+
if e.errno == errno.EINVAL:
|
341
|
+
raise ValueError(f"Cannot link file ranges; {base_msg}") from e
|
342
|
+
raise
|
343
|
+
|
344
|
+
|
345
|
+
def check_exists(path: StrPath) -> Optional[StrPath]:
|
346
|
+
"""Look for variations of `path` and return the first found.
|
347
|
+
|
348
|
+
This exists to support former behavior around system-dependent paths; we used to use
|
349
|
+
':' in Artifact paths unless we were on Windows, but this has issues when e.g. a
|
350
|
+
Linux machine is accessing an NTFS filesystem; we might need to look for the
|
351
|
+
alternate path. This checks all the possible directories we would consider creating.
|
352
|
+
"""
|
353
|
+
for dest in path_fallbacks(path):
|
354
|
+
if os.path.exists(dest):
|
355
|
+
return Path(dest) if isinstance(path, Path) else dest
|
356
|
+
return None
|
357
|
+
|
358
|
+
|
359
|
+
def system_preferred_path(path: StrPath, warn: bool = False) -> StrPath:
|
360
|
+
"""Replace ':' with '-' in paths on Windows.
|
361
|
+
|
362
|
+
Args:
|
363
|
+
path: The path to convert.
|
364
|
+
warn: Whether to warn if ':' is replaced.
|
365
|
+
"""
|
366
|
+
if platform.system() != "Windows":
|
367
|
+
return path
|
368
|
+
head, tail = os.path.splitdrive(path)
|
369
|
+
if warn and ":" in tail:
|
370
|
+
logger.warning(f"Replacing ':' in {tail} with '-'")
|
371
|
+
new_path = head + tail.replace(":", "-")
|
372
|
+
return Path(new_path) if isinstance(path, Path) else new_path
|