opensportslib 0.3.1.dev6__tar.gz → 0.3.1.dev8__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 (206) hide show
  1. {opensportslib-0.3.1.dev6/opensportslib.egg-info → opensportslib-0.3.1.dev8}/PKG-INFO +10 -1
  2. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/README.md +9 -0
  3. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/__init__.py +6 -1
  4. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/__init__.py +3 -0
  5. opensportslib-0.3.1.dev8/opensportslib/remote_registry.py +124 -0
  6. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8/opensportslib.egg-info}/PKG-INFO +10 -1
  7. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib.egg-info/SOURCES.txt +3 -0
  8. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/pyproject.toml +1 -1
  9. opensportslib-0.3.1.dev8/tests/test_remote_model_registry.py +94 -0
  10. opensportslib-0.3.1.dev8/tests/test_server_model_registry.py +100 -0
  11. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/LICENSE +0 -0
  12. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/LICENSE-COMMERCIAL +0 -0
  13. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/MANIFEST.in +0 -0
  14. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/examples/quickstart/basic_classification.py +0 -0
  15. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/examples/quickstart/basic_localization.py +0 -0
  16. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/examples/quickstart/basic_vqa.py +0 -0
  17. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/adaptation/__init__.py +0 -0
  18. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/adaptation/spotta.py +0 -0
  19. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/base_task_model.py +0 -0
  20. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/classification.py +0 -0
  21. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/config.py +0 -0
  22. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/configuration.py +0 -0
  23. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/localization.py +0 -0
  24. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/apis/vqa.py +0 -0
  25. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/cli.py +0 -0
  26. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/classification/default.yaml +0 -0
  27. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  28. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  29. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/classification/video.yaml +0 -0
  30. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/default.yaml +0 -0
  31. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  32. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/default.yaml +0 -0
  33. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/e2e_spotta.yaml +0 -0
  34. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  35. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/h5_header_skeleton.yaml +0 -0
  36. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  37. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/tracking_action_spotting.yaml +0 -0
  38. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/video_dali.yaml +0 -0
  39. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  40. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/default.yaml +0 -0
  41. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/qwen.yaml +0 -0
  42. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/qwen3_vl_native.yaml +0 -0
  43. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
  44. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
  45. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/configs/vqa/xvars.yaml +0 -0
  46. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/__init__.py +0 -0
  47. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/__init__.py +0 -0
  48. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/accessors.py +0 -0
  49. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/conflicts.py +0 -0
  50. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/editable.py +0 -0
  51. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/loader.py +0 -0
  52. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/migrate.py +0 -0
  53. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/migrations/__init__.py +0 -0
  54. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  55. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/rule_variants.py +0 -0
  56. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/runtime_adapter.py +0 -0
  57. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/schema.py +0 -0
  58. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/schemas/__init__.py +0 -0
  59. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  60. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  61. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/config/validate.py +0 -0
  62. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/__init__.py +0 -0
  63. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/builder.py +0 -0
  64. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/calf.py +0 -0
  65. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/ce.py +0 -0
  66. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/combine.py +0 -0
  67. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/loss/nll.py +0 -0
  68. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/optimizer/__init__.py +0 -0
  69. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/optimizer/builder.py +0 -0
  70. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  71. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/scheduler/__init__.py +0 -0
  72. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/scheduler/builder.py +0 -0
  73. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/trainer/__init__.py +0 -0
  74. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/trainer/classification_trainer.py +0 -0
  75. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/trainer/localization_trainer.py +0 -0
  76. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/trainer/vqa_trainer.py +0 -0
  77. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/checkpoint.py +0 -0
  78. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/config.py +0 -0
  79. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/config_normalize.py +0 -0
  80. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/data.py +0 -0
  81. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/ddp.py +0 -0
  82. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/default_args.py +0 -0
  83. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/direct_video.py +0 -0
  84. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/hf_runtime.py +0 -0
  85. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/lightning.py +0 -0
  86. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/load_annotations.py +0 -0
  87. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/seed.py +0 -0
  88. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/video_processing.py +0 -0
  89. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/core/utils/wandb.py +0 -0
  90. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/__init__.py +0 -0
  91. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/builder.py +0 -0
  92. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/classification_dataset.py +0 -0
  93. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/localization_dataset.py +0 -0
  94. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/utils/__init__.py +0 -0
  95. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  96. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/utils/tracking.py +0 -0
  97. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/datasets/vqa_dataset.py +0 -0
  98. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/classification.yaml +0 -0
  99. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  100. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  101. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  102. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/localization.yaml +0 -0
  103. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  104. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  105. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/metrics/classification_metric.py +0 -0
  106. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/metrics/localization_metric.py +0 -0
  107. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/metrics/vqa_metric.py +0 -0
  108. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/__init__.py +0 -0
  109. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/backbones/builder.py +0 -0
  110. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/contextaware.py +0 -0
  111. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/e2e.py +0 -0
  112. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/learnablepooling.py +0 -0
  113. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/qwen_vl_native.py +0 -0
  114. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/qwen_xvars.py +0 -0
  115. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/rule_based.py +0 -0
  116. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/tracking.py +0 -0
  117. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/vars.py +0 -0
  118. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/video.py +0 -0
  119. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  120. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/video_mae.py +0 -0
  121. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
  122. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/builder.py +0 -0
  123. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/heads/builder.py +0 -0
  124. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/neck/builder.py +0 -0
  125. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/common.py +0 -0
  126. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/__init__.py +0 -0
  127. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/asformer.py +0 -0
  128. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/calf.py +0 -0
  129. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/gsm.py +0 -0
  130. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/gtad.py +0 -0
  131. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/impl/tsm.py +0 -0
  132. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/litebase.py +0 -0
  133. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/modules.py +0 -0
  134. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/shift.py +0 -0
  135. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/utils.py +0 -0
  136. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  137. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/vqa_prompting.py +0 -0
  138. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  139. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/setup/setup.py +0 -0
  140. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/tools/__init__.py +0 -0
  141. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/tools/_common.py +0 -0
  142. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/tools/hf_transfer.py +0 -0
  143. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  144. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  145. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib.egg-info/dependency_links.txt +0 -0
  146. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib.egg-info/entry_points.txt +0 -0
  147. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib.egg-info/requires.txt +0 -0
  148. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/opensportslib.egg-info/top_level.txt +0 -0
  149. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/scripts/release_versions.py +0 -0
  150. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/scripts/run_h5_header_rule_inference.py +0 -0
  151. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/setup.cfg +0 -0
  152. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/conftest.py +0 -0
  153. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/release/__init__.py +0 -0
  154. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/release/_release_common.py +0 -0
  155. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/release/test_classification_release.py +0 -0
  156. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/release/test_localization_release.py +0 -0
  157. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/release/test_vqa_release.py +0 -0
  158. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_classification_dataset_paths.py +0 -0
  159. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_classification_trainer_dataloader.py +0 -0
  160. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_config_architecture.py +0 -0
  161. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_config_split_override_sync.py +0 -0
  162. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_config_utils_smoke.py +0 -0
  163. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_conversion_tools.py +0 -0
  164. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_editable_config.py +0 -0
  165. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_extract_xvars_features.py +0 -0
  166. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_h5_header_rule_spotter.py +0 -0
  167. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_h5_header_skeleton_spotter.py +0 -0
  168. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_h5_tracking_dataset.py +0 -0
  169. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_hf_transfer_tools.py +0 -0
  170. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_localization_dali_filenames.py +0 -0
  171. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_localization_hf_backend_override.py +0 -0
  172. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_localization_intervals.py +0 -0
  173. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_optional_hf_config.py +0 -0
  174. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_package_smoke.py +0 -0
  175. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_pretrained_config_merge_policy.py +0 -0
  176. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_public_apis_smoke.py +0 -0
  177. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_release_versions.py +0 -0
  178. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_setup_cli.py +0 -0
  179. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_spotta_e2e.py +0 -0
  180. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_subset_train_infer_integration.py +0 -0
  181. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_task_model_api_contract.py +0 -0
  182. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_vqa_api.py +0 -0
  183. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_vqa_metrics_semantic.py +0 -0
  184. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_vqa_qwen_xvars.py +0 -0
  185. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_vqa_training_lora.py +0 -0
  186. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tests/test_vqa_xvars_videochatgpt.py +0 -0
  187. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
  188. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_sngar_spotting.py +0 -0
  189. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_soccernet_gar.py +0 -0
  190. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  191. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_soccernet_gar_vqa.py +0 -0
  192. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/build_xvars_indexes.py +0 -0
  193. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/extract_xvars_clip_features.py +0 -0
  194. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  195. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  196. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/sngar_dataset_card.py +0 -0
  197. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/sngar_events.py +0 -0
  198. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/convert/verify_sngar_spotting.py +0 -0
  199. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/download/download_hf_repo.py +0 -0
  200. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/download/download_osl_hf.py +0 -0
  201. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/download/push_sngar_spotting.py +0 -0
  202. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/download/upload_osl_hf.py +0 -0
  203. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/training/classification.py +0 -0
  204. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/training/localization.py +0 -0
  205. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/tools/training/vqa.py +0 -0
  206. {opensportslib-0.3.1.dev6 → opensportslib-0.3.1.dev8}/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.dev6
