opensportslib 0.3.0.dev4__tar.gz → 0.3.0.dev6__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 (183) hide show
  1. {opensportslib-0.3.0.dev4/opensportslib.egg-info → opensportslib-0.3.0.dev6}/PKG-INFO +1 -1
  2. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/apis/localization.py +2 -1
  3. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/loader.py +36 -10
  4. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/localization_dataset.py +23 -14
  5. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6/opensportslib.egg-info}/PKG-INFO +1 -1
  6. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib.egg-info/SOURCES.txt +1 -0
  7. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/pyproject.toml +1 -1
  8. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_config_architecture.py +15 -1
  9. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_localization_dali_filenames.py +8 -1
  10. opensportslib-0.3.0.dev6/tests/test_localization_hf_backend_override.py +205 -0
  11. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/LICENSE +0 -0
  12. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/LICENSE-COMMERCIAL +0 -0
  13. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/MANIFEST.in +0 -0
  14. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/README.md +0 -0
  15. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/examples/quickstart/basic_classification.py +0 -0
  16. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/examples/quickstart/basic_localization.py +0 -0
  17. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/examples/quickstart/basic_vqa.py +0 -0
  18. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/__init__.py +0 -0
  19. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/apis/__init__.py +0 -0
  20. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/apis/base_task_model.py +0 -0
  21. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/apis/classification.py +0 -0
  22. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/apis/vqa.py +0 -0
  23. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/cli.py +0 -0
  24. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/classification/default.yaml +0 -0
  25. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  26. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  27. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/classification/video.yaml +0 -0
  28. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/default.yaml +0 -0
  29. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  30. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/default.yaml +0 -0
  31. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  32. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_distance_angle.yaml +0 -0
  33. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_distance_speed.yaml +0 -0
  34. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +0 -0
  35. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_rule.yaml +0 -0
  36. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/h5_header_skeleton.yaml +0 -0
  37. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  38. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/video_dali.yaml +0 -0
  39. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  40. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/default.yaml +0 -0
  41. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/qwen.yaml +0 -0
  42. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/qwen3_vl_native.yaml +0 -0
  43. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
  44. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
  45. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/configs/vqa/xvars.yaml +0 -0
  46. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/__init__.py +0 -0
  47. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/__init__.py +0 -0
  48. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/accessors.py +0 -0
  49. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/conflicts.py +0 -0
  50. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/migrate.py +0 -0
  51. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/migrations/__init__.py +0 -0
  52. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  53. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/runtime_adapter.py +0 -0
  54. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/schema.py +0 -0
  55. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/schemas/__init__.py +0 -0
  56. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  57. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  58. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/config/validate.py +0 -0
  59. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/__init__.py +0 -0
  60. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/builder.py +0 -0
  61. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/calf.py +0 -0
  62. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/ce.py +0 -0
  63. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/combine.py +0 -0
  64. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/loss/nll.py +0 -0
  65. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/optimizer/__init__.py +0 -0
  66. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/optimizer/builder.py +0 -0
  67. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  68. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/scheduler/__init__.py +0 -0
  69. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/scheduler/builder.py +0 -0
  70. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/trainer/__init__.py +0 -0
  71. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/trainer/classification_trainer.py +0 -0
  72. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/trainer/localization_trainer.py +0 -0
  73. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/trainer/vqa_trainer.py +0 -0
  74. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/checkpoint.py +0 -0
  75. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/config.py +0 -0
  76. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/config_normalize.py +0 -0
  77. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/data.py +0 -0
  78. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/ddp.py +0 -0
  79. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/default_args.py +0 -0
  80. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/hf_runtime.py +0 -0
  81. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/lightning.py +0 -0
  82. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/load_annotations.py +0 -0
  83. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/seed.py +0 -0
  84. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/video_processing.py +0 -0
  85. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/core/utils/wandb.py +0 -0
  86. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/__init__.py +0 -0
  87. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/builder.py +0 -0
  88. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/classification_dataset.py +0 -0
  89. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/utils/__init__.py +0 -0
  90. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  91. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/utils/tracking.py +0 -0
  92. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/datasets/vqa_dataset.py +0 -0
  93. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/classification.yaml +0 -0
  94. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  95. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  96. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  97. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/localization.yaml +0 -0
  98. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  99. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  100. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/metrics/classification_metric.py +0 -0
  101. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/metrics/localization_metric.py +0 -0
  102. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/metrics/vqa_metric.py +0 -0
  103. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/__init__.py +0 -0
  104. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/backbones/builder.py +0 -0
  105. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/contextaware.py +0 -0
  106. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/e2e.py +0 -0
  107. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/learnablepooling.py +0 -0
  108. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/qwen_vl_native.py +0 -0
  109. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/qwen_xvars.py +0 -0
  110. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/rule_based.py +0 -0
  111. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/tracking.py +0 -0
  112. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/vars.py +0 -0
  113. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/video.py +0 -0
  114. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  115. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/video_mae.py +0 -0
  116. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
  117. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/builder.py +0 -0
  118. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/heads/builder.py +0 -0
  119. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/neck/builder.py +0 -0
  120. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/common.py +0 -0
  121. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/__init__.py +0 -0
  122. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/asformer.py +0 -0
  123. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/calf.py +0 -0
  124. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/gsm.py +0 -0
  125. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/gtad.py +0 -0
  126. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/impl/tsm.py +0 -0
  127. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/litebase.py +0 -0
  128. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/modules.py +0 -0
  129. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/shift.py +0 -0
  130. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/utils.py +0 -0
  131. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  132. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/vqa_prompting.py +0 -0
  133. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  134. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/setup/setup.py +0 -0
  135. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/tools/__init__.py +0 -0
  136. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/tools/_common.py +0 -0
  137. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/tools/hf_transfer.py +0 -0
  138. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  139. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  140. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib.egg-info/dependency_links.txt +0 -0
  141. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib.egg-info/entry_points.txt +0 -0
  142. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib.egg-info/requires.txt +0 -0
  143. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/opensportslib.egg-info/top_level.txt +0 -0
  144. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/scripts/run_h5_header_rule_inference.py +0 -0
  145. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/scripts/run_header_spotting_eval.py +0 -0
  146. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/setup.cfg +0 -0
  147. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/conftest.py +0 -0
  148. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_classification_dataset_paths.py +0 -0
  149. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_classification_trainer_dataloader.py +0 -0
  150. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_config_split_override_sync.py +0 -0
  151. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_config_utils_smoke.py +0 -0
  152. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_conversion_tools.py +0 -0
  153. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_extract_xvars_features.py +0 -0
  154. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_h5_header_rule_spotter.py +0 -0
  155. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_h5_header_skeleton_spotter.py +0 -0
  156. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_h5_tracking_dataset.py +0 -0
  157. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_hf_transfer_tools.py +0 -0
  158. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_package_smoke.py +0 -0
  159. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_pretrained_config_merge_policy.py +0 -0
  160. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_public_apis_smoke.py +0 -0
  161. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_setup_cli.py +0 -0
  162. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_subset_train_infer_integration.py +0 -0
  163. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_task_model_api_contract.py +0 -0
  164. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_vqa_api.py +0 -0
  165. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_vqa_metrics_semantic.py +0 -0
  166. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_vqa_qwen_xvars.py +0 -0
  167. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_vqa_training_lora.py +0 -0
  168. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tests/test_vqa_xvars_videochatgpt.py +0 -0
  169. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
  170. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/build_soccernet_gar.py +0 -0
  171. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  172. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/build_soccernet_gar_vqa.py +0 -0
  173. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/build_xvars_indexes.py +0 -0
  174. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/extract_xvars_clip_features.py +0 -0
  175. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  176. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  177. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/download/download_hf_repo.py +0 -0
  178. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/download/download_osl_hf.py +0 -0
  179. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/download/upload_osl_hf.py +0 -0
  180. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/training/classification.py +0 -0
  181. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/training/localization.py +0 -0
  182. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/tools/training/vqa.py +0 -0
  183. {opensportslib-0.3.0.dev4 → opensportslib-0.3.0.dev6}/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.0.dev4
