opensportslib 0.3.1.dev25__tar.gz → 0.3.1.dev26__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 (245) hide show
  1. {opensportslib-0.3.1.dev25/opensportslib.egg-info → opensportslib-0.3.1.dev26}/PKG-INFO +7 -1
  2. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/README.md +6 -0
  3. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26/opensportslib.egg-info}/PKG-INFO +7 -1
  4. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib.egg-info/SOURCES.txt +6 -1
  5. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/pyproject.toml +1 -1
  6. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_hf_transfer.py +178 -0
  7. opensportslib-0.3.1.dev26/tests/unit/tools/test_spotting_classification.py +489 -0
  8. opensportslib-0.3.1.dev26/tools/convert/spotting_to_classification.py +902 -0
  9. opensportslib-0.3.1.dev26/tools/convert/spotting_tracking_to_classification.py +414 -0
  10. opensportslib-0.3.1.dev26/tools/upload/upload_sngar_tracking_full.py +107 -0
  11. opensportslib-0.3.1.dev26/tools/upload/upload_sngar_videos.py +130 -0
  12. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/LICENSE +0 -0
  13. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/LICENSE-COMMERCIAL +0 -0
  14. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/MANIFEST.in +0 -0
  15. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/examples/quickstart/basic_classification.py +0 -0
  16. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/examples/quickstart/basic_localization.py +0 -0
  17. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/examples/quickstart/basic_vqa.py +0 -0
  18. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/__init__.py +0 -0
  19. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/adaptation/__init__.py +0 -0
  20. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/adaptation/spotta.py +0 -0
  21. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/__init__.py +0 -0
  22. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/base_task_model.py +0 -0
  23. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/classification.py +0 -0
  24. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/config.py +0 -0
  25. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/configuration.py +0 -0
  26. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/localization.py +0 -0
  27. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/apis/vqa.py +0 -0
  28. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/cli.py +0 -0
  29. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/classification/default.yaml +0 -0
  30. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  31. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  32. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/classification/video.yaml +0 -0
  33. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/default.yaml +0 -0
  34. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  35. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/default.yaml +0 -0
  36. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/e2e_spotta.yaml +0 -0
  37. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  38. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/h5_header_skeleton.yaml +0 -0
  39. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  40. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/tracking_action_spotting.yaml +0 -0
  41. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/video_dali.yaml +0 -0
  42. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  43. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/default.yaml +0 -0
  44. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/qwen.yaml +0 -0
  45. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/qwen3_vl_native.yaml +0 -0
  46. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
  47. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
  48. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/configs/vqa/xvars.yaml +0 -0
  49. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/__init__.py +0 -0
  50. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/__init__.py +0 -0
  51. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/accessors.py +0 -0
  52. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/conflicts.py +0 -0
  53. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/editable.py +0 -0
  54. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/loader.py +0 -0
  55. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/migrate.py +0 -0
  56. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/migrations/__init__.py +0 -0
  57. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  58. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/rule_variants.py +0 -0
  59. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/runtime_adapter.py +0 -0
  60. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/schema.py +0 -0
  61. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/schemas/__init__.py +0 -0
  62. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  63. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  64. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/config/validate.py +0 -0
  65. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/__init__.py +0 -0
  66. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/builder.py +0 -0
  67. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/calf.py +0 -0
  68. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/ce.py +0 -0
  69. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/combine.py +0 -0
  70. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/loss/nll.py +0 -0
  71. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/optimizer/__init__.py +0 -0
  72. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/optimizer/builder.py +0 -0
  73. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  74. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/scheduler/__init__.py +0 -0
  75. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/scheduler/builder.py +0 -0
  76. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/trainer/__init__.py +0 -0
  77. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/trainer/classification_trainer.py +0 -0
  78. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/trainer/localization_trainer.py +0 -0
  79. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/trainer/vqa_trainer.py +0 -0
  80. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/checkpoint.py +0 -0
  81. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/config.py +0 -0
  82. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/config_normalize.py +0 -0
  83. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/data.py +0 -0
  84. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/ddp.py +0 -0
  85. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/default_args.py +0 -0
  86. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/direct_video.py +0 -0
  87. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/hf_runtime.py +0 -0
  88. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/lightning.py +0 -0
  89. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/load_annotations.py +0 -0
  90. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/seed.py +0 -0
  91. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/video_processing.py +0 -0
  92. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/core/utils/wandb.py +0 -0
  93. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/__init__.py +0 -0
  94. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/builder.py +0 -0
  95. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/classification_dataset.py +0 -0
  96. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/hf_json.py +0 -0
  97. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/hf_tracking.py +0 -0
  98. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/localization_dataset.py +0 -0
  99. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/utils/__init__.py +0 -0
  100. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  101. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/utils/tracking.py +0 -0
  102. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/datasets/vqa_dataset.py +0 -0
  103. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/classification.yaml +0 -0
  104. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  105. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  106. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  107. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/localization.yaml +0 -0
  108. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  109. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  110. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/metrics/classification_metric.py +0 -0
  111. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/metrics/localization_metric.py +0 -0
  112. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/metrics/vqa_metric.py +0 -0
  113. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/__init__.py +0 -0
  114. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/backbones/builder.py +0 -0
  115. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/contextaware.py +0 -0
  116. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/e2e.py +0 -0
  117. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/learnablepooling.py +0 -0
  118. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/qwen_vl_native.py +0 -0
  119. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/qwen_xvars.py +0 -0
  120. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/rule_based.py +0 -0
  121. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/tracking.py +0 -0
  122. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/vars.py +0 -0
  123. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/video.py +0 -0
  124. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  125. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/video_mae.py +0 -0
  126. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
  127. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/builder.py +0 -0
  128. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/heads/builder.py +0 -0
  129. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/neck/builder.py +0 -0
  130. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/common.py +0 -0
  131. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/__init__.py +0 -0
  132. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/asformer.py +0 -0
  133. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/calf.py +0 -0
  134. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/gsm.py +0 -0
  135. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/gtad.py +0 -0
  136. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/impl/tsm.py +0 -0
  137. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/litebase.py +0 -0
  138. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/modules.py +0 -0
  139. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/shift.py +0 -0
  140. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/utils.py +0 -0
  141. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  142. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/vqa_prompting.py +0 -0
  143. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  144. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/remote_registry.py +0 -0
  145. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/setup/setup.py +0 -0
  146. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/tools/__init__.py +0 -0
  147. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/tools/_common.py +0 -0
  148. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/tools/hf_transfer.py +0 -0
  149. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  150. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  151. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib.egg-info/dependency_links.txt +0 -0
  152. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib.egg-info/entry_points.txt +0 -0
  153. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib.egg-info/requires.txt +0 -0
  154. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/opensportslib.egg-info/top_level.txt +0 -0
  155. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/redact_test_stream.py +0 -0
  156. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/release_versions.py +0 -0
  157. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/run_h5_header_rule_inference.py +0 -0
  158. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/summarize_test_report.py +0 -0
  159. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/verify_release_manifests.py +0 -0
  160. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/scripts/write_release_manifest.py +0 -0
  161. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/setup.cfg +0 -0
  162. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/__init__.py +0 -0
  163. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/conftest.py +0 -0
  164. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/helpers/__init__.py +0 -0
  165. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/helpers/configs.py +0 -0
  166. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/helpers/pipeline_stubs.py +0 -0
  167. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/integration/classification/test_pipeline.py +0 -0
  168. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/integration/localization/test_pipeline.py +0 -0
  169. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/integration/localization/test_spotta.py +0 -0
  170. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/integration/vqa/test_pipeline.py +0 -0
  171. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/__init__.py +0 -0
  172. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/_release_common.py +0 -0
  173. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/test_00_environment.py +0 -0
  174. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/test_classification_release.py +0 -0
  175. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/test_localization_release.py +0 -0
  176. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/release/test_vqa_release.py +0 -0
  177. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/smoke/test_cli.py +0 -0
  178. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/smoke/test_config_utils.py +0 -0
  179. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/smoke/test_environment.py +0 -0
  180. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/smoke/test_package.py +0 -0
  181. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/smoke/test_public_apis.py +0 -0
  182. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_remote_registry.py +0 -0
  183. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_remote_sessions.py +0 -0
  184. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_server_jobs.py +0 -0
  185. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_server_registry.py +0 -0
  186. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_server_startup_scripts.py +0 -0
  187. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_task_model_contract.py +0 -0
  188. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/api/test_vqa.py +0 -0
  189. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/config/test_architecture.py +0 -0
  190. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/config/test_editable.py +0 -0
  191. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/config/test_optional_hf.py +0 -0
  192. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/config/test_pretrained_merge.py +0 -0
  193. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/config/test_split_overrides.py +0 -0
  194. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/contracts/test_architecture.py +0 -0
  195. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/contracts/test_dependencies.py +0 -0
  196. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/contracts/test_package.py +0 -0
  197. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/contracts/test_release_versions.py +0 -0
  198. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/contracts/test_runner_contract.py +0 -0
  199. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/core/test_classification_trainer.py +0 -0
  200. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/core/test_localization_hf_backend.py +0 -0
  201. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/core/test_training_components.py +0 -0
  202. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/core/test_video_processing.py +0 -0
  203. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_classification_paths.py +0 -0
  204. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_h5_tracking.py +0 -0
  205. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_hf_json_spotting.py +0 -0
  206. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_hf_json_tracking_spotting.py +0 -0
  207. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_hf_tracking_dataset.py +0 -0
  208. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_localization_dali.py +0 -0
  209. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_localization_intervals.py +0 -0
  210. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/data/test_osl_formats.py +0 -0
  211. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_classification_metrics.py +0 -0
  212. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_header_rule_spotter.py +0 -0
  213. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_header_skeleton_spotter.py +0 -0
  214. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_localization_metrics.py +0 -0
  215. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_temporal_shift.py +0 -0
  216. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_vqa_metrics.py +0 -0
  217. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_vqa_qwen_xvars.py +0 -0
  218. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_vqa_training_lora.py +0 -0
  219. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/models/test_vqa_xvars_videochatgpt.py +0 -0
  220. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_conversion.py +0 -0
  221. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_extract_xvars_features.py +0 -0
  222. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_release_manifest.py +0 -0
  223. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_report_summary.py +0 -0
  224. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tests/unit/tools/test_setup.py +0 -0
  225. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
  226. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_sngar_spotting.py +0 -0
  227. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_soccernet_gar.py +0 -0
  228. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  229. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_soccernet_gar_vqa.py +0 -0
  230. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/build_xvars_indexes.py +0 -0
  231. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/extract_xvars_clip_features.py +0 -0
  232. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  233. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  234. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/sngar_dataset_card.py +0 -0
  235. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/sngar_events.py +0 -0
  236. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/convert/verify_sngar_spotting.py +0 -0
  237. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/download/download_hf_repo.py +0 -0
  238. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/download/download_osl_hf.py +0 -0
  239. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/download/push_sngar_spotting.py +0 -0
  240. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/download/upload_osl_hf.py +0 -0
  241. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/train/train_config.py +0 -0
  242. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/training/classification.py +0 -0
  243. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/training/localization.py +0 -0
  244. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/tools/training/vqa.py +0 -0
  245. {opensportslib-0.3.1.dev25 → opensportslib-0.3.1.dev26}/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.dev25