3
+ Version: 0.3.1.dev8
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
@@ -36,6 +36,15 @@ Dynamic: license-file
36
36
 
37
37
  # OpenSportsLib
38
38
 
39
+ OpenSportsLib inference servers support runtime model registration through
40
+ `RemoteModelRegistry`. Its unified `register_model()` method accepts Hugging
41
+ Face or server-local weights; the returned model ID is then used by the existing
42
+ remote task APIs. Unregistered model IDs are rejected.
43
+
44
+ See the [complete inference server guide](docs/server/inference-server.md) for
45
+ installation, registry administration, curl requests, single-video inference,
46
+ full-test-set and per-sample remote inference, job polling, and sessions.
47
+
39
48
  ## Configuration From Hugging Face
40
49
 
41
50
  Prepare and inspect configuration before model weights are allocated:
@@ -1,5 +1,14 @@
1
1
  # OpenSportsLib
2
2
 
3
+ OpenSportsLib inference servers support runtime model registration through
4
+ `RemoteModelRegistry`. Its unified `register_model()` method accepts Hugging
5
+ Face or server-local weights; the returned model ID is then used by the existing
6
+ remote task APIs. Unregistered model IDs are rejected.
7
+
8
+ See the [complete inference server guide](docs/server/inference-server.md) for
9
+ installation, registry administration, curl requests, single-video inference,
10
+ full-test-set and per-sample remote inference, job polling, and sessions.
11
+
3
12
  ## Configuration From Hugging Face
