opensportslib 0.3.1.dev15__tar.gz → 0.3.1.dev16__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 (232) hide show
  1. {opensportslib-0.3.1.dev15/opensportslib.egg-info → opensportslib-0.3.1.dev16}/PKG-INFO +13 -9
  2. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/README.md +10 -8
  3. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/loader.py +18 -0
  4. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/video_processing.py +2 -3
  5. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/localization_dataset.py +2 -2
  6. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/remote_registry.py +29 -11
  7. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/setup/setup.py +61 -25
  8. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16/opensportslib.egg-info}/PKG-INFO +13 -9
  9. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib.egg-info/SOURCES.txt +56 -30
  10. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib.egg-info/requires.txt +2 -0
  11. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/pyproject.toml +7 -2
  12. opensportslib-0.3.1.dev16/scripts/redact_test_stream.py +49 -0
  13. opensportslib-0.3.1.dev16/scripts/summarize_test_report.py +147 -0
  14. opensportslib-0.3.1.dev16/tests/__init__.py +1 -0
  15. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tests/conftest.py +110 -3
  16. opensportslib-0.3.1.dev16/tests/helpers/__init__.py +1 -0
  17. opensportslib-0.3.1.dev16/tests/helpers/configs.py +16 -0
  18. opensportslib-0.3.1.dev16/tests/helpers/pipeline_stubs.py +71 -0
  19. opensportslib-0.3.1.dev16/tests/integration/classification/test_pipeline.py +31 -0
  20. opensportslib-0.3.1.dev16/tests/integration/localization/test_pipeline.py +26 -0
  21. opensportslib-0.3.1.dev16/tests/integration/localization/test_spotta.py +285 -0
  22. opensportslib-0.3.1.dev16/tests/integration/vqa/test_pipeline.py +46 -0
  23. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tests/release/_release_common.py +46 -15
  24. opensportslib-0.3.1.dev16/tests/release/test_00_environment.py +28 -0
  25. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tests/release/test_classification_release.py +153 -35
  26. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tests/release/test_localization_release.py +18 -16
  27. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tests/release/test_vqa_release.py +23 -17
  28. opensportslib-0.3.1.dev16/tests/smoke/test_cli.py +31 -0
  29. opensportslib-0.3.1.dev16/tests/smoke/test_environment.py +45 -0
  30. opensportslib-0.3.1.dev15/tests/test_remote_model_registry.py → opensportslib-0.3.1.dev16/tests/unit/api/test_remote_registry.py +26 -3
  31. opensportslib-0.3.1.dev16/tests/unit/api/test_remote_sessions.py +56 -0
  32. opensportslib-0.3.1.dev16/tests/unit/api/test_server_jobs.py +63 -0
  33. opensportslib-0.3.1.dev15/tests/test_server_model_registry.py → opensportslib-0.3.1.dev16/tests/unit/api/test_server_registry.py +20 -2
  34. opensportslib-0.3.1.dev16/tests/unit/api/test_server_startup_scripts.py +50 -0
  35. opensportslib-0.3.1.dev15/tests/test_task_model_api_contract.py → opensportslib-0.3.1.dev16/tests/unit/api/test_task_model_contract.py +50 -12
  36. opensportslib-0.3.1.dev15/tests/test_vqa_api.py → opensportslib-0.3.1.dev16/tests/unit/api/test_vqa.py +27 -133
  37. opensportslib-0.3.1.dev15/tests/test_config_architecture.py → opensportslib-0.3.1.dev16/tests/unit/config/test_architecture.py +27 -1
  38. opensportslib-0.3.1.dev15/tests/test_editable_config.py → opensportslib-0.3.1.dev16/tests/unit/config/test_editable.py +1 -1
  39. opensportslib-0.3.1.dev15/tests/test_pretrained_config_merge_policy.py → opensportslib-0.3.1.dev16/tests/unit/config/test_pretrained_merge.py +1 -1
  40. opensportslib-0.3.1.dev16/tests/unit/contracts/test_architecture.py +73 -0
  41. opensportslib-0.3.1.dev16/tests/unit/contracts/test_dependencies.py +71 -0
  42. opensportslib-0.3.1.dev16/tests/unit/contracts/test_package.py +64 -0
  43. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/contracts}/test_release_versions.py +1 -1
  44. opensportslib-0.3.1.dev16/tests/unit/contracts/test_runner_contract.py +37 -0
  45. opensportslib-0.3.1.dev16/tests/unit/core/test_training_components.py +63 -0
  46. opensportslib-0.3.1.dev16/tests/unit/core/test_video_processing.py +66 -0
  47. opensportslib-0.3.1.dev16/tests/unit/data/test_osl_formats.py +56 -0
  48. opensportslib-0.3.1.dev16/tests/unit/models/test_classification_metrics.py +21 -0
  49. opensportslib-0.3.1.dev16/tests/unit/models/test_localization_metrics.py +25 -0
  50. opensportslib-0.3.1.dev16/tests/unit/models/test_temporal_shift.py +29 -0
  51. opensportslib-0.3.1.dev16/tests/unit/tools/test_report_summary.py +50 -0
  52. opensportslib-0.3.1.dev15/tests/test_setup_cli.py → opensportslib-0.3.1.dev16/tests/unit/tools/test_setup.py +76 -2
  53. opensportslib-0.3.1.dev15/tests/test_subset_train_infer_integration.py +0 -292
  54. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/LICENSE +0 -0
  55. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/LICENSE-COMMERCIAL +0 -0
  56. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/MANIFEST.in +0 -0
  57. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/examples/quickstart/basic_classification.py +0 -0
  58. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/examples/quickstart/basic_localization.py +0 -0
  59. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/examples/quickstart/basic_vqa.py +0 -0
  60. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/__init__.py +0 -0
  61. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/adaptation/__init__.py +0 -0
  62. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/adaptation/spotta.py +0 -0
  63. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/__init__.py +0 -0
  64. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/base_task_model.py +0 -0
  65. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/classification.py +0 -0
  66. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/config.py +0 -0
  67. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/configuration.py +0 -0
  68. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/localization.py +0 -0
  69. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/apis/vqa.py +0 -0
  70. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/cli.py +0 -0
  71. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/classification/default.yaml +0 -0
  72. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  73. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  74. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/classification/video.yaml +0 -0
  75. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/default.yaml +0 -0
  76. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  77. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/default.yaml +0 -0
  78. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/e2e_spotta.yaml +0 -0
  79. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  80. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/h5_header_skeleton.yaml +0 -0
  81. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  82. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/tracking_action_spotting.yaml +0 -0
  83. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/video_dali.yaml +0 -0
  84. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  85. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/default.yaml +0 -0
  86. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/qwen.yaml +0 -0
  87. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/qwen3_vl_native.yaml +0 -0
  88. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
  89. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
  90. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/configs/vqa/xvars.yaml +0 -0
  91. {opensportslib-0.3.1.dev15/tests/release → opensportslib-0.3.1.dev16/opensportslib/core}/__init__.py +0 -0
  92. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/__init__.py +0 -0
  93. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/accessors.py +0 -0
  94. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/conflicts.py +0 -0
  95. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/editable.py +0 -0
  96. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/migrate.py +0 -0
  97. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/migrations/__init__.py +0 -0
  98. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  99. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/rule_variants.py +0 -0
  100. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/runtime_adapter.py +0 -0
  101. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/schema.py +0 -0
  102. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/schemas/__init__.py +0 -0
  103. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  104. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  105. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/config/validate.py +0 -0
  106. {opensportslib-0.3.1.dev15/opensportslib/models/utils/impl → opensportslib-0.3.1.dev16/opensportslib/core/loss}/__init__.py +0 -0
  107. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/loss/builder.py +0 -0
  108. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/loss/calf.py +0 -0
  109. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/loss/ce.py +0 -0
  110. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/loss/combine.py +0 -0
  111. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/loss/nll.py +0 -0
  112. {opensportslib-0.3.1.dev15/opensportslib/models → opensportslib-0.3.1.dev16/opensportslib/core/optimizer}/__init__.py +0 -0
  113. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/optimizer/builder.py +0 -0
  114. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  115. {opensportslib-0.3.1.dev15/opensportslib/datasets → opensportslib-0.3.1.dev16/opensportslib/core/scheduler}/__init__.py +0 -0
  116. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/scheduler/builder.py +0 -0
  117. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/trainer/__init__.py +0 -0
  118. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/trainer/classification_trainer.py +0 -0
  119. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/trainer/localization_trainer.py +0 -0
  120. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/trainer/vqa_trainer.py +0 -0
  121. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/checkpoint.py +0 -0
  122. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/config.py +0 -0
  123. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/config_normalize.py +0 -0
  124. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/data.py +0 -0
  125. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/ddp.py +0 -0
  126. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/default_args.py +0 -0
  127. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/direct_video.py +0 -0
  128. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/hf_runtime.py +0 -0
  129. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/lightning.py +0 -0
  130. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/load_annotations.py +0 -0
  131. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/seed.py +0 -0
  132. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/core/utils/wandb.py +0 -0
  133. {opensportslib-0.3.1.dev15/opensportslib/core/scheduler → opensportslib-0.3.1.dev16/opensportslib/datasets}/__init__.py +0 -0
  134. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/builder.py +0 -0
  135. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/classification_dataset.py +0 -0
  136. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/utils/__init__.py +0 -0
  137. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  138. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/utils/tracking.py +0 -0
  139. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/datasets/vqa_dataset.py +0 -0
  140. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/classification.yaml +0 -0
  141. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  142. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  143. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  144. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/localization.yaml +0 -0
  145. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  146. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  147. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/metrics/classification_metric.py +0 -0
  148. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/metrics/localization_metric.py +0 -0
  149. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/metrics/vqa_metric.py +0 -0
  150. {opensportslib-0.3.1.dev15/opensportslib/core/optimizer → opensportslib-0.3.1.dev16/opensportslib/models}/__init__.py +0 -0
  151. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/backbones/builder.py +0 -0
  152. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/contextaware.py +0 -0
  153. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/e2e.py +0 -0
  154. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/learnablepooling.py +0 -0
  155. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/qwen_vl_native.py +0 -0
  156. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/qwen_xvars.py +0 -0
  157. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/rule_based.py +0 -0
  158. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/tracking.py +0 -0
  159. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/vars.py +0 -0
  160. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/video.py +0 -0
  161. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  162. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/video_mae.py +0 -0
  163. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
  164. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/builder.py +0 -0
  165. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/heads/builder.py +0 -0
  166. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/neck/builder.py +0 -0
  167. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/common.py +0 -0
  168. {opensportslib-0.3.1.dev15/opensportslib/core/loss → opensportslib-0.3.1.dev16/opensportslib/models/utils/impl}/__init__.py +0 -0
  169. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/impl/asformer.py +0 -0
  170. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/impl/calf.py +0 -0
  171. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/impl/gsm.py +0 -0
  172. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/impl/gtad.py +0 -0
  173. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/impl/tsm.py +0 -0
  174. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/litebase.py +0 -0
  175. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/modules.py +0 -0
  176. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/shift.py +0 -0
  177. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/utils.py +0 -0
  178. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  179. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/vqa_prompting.py +0 -0
  180. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  181. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/tools/__init__.py +0 -0
  182. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/tools/_common.py +0 -0
  183. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/tools/hf_transfer.py +0 -0
  184. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  185. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  186. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib.egg-info/dependency_links.txt +0 -0
  187. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib.egg-info/entry_points.txt +0 -0
  188. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/opensportslib.egg-info/top_level.txt +0 -0
  189. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/scripts/release_versions.py +0 -0
  190. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/scripts/run_h5_header_rule_inference.py +0 -0
  191. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/setup.cfg +0 -0
  192. {opensportslib-0.3.1.dev15/opensportslib/core → opensportslib-0.3.1.dev16/tests/release}/__init__.py +0 -0
  193. /opensportslib-0.3.1.dev15/tests/test_config_utils_smoke.py → /opensportslib-0.3.1.dev16/tests/smoke/test_config_utils.py +0 -0
  194. /opensportslib-0.3.1.dev15/tests/test_package_smoke.py → /opensportslib-0.3.1.dev16/tests/smoke/test_package.py +0 -0
  195. /opensportslib-0.3.1.dev15/tests/test_public_apis_smoke.py → /opensportslib-0.3.1.dev16/tests/smoke/test_public_apis.py +0 -0
  196. /opensportslib-0.3.1.dev15/tests/test_optional_hf_config.py → /opensportslib-0.3.1.dev16/tests/unit/config/test_optional_hf.py +0 -0
  197. /opensportslib-0.3.1.dev15/tests/test_config_split_override_sync.py → /opensportslib-0.3.1.dev16/tests/unit/config/test_split_overrides.py +0 -0
  198. /opensportslib-0.3.1.dev15/tests/test_classification_trainer_dataloader.py → /opensportslib-0.3.1.dev16/tests/unit/core/test_classification_trainer.py +0 -0
  199. /opensportslib-0.3.1.dev15/tests/test_localization_hf_backend_override.py → /opensportslib-0.3.1.dev16/tests/unit/core/test_localization_hf_backend.py +0 -0
  200. /opensportslib-0.3.1.dev15/tests/test_classification_dataset_paths.py → /opensportslib-0.3.1.dev16/tests/unit/data/test_classification_paths.py +0 -0
  201. /opensportslib-0.3.1.dev15/tests/test_h5_tracking_dataset.py → /opensportslib-0.3.1.dev16/tests/unit/data/test_h5_tracking.py +0 -0
  202. /opensportslib-0.3.1.dev15/tests/test_localization_dali_filenames.py → /opensportslib-0.3.1.dev16/tests/unit/data/test_localization_dali.py +0 -0
  203. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/data}/test_localization_intervals.py +0 -0
  204. /opensportslib-0.3.1.dev15/tests/test_h5_header_rule_spotter.py → /opensportslib-0.3.1.dev16/tests/unit/models/test_header_rule_spotter.py +0 -0
  205. /opensportslib-0.3.1.dev15/tests/test_h5_header_skeleton_spotter.py → /opensportslib-0.3.1.dev16/tests/unit/models/test_header_skeleton_spotter.py +0 -0
  206. /opensportslib-0.3.1.dev15/tests/test_vqa_metrics_semantic.py → /opensportslib-0.3.1.dev16/tests/unit/models/test_vqa_metrics.py +0 -0
  207. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/models}/test_vqa_qwen_xvars.py +0 -0
  208. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/models}/test_vqa_training_lora.py +0 -0
  209. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/models}/test_vqa_xvars_videochatgpt.py +0 -0
  210. /opensportslib-0.3.1.dev15/tests/test_conversion_tools.py → /opensportslib-0.3.1.dev16/tests/unit/tools/test_conversion.py +0 -0
  211. {opensportslib-0.3.1.dev15/tests → opensportslib-0.3.1.dev16/tests/unit/tools}/test_extract_xvars_features.py +0 -0
  212. /opensportslib-0.3.1.dev15/tests/test_hf_transfer_tools.py → /opensportslib-0.3.1.dev16/tests/unit/tools/test_hf_transfer.py +0 -0
  213. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
  214. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_sngar_spotting.py +0 -0
  215. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_soccernet_gar.py +0 -0
  216. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  217. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_soccernet_gar_vqa.py +0 -0
  218. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/build_xvars_indexes.py +0 -0
  219. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/extract_xvars_clip_features.py +0 -0
  220. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  221. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  222. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/sngar_dataset_card.py +0 -0
  223. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/sngar_events.py +0 -0
  224. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/convert/verify_sngar_spotting.py +0 -0
  225. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/download/download_hf_repo.py +0 -0
  226. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/download/download_osl_hf.py +0 -0
  227. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/download/push_sngar_spotting.py +0 -0
  228. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/download/upload_osl_hf.py +0 -0
  229. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/training/classification.py +0 -0
  230. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/training/localization.py +0 -0
  231. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/training/vqa.py +0 -0
  232. {opensportslib-0.3.1.dev15 → opensportslib-0.3.1.dev16}/tools/upload/upload_model_hf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.3.1.dev15