3
+ Version: 0.3.0.dev6
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
@@ -19,6 +19,7 @@ from opensportslib.core.config.accessors import (
19
19
  get_model_family,
20
20
  )
21
21
  from opensportslib.core.utils.config import expand
22
+ from opensportslib.core.config.loader import _dali_available
22
23
 
23
24
 
24
25
  class LocalizationModel(BaseTaskModel):
@@ -126,7 +127,7 @@ class LocalizationModel(BaseTaskModel):
126
127
  from opensportslib.core.utils.config import select_device
127
128
 
128
129
  device = select_device(self.config.SYSTEM)
129
- backend = "dali" if self._device_type(device) == "cuda" else "opencv"
130
+ backend = "dali" if self._device_type(device) == "cuda" and _dali_available() else "opencv"
130
131
  current_backend = get_loader_backend(self.config)
131
132
  set_loader_backend(self.config, backend)
132
133
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import importlib.util
5
6
  import json
6
7
  from copy import deepcopy
7
8
  from pathlib import Path
@@ -135,12 +136,36 @@ def load_raw_config(path: str | Path) -> dict[str, Any]:
135
136
  raise ValueError("Unsupported config format. Use YAML or JSON.")
136
137
 
137
138
 
138
- def _normalize_cpu_loader_backend(payload: dict[str, Any]) -> dict[str, Any]:
139
+ def _torch_cuda_available() -> bool:
140
+ try:
141
+ import torch
142
+ except Exception:
143
+ return False
144
+ return bool(torch.cuda.is_available())
145
+
146
+
147
+ def _dali_available() -> bool:
148
+ return importlib.util.find_spec("nvidia.dali") is not None
149
+
150
+
151
+ def _preferred_loader_backend(payload: dict[str, Any]) -> str | None:
139
152
  system = payload.get("SYSTEM", {})