4
13
 
5
14
  Prepare and inspect configuration before model weights are allocated:
@@ -1,5 +1,7 @@
1
1
  import importlib
2
2
 
3
+ from opensportslib.remote_registry import RemoteModelRegistry, RemoteRegistryError
4
+
3
5
 
4
6
  def __getattr__(name):
5
7
  if name == "model":
@@ -15,4 +17,7 @@ def __getattr__(name):
15
17
  raise AttributeError(f"module 'opensportslib' has no attribute '{name}'")
16
18
 
17
19
 
18
- __all__ = ["model", "metrics", "datasets", "core", "tools"]
20
+ __all__ = [
21
+ "model", "metrics", "datasets", "core", "tools",
22
+ "RemoteModelRegistry", "RemoteRegistryError",
23
+ ]
@@ -6,6 +6,7 @@ from opensportslib.apis.base_task_model import BaseTaskModel
6
6
  from opensportslib.apis.classification import ClassificationModel
7
7
  from opensportslib.apis.localization import LocalizationModel
8
8
  from opensportslib.apis.vqa import VQAModel
9
+ from opensportslib.remote_registry import RemoteModelRegistry, RemoteRegistryError
9
10
  import warnings
10
11
  warnings.filterwarnings("ignore")
11
12
 
@@ -16,4 +17,6 @@ __all__ = [
16
17
  "ClassificationModel",
17
18
  "LocalizationModel",
18
19
  "VQAModel",
20
+ "RemoteModelRegistry",
21
+ "RemoteRegistryError",
19
22
  ]
