openrunner-sdk 2.37.34__tar.gz → 2.37.35__tar.gz
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.
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/PKG-INFO +5 -1
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/cli.py +31 -4
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/datasets.py +32 -4
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/__init__.py +54 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/modal_provider.py +7 -1
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/mcp_server.py +5 -2
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/pyproject.toml +2 -2
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/conftest.py +12 -2
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/integration/conftest.py +7 -1
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_aliases.py +4 -0
- openrunner_sdk-2.37.35/tests/test_api_client_methods.py +596 -0
- openrunner_sdk-2.37.35/tests/test_api_client_transport.py +981 -0
- openrunner_sdk-2.37.35/tests/test_cli_artifact_sweep.py +562 -0
- openrunner_sdk-2.37.35/tests/test_cli_datasets.py +505 -0
- openrunner_sdk-2.37.35/tests/test_cli_gpu_registry_deploy.py +648 -0
- openrunner_sdk-2.37.35/tests/test_cli_infra.py +628 -0
- openrunner_sdk-2.37.35/tests/test_cli_remainder.py +1525 -0
- openrunner_sdk-2.37.35/tests/test_cli_topup.py +989 -0
- openrunner_sdk-2.37.35/tests/test_datasets_module.py +1048 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_finish.py +14 -15
- openrunner_sdk-2.37.35/tests/test_gpu/test_gpu_cluster.py +994 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_sdk_gpu_api.py +9 -7
- openrunner_sdk-2.37.35/tests/test_gpu_modal_creds.py +183 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_init.py +7 -7
- openrunner_sdk-2.37.35/tests/test_init_facade.py +908 -0
- openrunner_sdk-2.37.35/tests/test_integration_setA.py +895 -0
- openrunner_sdk-2.37.35/tests/test_integration_setB.py +1387 -0
- openrunner_sdk-2.37.35/tests/test_integration_setC.py +1099 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_log.py +16 -9
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_log_code.py +13 -13
- openrunner_sdk-2.37.35/tests/test_machine_migrate.py +922 -0
- openrunner_sdk-2.37.35/tests/test_mcp_server.py +2503 -0
- openrunner_sdk-2.37.35/tests/test_media_extra.py +756 -0
- openrunner_sdk-2.37.35/tests/test_patent_scan.py +777 -0
- openrunner_sdk-2.37.35/tests/test_plot_media_extra2.py +647 -0
- openrunner_sdk-2.37.35/tests/test_prompt_module.py +603 -0
- openrunner_sdk-2.37.35/tests/test_pure_modules.py +551 -0
- openrunner_sdk-2.37.35/tests/test_redact.py +476 -0
- openrunner_sdk-2.37.35/tests/test_reload_module.py +795 -0
- openrunner_sdk-2.37.35/tests/test_research_module.py +669 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_resume.py +6 -6
- openrunner_sdk-2.37.35/tests/test_run_module.py +1201 -0
- openrunner_sdk-2.37.35/tests/test_sdk_cluster_j1.py +744 -0
- openrunner_sdk-2.37.35/tests/test_sdk_cluster_j2.py +863 -0
- openrunner_sdk-2.37.35/tests/test_sdk_cluster_j3.py +1086 -0
- openrunner_sdk-2.37.35/tests/test_sdk_cluster_j4.py +1569 -0
- openrunner_sdk-2.37.35/tests/test_sdk_core_edges.py +200 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_sdk_features.py +18 -17
- openrunner_sdk-2.37.35/tests/test_session_module.py +848 -0
- openrunner_sdk-2.37.35/tests/test_topup_hi.py +733 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/.gitignore +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/=6.0 +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/=8.1 +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/README.md +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/CLAUDE.md +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/_safepath.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/_secret_rules.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/api_client.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/artifact.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/autoresearch.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/buffer.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/cache.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/config.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/cost.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/dataset.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/environment.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/evaluation.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/feedback.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/git_info.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/api_integration.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/cost_guard.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/gpu_types.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/price_compare.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/provider_base.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/lambda_cloud.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/ovhcloud.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/runpod.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/vastai.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/runner.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/workspace_sync.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/guardrails.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/handover.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/hooks/patent-lab-post-commit +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/install_commands.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/accelerate.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/anthropic_tracer.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/catboost.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/diffusers.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/fastai.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/forced_alignment.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/gladia.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/gymnasium.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/huggingface.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/hydra.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/ignite.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/jax.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/keras.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/langchain.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/lightgbm.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/lightning.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/llamaindex.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/openai_finetune.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/openai_tracer.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/optuna.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/pytorch.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/sb3.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/sklearn.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/skypilot.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/tensorflow.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/trl.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/tts.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/ultralytics.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/voice_agent.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/whisper.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/integration/xgboost.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/launch.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/machine.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/media.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/migrate.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/model.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/model_card.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/offline.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/patent_scan.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/pii.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/plot.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/projects.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/prompt.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/query_api.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/redact.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/reload.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/research.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/research_policy.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/run.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/scorers.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/sender.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/session.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/settings.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/summary.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/sweep.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/sync.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/system_metrics.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/tensorboard.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/tools/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/tools/patent_report.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/trace.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/transcript_formatter.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/wal.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/wandb_compat/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/wandb_compat/_shim.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/wer.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/scripts/gen_betterleaks_rules.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-aaa/config.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-aaa/metadata.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-aaa/metrics.jsonl +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-aaa/summary.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/manifest.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/weights.bin +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/manifest.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/preview.png +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/config.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/metadata.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/metrics.jsonl +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/fixtures/wandb-export-mini/run-bbb/summary.json +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/integration/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/integration/test_artifact_round_trip.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_alert.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_api_client.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_artifact.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_buffer.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_cache.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_class_scorers.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_cli.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_config.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_evaluation.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_git_info.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/__init__.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/conftest.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_cost_guard.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_gpu_types.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_lambda.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_modal.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_ovhcloud.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_price_compare.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_provider_base.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_runner.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_runpod.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_vastai.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_gpu/test_workspace_sync.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_install_commands.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_fastai.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_huggingface.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_keras.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_langchain.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_lightning.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_pytorch.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_sklearn.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_integration_xgboost.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_launch.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_mcp_decisions.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_mcp_monitor.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_mcp_predictions.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_media.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_migrate.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_offline.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_offline_sync.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_pii.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_plot.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_query_api.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_sender.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_session_sync.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_summary.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_sweep.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_system_metrics.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_trace.py +0 -0
- {openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/tests/test_wandb_compat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrunner-sdk
|
|
3
|
-
Version: 2.37.
|
|
3
|
+
Version: 2.37.35
|
|
4
4
|
Summary: OpenRunner SDK - W&B-compatible ML experiment tracking client
|
|
5
5
|
Project-URL: Homepage, https://github.com/jqueguiner/openrunner
|
|
6
6
|
Project-URL: Repository, https://github.com/jqueguiner/openrunner
|
|
@@ -32,10 +32,14 @@ Requires-Dist: anthropic<1.0,>=0.20; extra == 'anthropic'
|
|
|
32
32
|
Provides-Extra: catboost
|
|
33
33
|
Requires-Dist: catboost<2.0,>=1.2; extra == 'catboost'
|
|
34
34
|
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: matplotlib<5.0,>=3.7; extra == 'dev'
|
|
36
|
+
Requires-Dist: num2words2<2.0,>=0.1; extra == 'dev'
|
|
35
37
|
Requires-Dist: numpy<3.0,>=1.24; extra == 'dev'
|
|
38
|
+
Requires-Dist: pillow<13.0,>=10.0; extra == 'dev'
|
|
36
39
|
Requires-Dist: pytest-asyncio<1.0,>=0.23; extra == 'dev'
|
|
37
40
|
Requires-Dist: pytest-cov<6.0,>=5.0; extra == 'dev'
|
|
38
41
|
Requires-Dist: pytest<9.0,>=8.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: scikit-learn<2.0,>=1.3; extra == 'dev'
|
|
39
43
|
Provides-Extra: diffusers
|
|
40
44
|
Requires-Dist: diffusers<1.0,>=0.25; extra == 'diffusers'
|
|
41
45
|
Provides-Extra: fastai
|
|
@@ -4110,10 +4110,37 @@ def gpu_credentials() -> None:
|
|
|
4110
4110
|
|
|
4111
4111
|
@gpu_credentials.command("add")
|
|
4112
4112
|
@click.option("--org", "org_id", required=True, help="Organization ID (UUID)")
|
|
4113
|
-
@click.option("--provider", required=True, help="Provider, e.g. runpod, vastai, ovhcloud, lambda")
|
|
4114
|
-
@click.option("--api-key", "provider_key",
|
|
4115
|
-
|
|
4116
|
-
|
|
4113
|
+
@click.option("--provider", required=True, help="Provider, e.g. runpod, vastai, ovhcloud, lambda, modal")
|
|
4114
|
+
@click.option("--api-key", "provider_key", default=None, help="Provider API key. For ovhcloud/lambda pass a JSON blob. For modal use --token-id/--token-secret instead.")
|
|
4115
|
+
@click.option("--token-id", default=None, help="Modal token id (from `modal token new`). Use with --token-secret.")
|
|
4116
|
+
@click.option("--token-secret", default=None, help="Modal token secret. Use with --token-id.")
|
|
4117
|
+
@click.option("--profile", default=None, help="Modal profile / workspace (org), e.g. gladia. Optional.")
|
|
4118
|
+
def gpu_credentials_add(org_id: str, provider: str, provider_key: str | None,
|
|
4119
|
+
token_id: str | None, token_secret: str | None,
|
|
4120
|
+
profile: str | None) -> None:
|
|
4121
|
+
"""Store a provider credential on the platform (Fernet-encrypted, never returned).
|
|
4122
|
+
|
|
4123
|
+
Modal authenticates with a token PAIR, not a single key, plus an optional
|
|
4124
|
+
profile (workspace/org):
|
|
4125
|
+
|
|
4126
|
+
openrunner gpu credentials add --org ORG --provider modal \\
|
|
4127
|
+
--token-id ak-xxxx --token-secret as-xxxx --profile gladia
|
|
4128
|
+
"""
|
|
4129
|
+
import json as _json
|
|
4130
|
+
|
|
4131
|
+
# Modal: pack the token pair (+ optional profile) into the JSON blob.
|
|
4132
|
+
if token_id or token_secret:
|
|
4133
|
+
if not (token_id and token_secret):
|
|
4134
|
+
click.echo("Error: modal needs BOTH --token-id and --token-secret.", err=True)
|
|
4135
|
+
raise SystemExit(1)
|
|
4136
|
+
blob = {"token_id": token_id, "token_secret": token_secret}
|
|
4137
|
+
if profile:
|
|
4138
|
+
blob["profile"] = profile
|
|
4139
|
+
provider_key = _json.dumps(blob)
|
|
4140
|
+
if not provider_key:
|
|
4141
|
+
click.echo("Error: pass --api-key (or --token-id/--token-secret for modal).", err=True)
|
|
4142
|
+
raise SystemExit(1)
|
|
4143
|
+
|
|
4117
4144
|
from openrunner.gpu.api_integration import GpuAPIClient
|
|
4118
4145
|
|
|
4119
4146
|
settings = _load_settings()
|
|
@@ -330,8 +330,17 @@ class DatasetsClient:
|
|
|
330
330
|
try:
|
|
331
331
|
pr = self._http.post(f"/datasets/{ds_id}/files/presign", json=body)
|
|
332
332
|
_check(pr)
|
|
333
|
-
|
|
334
|
-
|
|
333
|
+
pj = pr.json()
|
|
334
|
+
url = pj["url"]
|
|
335
|
+
# If the presign signed a storage class (SignedHeaders include
|
|
336
|
+
# x-amz-storage-class), the PUT MUST echo that exact header value
|
|
337
|
+
# or S3 returns SignatureDoesNotMatch (403). OVH maps non-json
|
|
338
|
+
# content types to EXPRESS_ONEZONE, so a plain PUT fails for .jsonl.
|
|
339
|
+
put_headers = {}
|
|
340
|
+
sc = pj.get("storage_class")
|
|
341
|
+
if sc:
|
|
342
|
+
put_headers["x-amz-storage-class"] = sc
|
|
343
|
+
put = httpx.put(url, content=data, headers=put_headers, timeout=300.0)
|
|
335
344
|
put.raise_for_status()
|
|
336
345
|
return {"path": rel, "size_bytes": len(data), "sha256": sha, "content_type": ctype}
|
|
337
346
|
except Exception as e: # noqa: BLE001
|
|
@@ -765,9 +774,28 @@ class DatasetsClient:
|
|
|
765
774
|
return DatasetInfo._from_json(r.json())
|
|
766
775
|
|
|
767
776
|
def add_derivation(self, repo_id: str, parent_repo_id: str) -> DatasetInfo:
|
|
777
|
+
"""Record that ``repo_id`` is derived from ``parent_repo_id``.
|
|
778
|
+
|
|
779
|
+
The parent may be another OpenRunner dataset (``org/name``) OR an external
|
|
780
|
+
HuggingFace dataset. Prefix the ref with ``hf://`` (or pass a HF repo that
|
|
781
|
+
isn't an internal dataset) to record external Hub provenance, e.g.::
|
|
782
|
+
|
|
783
|
+
add_derivation("gladia/common-voice-16-1", "hf://fsicoli/common_voice_16_1")
|
|
784
|
+
add_derivation("gladia/common-voice-16-1", "fsicoli/common_voice_16_1")
|
|
785
|
+
"""
|
|
768
786
|
ds = self._resolve(repo_id)
|
|
769
|
-
|
|
770
|
-
|
|
787
|
+
explicit_hf = parent_repo_id.startswith(("hf://", "hf:"))
|
|
788
|
+
if not explicit_hf:
|
|
789
|
+
try:
|
|
790
|
+
parent = self._resolve(parent_repo_id)
|
|
791
|
+
r = self._http.post(f"/datasets/{ds.id}/derived-from",
|
|
792
|
+
json={"parent_dataset_id": str(parent.id)})
|
|
793
|
+
_check(r)
|
|
794
|
+
return DatasetInfo._from_json(r.json())
|
|
795
|
+
except Exception:
|
|
796
|
+
pass # not an internal dataset -> treat as external HF ref
|
|
797
|
+
r = self._http.post(f"/datasets/{ds.id}/derived-from",
|
|
798
|
+
json={"parent_hf_repo": parent_repo_id})
|
|
771
799
|
_check(r)
|
|
772
800
|
return DatasetInfo._from_json(r.json())
|
|
773
801
|
|
|
@@ -142,6 +142,20 @@ def _get_provider_instance(
|
|
|
142
142
|
Raises:
|
|
143
143
|
ValueError: If provider is unknown or no API key found.
|
|
144
144
|
"""
|
|
145
|
+
# Modal authenticates with a token PAIR (token_id + token_secret), not a
|
|
146
|
+
# single key. Resolve both and pass them through to ModalProvider.
|
|
147
|
+
if provider == "modal":
|
|
148
|
+
token_id, token_secret, profile = _resolve_modal_tokens(api_key)
|
|
149
|
+
if not (token_id and token_secret):
|
|
150
|
+
raise ValueError(
|
|
151
|
+
"No Modal credentials found. Set MODAL_TOKEN_ID + MODAL_TOKEN_SECRET "
|
|
152
|
+
"(from `modal token new`), pass api_key='{\"token_id\":..,\"token_secret\":..}', "
|
|
153
|
+
"or store them on the platform: "
|
|
154
|
+
"`openrunner gpu credentials add --provider modal --token-id .. --token-secret ..`."
|
|
155
|
+
)
|
|
156
|
+
cls = get_provider("modal")
|
|
157
|
+
return cls(api_key=token_id, api_secret=token_secret, profile=profile)
|
|
158
|
+
|
|
145
159
|
resolved_key = _resolve_api_key(provider, api_key, api_client)
|
|
146
160
|
if not resolved_key:
|
|
147
161
|
raise ValueError(
|
|
@@ -154,6 +168,46 @@ def _get_provider_instance(
|
|
|
154
168
|
return cls(api_key=resolved_key)
|
|
155
169
|
|
|
156
170
|
|
|
171
|
+
def _resolve_modal_tokens(
|
|
172
|
+
api_key: str | None,
|
|
173
|
+
) -> tuple[str | None, str | None, str | None]:
|
|
174
|
+
"""Resolve Modal's (token_id, token_secret, profile) triple.
|
|
175
|
+
|
|
176
|
+
``profile`` is Modal's workspace/organization (e.g. ``gladia``) and is
|
|
177
|
+
OPTIONAL. Priority: explicit ``api_key`` (a JSON blob
|
|
178
|
+
``{"token_id","token_secret","profile"?}``) > MODAL_TOKEN_ID +
|
|
179
|
+
MODAL_TOKEN_SECRET (+ MODAL_PROFILE) env > a JSON blob in MODAL_API_KEY.
|
|
180
|
+
Returns (None, None, None) if the tokens aren't resolvable.
|
|
181
|
+
"""
|
|
182
|
+
import json as _json
|
|
183
|
+
|
|
184
|
+
def _from_blob(raw: str) -> tuple[str | None, str | None, str | None]:
|
|
185
|
+
try:
|
|
186
|
+
c = _json.loads(raw)
|
|
187
|
+
except Exception:
|
|
188
|
+
return None, None, None
|
|
189
|
+
if not isinstance(c, dict):
|
|
190
|
+
return None, None, None
|
|
191
|
+
return (
|
|
192
|
+
c.get("token_id") or c.get("MODAL_TOKEN_ID"),
|
|
193
|
+
c.get("token_secret") or c.get("MODAL_TOKEN_SECRET"),
|
|
194
|
+
c.get("profile") or c.get("MODAL_PROFILE"),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if api_key:
|
|
198
|
+
tid, tsec, prof = _from_blob(api_key)
|
|
199
|
+
if tid and tsec:
|
|
200
|
+
return tid, tsec, prof
|
|
201
|
+
tid = os.environ.get("MODAL_TOKEN_ID")
|
|
202
|
+
tsec = os.environ.get("MODAL_TOKEN_SECRET")
|
|
203
|
+
if tid and tsec:
|
|
204
|
+
return tid, tsec, os.environ.get("MODAL_PROFILE")
|
|
205
|
+
blob = os.environ.get("MODAL_API_KEY")
|
|
206
|
+
if blob:
|
|
207
|
+
return _from_blob(blob)
|
|
208
|
+
return None, None, None
|
|
209
|
+
|
|
210
|
+
|
|
157
211
|
def _cost_guard_loop(
|
|
158
212
|
provider: GpuProvider,
|
|
159
213
|
instance: GpuInstance,
|
{openrunner_sdk-2.37.34 → openrunner_sdk-2.37.35}/openrunner/gpu/providers/modal_provider.py
RENAMED
|
@@ -86,7 +86,7 @@ class ModalProvider(GpuProvider):
|
|
|
86
86
|
it runs Python functions on-demand on GPU containers.
|
|
87
87
|
"""
|
|
88
88
|
|
|
89
|
-
def __init__(self, api_key: str, api_secret: str = "") -> None:
|
|
89
|
+
def __init__(self, api_key: str, api_secret: str = "", profile: str | None = None) -> None:
|
|
90
90
|
if not HAS_MODAL:
|
|
91
91
|
raise ProviderError(
|
|
92
92
|
provider="modal",
|
|
@@ -97,6 +97,12 @@ class ModalProvider(GpuProvider):
|
|
|
97
97
|
)
|
|
98
98
|
self._api_key = api_key
|
|
99
99
|
self._api_secret = api_secret
|
|
100
|
+
# Modal's workspace/organization (e.g. "gladia"); optional. Surfaced to
|
|
101
|
+
# the Modal client via the MODAL_PROFILE env var so deploys target it.
|
|
102
|
+
self._profile = profile or None
|
|
103
|
+
if self._profile:
|
|
104
|
+
import os
|
|
105
|
+
os.environ.setdefault("MODAL_PROFILE", self._profile)
|
|
100
106
|
# Track deployed apps in memory (Modal doesn't have a list-instances API)
|
|
101
107
|
self._apps: dict[str, dict[str, Any]] = {}
|
|
102
108
|
|
|
@@ -3232,7 +3232,10 @@ async def _tool_upload_artifact(args: dict) -> str:
|
|
|
3232
3232
|
# 3. Create a lightweight run for the upload
|
|
3233
3233
|
ts = datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
3234
3234
|
run_data = await _api_post("/runs", data={
|
|
3235
|
-
|
|
3235
|
+
# project_id already resolved above — pass it directly so run creation
|
|
3236
|
+
# never re-resolves the "org/project" string (which needs a separate org
|
|
3237
|
+
# field server-side and 400s without it).
|
|
3238
|
+
"project_id": project_id,
|
|
3236
3239
|
"display_name": f"artifact-upload-{art_name}-{ts}",
|
|
3237
3240
|
"tags": ["artifact-upload"] + ([art_type] if art_type else []),
|
|
3238
3241
|
"config": {"artifact_name": art_name, "artifact_type": art_type, "file_count": len(file_entries)},
|
|
@@ -3276,7 +3279,7 @@ async def _tool_upload_artifact(args: dict) -> str:
|
|
|
3276
3279
|
# 5. Upload files to presigned URLs
|
|
3277
3280
|
uploaded = 0
|
|
3278
3281
|
skipped = 0
|
|
3279
|
-
url_map = {u["name"]: u
|
|
3282
|
+
url_map = {u["name"]: (u.get("url") or u.get("presigned_url")) for u in upload_urls}
|
|
3280
3283
|
|
|
3281
3284
|
async with httpx.AsyncClient(timeout=300.0) as client:
|
|
3282
3285
|
for entry in file_entries:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "openrunner-sdk"
|
|
3
|
-
version = "2.37.
|
|
3
|
+
version = "2.37.35"
|
|
4
4
|
description = "OpenRunner SDK - W&B-compatible ML experiment tracking client"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -65,7 +65,7 @@ voice-agent = []
|
|
|
65
65
|
forced-alignment = ["matplotlib>=3.7,<4.0", "numpy>=1.24,<3.0"]
|
|
66
66
|
mcp = ["mcp>=1.0,<2.0"]
|
|
67
67
|
patent = ["httpx>=0.27,<1.0"]
|
|
68
|
-
dev = ["pytest>=8.0,<9.0", "pytest-asyncio>=0.23,<1.0", "pytest-cov>=5.0,<6.0", "numpy>=1.24,<3.0"]
|
|
68
|
+
dev = ["pytest>=8.0,<9.0", "pytest-asyncio>=0.23,<1.0", "pytest-cov>=5.0,<6.0", "numpy>=1.24,<3.0", "Pillow>=10.0,<13.0", "scikit-learn>=1.3,<2.0", "matplotlib>=3.7,<5.0", "num2words2>=0.1,<2.0"]
|
|
69
69
|
|
|
70
70
|
[tool.hatch.build.targets.wheel]
|
|
71
71
|
packages = ["openrunner"]
|
|
@@ -13,11 +13,21 @@ import pytest
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
@pytest.fixture
|
|
16
|
-
def clean_env(monkeypatch: pytest.MonkeyPatch) -> pytest.MonkeyPatch:
|
|
17
|
-
"""Clear all OPENRUNNER_*, OPENRUN_*, and WANDB_* env vars for a clean test environment.
|
|
16
|
+
def clean_env(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> pytest.MonkeyPatch:
|
|
17
|
+
"""Clear all OPENRUNNER_*, OPENRUN_*, and WANDB_* env vars for a clean test environment.
|
|
18
|
+
|
|
19
|
+
Also redirects HOME (and USERPROFILE) to a throwaway dir so tests never pick up
|
|
20
|
+
the developer's real ``~/.openrunner/session_config.json`` creds -- otherwise a
|
|
21
|
+
machine that has run ``openrunner login`` fails "no api key" / default-URL tests
|
|
22
|
+
that pass on a clean CI box.
|
|
23
|
+
"""
|
|
18
24
|
for var in list(os.environ):
|
|
19
25
|
if var.startswith(("OPENRUNNER_", "OPENRUN_", "WANDB_")):
|
|
20
26
|
monkeypatch.delenv(var, raising=False)
|
|
27
|
+
fake_home = tmp_path / "home"
|
|
28
|
+
fake_home.mkdir(exist_ok=True)
|
|
29
|
+
monkeypatch.setenv("HOME", str(fake_home))
|
|
30
|
+
monkeypatch.setenv("USERPROFILE", str(fake_home))
|
|
21
31
|
return monkeypatch
|
|
22
32
|
|
|
23
33
|
|
|
@@ -23,5 +23,11 @@ def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item
|
|
|
23
23
|
skip = pytest.mark.skip(
|
|
24
24
|
reason=f"live integration: set {', '.join(missing)} to enable"
|
|
25
25
|
)
|
|
26
|
+
# NOTE: a subdirectory conftest's modifyitems hook receives the WHOLE session's
|
|
27
|
+
# items, not just this directory's. Only skip the live integration tests that
|
|
28
|
+
# actually live under tests/integration/ -- otherwise the entire unit suite is
|
|
29
|
+
# skipped whenever these env vars are unset.
|
|
30
|
+
integration_dir = os.path.dirname(__file__)
|
|
26
31
|
for item in items:
|
|
27
|
-
item.
|
|
32
|
+
if str(item.fspath).startswith(integration_dir):
|
|
33
|
+
item.add_marker(skip)
|
|
@@ -187,6 +187,8 @@ def test_run_link_artifact_sets_aliases():
|
|
|
187
187
|
run._job_type = None
|
|
188
188
|
run._step = 0
|
|
189
189
|
run._state = "running"
|
|
190
|
+
run._artifacts_logged = 0
|
|
191
|
+
run._artifacts_used = 0
|
|
190
192
|
|
|
191
193
|
from openrunner.api_client import APIClient
|
|
192
194
|
from openrunner.buffer import WriteBuffer
|
|
@@ -236,6 +238,8 @@ def test_run_use_artifact_colon_syntax():
|
|
|
236
238
|
run._name = "test-run"
|
|
237
239
|
run._step = 0
|
|
238
240
|
run._state = "running"
|
|
241
|
+
run._artifacts_logged = 0
|
|
242
|
+
run._artifacts_used = 0
|
|
239
243
|
run._client = APIClient("http://test", "test-key", transport=transport)
|
|
240
244
|
run._buffer = WriteBuffer()
|
|
241
245
|
run._summary = Summary()
|