3
+ Version: 0.3.1.dev16
4
4
  Summary: OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data.
5
5
  Author: Jeet Vora
6
6
  Requires-Python: >=3.12
@@ -32,6 +32,8 @@ Requires-Dist: easydict
32
32
  Provides-Extra: test
33
33
  Requires-Dist: pytest; extra == "test"
34
34
  Requires-Dist: pytest-cov; extra == "test"
35
+ Requires-Dist: pytest-json-report; extra == "test"
36
+ Requires-Dist: pytest-timeout; extra == "test"
35
37
  Dynamic: license-file
36
38
 
37
39
  # OpenSportsLib
@@ -45,9 +47,9 @@ See the [complete inference server guide](docs/server/inference-server.md) for
45
47
  installation, registry administration, curl requests, single-video inference,
46
48
  full-test-set and per-sample remote inference, job polling, and sessions.
47
49
 
48
- For Docker administration, set `OSL_MODEL_ADMIN_TOKEN` in the private
49
- `server/.env` file, recreate the containers after changes, and use the exact
50
- same value as the Python client's `admin_token`. Never commit the real token.
50
+ Hugging Face registration is authorized by repository access. Set `HF_TOKEN`
51
+ on the worker or pass `hf_token` per request. The optional `OSL_API_KEY`
52
+ protects local-model and general administrative operations.
51
53
 