@@ -0,0 +1,124 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import time
5
+ from pathlib import Path
6
+ from typing import Any
7
+ from urllib import error, parse, request
8
+
9
+
10
+ class RemoteRegistryError(RuntimeError):
11
+ def __init__(self, status_code: int, detail: Any):
12
+ self.status_code = status_code
13
+ self.detail = detail
14
+ super().__init__(f"Remote model registry returned HTTP {status_code}: {detail}")
15
+
16
+
17
+ class RemoteModelRegistry:
18
+ """Administrative client for an OpenSportsLib server model registry."""
19
+
20
+ def __init__(self, remote: str, admin_token: str, timeout: float = 30.0):
21
+ if not remote:
22
+ raise ValueError("remote is required.")
23
+ if not admin_token:
24
+ raise ValueError("admin_token is required.")
25
+ self.remote = remote.rstrip("/")
26
+ self.admin_token = admin_token
27
+ self.timeout = float(timeout)
28
+ if self.timeout <= 0:
29
+ raise ValueError("timeout must be positive.")
30
+
31
+ def register_model(
32
+ self,
33
+ *,
34
+ task_type: str,
35
+ huggingface_model_id: str | None = None,
36
+ weights_path: str | Path | None = None,
37
+ config_path: str | Path | None = None,
38
+ model_id: str | None = None,
39
+ ) -> dict[str, Any]:
40
+ """Register exactly one Hugging Face or server-local model source."""
41
+ if (huggingface_model_id is None) == (weights_path is None):
42
+ raise ValueError("Provide exactly one of huggingface_model_id or weights_path.")
43
+ if huggingface_model_id is not None:
44
+ if config_path is not None:
45
+ raise ValueError("config_path applies only to local models.")
46
+ if model_id is not None and model_id != huggingface_model_id:
47
+ raise ValueError("A Hugging Face model uses its repository ID as model_id.")
48
+ payload = {
49
+ "task_type": task_type,
50
+ "source": {"type": "huggingface", "model_id": huggingface_model_id},
51
+ }
52
+ else:
53
+ payload = {
54
+ "task_type": task_type,
55
+ "model_id": model_id,
56
+ "source": {
57
+ "type": "local",
58
+ "weights_path": str(weights_path),
59
+ "config_path": str(config_path) if config_path is not None else None,
60
+ },
61
+ }
62
+ return self._request("POST", "/models", payload, authenticated=True)
63
+
64
+ def list_models(self) -> list[dict[str, Any]]:
65
+ return self._request("GET", "/models")["models"]
66
+
67
+ def get_model(self, model_id: str) -> dict[str, Any]:
68
+ query = parse.urlencode({"model_id": model_id})
69
+ return self._request("GET", f"/models/status?{query}")
70
+
71
+ 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)
73
+
74
+ def wait_for_operation(
75
+ self,
76
+ operation_id: str,
77
+ *,
78
+ timeout: float = 7200.0,
79
+ poll_interval: float = 1.0,
80
+ ) -> dict[str, Any]:
81
+ deadline = time.monotonic() + timeout
82
+ while True:
83
+ operation = self.get_operation(operation_id)
84
+ if operation["status"] == "succeeded":
85
+ return operation
86
+ if operation["status"] == "failed":
87
+ raise RuntimeError(operation.get("error") or "Model operation failed.")
88
+ if time.monotonic() >= deadline:
89
+ raise TimeoutError(f"Timed out waiting for model operation `{operation_id}`.")
90
+ time.sleep(poll_interval)
91
+
92
+ def set_default(self, task_type: str, model_id: str) -> dict[str, Any]:
93
+ task = parse.quote(task_type, safe="")
94
+ return self._request("PUT", f"/models/defaults/{task}", {"model_id": model_id}, authenticated=True)
95
+
96
+ def unregister_model(self, model_id: str) -> dict[str, Any]:
97
+ encoded = parse.quote(model_id, safe="")
98
+ return self._request("DELETE", f"/models/{encoded}", authenticated=True)
99
+
100
+ def _request(
101
+ self,
102
+ method: str,
103
+ endpoint: str,
104
+ payload: dict[str, Any] | None = None,
105
+ authenticated: bool = False,
106
+ ) -> dict[str, Any]:
107
+ body = json.dumps(payload).encode() if payload is not None else None
108
+ headers = {"Content-Type": "application/json"}
109
+ if authenticated:
110
+ headers["Authorization"] = f"Bearer {self.admin_token}"
111
+ outgoing = request.Request(self.remote + endpoint, data=body, method=method, headers=headers)
112
+ try:
113
+ with request.urlopen(outgoing, timeout=self.timeout) as response:
114
+ return json.loads(response.read().decode())
115
+ except error.HTTPError as exc:
116
+ detail = exc.read().decode(errors="replace")
117
+ try:
118
+ parsed = json.loads(detail)
119
+ detail = parsed.get("detail", parsed)
120
+ except json.JSONDecodeError:
121
+ pass
122
+ raise RemoteRegistryError(exc.code, detail) from exc
123
+ except error.URLError as exc:
124
+ raise ConnectionError(f"Could not reach remote server `{self.remote}`: {exc.reason}") from exc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.3.1.dev6
3
+ Version: 0.3.1.dev8
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
@@ -36,6 +36,15 @@ Dynamic: license-file
36
36
 
37
37
  # OpenSportsLib
38
38
 
