openrunner-sdk 2.37.1__tar.gz → 2.37.4__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.
Files changed (187) hide show
  1. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/.gitignore +4 -0
  2. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/PKG-INFO +1 -1
  3. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/__init__.py +322 -2
  4. openrunner_sdk-2.37.4/openrunner/_safepath.py +33 -0
  5. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/api_client.py +237 -8
  6. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/artifact.py +23 -12
  7. openrunner_sdk-2.37.4/openrunner/cache.py +263 -0
  8. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/cli.py +606 -1
  9. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/datasets.py +236 -13
  10. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/__init__.py +2 -0
  11. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/api_integration.py +23 -0
  12. openrunner_sdk-2.37.4/openrunner/gpu/runner.py +214 -0
  13. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/workspace_sync.py +2 -5
  14. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/install_commands.py +335 -0
  15. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/mcp_server.py +252 -8
  16. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/migrate.py +2 -3
  17. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/model.py +12 -2
  18. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/reload.py +10 -3
  19. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/run.py +129 -52
  20. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/session.py +10 -0
  21. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/pyproject.toml +1 -1
  22. openrunner_sdk-2.37.4/tests/test_gpu/test_runner.py +154 -0
  23. openrunner_sdk-2.37.1/openrunner/cache.py +0 -92
  24. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/=6.0 +0 -0
  25. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/=8.1 +0 -0
  26. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/README.md +0 -0
  27. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/CLAUDE.md +0 -0
  28. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/_secret_rules.py +0 -0
  29. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/autoresearch.py +0 -0
  30. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/buffer.py +0 -0
  31. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/config.py +0 -0
  32. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/cost.py +0 -0
  33. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/dataset.py +0 -0
  34. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/environment.py +0 -0
  35. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/evaluation.py +0 -0
  36. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/feedback.py +0 -0
  37. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/git_info.py +0 -0
  38. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/cost_guard.py +0 -0
  39. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/gpu_types.py +0 -0
  40. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/price_compare.py +0 -0
  41. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/provider_base.py +0 -0
  42. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/__init__.py +0 -0
  43. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/lambda_cloud.py +0 -0
  44. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/modal_provider.py +0 -0
  45. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/ovhcloud.py +0 -0
  46. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/runpod.py +0 -0
  47. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/gpu/providers/vastai.py +0 -0
  48. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/guardrails.py +0 -0
  49. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/handover.py +0 -0
  50. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/hooks/patent-lab-post-commit +0 -0
  51. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/__init__.py +0 -0
  52. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/accelerate.py +0 -0
  53. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/anthropic_tracer.py +0 -0
  54. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/catboost.py +0 -0
  55. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/diffusers.py +0 -0
  56. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/fastai.py +0 -0
  57. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/forced_alignment.py +0 -0
  58. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/gladia.py +0 -0
  59. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/gymnasium.py +0 -0
  60. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/huggingface.py +0 -0
  61. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/hydra.py +0 -0
  62. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/ignite.py +0 -0
  63. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/jax.py +0 -0
  64. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/keras.py +0 -0
  65. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/langchain.py +0 -0
  66. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/lightgbm.py +0 -0
  67. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/lightning.py +0 -0
  68. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/llamaindex.py +0 -0
  69. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/openai_finetune.py +0 -0
  70. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/openai_tracer.py +0 -0
  71. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/optuna.py +0 -0
  72. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/pytorch.py +0 -0
  73. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/sb3.py +0 -0
  74. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/sklearn.py +0 -0
  75. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/skypilot.py +0 -0
  76. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/tensorflow.py +0 -0
  77. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/trl.py +0 -0
  78. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/tts.py +0 -0
  79. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/ultralytics.py +0 -0
  80. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/voice_agent.py +0 -0
  81. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/whisper.py +0 -0
  82. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/integration/xgboost.py +0 -0
  83. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/launch.py +0 -0
  84. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/machine.py +0 -0
  85. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/media.py +0 -0
  86. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/model_card.py +0 -0
  87. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/offline.py +0 -0
  88. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/patent_scan.py +0 -0
  89. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/pii.py +0 -0
  90. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/plot.py +0 -0
  91. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/projects.py +0 -0
  92. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/prompt.py +0 -0
  93. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/query_api.py +0 -0
  94. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/redact.py +0 -0
  95. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/research.py +0 -0
  96. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/research_policy.py +0 -0
  97. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/scorers.py +0 -0
  98. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/sender.py +0 -0
  99. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/settings.py +0 -0
  100. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/summary.py +0 -0
  101. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/sweep.py +0 -0
  102. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/sync.py +0 -0
  103. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/system_metrics.py +0 -0
  104. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/tensorboard.py +0 -0
  105. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/tools/__init__.py +0 -0
  106. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/tools/patent_report.py +0 -0
  107. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/trace.py +0 -0
  108. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/transcript_formatter.py +0 -0
  109. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/wal.py +0 -0
  110. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/wandb_compat/__init__.py +0 -0
  111. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/wandb_compat/_shim.py +0 -0
  112. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/openrunner/wer.py +0 -0
  113. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/scripts/gen_betterleaks_rules.py +0 -0
  114. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/__init__.py +0 -0
  115. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/conftest.py +0 -0
  116. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-aaa/config.json +0 -0
  117. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-aaa/metadata.json +0 -0
  118. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-aaa/metrics.jsonl +0 -0
  119. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-aaa/summary.json +0 -0
  120. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/manifest.json +0 -0
  121. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/weights.bin +0 -0
  122. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/manifest.json +0 -0
  123. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/preview.png +0 -0
  124. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/config.json +0 -0
  125. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/metadata.json +0 -0
  126. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/metrics.jsonl +0 -0
  127. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/fixtures/wandb-export-mini/run-bbb/summary.json +0 -0
  128. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/integration/__init__.py +0 -0
  129. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/integration/conftest.py +0 -0
  130. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/integration/test_artifact_round_trip.py +0 -0
  131. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_alert.py +0 -0
  132. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_aliases.py +0 -0
  133. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_api_client.py +0 -0
  134. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_artifact.py +0 -0
  135. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_buffer.py +0 -0
  136. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_cache.py +0 -0
  137. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_class_scorers.py +0 -0
  138. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_cli.py +0 -0
  139. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_config.py +0 -0
  140. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_evaluation.py +0 -0
  141. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_finish.py +0 -0
  142. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_git_info.py +0 -0
  143. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/__init__.py +0 -0
  144. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/conftest.py +0 -0
  145. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_cost_guard.py +0 -0
  146. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_gpu_types.py +0 -0
  147. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_lambda.py +0 -0
  148. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_modal.py +0 -0
  149. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_ovhcloud.py +0 -0
  150. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_price_compare.py +0 -0
  151. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_provider_base.py +0 -0
  152. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_runpod.py +0 -0
  153. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_sdk_gpu_api.py +0 -0
  154. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_vastai.py +0 -0
  155. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_gpu/test_workspace_sync.py +0 -0
  156. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_init.py +0 -0
  157. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_install_commands.py +0 -0
  158. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_fastai.py +0 -0
  159. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_huggingface.py +0 -0
  160. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_keras.py +0 -0
  161. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_langchain.py +0 -0
  162. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_lightning.py +0 -0
  163. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_pytorch.py +0 -0
  164. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_sklearn.py +0 -0
  165. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_integration_xgboost.py +0 -0
  166. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_launch.py +0 -0
  167. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_log.py +0 -0
  168. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_log_code.py +0 -0
  169. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_mcp_decisions.py +0 -0
  170. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_mcp_monitor.py +0 -0
  171. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_mcp_predictions.py +0 -0
  172. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_media.py +0 -0
  173. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_migrate.py +0 -0
  174. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_offline.py +0 -0
  175. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_offline_sync.py +0 -0
  176. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_pii.py +0 -0
  177. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_plot.py +0 -0
  178. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_query_api.py +0 -0
  179. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_resume.py +0 -0
  180. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_sdk_features.py +0 -0
  181. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_sender.py +0 -0
  182. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_session_sync.py +0 -0
  183. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_summary.py +0 -0
  184. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_sweep.py +0 -0
  185. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_system_metrics.py +0 -0
  186. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_trace.py +0 -0
  187. {openrunner_sdk-2.37.1 → openrunner_sdk-2.37.4}/tests/test_wandb_compat.py +0 -0