52
54
  ## Configuration From Hugging Face
53
55
 
@@ -138,7 +140,7 @@ OpenSportsLib is designed for **researchers, ML engineers, and sports analytics
138
140
 
139
141
  > Requires **Python 3.12+**.
140
142
  > Supports CUDA 12.6 / 12.8 / 13.0 (with CPU fallback).
141
- > PyTorch Geometric is supported up to PyTorch 2.10.*.
143
+ > PyTorch Geometric uses a dedicated PyTorch 2.12.1 compatibility profile.
142
144
 
143
145
  ### Create conda env
144
146
 
@@ -170,7 +172,8 @@ pip install -e .
170
172
  # Install PyTorch (CPU/GPU auto-detected)
171
173
  opensportslib setup
172
174
 
173
- # Optional: install PyTorch Geometric support
175
+ # Optional: install PyTorch Geometric support. This replaces the installed
176
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
174
177
  opensportslib setup --pyg
175
178
 
176
179
  # Optional: install for DALI support
@@ -554,7 +557,8 @@ pip install -e .
554
557
  # Install PyTorch (CPU/GPU auto-detected)
555
558
  opensportslib setup
556
559
 
557
- # Optional: install PyTorch Geometric support
560
+ # Optional: install PyTorch Geometric support. This replaces the installed
561
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
558
562
  opensportslib setup --pyg