140
153
  if not isinstance(system, dict):
141
- return payload
154
+ return None
142
155
 
143
- if str(system.get("device", "auto")).lower() != "cpu":
156
+ mode = str(system.get("device", "auto")).lower()
157
+ if mode == "cpu":
158
+ return "opencv"
159
+ if mode == "cuda":
160
+ return "dali" if _dali_available() else "opencv"
161
+ if mode == "auto":
162
+ return "dali" if (_torch_cuda_available() and _dali_available()) else "opencv"
163
+ return None
164
+
165
+
166
+ def _normalize_cpu_loader_backend(payload: dict[str, Any]) -> dict[str, Any]:
167
+ preferred_backend = _preferred_loader_backend(payload)
168
+ if preferred_backend is None:
144
169
  return payload
145
170
 
146
171
  data = payload.get("DATA", {})
@@ -155,18 +180,19 @@ def _normalize_cpu_loader_backend(payload: dict[str, Any]) -> dict[str, Any]:
155
180
  if not isinstance(runtime, dict):
156
181
  runtime = {}
157
182
  common["runtime"] = runtime
158
- runtime["loader_backend"] = "opencv"
183
+ runtime["loader_backend"] = preferred_backend
159
184
 
160
185
  splits = common.get("splits", {})
161
186
  if not isinstance(splits, dict):
162
187
  return payload
163
188
 
164
- for split_cfg in splits.values():
165
- if not isinstance(split_cfg, dict):
166
- continue
167
- split_type = split_cfg.get("type")
168
- if split_type in _CPU_OPENCV_SPLIT_TYPES:
169
- split_cfg["type"] = _CPU_OPENCV_SPLIT_TYPES[split_type]
189
+ if preferred_backend == "opencv":
190
+ for split_cfg in splits.values():
191
+ if not isinstance(split_cfg, dict):
192
+ continue
193
+ split_type = split_cfg.get("type")
194
+ if split_type in _CPU_OPENCV_SPLIT_TYPES:
195
+ split_cfg["type"] = _CPU_OPENCV_SPLIT_TYPES[split_type]
170
196
 
171
197
  return payload
172
198
 
@@ -74,6 +74,15 @@ def _build_dali_filenames_and_labels(labels):
74
74
  return filenames, label_indices
75
75
 
76
76
 
77
+ def _normalize_dali_devices(devices, sample_count):
78
+ devices = list(devices or [])
79
+ if not devices:
80
+ return [0]
81
+ if sample_count <= 0:
82
+ return devices[:1]
83
+ return devices[: max(1, min(len(devices), int(sample_count)))]
84
+
85
+
77
86
  def _dali_frame_num_to_local_frame(frame_num, stride):
78
87
  return frame_num // stride + 1
79
88
 
@@ -1538,13 +1547,16 @@ if DALI_AVAILABLE:
1538
1547
  else:
1539
1548
  self.batch_size = batch_size
1540
1549
 