@@ -237,3 +237,7 @@ data/
237
237
  # MkDocs build output
238
238
  /site/
239
239
  .claude/worktrees/
240
+
241
+ # Never commit DB dumps / backups (may contain prod user data)
242
+ *.sql
243
+ backup_*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrunner-sdk
3
- Version: 2.37.1
3
+ Version: 2.37.4
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
@@ -30,6 +30,10 @@ Public API:
30
30
  openrunner.alert -> Send an alert for the active run
31
31
  openrunner.log_artifact -> Upload an artifact
32
32
  openrunner.use_artifact -> Download an artifact (cached)
33
+ openrunner.push -> Publish a model/artifact in one call (HF push_to_hub)
34
+ openrunner.pull -> Download a model/artifact in one call (HF from_pretrained)
35
+ openrunner.load_model -> Pull + unpickle a Model (or return the local dir)
36
+ openrunner.list_files -> List file paths in an artifact version
33
37
  openrunner.sweep -> Create a hyperparameter sweep
34
38
  openrunner.agent -> Run a sweep agent loop
35
39
  openrunner.launch -> Create a remote execution job
@@ -92,9 +96,9 @@ from openrunner.datasets import (
92
96
  create_dataset,
93
97
  dataset_info,
94
98
  index_dataset,
99
+ iter_rows,
95
100
  list_datasets,
96
101
  link_project,
97
- list_files,
98
102
  load_dataset,
99
103
  add_derivation,
100
104
  push_dataset,
@@ -177,7 +181,7 @@ launch.from_run = _launch_from_run # type: ignore[attr-defined]
177
181
  # openrunner.trace.patch_openai() syntax
178
182
  trace.patch_openai = _patch_openai # type: ignore[attr-defined]
179
183
 
180
- __version__ = "2.37.1"
184
+ __version__ = "2.37.4"
181
185
 
182
186
  logger = logging.getLogger("openrunner")
183
187
 
@@ -936,6 +940,24 @@ def get_model_card(name: str) -> str | None:
936
940
  return None
937
941
 
938
942
 
943
+ # --- README aliases -------------------------------------------------------
944
+ # Artifacts are untyped file buckets; each carries a README.md, which is
945
+ # stored as the artifact's model card (``card_markdown``). ``set_readme`` /
946
+ # ``get_readme`` are thin aliases over ``set_model_card`` / ``get_model_card``
947
+ # for callers who think of it as a README rather than a "model card".
948
+
949
+ def set_readme(name: str, readme: str) -> dict[str, Any] | None:
950
+ """Set the README (model card) on an artifact by name. Alias of
951
+ :func:`set_model_card`. Never raises."""
952
+ return set_model_card(name, readme)
953
+
954
+
955
+ def get_readme(name: str) -> str | None:
956
+ """Return the README (card_markdown) for an artifact by name. Alias of
957
+ :func:`get_model_card`. Never raises."""
958
+ return get_model_card(name)
959
+
960
+
939
961
  def use_artifact(
940
962
  name: str, version: int | None = None, alias: str | None = None
941
963
  ) -> Path | None:
@@ -962,6 +984,304 @@ def use_artifact(
962
984
  return None
963
985
 
964
986
 
987
+ # ---------------------------------------------------------------------------
988
+ # HuggingFace-style one-liner ergonomics: push / pull / load_model / list_files
989
+ # ---------------------------------------------------------------------------
990
+
991
+
992
+ def _split_name(name: str, project: str | None) -> tuple[str, str | None]:
993
+ """Split a ``"project/name"`` (or ``"org/project/name"``) reference.
994
+
995
+ Accepts either the combined ``"project/name"`` form or a bare ``name``
996
+ plus an explicit ``project=`` argument. The project part may itself be an
997
+ ``"org/project"`` reference (which ``init()`` requires).
998
+
999
+ Returns ``(artifact_name, project_or_None)``.
1000
+
1001
+ Examples:
1002
+ _split_name("gladia/my-proj/my-model", None) -> ("my-model", "gladia/my-proj")
1003
+ _split_name("my-proj/my-model", None) -> ("my-model", "my-proj")
1004
+ _split_name("my-model", "gladia/my-proj") -> ("my-model", "gladia/my-proj")
1005
+ """
1006
+ if "/" in name and project is None:
1007
+ proj, _, artifact = name.rpartition("/")
1008
+ return artifact, (proj or None)
1009
+ return name, project
1010
+
1011
+
1012
+ def _ensure_run(project: str | None) -> "Run | None":
1013
+ """Return the active run, auto-initializing one if none exists.
1014
+
1015
+ Mirrors how ``model.Model`` resolves a run: reuse ``_active_run`` if set,
1016
+ otherwise create one with ``init(project=...)``. Never double-creates.
1017
+ """
1018
+ if _active_run is not None:
1019
+ return _active_run
1020
+ return init(project=project, save_code=False)
1021
+
1022
+
1023
+ def push(
1024
+ path: str,
1025
+ name: str,
1026
+ *,
1027
+ aliases: list[str] | None = None,
1028
+ description: str | None = None,
1029
+ card: str | None = None,
1030
+ metadata: dict[str, Any] | None = None,
1031
+ project: str | None = None,
1032
+ ) -> dict[str, Any] | None:
1033
+ """Publish a model/artifact in one call (HuggingFace ``push_to_hub`` style).
1034
+
1035
+ Uploads the file OR directory at ``path`` as an artifact named ``name``.
1036
+ Auto-initializes a run if none is active (reusing the active run otherwise).
1037
+
1038
+ Args:
1039
+ path: Path to a file or directory to upload.
1040
+ name: Artifact name — either ``"project/name"`` or a bare ``name`` with
1041
+ ``project=`` supplied.
1042
+ aliases: Optional aliases to tag the version (e.g. ``["production"]``).
1043
+ description: Optional artifact description.
1044
+ card: Optional markdown model card / README set on the artifact after
1045
+ upload (via :func:`set_model_card`).
1046
+ metadata: Optional artifact metadata dict.
1047
+ project: Project (``"org/project"``) when ``name`` is bare.
1048
+
1049
+ Returns:
1050
+ The created version info dict, or None on failure.
1051
+
1052
+ Example::
1053
+
1054
+ openrunner.push("model.safetensors", "gladia/my-project/my-model",
1055
+ aliases=["production"], card=open("README.md").read())
1056
+ """
1057
+ try:
1058
+ artifact_name, proj = _split_name(name, project)
1059
+ run = _ensure_run(proj)
1060
+ if run is None:
1061
+ logger.warning("openrunner.push(): could not resolve/create a run")
1062
+ return None
1063
+ result = run.log_model(
1064
+ path,
1065
+ name=artifact_name,
1066
+ aliases=aliases,
1067
+ description=description,
1068
+ metadata=metadata,
1069
+ )
1070
+ if result is not None and card:
1071
+ try:
1072
+ run.set_model_card(artifact_name, card)
1073
+ except Exception as e: # noqa: BLE001
1074
+ logger.warning("openrunner.push(): set_model_card failed: %s", e)
1075
+ return result
1076
+ except Exception as e: # noqa: BLE001
1077
+ logger.warning("openrunner.push() failed: %s", e)
1078
+ return None
1079
+
1080
+
1081
+ def pull(
1082
+ name: str,
1083
+ *,
1084
+ revision: int | str | None = None,
1085
+ filename: str | None = None,
1086
+ local_dir: str | None = None,
1087
+ project: str | None = None,
1088
+ ) -> str | None:
1089
+ """Download a model/artifact in one call (HuggingFace ``from_pretrained`` style).
1090
+
1091
+ Auto-initializes a run if none is active (read-only use still needs a run
1092
+ context today).
1093
+
1094
+ Args:
1095
+ name: Artifact name — ``"project/name"`` or bare ``name`` with ``project=``.
1096
+ revision: A version int OR an alias string (e.g. ``"production"``,
1097
+ ``"latest"``). Ints map to ``version=``; strings map to ``alias=``.
1098
+ filename: If given, return the path to just this one file within the
1099
+ version (the whole version is still fetched).
1100
+ local_dir: If given, download into this directory instead of the cache.
1101
+ project: Project (``"org/project"``) when ``name`` is bare.
1102
+
1103
+ Returns:
1104
+ The local directory path (or, when ``filename`` is set, the path to that
1105
+ file), or None on failure.
1106
+
1107
+ Example::
1108
+
1109
+ path = openrunner.pull("gladia/my-project/my-model", revision="production")
1110
+ """
1111
+ try:
1112
+ from pathlib import Path
1113
+
1114
+ artifact_name, proj = _split_name(name, project)
1115
+ run = _ensure_run(proj)
1116
+ if run is None:
1117
+ logger.warning("openrunner.pull(): could not resolve/create a run")
1118
+ return None
1119
+
1120
+ version: int | None = None
1121
+ alias: str | None = None
1122
+ if isinstance(revision, bool): # guard: bool is an int subclass
1123
+ revision = None
1124
+ if isinstance(revision, int):
1125
+ version = revision
1126
+ elif isinstance(revision, str):
1127
+ alias = revision
1128
+
1129
+ if local_dir is not None:
1130
+ local_path = run.use_model(
1131
+ artifact_name, version=version, alias=alias, dest_dir=local_dir
1132
+ )
1133
+ else:
1134
+ result = run.use_artifact(artifact_name, version=version, alias=alias)
1135
+ local_path = str(result) if result is not None else None
1136
+
1137
+ if local_path is None:
1138
+ return None
1139
+
1140
+ if filename:
1141
+ candidate = Path(local_path) / filename
1142
+ if candidate.exists():
1143
+ return str(candidate)
1144
+ # Fall back to a basename match anywhere in the tree.
1145
+ for p in Path(local_path).rglob("*"):
1146
+ if p.is_file() and p.name == filename:
1147
+ return str(p)
1148
+ logger.warning("openrunner.pull(): file %r not found in %s", filename, local_path)
1149
+ return None
1150
+
1151
+ return local_path
1152
+ except Exception as e: # noqa: BLE001
1153
+ logger.warning("openrunner.pull() failed: %s", e)
1154
+ return None
1155
+
1156
+
1157
+ def load_model(
1158
+ name: str,
1159
+ *,
1160
+ revision: int | str | None = None,
1161
+ project: str | None = None,
1162
+ ) -> "Any":
1163
+ """Load a model in one call. Thin wrapper over :func:`pull`.
1164
+
1165
+ If the pulled artifact looks like a pickled :class:`~openrunner.model.Model`
1166
+ (a single ``.pkl`` / ``model.pkl``), it is deserialized via
1167
+ ``Model.load``. Otherwise the local directory path is returned.
1168
+
1169
+ Args:
1170
+ name: Artifact name — ``"project/name"`` or bare ``name`` with ``project=``.
1171
+ revision: Version int or alias string.
1172
+ project: Project (``"org/project"``) when ``name`` is bare.
1173
+
1174
+ Returns:
1175
+ A :class:`~openrunner.model.Model` instance if the artifact is a
1176
+ pickled model, else the local directory path (str), or None on failure.
1177
+
1178
+ Example::
1179
+
1180
+ m = openrunner.load_model("gladia/my-project/my-model", revision="production")
1181
+ """
1182
+ try:
1183
+ from pathlib import Path
1184
+
1185
+ local_path = pull(name, revision=revision, project=project)
1186
+ if local_path is None:
1187
+ return None
1188
+
1189
+ p = Path(local_path)
1190
+ pkl = None
1191
+ if p.is_dir():
1192
+ candidate = p / "model.pkl"
1193
+ if candidate.exists():
1194
+ pkl = candidate
1195
+ else:
1196
+ pkls = list(p.glob("*.pkl"))
1197
+ if len(pkls) == 1:
1198
+ pkl = pkls[0]
1199
+ elif p.suffix == ".pkl":
1200
+ pkl = p
1201
+
1202
+ if pkl is not None:
1203
+ artifact_name, proj = _split_name(name, project)
1204
+ version = revision if isinstance(revision, int) and not isinstance(revision, bool) else None
1205
+ loaded = Model.load(artifact_name, version=version, project=proj)
1206
+ if loaded is not None:
1207
+ return loaded
1208
+ # Fall back to a direct unpickle if Model.load couldn't resolve it.
1209
+ try:
1210
+ import pickle
1211
+ with open(pkl, "rb") as f:
1212
+ return pickle.load(f)
1213
+ except Exception as e: # noqa: BLE001
1214
+ logger.warning("openrunner.load_model(): unpickle failed: %s", e)
1215
+
1216
+ return local_path
1217
+ except Exception as e: # noqa: BLE001
1218
+ logger.warning("openrunner.load_model() failed: %s", e)
1219
+ return None
1220
+
1221
+
1222
+ def list_files(
1223
+ name: str,
1224
+ *,
1225
+ revision: int | str | None = None,
1226
+ project: str | None = None,
1227
+ ) -> list[str]:
1228
+ """Return the file paths in an artifact version. Never raises.
1229
+
1230
+ Args:
1231
+ name: Artifact name — ``"project/name"`` or bare ``name`` with ``project=``.
1232
+ revision: Version int or alias string (default: latest).
1233
+ project: Project (``"org/project"``) when ``name`` is bare.
1234
+
1235
+ Returns:
1236
+ A list of file paths in the version (empty list on failure).
1237
+
1238
+ Example::
1239
+
1240
+ openrunner.list_files("gladia/my-project/my-model", revision="production")
1241
+ """
1242
+ try:
1243
+ artifact_name, proj = _split_name(name, project)
1244
+ run = _ensure_run(proj)
1245
+ if run is None:
1246
+ logger.warning("openrunner.list_files(): could not resolve/create a run")
1247
+ return []
1248
+
1249
+ version: int | None = None
1250
+ alias: str | None = None
1251
+ if isinstance(revision, bool):
1252
+ revision = None
1253
+ if isinstance(revision, int):
1254
+ version = revision
1255
+ elif isinstance(revision, str):
1256
+ alias = revision
1257
+
1258
+ info = run._client.use_artifact(run.id, artifact_name, version=version, alias=alias)
1259
+ if not info:
1260
+ return []
1261
+
1262
+ # Prefer the version's file listing if a version_id is available.
1263
+ version_id = info.get("version_id")
1264
+ if version_id:
1265
+ files = run._client.list_artifact_files(str(version_id))
1266
+ paths = [
1267
+ f.get("name") or f.get("path")
1268
+ for f in files
1269
+ if (f.get("name") or f.get("path"))
1270
+ ]
1271
+ if paths:
1272
+ return [str(p) for p in paths]
1273
+
1274
+ # Fall back to the file names embedded in the use-artifact response.
1275
+ return [
1276
+ str(f.get("name") or f.get("path"))
1277
+ for f in info.get("files", [])
1278
+ if (f.get("name") or f.get("path"))
1279
+ ]
1280
+ except Exception as e: # noqa: BLE001
1281
+ logger.warning("openrunner.list_files() failed: %s", e)
1282
+ return []
1283
+
1284
+
965
1285
  def should_stop() -> bool:
966
1286
  """Check if the server has requested the active run to stop.
967
1287
 
@@ -0,0 +1,33 @@
1
+ """Path-containment helper — the server controls artifact/dataset file names, so
2
+ a name like ``../../.ssh/authorized_keys`` or an absolute path must never escape
3
+ the download directory (would be arbitrary file write == RCE on the user's box)."""
4
+ from pathlib import Path
5
+
6
+
7
+ def safe_join(base, rel: str) -> Path:
8
+ """Return ``base/rel`` resolved, guaranteeing it stays under ``base``.
9
+ Raises ValueError if ``rel`` is absolute or traverses outside ``base``."""
10
+ base_p = Path(base).resolve()
11
+ target = (base_p / str(rel)).resolve()
12
+ if target != base_p and base_p not in target.parents:
13
+ raise ValueError(f"unsafe path escapes destination: {rel!r}")
14
+ return target
15
+
16
+
17
+ def safe_extractall(tar, path) -> None:
18
+ """Extract a tarball with zip-slip protection on ALL Python versions
19
+ (``filter='data'`` only exists on 3.12+; a malicious member with ``..`` or an
20
+ absolute path or a link would otherwise write outside ``path``)."""
21
+ import sys
22
+
23
+ if sys.version_info >= (3, 12):
24
+ tar.extractall(path=path, filter="data")
25
+ return
26
+ base = Path(path).resolve()
27
+ for m in tar.getmembers():
28
+ target = (base / m.name).resolve()
29
+ if target != base and base not in target.parents:
30
+ raise ValueError(f"unsafe tar member escapes destination: {m.name!r}")
31
+ if m.issym() or m.islnk():
32
+ raise ValueError(f"refusing tar link member: {m.name!r}")
33
+ tar.extractall(path=path)