559
563
 
560
564
  # Optional: install for DALI support
@@ -635,8 +639,8 @@ this repository, activate a fresh Python 3.12 or newer environment and install t
635
639
 
636
640
  ```bash
637
641
  pip install -e ./server
638
- bash server/scripts/setup_env.sh
639
- bash server/scripts/start_all.sh
642
+ server/scripts/serverctl setup
643
+ server/scripts/serverctl start
640
644
  ```
641
645
 
642
646
  The server installs the OpenSportsLib release from PyPI pinned to the root project
@@ -9,9 +9,9 @@ See the [complete inference server guide](docs/server/inference-server.md) for
9
9
  installation, registry administration, curl requests, single-video inference,
10
10
  full-test-set and per-sample remote inference, job polling, and sessions.
11
11
 
12
- For Docker administration, set `OSL_MODEL_ADMIN_TOKEN` in the private
13
- `server/.env` file, recreate the containers after changes, and use the exact
14
- same value as the Python client's `admin_token`. Never commit the real token.
12
+ Hugging Face registration is authorized by repository access. Set `HF_TOKEN`
13
+ on the worker or pass `hf_token` per request. The optional `OSL_API_KEY`
14
+ protects local-model and general administrative operations.
15
15
 
16
16
  ## Configuration From Hugging Face
17
17
 
@@ -102,7 +102,7 @@ OpenSportsLib is designed for **researchers, ML engineers, and sports analytics
102
102
 
103
103
  > Requires **Python 3.12+**.
104
104
  > Supports CUDA 12.6 / 12.8 / 13.0 (with CPU fallback).
105
- > PyTorch Geometric is supported up to PyTorch 2.10.*.
105
+ > PyTorch Geometric uses a dedicated PyTorch 2.12.1 compatibility profile.
106
106
 
107
107
  ### Create conda env
108
108
 
@@ -134,7 +134,8 @@ pip install -e .
134
134
  # Install PyTorch (CPU/GPU auto-detected)
135
135
  opensportslib setup
136
136
 
137
- # Optional: install PyTorch Geometric support
137
+ # Optional: install PyTorch Geometric support. This replaces the installed
138
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
138
139
  opensportslib setup --pyg
139
140
 
140
141
  # Optional: install for DALI support
@@ -518,7 +519,8 @@ pip install -e .
518
519
  # Install PyTorch (CPU/GPU auto-detected)
519
520
  opensportslib setup
520
521
 
521
- # Optional: install PyTorch Geometric support
522
+ # Optional: install PyTorch Geometric support. This replaces the installed
523
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
522
524
  opensportslib setup --pyg
523
525
 
524
526
  # Optional: install for DALI support
@@ -599,8 +601,8 @@ this repository, activate a fresh Python 3.12 or newer environment and install t
599
601
 
600
602
  ```bash
601
603
  pip install -e ./server
602
- bash server/scripts/setup_env.sh
603
- bash server/scripts/start_all.sh
604
+ server/scripts/serverctl setup
605
+ server/scripts/serverctl start
604
606
  ```
605
607
 
606
608
  The server installs the OpenSportsLib release from PyPI pinned to the root project
@@ -206,9 +206,27 @@ def _preferred_loader_backend(payload: dict[str, Any]) -> str | None:
206
206
  if _declares_opencv_split_types(payload):
207
207
  return "opencv"
208
208
 
209
+ # DALI cannot run on CPU, regardless of an explicit preference in a
210
+ # configuration. This safety fallback also remaps DALI split types below.
209
211
  mode = str(system.get("device", "auto")).lower()
210
212
  if mode == "cpu":
211
213
  return "opencv"
214
+
215
+ data = payload.get("DATA", {})
216
+ common = data.get("common", {}) if isinstance(data, dict) else {}
217
+ runtime = common.get("runtime", {}) if isinstance(common, dict) else {}
218
+ configured_backend = (
219
+ str(runtime.get("loader_backend", "auto")).lower()
220
+ if isinstance(runtime, dict)
221
+ else "auto"
222
+ )
223
+ # An explicit backend is part of the configuration contract. Runtime
224
+ # detection is only a default for configs which leave that choice as auto.
225
+ if configured_backend == "opencv":
226
+ return "opencv"
227
+ if configured_backend == "dali":
228
+ return "dali" if _dali_available() else "opencv"
229
+
212
230
  if mode == "cuda":