3
+ Version: 0.3.1.dev26
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
@@ -324,3 +324,9 @@ video understanding. Core contributors affiliated with KAUST include:
324
324
  - [Jeet Vora](https://jeetv.github.io/) — Remote Research Engineer
325
325
  - [Dr. Merey Ramazanova](https://meryusha.github.io/) — Post-Doc
326
326
  - [Dr. Silvio Giancola](https://www.silviogiancola.com/) — Research Scientist
327
+
328
+ For synchronized native-FPS GAR action clips and optional exact frame reproduction, see the
329
+ [spotting-to-classification converter](docs/tools/spotting-to-classification.md).
330
+
331
+ For full-rate tracking clips with the same classification sample IDs, see the
332
+ [tracking conversion script](docs/tools/spotting-tracking-to-classification.md).
@@ -285,3 +285,9 @@ video understanding. Core contributors affiliated with KAUST include:
285
285
  - [Jeet Vora](https://jeetv.github.io/) — Remote Research Engineer
286
286
  - [Dr. Merey Ramazanova](https://meryusha.github.io/) — Post-Doc
287
287
  - [Dr. Silvio Giancola](https://www.silviogiancola.com/) — Research Scientist
288
+
289
+ For synchronized native-FPS GAR action clips and optional exact frame reproduction, see the
290
+ [spotting-to-classification converter](docs/tools/spotting-to-classification.md).
291
+
292
+ For full-rate tracking clips with the same classification sample IDs, see the
293
+ [tracking conversion script](docs/tools/spotting-tracking-to-classification.md).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.3.1.dev25
3
+ Version: 0.3.1.dev26
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
@@ -324,3 +324,9 @@ video understanding. Core contributors affiliated with KAUST include:
324
324
  - [Jeet Vora](https://jeetv.github.io/) — Remote Research Engineer
325
325
  - [Dr. Merey Ramazanova](https://meryusha.github.io/) — Post-Doc
326
326
  - [Dr. Silvio Giancola](https://www.silviogiancola.com/) — Research Scientist
327
+
328
+ For synchronized native-FPS GAR action clips and optional exact frame reproduction, see the
329
+ [spotting-to-classification converter](docs/tools/spotting-to-classification.md).
330
+
331
+ For full-rate tracking clips with the same classification sample IDs, see the
332
+ [tracking conversion script](docs/tools/spotting-tracking-to-classification.md).
@@ -215,6 +215,7 @@ tests/unit/tools/test_hf_transfer.py
215
215
  tests/unit/tools/test_release_manifest.py
216
216
  tests/unit/tools/test_report_summary.py
217
217
  tests/unit/tools/test_setup.py
218
+ tests/unit/tools/test_spotting_classification.py
218
219
  tools/convert/build_sn_vqa_2026_vqa.py
219
220
  tools/convert/build_sngar_spotting.py
220
221
  tools/convert/build_soccernet_gar.py
@@ -226,6 +227,8 @@ tools/convert/osl_json_to_parquet_webdataset.py
226
227
  tools/convert/parquet_webdataset_to_osl_json.py
227
228
  tools/convert/sngar_dataset_card.py
228
229
  tools/convert/sngar_events.py
230
+ tools/convert/spotting_to_classification.py
231
+ tools/convert/spotting_tracking_to_classification.py
229
232
  tools/convert/verify_sngar_spotting.py
230
233
  tools/download/download_hf_repo.py
231
234
  tools/download/download_osl_hf.py
@@ -235,4 +238,6 @@ tools/train/train_config.py
235
238
  tools/training/classification.py
236
239
  tools/training/localization.py
237
240
  tools/training/vqa.py
238
- tools/upload/upload_model_hf.py
241
+ tools/upload/upload_model_hf.py
242
+ tools/upload/upload_sngar_tracking_full.py
243
+ tools/upload/upload_sngar_videos.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opensportslib"
7
- version = "0.3.1.dev25"
7
+ version = "0.3.1.dev26"
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"
@@ -1942,3 +1942,181 @@ def test_upload_dataset_inputs_from_json_to_hf_can_be_cancelled_before_upload(mo
1942
1942
  )
1943
1943
 
1944
1944
  assert calls["create_commit"] == 0
1945
+
1946
+
1947
+ @pytest.fixture
1948
+ def tracking_full_upload(tmp_path, monkeypatch):
1949
+ import importlib.util
1950
+ import pyarrow as pa
1951
+ import pyarrow.parquet as pq
1952
+
1953
+ script = Path(__file__).resolve().parents[3] / "tools/upload/upload_sngar_tracking_full.py"
1954
+ spec = importlib.util.spec_from_file_location("tracking_full_upload", script)
1955
+ module = importlib.util.module_from_spec(spec)
1956
+ spec.loader.exec_module(module)
1957
+ monkeypatch.setattr(module, "COUNTS", {"train": 1, "valid": 1, "test": 1})
1958
+ root = tmp_path / "tracking"
1959
+ reports = tmp_path / "reports"
1960
+ reports.mkdir()
1961
+ (reports / "build.json").write_text(json.dumps({"status": "passed", "completed": 3, "identity": "build"}))
1962
+ for split in module.COUNTS:
1963
+ (root / split).mkdir(parents=True)
1964
+ pq.write_table(pa.table({"frameNum": range(144), "tracking_valid": [True] * 144}), root / split / "clip.parquet")
1965
+ sample = {"id": split + "_000000", "inputs": [{"type": "tracking_parquet", "path": f"{split}/clip.parquet"}],
1966
+ "metadata": {"conversion": {"identity": "build", "frame_interval": 1,
1967
+ "window_slots": 144, "output_rows": 144, "gap_policy": "pad"}}}
1968
+ (root / f"annotations_{split}.json").write_text(json.dumps({"task": "action_classification", "data": [sample]}))
1969
+ calls = []
1970
+ monkeypatch.setattr(module, "dataset_repo_exists_on_hf", lambda repo: calls.append(("exists", repo)) or True)
1971
+ monkeypatch.setattr(module, "create_dataset_branch_on_hf", lambda *args, **kw: calls.append(("branch", args)))
1972
+ monkeypatch.setattr(module, "upload_dataset_as_parquet_to_hf", lambda *args, **kw: calls.append(("upload", args, kw)) or {})
1973
+ return module, root, calls
1974
+
1975
+
1976
+ def test_tracking_full_check_is_offline(tracking_full_upload):
1977
+ module, root, calls = tracking_full_upload
1978
+ assert module.main(["--data-root", str(root), "--check-only"]) == 0
1979
+ assert calls == []
1980
+
1981
+
1982
+ @pytest.mark.parametrize("failure", ["unfinished", "missing", "downsampled", "wrong_rows"])
1983
+ def test_tracking_full_invalid_build_never_contacts_hub(tracking_full_upload, failure):
1984
+ module, root, calls = tracking_full_upload
1985
+ if failure == "unfinished":
1986
+ (root.parent / "reports/build.json").write_text('{"status": "running"}')
1987
+ elif failure == "missing":
1988
+ (root / "test/clip.parquet").unlink()
1989
+ else:
1990
+ path = root / "annotations_test.json"
1991
+ data = json.loads(path.read_text())
1992
+ conversion = data["data"][0]["metadata"]["conversion"]
1993
+ conversion["frame_interval" if failure == "downsampled" else "output_rows"] = 9
1994
+ path.write_text(json.dumps(data))
1995
+ assert module.main(["--data-root", str(root)]) == 1
1996
+ assert calls == []
1997
+
1998
+
1999
+ def test_tracking_full_routes_to_internal_sharded_uploader(tracking_full_upload):
2000
+ module, root, calls = tracking_full_upload
2001
+ assert module.main(["--data-root", str(root), "--shard-size", "500MB", "--splits", "valid", "test"]) == 0
2002
+ assert calls[1] == ("branch", ("OpenSportsLab/SoccerNet-GAR", "tracking-full"))
2003
+ uploads = calls[2:]
2004
+ assert [call[2]["split"] for call in uploads] == ["valid", "test"]
2005
+ for _, args, kwargs in uploads:
2006
+ assert args[0] == "OpenSportsLab/SoccerNet-GAR"
2007
+ assert Path(args[1]) == root / f"annotations_{kwargs['split']}.json"
2008
+ assert kwargs["revision"] == "tracking-full"
2009
+ assert kwargs["shard_mode"] == "size"
2010
+ assert kwargs["shard_size"] == module.parse_shard_size("500MB")
2011
+
2012
+
2013
+ def test_tracking_full_stops_on_upload_failure(tracking_full_upload, monkeypatch):
2014
+ module, root, calls = tracking_full_upload
2015
+ attempted = []
2016
+ def fail(*args, **kwargs):
2017
+ attempted.append(kwargs["split"])
2018
+ raise RuntimeError("Upload interrupted")
2019
+ monkeypatch.setattr(module, "upload_dataset_as_parquet_to_hf", fail)
2020
+ assert module.main(["--data-root", str(root)]) == 1
2021
+ assert attempted == ["train"]
2022
+
2023
+
2024
+ @pytest.fixture
2025
+ def videos_upload(tracking_full_upload, monkeypatch):
2026
+ import importlib.util
2027
+ from fractions import Fraction
2028
+ import av
2029
+ import numpy as np
2030
+
2031
+ _, root, _ = tracking_full_upload
2032
+ script = Path(__file__).resolve().parents[3] / "tools/upload/upload_sngar_videos.py"
2033
+ spec = importlib.util.spec_from_file_location("videos_upload", script)
2034
+ module = importlib.util.module_from_spec(spec)
2035
+ spec.loader.exec_module(module)
2036
+ monkeypatch.setattr(module, "COUNTS", {"train": 1, "valid": 1, "test": 1})
2037
+ rate = Fraction(30000, 1001)
2038
+ for split in module.COUNTS:
2039
+ path = root / split / "clip.mp4"
2040
+ with av.open(str(path), "w") as output:
2041
+ stream = output.add_stream("libx264", rate=rate)
2042
+ stream.width, stream.height, stream.pix_fmt = 16, 16, "yuv420p"
2043
+ for i in range(144):
2044
+ frame = av.VideoFrame.from_ndarray(np.zeros((16, 16, 3), dtype=np.uint8), format="rgb24")
2045
+ frame.pts, frame.time_base = i, 1 / rate
2046
+ for packet in stream.encode(frame):
2047
+ output.mux(packet)
2048
+ for packet in stream.encode():
2049
+ output.mux(packet)
2050
+ manifest = root / f"annotations_{split}.json"
2051
+ data = json.loads(manifest.read_text())
2052
+ sample = data["data"][0]
2053
+ sample["inputs"] = [{"type": "video", "path": f"{split}/clip.mp4", "fps": float(rate)}]
2054
+ sample["metadata"]["conversion"] = {
2055
+ "identity": "build", "validation": "temporal", "alignment": {"passed": True},
2056
+ "sampled_frame_indices": list(range(90, 234, 9)),
2057
+ "clip": {"start_frame": 90, "end_frame_exclusive": 234, "frame_count": 144,
2058
+ "native_rate": str(rate), "width": 16, "height": 16,
2059
+ "duration_seconds": float(144 / rate)},
2060
+ }
2061
+ manifest.write_text(json.dumps(data))
2062
+ calls = []
2063
+ monkeypatch.setattr(module, "dataset_repo_exists_on_hf", lambda repo: calls.append(("exists", repo)) or True)
2064
+ monkeypatch.setattr(module, "create_dataset_branch_on_hf", lambda *args, **kw: calls.append(("branch", args)))
2065
+ monkeypatch.setattr(module, "upload_dataset_as_parquet_to_hf", lambda *args, **kw: calls.append(("upload", args, kw)) or {})
2066
+ return module, root, calls
2067
+
2068
+
2069
+ def test_videos_upload_offline_fractional_fps(videos_upload):
2070
+ module, root, calls = videos_upload
2071
+ assert module.main(["--data-root", str(root), "--check-only"]) == 0
2072
+ assert calls == []
2073
+
2074
+
2075
+ @pytest.mark.parametrize("failure", ["unfinished", "missing", "corrupt", "alignment", "frame_count", "native_rate", "duration_seconds"])
2076
+ def test_videos_invalid_build_never_contacts_hub(videos_upload, failure, capsys):
2077
+ module, root, calls = videos_upload
2078
+ if failure == "unfinished":
2079
+ (root.parent / "reports/build.json").write_text('{"status": "running"}')
2080
+ elif failure == "missing":
2081
+ (root / "test/clip.mp4").unlink()
2082
+ elif failure == "corrupt":
2083
+ (root / "test/clip.mp4").write_bytes(b"invalid mp4")
2084
+ else:
2085
+ manifest = root / "annotations_test.json"
2086
+ data = json.loads(manifest.read_text())
2087
+ conversion = data["data"][0]["metadata"]["conversion"]
2088
+ if failure == "alignment":
2089
+ conversion["alignment"]["passed"] = False
2090
+ else:
2091
+ conversion["clip"][failure] = 16
2092
+ manifest.write_text(json.dumps(data))
2093
+ assert module.main(["--data-root", str(root)]) == 1
2094
+ assert calls == []
2095
+ assert "Error:" in capsys.readouterr().err
2096
+
2097
+
2098
+ def test_videos_routes_to_internal_uploader(videos_upload):
2099
+ module, root, calls = videos_upload
2100
+ assert module.main(["--data-root", str(root), "--splits", "test", "--shard-size", "500MB"]) == 0
2101
+ assert calls[1] == ("branch", ("OpenSportsLab/SoccerNet-GAR", "videos"))
2102
+ assert len(calls) == 3
2103
+ _, args, kwargs = calls[2]
2104
+ assert args == ("OpenSportsLab/SoccerNet-GAR", str(root / "annotations_test.json"))
2105
+ assert kwargs["revision"] == "videos"
2106
+ assert kwargs["split"] == "test"
2107
+ assert kwargs["shard_mode"] == "size"
2108
+ assert kwargs["shard_size"] == module.parse_shard_size("500MB")
2109
+
2110
+
2111
+ def test_videos_accepts_legacy_timestamp_quantization(videos_upload):
2112
+ module, root, calls = videos_upload
2113
+ from fractions import Fraction
2114
+ # Legacy provenance stores nominal FPS, slightly different from measured
2115
+ # output FPS when the source timestamps include a one-tick correction.
2116
+ path = root / "annotations_test.json"
2117
+ data = json.loads(path.read_text())
2118
+ clip = data["data"][0]["metadata"]["conversion"]["clip"]
2119
+ clip["native_rate"] = str(Fraction(12960000, 432433))
2120
+ path.write_text(json.dumps(data))
2121
+ assert module.main(["--data-root", str(root), "--check-only"]) == 0
2122
+ assert calls == []