39
+ OpenSportsLib inference servers support runtime model registration through
40
+ `RemoteModelRegistry`. Its unified `register_model()` method accepts Hugging
41
+ Face or server-local weights; the returned model ID is then used by the existing
42
+ remote task APIs. Unregistered model IDs are rejected.
43
+
44
+ See the [complete inference server guide](docs/server/inference-server.md) for
45
+ installation, registry administration, curl requests, single-video inference,
46
+ full-test-set and per-sample remote inference, job polling, and sessions.
47
+
39
48
  ## Configuration From Hugging Face
40
49
 
41
50
  Prepare and inspect configuration before model weights are allocated:
@@ -8,6 +8,7 @@ examples/quickstart/basic_localization.py
8
8
  examples/quickstart/basic_vqa.py
9
9
  opensportslib/__init__.py
10
10
  opensportslib/cli.py
11
+ opensportslib/remote_registry.py
11
12
  opensportslib.egg-info/PKG-INFO
12
13
  opensportslib.egg-info/SOURCES.txt
13
14
  opensportslib.egg-info/dependency_links.txt
@@ -165,6 +166,8 @@ tests/test_package_smoke.py
165
166
  tests/test_pretrained_config_merge_policy.py
166
167
  tests/test_public_apis_smoke.py
167
168
  tests/test_release_versions.py
169
+ tests/test_remote_model_registry.py
170
+ tests/test_server_model_registry.py
168
171
  tests/test_setup_cli.py
169
172
  tests/test_spotta_e2e.py
170
173
  tests/test_subset_train_infer_integration.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opensportslib"