1541
- self.batch_size_per_pipe = distribute_elements(self.batch_size, len(devices))
1550
+ self._filenames, self._video_indices = _build_dali_filenames_and_labels(
1551
+ self._labels
1552
+ )
1553
+ self.devices = _normalize_dali_devices(devices, len(self._filenames))
1554
+ self.batch_size_per_pipe = distribute_elements(self.batch_size, len(self.devices))
1542
1555
 
1543
1556
  self.batch_size = batch_size
1544
1557
  self.nb_videos = dataset_len * 2 if mixup else dataset_len
1545
1558
  self.mixup = mixup
1546
1559
  self.output_map = output_map
1547
- self.devices = devices
1548
1560
  self.is_eval = is_eval
1549
1561
  self.crop_dim = crop_dim
1550
1562
  self.dilate_len = dilate_len
@@ -1555,9 +1567,6 @@ if DALI_AVAILABLE:
1555
1567
  self.TARGET_WIDTH = TARGET_WIDTH
1556
1568
 
1557
1569
  self._stride = get_stride(input_fps, extract_fps)
1558
- self._filenames, self._video_indices = _build_dali_filenames_and_labels(
1559
- self._labels
1560
- )
1561
1570
 
1562
1571
  self.pipes = [
1563
1572
  self.video_pipe(
@@ -1570,9 +1579,9 @@ if DALI_AVAILABLE:
1570
1579
  num_threads=8,
1571
1580
  device_id=i,
1572
1581
  shard_id=index,
1573
- num_shards=len(devices),
1582
+ num_shards=len(self.devices),
1574
1583
  )
1575
- for index, i in enumerate(devices)
1584
+ for index, i in enumerate(self.devices)
1576
1585
  ]
1577
1586
 
1578
1587
  for pipe in self.pipes:
@@ -1931,16 +1940,16 @@ if DALI_AVAILABLE:
1931
1940
  self._stride_dali = stride_dali
1932
1941
  self._flip = flip
1933
1942
  self._multi_crop = multi_crop
1934
- self.batch_size = batch_size // len(devices)
1943
+ self._filenames, self._video_indices = _build_dali_filenames_and_labels(
1944
+ self._labels
1945
+ )
1946
+ self.devices = _normalize_dali_devices(devices, len(self._filenames))
1947
+ self.batch_size = batch_size // len(self.devices)
1935
1948
  self.global_batch_size = batch_size
1936
- self.devices = devices
1937
1949
  self.IMAGENET_MEAN = IMAGENET_MEAN
1938
1950
  self.IMAGENET_STD = IMAGENET_STD
1939
1951
  self.TARGET_HEIGHT = TARGET_HEIGHT
1940
1952
  self.TARGET_WIDTH = TARGET_WIDTH
1941
- self._filenames, self._video_indices = _build_dali_filenames_and_labels(
1942
- self._labels
1943
- )
1944
1953
  clip_count = 0
1945
1954
  for video in self._labels:
1946
1955
  num_clips = _count_dali_video_samples(
@@ -1961,9 +1970,9 @@ if DALI_AVAILABLE:
1961
1970
  num_threads=8,
1962
1971
  device_id=i,
1963
1972
  shard_id=index,
1964
- num_shards=len(devices),
1973
+ num_shards=len(self.devices),
1965
1974
  )
1966
- for index, i in enumerate(devices)
1975
+ for index, i in enumerate(self.devices)
1967
1976
  ]
1968
1977
 
1969
1978
  for pipe in self.pipes:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.3.0.dev4
3
+ Version: 0.3.0.dev6
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
@@ -152,6 +152,7 @@ tests/test_h5_header_skeleton_spotter.py
152
152
  tests/test_h5_tracking_dataset.py
153
153
  tests/test_hf_transfer_tools.py
154
154
  tests/test_localization_dali_filenames.py
155
+ tests/test_localization_hf_backend_override.py
155
156
  tests/test_package_smoke.py
156
157
  tests/test_pretrained_config_merge_policy.py
157
158
  tests/test_public_apis_smoke.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opensportslib"
7
- version = "0.3.0.dev4"
7
+ version = "0.3.0.dev6"
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"
@@ -81,7 +81,7 @@ def test_localization_experiment_composes_all_layers():
81
81
  assert cfg["SYSTEM"]["paths"]["log_dir"] == "./logs"
82
82
  assert cfg["SYSTEM"]["paths"]["save_dir"] == "./checkpoints"
83
83
  assert cfg["SYSTEM"]["paths"]["work_dir"] == "./checkpoints"