213
231
  return "dali" if _dali_available() else "opencv"
214
232
  if mode == "auto":
@@ -145,9 +145,8 @@ def distribute_elements(batch_size, len_devices):
145
145
  """
146
146
  quotient, remainder = divmod(batch_size, len_devices)
147
147
  distribution = [quotient] * len_devices
148
- if remainder > 0:
149
- for i in range(len(distribution)):
150
- distribution[i] += 1
148
+ for i in range(remainder):
149
+ distribution[i] += 1
151
150
 
152
151
  return distribution
153
152
 
@@ -1009,7 +1009,7 @@ class ActionSpotDataset(Dataset):
1009
1009
  return self._dataset_len
1010
1010
 
1011
1011
  def print_info(self):
1012
- from core.utils.config import _print_info_helper
1012
+ from opensportslib.core.utils.config import _print_info_helper
1013
1013
  _print_info_helper(self._src_file, self._labels)
1014
1014
 
1015
1015
 
@@ -1998,7 +1998,7 @@ if DALI_AVAILABLE:
1998
1998
  return labels
1999
1999
 
2000
2000
  def print_info(self):
2001
- from core.utils.config import _print_info_helper
2001
+ from opensportslib.core.utils.config import _print_info_helper
2002
2002
  _print_info_helper(self._src_file, self._labels)
2003
2003
 
2004
2004
 
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import time
5
+ import warnings
5
6
  from pathlib import Path
6
7
  from typing import Any
7
8
  from urllib import error, parse, request
@@ -17,13 +18,23 @@ class RemoteRegistryError(RuntimeError):
17
18
  class RemoteModelRegistry:
18
19
  """Administrative client for an OpenSportsLib server model registry."""
19
20
 
20
- def __init__(self, remote: str, admin_token: str, timeout: float = 30.0):
21
+ def __init__(
22
+ self,
23
+ remote: str,
24
+ api_key: str | None = None,
25
+ timeout: float = 30.0,
26
+ *,
27
+ admin_token: str | None = None,
28
+ ):
21
29
  if not remote:
22
30
  raise ValueError("remote is required.")
23
- if not admin_token:
24
- raise ValueError("admin_token is required.")
31
+ if admin_token is not None:
32
+ warnings.warn("admin_token is deprecated; use api_key.", DeprecationWarning, stacklevel=2)
33
+ if api_key is not None and api_key != admin_token:
34
+ raise ValueError("api_key and admin_token must match when both are provided.")
35
+ api_key = admin_token
25
36
  self.remote = remote.rstrip("/")
26
- self.admin_token = admin_token
37
+ self.api_key = api_key
27
38
  self.timeout = float(timeout)
28
39
  if self.timeout <= 0:
29
40
  raise ValueError("timeout must be positive.")
@@ -36,6 +47,7 @@ class RemoteModelRegistry:
36
47
  weights_path: str | Path | None = None,
37
48
  config_path: str | Path | None = None,
38
49
  model_id: str | None = None,
50
+ hf_token: str | None = None,
39
51
  ) -> dict[str, Any]:
40
52
  """Register exactly one Hugging Face or server-local model source."""
41
53
  if (huggingface_model_id is None) == (weights_path is None):
@@ -45,9 +57,12 @@ class RemoteModelRegistry:
45
57
  raise ValueError("config_path applies only to local models.")
46
58
  if model_id is not None and model_id != huggingface_model_id:
47
59
  raise ValueError("A Hugging Face model uses its repository ID as model_id.")
60
+ source = {"type": "huggingface", "model_id": huggingface_model_id}
61
+ if hf_token is not None:
62
+ source["hf_token"] = hf_token
48
63
  payload = {
49
64
  "task_type": task_type,
50
- "source": {"type": "huggingface", "model_id": huggingface_model_id},
65
+ "source": source,
51
66
  }
52
67
  else:
53
68
  payload = {
@@ -59,7 +74,7 @@ class RemoteModelRegistry:
59
74
  "config_path": str(config_path) if config_path is not None else None,
60
75
  },
61
76
  }
62
- return self._request("POST", "/models", payload, authenticated=True)
77
+ return self._request("POST", "/models", payload, authenticated=weights_path is not None)
63
78
 
64
79
  def list_models(self) -> list[dict[str, Any]]:
65
80
  return self._request("GET", "/models")["models"]
@@ -69,7 +84,7 @@ class RemoteModelRegistry:
69
84
  return self._request("GET", f"/models/status?{query}")
70
85
 
71
86
  def get_operation(self, operation_id: str) -> dict[str, Any]:
72
- return self._request("GET", f"/model-operations/{parse.quote(operation_id, safe='')}", authenticated=True)
87
+ return self._request("GET", f"/model-operations/{parse.quote(operation_id, safe='')}")
73
88
 
74
89
  def wait_for_operation(
75
90
  self,
@@ -93,9 +108,9 @@ class RemoteModelRegistry:
93
108
  task = parse.quote(task_type, safe="")
94
109
  return self._request("PUT", f"/models/defaults/{task}", {"model_id": model_id}, authenticated=True)
95
110
 
96
- def unregister_model(self, model_id: str) -> dict[str, Any]:
111
+ def unregister_model(self, model_id: str, hf_token: str | None = None) -> dict[str, Any]:
97
112
  encoded = parse.quote(model_id, safe="")
98
- return self._request("DELETE", f"/models/{encoded}", authenticated=True)
113
+ return self._request("DELETE", f"/models/{encoded}", authenticated=True, hf_token=hf_token)
99
114
 
100
115
  def reconcile_runtime(
101
116
  self,
@@ -117,11 +132,14 @@ class RemoteModelRegistry:
117
132
  endpoint: str,
118
133
  payload: dict[str, Any] | None = None,
119
134
  authenticated: bool = False,
135
+ hf_token: str | None = None,
120
136
  ) -> dict[str, Any]:
121
137
  body = json.dumps(payload).encode() if payload is not None else None
122
138
  headers = {"Content-Type": "application/json"}
123
- if authenticated:
124
- headers["Authorization"] = f"Bearer {self.admin_token}"
139
+ if authenticated and self.api_key:
140
+ headers["Authorization"] = f"Bearer {self.api_key}"
141
+ if hf_token:
142
+ headers["X-HF-Token"] = hf_token
125
143
  outgoing = request.Request(self.remote + endpoint, data=body, method=method, headers=headers)
126
144
  try:
127
145
  with request.urlopen(outgoing, timeout=self.timeout) as response:
@@ -1,6 +1,7 @@
1
1
  import platform
2
2
  import subprocess
3
3
  import sys
4
+ import tempfile
4
5
 
5
6
 
6
7
  CUDA_WHEEL_VERSIONS = {
@@ -14,6 +15,20 @@ LEGACY_GPU_CUDA_WHEEL = "cu126"
14
15
  LEGACY_GPU_CUDA_WHEEL_MAX_COMPUTE_CAPABILITY = (9, 0)
15
16
  CUDA13_REQUIRED_MIN_COMPUTE_CAPABILITY = (10, 0)
16
17
 
18
+ # PyG extension wheels are published for a narrower PyTorch matrix than the
19
+ # base PyTorch packages. Keep this profile explicit: selecting ``--pyg`` is
20
+ # allowed to replace an otherwise newer PyTorch installation.
21
+ PYG_TORCH_VERSION = "2.12.1"
22
+ PYG_TORCH_PACKAGES = (
23
+ f"torch=={PYG_TORCH_VERSION}",
24
+ "torchvision==0.27.1",
25
+ )
26
+ PYG_EXTENSION_PACKAGES = (
27
+ "pyg-lib",
28
+ "torch-scatter",
29
+ "torch-sparse",
30
+ )
31
+
17
32
  XVARS_DEPENDENCY_PINS = {
18
33
  "transformers": "4.38.2",
19
34
  "peft": "0.9.0",
@@ -154,10 +169,17 @@ def install_xvars_dependencies(DEPENDENCY_PINS):
154
169
  subprocess.check_call([python, "-m", "pip", "install", *pinned_packages])
155
170
  print("Dependencies installed successfully.")
156
171
 
157
- def install_torch():
172
+ def install_torch(*, pyg_compatible=False):
173
+ """Install the default Torch stack or the pinned PyG-compatible stack."""
158
174
  python = sys.executable
159
175
  subprocess.call([python, "-m", "pip", "uninstall", "-y", "torch", "torchvision", "torchaudio"])
160
- packages = select_torch_packages(GPU_COMPUTE_CAPABILITIES)
176
+ packages = PYG_TORCH_PACKAGES if pyg_compatible else select_torch_packages(GPU_COMPUTE_CAPABILITIES)
177
+
178
+ if pyg_compatible:
179
+ print(
180
+ "\nInstalling the PyTorch Geometric compatibility profile: "
181
+ f"PyTorch {PYG_TORCH_VERSION}. This replaces the installed Torch stack.\n"
182
+ )
161
183
 
162
184
  subprocess.check_call([
163
185
  python, "-m", "pip", "install",
@@ -168,6 +190,30 @@ def install_torch():
168
190
  print(f"\nSuccess with {CUDA_TAG}: {', '.join(packages)}")
169
191
  return CUDA_TAG
170
192
 
193
+
194
+ def pyg_wheel_url(torch_version=None, cuda_tag=None):
195
+ torch_version = torch_version or PYG_TORCH_VERSION
196
+ cuda_tag = CUDA_TAG if cuda_tag is None else cuda_tag
197
+ suffix = "cpu" if cuda_tag == "cpu" else cuda_tag
198
+ return f"https://data.pyg.org/whl/torch-{torch_version}+{suffix}.html"
199
+
200
+
201
+ def validate_pyg_wheels():
202
+ """Ensure every required PyG wheel exists before replacing Torch.
203
+
204
+ ``--only-binary`` is intentional: pip otherwise falls back to a source
205
+ build, which is both slow and incompatible with its isolated build
206
+ environment unless Torch is installed there as well.
207
+ """
208
+ python = sys.executable
209
+ url = pyg_wheel_url()
210
+ print("\nChecking PyTorch Geometric wheels before replacing the Torch stack...\n")
211
+ with tempfile.TemporaryDirectory(prefix="opensportslib-pyg-wheel-check-") as download_dir:
212
+ subprocess.check_call([
213
+ python, "-m", "pip", "download", "--no-deps", "--only-binary=:all:",
214
+ "--dest", download_dir, *PYG_EXTENSION_PACKAGES, "-f", url,
215
+ ])
216
+
171
217
  def install_dali():
172
218
 
173
219
  python = sys.executable
@@ -202,36 +248,24 @@ def install_dali():
202
248
 
203
249
  def install_pyg():
204
250
  import torch
205
- from packaging import version
206
251
 
207
252
  python = sys.executable
208
- torch_version = "2.10.0" if version.parse(torch.__version__.split("+")[0]) > version.parse("2.10.0") else torch.__version__.split("+")[0]
209
- cuda_tag = CUDA_TAG
253
+ torch_version = torch.__version__.split("+")[0]
254
+ if torch_version != PYG_TORCH_VERSION:
255
+ raise RuntimeError(
256
+ "PyTorch Geometric extensions require the OpenSportsLib PyG compatibility "
257
+ f"profile (PyTorch {PYG_TORCH_VERSION}); found PyTorch {torch_version}. "
258
+ "Run 'opensportslib setup --pyg' so the matching Torch stack is installed."
259
+ )
210
260
  print("\nInstalling Py-Geometric ecosystem...\n")
211
- if cuda_tag == "cpu":
212
- url = f"https://data.pyg.org/whl/torch-{torch_version}+cpu.html"
213
- else:
214
- url = f"https://data.pyg.org/whl/torch-{torch_version}+{cuda_tag}.html"
261
+ url = pyg_wheel_url(torch_version)
215
262
 
216
263
  subprocess.check_call([
217
- python, "-m", "pip", "install",
218
- "torch-geometric", "-f", url
219
- ])
220
- subprocess.check_call([
221
- python, "-m", "pip", "install",
222
- "torch-scatter", "-f", url
264
+ python, "-m", "pip", "install", "torch-geometric",
223
265
  ])
224
266
  subprocess.check_call([
225
267
  python, "-m", "pip", "install",
226
- "torch-sparse", "-f", url
227
- ])
228
- subprocess.check_call([
229
- python, "-m", "pip", "install",
230
- "torch-cluster", "-f", url
231
- ])
232
- subprocess.check_call([
233
- python, "-m", "pip", "install",
234
- "torch-spline-conv", "-f", url
268
+ *PYG_EXTENSION_PACKAGES, "--only-binary=:all:", "-f", url
235
269
  ])
236
270
 
237
271
  def install_extras(dali=False, pyg=False):
@@ -256,7 +290,9 @@ def verify():
256
290
  print("Running on CPU")
257
291
 
258
292
  def setup(dali=False, pyg=False, vqa_xvars=False, vqa_qwen=False):
259
- install_torch()
293
+ if pyg:
294
+ validate_pyg_wheels()
295
+ install_torch(pyg_compatible=pyg)
260
296
  install_extras(dali=dali, pyg=pyg)
261
297
  if vqa_xvars:
262
298
  install_xvars_dependencies(XVARS_DEPENDENCY_PINS)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.3.1.dev15
3
+ Version: 0.3.1.dev16
4
4
  Summary: OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data.
5
5
  Author: Jeet Vora
6
6
  Requires-Python: >=3.12
@@ -32,6 +32,8 @@ Requires-Dist: easydict
32
32
  Provides-Extra: test
33
33
  Requires-Dist: pytest; extra == "test"
34
34
  Requires-Dist: pytest-cov; extra == "test"
35
+ Requires-Dist: pytest-json-report; extra == "test"
36
+ Requires-Dist: pytest-timeout; extra == "test"
35
37
  Dynamic: license-file
36
38
 
37
39
  # OpenSportsLib
@@ -45,9 +47,9 @@ See the [complete inference server guide](docs/server/inference-server.md) for
45
47
  installation, registry administration, curl requests, single-video inference,
46
48
  full-test-set and per-sample remote inference, job polling, and sessions.
47
49
 
48
- For Docker administration, set `OSL_MODEL_ADMIN_TOKEN` in the private
49
- `server/.env` file, recreate the containers after changes, and use the exact
50
- same value as the Python client's `admin_token`. Never commit the real token.
50
+ Hugging Face registration is authorized by repository access. Set `HF_TOKEN`
51
+ on the worker or pass `hf_token` per request. The optional `OSL_API_KEY`
52
+ protects local-model and general administrative operations.
51
53
 
52
54
  ## Configuration From Hugging Face
53
55
 
@@ -138,7 +140,7 @@ OpenSportsLib is designed for **researchers, ML engineers, and sports analytics
138
140
 
139
141
  > Requires **Python 3.12+**.
140
142
  > Supports CUDA 12.6 / 12.8 / 13.0 (with CPU fallback).
141
- > PyTorch Geometric is supported up to PyTorch 2.10.*.
143
+ > PyTorch Geometric uses a dedicated PyTorch 2.12.1 compatibility profile.
142
144
 
143
145
  ### Create conda env
144
146
 
@@ -170,7 +172,8 @@ pip install -e .
170
172
  # Install PyTorch (CPU/GPU auto-detected)
171
173
  opensportslib setup
172
174
 
173
- # Optional: install PyTorch Geometric support
175
+ # Optional: install PyTorch Geometric support. This replaces the installed
176
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
174
177
  opensportslib setup --pyg
175
178
 
176
179
  # Optional: install for DALI support
@@ -554,7 +557,8 @@ pip install -e .
554
557
  # Install PyTorch (CPU/GPU auto-detected)
555
558
  opensportslib setup
556
559
 
557
- # Optional: install PyTorch Geometric support
560
+ # Optional: install PyTorch Geometric support. This replaces the installed
561
+ # Torch stack with the PyG-compatible PyTorch 2.12.1 profile.
558
562
  opensportslib setup --pyg
559
563
 
560
564
  # Optional: install for DALI support
@@ -635,8 +639,8 @@ this repository, activate a fresh Python 3.12 or newer environment and install t
635
639
 
636
640
  ```bash
637
641
  pip install -e ./server
638
- bash server/scripts/setup_env.sh
639
- bash server/scripts/start_all.sh
642
+ server/scripts/serverctl setup
643
+ server/scripts/serverctl start
640
644
  ```
641
645
 
642
646
  The server installs the OpenSportsLib release from PyPI pinned to the root project
@@ -143,44 +143,70 @@ opensportslib/tools/_common.py
143
143
  opensportslib/tools/hf_transfer.py
144
144
  opensportslib/tools/osl_json_to_parquet.py
145
145
  opensportslib/tools/parquet_to_osl_json.py
146
+ scripts/redact_test_stream.py
146
147
  scripts/release_versions.py
147
148
  scripts/run_h5_header_rule_inference.py
149
+ scripts/summarize_test_report.py
150
+ tests/__init__.py
148
151
  tests/conftest.py
149
- tests/test_classification_dataset_paths.py
150
- tests/test_classification_trainer_dataloader.py
151
- tests/test_config_architecture.py
152
- tests/test_config_split_override_sync.py
153
- tests/test_config_utils_smoke.py
154
- tests/test_conversion_tools.py
155
- tests/test_editable_config.py
156
- tests/test_extract_xvars_features.py
157
- tests/test_h5_header_rule_spotter.py
158
- tests/test_h5_header_skeleton_spotter.py
159
- tests/test_h5_tracking_dataset.py
160
- tests/test_hf_transfer_tools.py
161
- tests/test_localization_dali_filenames.py
162
- tests/test_localization_hf_backend_override.py
163
- tests/test_localization_intervals.py
164
- tests/test_optional_hf_config.py
165
- tests/test_package_smoke.py
166
- tests/test_pretrained_config_merge_policy.py
167
- tests/test_public_apis_smoke.py
168
- tests/test_release_versions.py
169
- tests/test_remote_model_registry.py
170
- tests/test_server_model_registry.py
171
- tests/test_setup_cli.py
172
- tests/test_subset_train_infer_integration.py
173
- tests/test_task_model_api_contract.py
174
- tests/test_vqa_api.py
175
- tests/test_vqa_metrics_semantic.py
176
- tests/test_vqa_qwen_xvars.py
177
- tests/test_vqa_training_lora.py
178
- tests/test_vqa_xvars_videochatgpt.py
152
+ tests/helpers/__init__.py
153
+ tests/helpers/configs.py
154
+ tests/helpers/pipeline_stubs.py
155
+ tests/integration/classification/test_pipeline.py
156
+ tests/integration/localization/test_pipeline.py
157
+ tests/integration/localization/test_spotta.py
158
+ tests/integration/vqa/test_pipeline.py
179
159
  tests/release/__init__.py
180
160
  tests/release/_release_common.py
161
+ tests/release/test_00_environment.py
181
162
  tests/release/test_classification_release.py
182
163
  tests/release/test_localization_release.py
183
164
  tests/release/test_vqa_release.py
165
+ tests/smoke/test_cli.py
166
+ tests/smoke/test_config_utils.py
167
+ tests/smoke/test_environment.py
168
+ tests/smoke/test_package.py
169
+ tests/smoke/test_public_apis.py
170
+ tests/unit/api/test_remote_registry.py
171
+ tests/unit/api/test_remote_sessions.py
172
+ tests/unit/api/test_server_jobs.py
173
+ tests/unit/api/test_server_registry.py
174
+ tests/unit/api/test_server_startup_scripts.py
175
+ tests/unit/api/test_task_model_contract.py
176
+ tests/unit/api/test_vqa.py
177
+ tests/unit/config/test_architecture.py
178
+ tests/unit/config/test_editable.py
179
+ tests/unit/config/test_optional_hf.py
180
+ tests/unit/config/test_pretrained_merge.py
181
+ tests/unit/config/test_split_overrides.py
182
+ tests/unit/contracts/test_architecture.py
183
+ tests/unit/contracts/test_dependencies.py
184
+ tests/unit/contracts/test_package.py
185
+ tests/unit/contracts/test_release_versions.py
186
+ tests/unit/contracts/test_runner_contract.py
187
+ tests/unit/core/test_classification_trainer.py
188
+ tests/unit/core/test_localization_hf_backend.py
189
+ tests/unit/core/test_training_components.py
190
+ tests/unit/core/test_video_processing.py
191
+ tests/unit/data/test_classification_paths.py
192
+ tests/unit/data/test_h5_tracking.py
193
+ tests/unit/data/test_localization_dali.py
194
+ tests/unit/data/test_localization_intervals.py
195
+ tests/unit/data/test_osl_formats.py
196
+ tests/unit/models/test_classification_metrics.py
197
+ tests/unit/models/test_header_rule_spotter.py
198
+ tests/unit/models/test_header_skeleton_spotter.py
199
+ tests/unit/models/test_localization_metrics.py
200
+ tests/unit/models/test_temporal_shift.py
201
+ tests/unit/models/test_vqa_metrics.py
202
+ tests/unit/models/test_vqa_qwen_xvars.py
203
+ tests/unit/models/test_vqa_training_lora.py
204
+ tests/unit/models/test_vqa_xvars_videochatgpt.py
205
+ tests/unit/tools/test_conversion.py
206
+ tests/unit/tools/test_extract_xvars_features.py
207
+ tests/unit/tools/test_hf_transfer.py
208
+ tests/unit/tools/test_report_summary.py
209
+ tests/unit/tools/test_setup.py
184
210
  tools/convert/build_sn_vqa_2026_vqa.py
185
211
  tools/convert/build_sngar_spotting.py
186
212
  tools/convert/build_soccernet_gar.py
@@ -26,3 +26,5 @@ decord
26
26
  [test]
27
27
  pytest
28
28
  pytest-cov
29
+ pytest-json-report
30
+ pytest-timeout
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opensportslib"
7
- version = "0.3.1.dev15"
7
+ version = "0.3.1.dev16"
8
8
  description = "OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -13,7 +13,7 @@ dependencies = [ "SoccerNet", "av", "decord; platform_system != 'Darwin' and pla
13
13
  name = "Jeet Vora"
14
14
 
15
15
  [project.optional-dependencies]
16
- test = [ "pytest", "pytest-cov",]
16
+ test = [ "pytest", "pytest-cov", "pytest-json-report", "pytest-timeout",]
17
17
 
18
18
  [project.scripts]
19
19
  opensportslib = "opensportslib.cli:main"
@@ -29,5 +29,10 @@ omit = [ "*/.ipynb_checkpoints/*",]
29
29
  [tool.coverage.report]
30
30
  show_missing = true
31
31
 
32
+ [tool.pytest.ini_options]
33
+ addopts = "--strict-markers --import-mode=importlib"
34
+ timeout = 300
35
+ timeout_method = "thread"
36
+
32
37
  [tool.setuptools.packages.find]
33
38
  exclude = [ "server", "server.*",]