7
- version = "0.3.1.dev6"
7
+ version = "0.3.1.dev8"
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"
@@ -0,0 +1,94 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ import pytest
5
+
6
+ from opensportslib import RemoteModelRegistry, RemoteRegistryError
7
+
8
+
9
+ class FakeResponse:
10
+ def __init__(self, payload):
11
+ self.payload = payload
12
+
13
+ def __enter__(self):
14
+ return self
15
+
16
+ def __exit__(self, *args):
17
+ return False
18
+
19
+ def read(self):
20
+ return json.dumps(self.payload).encode()
21
+
22
+
23
+ def test_register_huggingface_uses_one_registration_method():
24
+ client = RemoteModelRegistry("http://server", "secret")
25
+ with patch("opensportslib.remote_registry.request.urlopen") as urlopen:
26
+ urlopen.return_value = FakeResponse({"model_id": "org/model", "status": "registering"})
27
+ result = client.register_model(task_type="classification", huggingface_model_id="org/model")
28
+
29
+ outgoing = urlopen.call_args.args[0]
30
+ assert json.loads(outgoing.data) == {
31
+ "task_type": "classification",
32
+ "source": {"type": "huggingface", "model_id": "org/model"},
33
+ }
34
+ assert outgoing.headers["Authorization"] == "Bearer secret"
35
+ assert result["model_id"] == "org/model"
36
+
37
+
38
+ def test_register_local_supports_custom_or_generated_model_id():
39
+ client = RemoteModelRegistry("http://server", "secret")
40
+ with patch("opensportslib.remote_registry.request.urlopen") as urlopen:
41
+ urlopen.return_value = FakeResponse({"model_id": "custom", "status": "registering"})
42
+ client.register_model(
43
+ task_type="localization",
44
+ model_id="custom",
45
+ weights_path="/models/custom/model.pth",
46
+ config_path="/models/custom/config.yaml",
47
+ )
48
+
49
+ payload = json.loads(urlopen.call_args.args[0].data)
50
+ assert payload["model_id"] == "custom"
51
+ assert payload["source"] == {
52
+ "type": "local",
53
+ "weights_path": "/models/custom/model.pth",
54
+ "config_path": "/models/custom/config.yaml",
55
+ }
56
+
57
+
58
+ @pytest.mark.parametrize(
59
+ "kwargs",
60
+ [
61
+ {},
62
+ {"huggingface_model_id": "org/model", "weights_path": "/models/model"},
63
+ ],
64
+ )
65
+ def test_register_model_requires_exactly_one_source(kwargs):
66
+ client = RemoteModelRegistry("http://server", "secret")
67
+ with pytest.raises(ValueError, match="exactly one"):
68
+ client.register_model(task_type="classification", **kwargs)
69
+
70
+
71
+ def test_huggingface_model_cannot_be_renamed():
72
+ client = RemoteModelRegistry("http://server", "secret")
73
+ with pytest.raises(ValueError, match="repository ID"):
74
+ client.register_model(
75
+ task_type="classification",
76
+ huggingface_model_id="org/model",
77
+ model_id="alias",
78
+ )
79
+
80
+
81
+ def test_http_errors_preserve_structured_detail():
82
+ from urllib.error import HTTPError
83
+ from io import BytesIO
84
+
85
+ client = RemoteModelRegistry("http://server", "secret")
86
+ response = HTTPError(
87
+ "http://server/models", 409, "Conflict", {},
88
+ BytesIO(json.dumps({"detail": {"code": "MODEL_NOT_READY"}}).encode()),
89
+ )
90
+ with patch("opensportslib.remote_registry.request.urlopen", side_effect=response):
91
+ with pytest.raises(RemoteRegistryError) as raised:
92
+ client.get_model("model")
93
+ assert raised.value.status_code == 409
94
+ assert raised.value.detail == {"code": "MODEL_NOT_READY"}
@@ -0,0 +1,100 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from types import SimpleNamespace
4
+
5
+ import pytest
6
+
7
+
8
+ SERVER_ROOT = Path(__file__).parents[1] / "server"
9
+ sys.path.insert(0, str(SERVER_ROOT))
10
+
11
+ from config.model_registry import ( # noqa: E402
12
+ ModelRegistry,
13
+ generated_local_model_id,
14
+ public_record,
15
+ resolve_local_source,
16
+ validate_local_model_id,
17
+ )
18
+
19
+
20
+ class FakeRedis:
21
+ def __init__(self):
22
+ self.hashes = {}
23
+
24
+ def hget(self, key, field):
25
+ return self.hashes.get(key, {}).get(field)
26
+
27
+ def hvals(self, key):
28
+ return list(self.hashes.get(key, {}).values())
29
+
30
+ def hset(self, key, field, value):
31
+ self.hashes.setdefault(key, {})[field] = value
32
+
33
+ def hsetnx(self, key, field, value):
34
+ values = self.hashes.setdefault(key, {})
35
+ if field in values:
36
+ return 0
37
+ values[field] = value
38
+ return 1
39
+
40
+ def hdel(self, key, field):
41
+ self.hashes.get(key, {}).pop(field, None)
42
+
43
+ def hgetall(self, key):
44
+ return dict(self.hashes.get(key, {}))
45
+
46
+
47
+ def record(model_id="model", source="org/model"):
48
+ return {
49
+ "model_id": model_id,
50
+ "task_type": "classification",
51
+ "source_type": "huggingface",
52
+ "source": source,
53
+ "config_path": None,
54
+ "status": "ready",
55
+ "generation": 1,
56
+ "created_at": "now",
57
+ "updated_at": "now",
58
+ "error": None,
59
+ }
60
+
61
+
62
+ def test_registry_reserves_idempotently_and_rejects_conflicts():
63
+ registry = ModelRegistry(SimpleNamespace(redis_url="redis://unused"), FakeRedis())
64
+ _, created = registry.reserve(record())
65
+ assert created
66
+ existing, created = registry.reserve(record())
67
+ assert not created
68
+ assert existing["source"] == "org/model"
69
+ with pytest.raises(FileExistsError):
70
+ registry.reserve(record(source="other/model"))
71
+
72
+
73
+ def test_local_source_stays_inside_model_root(tmp_path):
74
+ root = tmp_path / "models"
75
+ folder = root / "custom"
76
+ folder.mkdir(parents=True)
77
+ (folder / "config.yaml").write_text("MODEL: {}")
78
+ settings = SimpleNamespace(model_root=root)
79
+
80
+ weights, config = resolve_local_source(settings, str(folder), None)
81
+ assert weights == folder
82
+ assert config == folder / "config.yaml"
83
+ assert generated_local_model_id(folder).startswith("local:custom-")
84
+
85
+ outside = tmp_path / "outside"
86
+ outside.mkdir()
87
+ with pytest.raises(ValueError, match="OSL_MODEL_ROOT"):
88
+ resolve_local_source(settings, str(outside), None)
89
+
90
+
91
+ def test_custom_id_and_public_local_record_validation():
92
+ assert validate_local_model_id("football-model:v2") == "football-model:v2"
93
+ with pytest.raises(ValueError):
94
+ validate_local_model_id("folder/model")
95
+ local = record()
96
+ local.update({"source_type": "local", "source": "/secret/model", "config_path": "/secret/config", "error": "at /secret/model"})
97
+ visible = public_record(local)
98
+ assert "source" not in visible
99
+ assert "config_path" not in visible
100
+ assert "/secret" not in visible["error"]