84
- assert cfg["DATA"]["common"]["runtime"]["loader_backend"] == "dali"
84
+ assert cfg["DATA"]["common"]["runtime"]["loader_backend"] in {"dali", "opencv"}
85
85
  assert cfg["MODEL"]["components"]["video_encoder"]["source"]["name"] == "rny008_gsm"
86
86
 
87
87
 
@@ -99,6 +99,20 @@ def test_resolve_config_cpu_normalizes_canonical_dali_localization_config():
99
99
  assert resolved["DATA"]["common"]["splits"]["test"]["type"] == "VideoGameWithOpencvVideo"
100
100
 
101
101
 
102
+ def test_resolve_config_cuda_without_dali_normalizes_to_opencv(monkeypatch):
103
+ cfg = load_config("opensportslib/configs/localization/video_dali.yaml", as_namespace=False)
104
+ cfg["SYSTEM"]["device"] = "cuda"
105
+
106
+ monkeypatch.setattr("opensportslib.core.config.loader._dali_available", lambda: False)
107
+
108
+ resolved = resolve_config(cfg, as_namespace=False)
109
+
110
+ assert resolved["DATA"]["common"]["runtime"]["loader_backend"] == "opencv"
111
+ assert resolved["DATA"]["common"]["splits"]["train"]["type"] == "VideoGameWithOpencv"
112
+ assert resolved["DATA"]["common"]["splits"]["valid"]["type"] == "VideoGameWithOpencv"
113
+ assert resolved["DATA"]["common"]["splits"]["test"]["type"] == "VideoGameWithOpencvVideo"
114
+
115
+
102
116
  def test_vqa_xvars_experiment_composes_all_layers():
103
117
  cfg = load_config("opensportslib/configs/vqa/xvars.yaml", as_namespace=False)
104
118
 
@@ -4,6 +4,7 @@ from opensportslib.datasets.localization_dataset import (
4
4
  _build_dali_filenames_and_labels,
5
5
  _count_dali_video_samples,
6
6
  _dali_frame_num_to_local_frame,
7
+ _normalize_dali_devices,
7
8
  _pad_dali_iterator_size,
8
9
  _resolve_dali_video_sample,
9
10
  )
@@ -56,4 +57,10 @@ def test_resolve_dali_video_sample_uses_relative_path_and_one_based_start():
56
57
  video_name, start = _resolve_dali_video_sample(labels, 0, 24, 12)
57
58
 
58
59
  assert video_name == "train/match one.mp4"
59
- assert start == 3
60
+ assert start == 3
61
+
62
+
63
+ def test_normalize_dali_devices_caps_shards_to_sample_count():
64
+ assert _normalize_dali_devices([0, 1, 2, 3], 1) == [0]
65
+ assert _normalize_dali_devices([0, 1, 2, 3], 2) == [0, 1]
66
+ assert _normalize_dali_devices([], 1) == [0]
@@ -0,0 +1,205 @@
1
+ import os
2
+ import sys
3
+ from types import ModuleType, SimpleNamespace
4
+
5
+ from opensportslib.apis.localization import LocalizationModel
6
+ from opensportslib.core.config.accessors import get_loader_backend
7
+
8
+
9
+ def _split(split_type, batch_size=4, shuffle=False):
10
+ return SimpleNamespace(
11
+ type=split_type,
12
+ annotation_path="/tmp/annotations.json",
13
+ source_path="/tmp/data",
14
+ dataloader=SimpleNamespace(batch_size=batch_size, shuffle=shuffle),
15
+ )
16
+
17
+
18
+ def _make_config(loader_backend="dali"):
19
+ return SimpleNamespace(
20
+ TASK="localization",
21
+ DATA=SimpleNamespace(
22
+ common=SimpleNamespace(
23
+ runtime=SimpleNamespace(loader_backend=loader_backend),
24
+ classes=["PASS", "SHOT"],
25
+ splits=SimpleNamespace(
26
+ train=_split("VideoGameWithDali", shuffle=True),
27
+ valid=_split("VideoGameWithDali", shuffle=True),
28
+ test=_split("VideoGameWithDaliVideo"),
29
+ ),
30
+ ),
31
+ inputs=SimpleNamespace(
32
+ video=SimpleNamespace(
33
+ modality="video",
34
+ representation="raw",
35
+ sampling=SimpleNamespace(),
36
+ transform=SimpleNamespace(),
37
+ params=SimpleNamespace(),
38
+ )
39
+ ),
40
+ ),
41
+ MODEL=SimpleNamespace(task="localization", components=SimpleNamespace(), topology=[]),
42
+ SYSTEM=SimpleNamespace(
43
+ device="cpu",
44
+ gpu=SimpleNamespace(count=0, id=0),
45
+ reproducibility=SimpleNamespace(seed=0, use_seed=False),
46
+ paths=SimpleNamespace(save_dir="/tmp", work_dir="/tmp", log_dir="/tmp"),
47
+ ),
48
+ TRAIN=SimpleNamespace(
49
+ execution=SimpleNamespace(multi_gpu=False),
50
+ trainer=SimpleNamespace(type="trainer_e2e"),
51
+ ),
52
+ )
53
+
54
+
55
+ def _make_api(config):
56
+ api = LocalizationModel.__new__(LocalizationModel)
57
+ api.config = config
58
+ api.config_path = "/tmp/localization.yaml"
59
+ api.model = None
60
+ api.processor = None
61
+ api.trainer = None
62
+ api.last_loaded_weights = None
63
+ api.best_checkpoint = None
64
+ api.train_flag = False
65
+ return api
66
+
67
+
68
+ def test_hf_localization_cpu_switches_to_opencv_and_normalizes_dataloader(monkeypatch):
69
+ api = _make_api(_make_config(loader_backend="dali"))
70
+ api.config = _make_config(loader_backend="dali")
71
+
72
+ monkeypatch.setattr(
73
+ "opensportslib.core.utils.config.select_device",
74
+ lambda system: SimpleNamespace(type="cpu"),
75
+ )
76
+
77
+ api._adapt_hf_backend_for_device("OpenSportsLab/OSL-loc-snbas-2025-e2e")
78
+
79
+ assert get_loader_backend(api.config) == "opencv"
80
+ assert api.config.DATA.common.splits.train.type == "VideoGameWithOpencv"
81
+ assert api.config.DATA.common.splits.valid.type == "VideoGameWithOpencv"
82
+ assert api.config.DATA.common.splits.test.type == "VideoGameWithOpencvVideo"
83
+ assert api.config.DATA.common.splits.valid.dataloader.num_workers == 0
84
+ assert api.config.DATA.common.splits.valid.dataloader.pin_memory is False
85
+
86
+
87
+ def test_hf_localization_auto_cuda_switches_to_dali(monkeypatch):
88
+ api = _make_api(_make_config(loader_backend="opencv"))
89
+ api.config.DATA.common.splits.train.type = "VideoGameWithOpencv"
90
+ api.config.DATA.common.splits.valid.type = "VideoGameWithOpencv"
91
+ api.config.DATA.common.splits.test.type = "VideoGameWithOpencvVideo"
92
+ api.config.SYSTEM.device = "auto"
93
+
94
+ monkeypatch.setattr(
95
+ "opensportslib.core.utils.config.select_device",
96
+ lambda system: SimpleNamespace(type="cuda"),
97
+ )
98
+ monkeypatch.setattr("opensportslib.apis.localization._dali_available", lambda: True)
99
+
100
+ api._adapt_hf_backend_for_device("OpenSportsLab/OSL-loc-snbas-2023-e2e")
101
+
102
+ assert get_loader_backend(api.config) == "dali"
103
+ assert api.config.DATA.common.splits.train.type == "VideoGameWithDali"
104
+ assert api.config.DATA.common.splits.valid.type == "VideoGameWithDali"
105
+ assert api.config.DATA.common.splits.test.type == "VideoGameWithDaliVideo"
106
+
107
+
108
+ def test_hf_localization_cuda_without_dali_falls_back_to_opencv(monkeypatch):
109
+ api = _make_api(_make_config(loader_backend="dali"))
110
+
111
+ monkeypatch.setattr(
112
+ "opensportslib.core.utils.config.select_device",
113
+ lambda system: SimpleNamespace(type="cuda"),
114
+ )
115
+ monkeypatch.setattr("opensportslib.apis.localization._dali_available", lambda: False)
116
+
117
+ api._adapt_hf_backend_for_device("OpenSportsLab/OSL-loc-snbas-2023-e2e")
118
+
119
+ assert get_loader_backend(api.config) == "opencv"
120
+ assert api.config.DATA.common.splits.train.type == "VideoGameWithOpencv"
121
+ assert api.config.DATA.common.splits.valid.type == "VideoGameWithOpencv"
122
+ assert api.config.DATA.common.splits.test.type == "VideoGameWithOpencvVideo"
123
+
124
+
125
+ def test_local_weights_do_not_trigger_hf_backend_override(monkeypatch):
126
+ api = _make_api(_make_config(loader_backend="dali"))
127
+
128
+ monkeypatch.setattr(
129
+ "opensportslib.core.utils.config.select_device",
130
+ lambda system: SimpleNamespace(type="cpu"),
131
+ )
132
+
133
+ api._adapt_hf_backend_for_device("/tmp/model.pt")
134
+
135
+ assert get_loader_backend(api.config) == "dali"
136
+ assert api.config.DATA.common.splits.train.type == "VideoGameWithDali"
137
+ assert not hasattr(api.config.DATA.common.splits.valid.dataloader, "num_workers")
138
+
139
+
140
+ def test_localization_infer_applies_hf_backend_override_before_dataset_build(
141
+ tmp_path,
142
+ monkeypatch,
143
+ ):
144
+ test_set = tmp_path / "test.json"
145
+ test_set.write_text("{}", encoding="utf-8")
146
+ observed = {}
147
+
148
+ class FakeData:
149
+ cfg = SimpleNamespace(dataloader=SimpleNamespace(batch_size=1, shuffle=False))
150
+ default_args = {}
151
+
152
+ def building_dataset(self, cfg, gpu, default_args):
153
+ del cfg, gpu, default_args
154
+ return ["dataset"]
155
+
156
+ def building_dataloader(self, dataset, cfg, gpu, dali):
157
+ del dataset, cfg, gpu
158
+ observed["dali"] = dali
159
+ return ["batch"]
160
+
161
+ class FakeInferer:
162
+ def infer(self, cfg, data, dataloader):
163
+ del data, dataloader
164
+ observed["backend"] = get_loader_backend(cfg)
165
+ observed["dataset_type"] = cfg.DATA.common.splits.test.type
166
+ return {"task": "localization"}
167
+
168
+ fake_load_annotations = ModuleType("opensportslib.core.utils.load_annotations")
169
+ fake_load_annotations.check_config = lambda config, split: None
170
+ fake_load_annotations.whether_infer_split = lambda test_cfg: False
171
+ monkeypatch.setitem(sys.modules, "opensportslib.core.utils.load_annotations", fake_load_annotations)
172
+
173
+ fake_localization_trainer = ModuleType("opensportslib.core.trainer.localization_trainer")
174
+ fake_localization_trainer.build_inferer = lambda cfg, model: FakeInferer()
175
+ monkeypatch.setitem(
176
+ sys.modules,
177
+ "opensportslib.core.trainer.localization_trainer",
178
+ fake_localization_trainer,
179
+ )
180
+
181
+ fake_builder = ModuleType("opensportslib.datasets.builder")
182
+ fake_builder.build_dataset = lambda config, split: FakeData()
183
+ monkeypatch.setitem(sys.modules, "opensportslib.datasets.builder", fake_builder)
184
+
185
+ fake_wandb = ModuleType("opensportslib.core.utils.wandb")
186
+ fake_wandb.init_wandb = lambda *args, **kwargs: None
187
+ monkeypatch.setitem(sys.modules, "opensportslib.core.utils.wandb", fake_wandb)
188
+
189
+ monkeypatch.setattr("opensportslib.core.utils.config.resolve_config_omega", lambda config, weights=None: config)
190
+ monkeypatch.setattr(
191
+ "opensportslib.core.utils.config.select_device",
192
+ lambda system: SimpleNamespace(type="cpu"),
193
+ )
194
+ monkeypatch.setattr(LocalizationModel, "load_weights", lambda self, weights=None, **kwargs: setattr(self, "model", object()))
195
+
196
+ api = _make_api(_make_config(loader_backend="dali"))
197
+ os.environ["RUN_ID"] = "test-run"
198
+ api.last_loaded_weights = "OpenSportsLab/OSL-loc-snbas-2025-e2e"
199
+
200
+ predictions = api.infer(test_set=str(test_set), use_wandb=False)
201
+
202
+ assert predictions == {"task": "localization"}
203
+ assert observed["backend"] == "opencv"
204
+ assert observed["dataset_type"] == "VideoGameWithOpencvVideo"
205
+ assert observed["dali"] is False