opensportslib 0.1.2.dev2__tar.gz → 0.1.2.dev4__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.
- {opensportslib-0.1.2.dev2/opensportslib.egg-info → opensportslib-0.1.2.dev4}/PKG-INFO +28 -2
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/README.md +26 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/__init__.py +5 -5
- opensportslib-0.1.2.dev4/opensportslib/cli.py +28 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/load_annotations.py +1 -1
- opensportslib-0.1.2.dev4/opensportslib/tools/__init__.py +49 -0
- opensportslib-0.1.2.dev4/opensportslib/tools/_common.py +28 -0
- opensportslib-0.1.2.dev4/opensportslib/tools/hf_transfer.py +895 -0
- opensportslib-0.1.2.dev4/opensportslib/tools/osl_json_to_parquet.py +411 -0
- opensportslib-0.1.2.dev4/opensportslib/tools/parquet_to_osl_json.py +265 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4/opensportslib.egg-info}/PKG-INFO +28 -2
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib.egg-info/SOURCES.txt +15 -1
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib.egg-info/requires.txt +1 -1
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib.egg-info/top_level.txt +1 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/pyproject.toml +2 -2
- opensportslib-0.1.2.dev4/tests/test_conversion_tools.py +273 -0
- opensportslib-0.1.2.dev4/tests/test_hf_transfer_tools.py +788 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/test_package_smoke.py +1 -0
- opensportslib-0.1.2.dev4/tools/convert/osl_json_to_parquet_webdataset.py +104 -0
- opensportslib-0.1.2.dev4/tools/convert/parquet_webdataset_to_osl_json.py +69 -0
- opensportslib-0.1.2.dev4/tools/download/download_hf_repo.py +109 -0
- opensportslib-0.1.2.dev4/tools/download/download_osl_hf.py +120 -0
- opensportslib-0.1.2.dev4/tools/download/upload_osl_hf.py +164 -0
- opensportslib-0.1.2.dev4/tools/training/classification.py +43 -0
- opensportslib-0.1.2.dev4/tools/training/localization.py +43 -0
- opensportslib-0.1.2.dev2/opensportslib/cli.py +0 -22
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/LICENSE +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/LICENSE-COMMERCIAL +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/MANIFEST.in +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/examples/quickstart/basic_classification.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/examples/quickstart/basic_localization.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/apis/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/apis/base_task_model.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/apis/classification.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/apis/localization.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/classification.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/localization-e2e-ocv.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/localization-json_calf_resnetpca512.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/localization-json_netvlad++_resnetpca512.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/localization.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/sngar-frames.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/config/sngar-tracking.yaml +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/calf.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/ce.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/combine.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/loss/nll.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/optimizer/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/optimizer/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/sampler/weighted_sampler.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/scheduler/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/scheduler/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/trainer/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/trainer/classification_trainer.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/trainer/localization_trainer.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/checkpoint.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/config.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/data.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/ddp.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/default_args.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/lightning.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/seed.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/video_processing.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/wandb.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/classification_dataset.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/localization_dataset.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/utils/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/datasets/utils/tracking.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/metrics/classification_metric.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/metrics/localization_metric.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/backbones/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/contextaware.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/e2e.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/learnablepooling.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/tracking.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/vars.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/video.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/base/video_mae.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/heads/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/neck/builder.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/common.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/__init__.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/asformer.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/calf.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/gsm.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/gtad.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/impl/tsm.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/litebase.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/modules.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/shift.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/models/utils/utils.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/setup/setup.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib.egg-info/dependency_links.txt +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib.egg-info/entry_points.txt +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/setup.cfg +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/conftest.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/test_config_utils_smoke.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/test_public_apis_smoke.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/test_subset_train_infer_integration.py +0 -0
- {opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/tests/test_task_model_api_contract.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensportslib
|
|
3
|
-
Version: 0.1.2.
|
|
3
|
+
Version: 0.1.2.dev4
|
|
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
|
|
@@ -9,7 +9,7 @@ License-File: LICENSE
|
|
|
9
9
|
License-File: LICENSE-COMMERCIAL
|
|
10
10
|
Requires-Dist: SoccerNet
|
|
11
11
|
Requires-Dist: av
|
|
12
|
-
Requires-Dist: decord; platform_system != "Darwin" and platform_machine != "arm64"
|
|
12
|
+
Requires-Dist: decord; platform_system != "Darwin" and platform_machine != "arm64" and platform_machine != "aarch64"
|
|
13
13
|
Requires-Dist: evaluate
|
|
14
14
|
Requires-Dist: scikit-learn
|
|
15
15
|
Requires-Dist: torch
|
|
@@ -196,6 +196,32 @@ metrics_from_file = my_model.evaluate(
|
|
|
196
196
|
)
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Hugging Face Dataset Transfer
|
|
203
|
+
|
|
204
|
+
OpenSportsLib provides APIs and scripts for downloading and uploading OSL datasets with Hugging Face.
|
|
205
|
+
|
|
206
|
+
### Python API
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from opensportslib.tools import (
|
|
210
|
+
download_dataset_split_from_hf,
|
|
211
|
+
upload_dataset_inputs_from_json_to_hf,
|
|
212
|
+
upload_dataset_as_parquet_to_hf,
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Scripts
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
python tools/download_osl_hf.py --repo-id <org/repo> --revision main --split test --format parquet --output-dir downloaded_data
|
|
220
|
+
python tools/upload_osl_hf.py --repo-id <org/repo> --json-path <local_dataset.json> --split test --revision main
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Downloads are placed under `<output-dir>/<revision>/<split>`.
|
|
224
|
+
|
|
199
225
|
---
|
|
200
226
|
|
|
201
227
|
## What you can do with OpenSportsLib
|
|
@@ -165,6 +165,32 @@ metrics_from_file = my_model.evaluate(
|
|
|
165
165
|
)
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Hugging Face Dataset Transfer
|
|
172
|
+
|
|
173
|
+
OpenSportsLib provides APIs and scripts for downloading and uploading OSL datasets with Hugging Face.
|
|
174
|
+
|
|
175
|
+
### Python API
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from opensportslib.tools import (
|
|
179
|
+
download_dataset_split_from_hf,
|
|
180
|
+
upload_dataset_inputs_from_json_to_hf,
|
|
181
|
+
upload_dataset_as_parquet_to_hf,
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Scripts
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
python tools/download_osl_hf.py --repo-id <org/repo> --revision main --split test --format parquet --output-dir downloaded_data
|
|
189
|
+
python tools/upload_osl_hf.py --repo-id <org/repo> --json-path <local_dataset.json> --split test --revision main
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Downloads are placed under `<output-dir>/<revision>/<split>`.
|
|
193
|
+
|
|
168
194
|
---
|
|
169
195
|
|
|
170
196
|
## What you can do with OpenSportsLib
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import importlib
|
|
2
|
-
|
|
3
|
-
# from . import metrics
|
|
4
|
-
# from . import datasets
|
|
5
|
-
# from . import core
|
|
2
|
+
|
|
6
3
|
|
|
7
4
|
def __getattr__(name):
|
|
8
5
|
if name == "model":
|
|
@@ -13,6 +10,9 @@ def __getattr__(name):
|
|
|
13
10
|
return importlib.import_module("opensportslib.datasets")
|
|
14
11
|
if name == "core":
|
|
15
12
|
return importlib.import_module("opensportslib.core")
|
|
13
|
+
if name == "tools":
|
|
14
|
+
return importlib.import_module("opensportslib.tools")
|
|
16
15
|
raise AttributeError(f"module 'opensportslib' has no attribute '{name}'")
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
__all__ = ["model", "metrics", "datasets", "core", "tools"]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from opensportslib.setup.setup import setup
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main(argv: Optional[list[str]] = None) -> int:
|
|
10
|
+
parser = argparse.ArgumentParser(prog="opensportslib")
|
|
11
|
+
parser.add_argument("command", choices=["setup"])
|
|
12
|
+
parser.add_argument("--pyg", action="store_true")
|
|
13
|
+
parser.add_argument("--dali", action="store_true")
|
|
14
|
+
|
|
15
|
+
args = parser.parse_args(argv)
|
|
16
|
+
|
|
17
|
+
if args.command == "setup":
|
|
18
|
+
setup(
|
|
19
|
+
pyg=args.pyg,
|
|
20
|
+
dali=args.dali,
|
|
21
|
+
)
|
|
22
|
+
return 0
|
|
23
|
+
|
|
24
|
+
return 2
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
raise SystemExit(main())
|
{opensportslib-0.1.2.dev2 → opensportslib-0.1.2.dev4}/opensportslib/core/utils/load_annotations.py
RENAMED
|
@@ -220,7 +220,7 @@ def annotationstoe2eformat(
|
|
|
220
220
|
|
|
221
221
|
for video in tqdm.tqdm(videos):
|
|
222
222
|
# ---- Video path & metadata ----
|
|
223
|
-
video_path = video["inputs"][0]["path"]
|
|
223
|
+
video_path = video["inputs"][0]["path"] #.replace(" ", "_")
|
|
224
224
|
#game_dir = os.path.dirname(video_path)
|
|
225
225
|
#game_name = os.path.basename(video_path)
|
|
226
226
|
full_video_path = os.path.join(video_dir, video_path)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""OpenSportsLib dataset conversion and Hugging Face transfer tools."""
|
|
2
|
+
|
|
3
|
+
from .hf_transfer import (
|
|
4
|
+
HF_BRANCH_KEY,
|
|
5
|
+
HF_REPO_ID_KEY,
|
|
6
|
+
HF_SPLIT_KEY,
|
|
7
|
+
HfTransferCancelled,
|
|
8
|
+
create_dataset_branch_on_hf,
|
|
9
|
+
create_dataset_repo_on_hf,
|
|
10
|
+
dataset_repo_exists_on_hf,
|
|
11
|
+
download_dataset_split_from_hf,
|
|
12
|
+
extract_local_input_upload_entries_from_json,
|
|
13
|
+
extract_repo_paths_from_json,
|
|
14
|
+
get_json_repo_folder,
|
|
15
|
+
is_hf_download_url_not_found_error,
|
|
16
|
+
is_hf_repo_not_found_error,
|
|
17
|
+
is_hf_revision_not_found_error,
|
|
18
|
+
read_hf_source_metadata_from_dataset,
|
|
19
|
+
upload_dataset_as_parquet_to_hf,
|
|
20
|
+
upload_dataset_inputs_from_json_to_hf,
|
|
21
|
+
write_hf_source_metadata_to_dataset_json,
|
|
22
|
+
)
|
|
23
|
+
from .osl_json_to_parquet import DEFAULT_SHARD_SIZE, convert_json_to_parquet, parse_shard_size
|
|
24
|
+
from .parquet_to_osl_json import convert_parquet_to_json
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"convert_json_to_parquet",
|
|
28
|
+
"DEFAULT_SHARD_SIZE",
|
|
29
|
+
"parse_shard_size",
|
|
30
|
+
"convert_parquet_to_json",
|
|
31
|
+
"HfTransferCancelled",
|
|
32
|
+
"HF_REPO_ID_KEY",
|
|
33
|
+
"HF_BRANCH_KEY",
|
|
34
|
+
"HF_SPLIT_KEY",
|
|
35
|
+
"download_dataset_split_from_hf",
|
|
36
|
+
"upload_dataset_inputs_from_json_to_hf",
|
|
37
|
+
"upload_dataset_as_parquet_to_hf",
|
|
38
|
+
"create_dataset_repo_on_hf",
|
|
39
|
+
"dataset_repo_exists_on_hf",
|
|
40
|
+
"create_dataset_branch_on_hf",
|
|
41
|
+
"read_hf_source_metadata_from_dataset",
|
|
42
|
+
"write_hf_source_metadata_to_dataset_json",
|
|
43
|
+
"is_hf_repo_not_found_error",
|
|
44
|
+
"is_hf_revision_not_found_error",
|
|
45
|
+
"is_hf_download_url_not_found_error",
|
|
46
|
+
"get_json_repo_folder",
|
|
47
|
+
"extract_repo_paths_from_json",
|
|
48
|
+
"extract_local_input_upload_entries_from_json",
|
|
49
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def json_dumps_compact(obj: Any) -> str:
|
|
10
|
+
return json.dumps(obj, ensure_ascii=False, separators=(",", ":"))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def maybe_json_loads(value: Any, default: Any) -> Any:
|
|
14
|
+
if value is None:
|
|
15
|
+
return default
|
|
16
|
+
if isinstance(value, float) and pd.isna(value):
|
|
17
|
+
return default
|
|
18
|
+
if isinstance(value, (dict, list)):
|
|
19
|
+
return value
|
|
20
|
+
if isinstance(value, str):
|
|
21
|
+
value = value.strip()
|
|
22
|
+
if not value:
|
|
23
|
+
return default
|
|
24
|
+
try:
|
|
25
|
+
return json.loads(value)
|
|
26
|
+
except Exception:
|
|
27
|
+
return default
|
|
28
|
+
return default
|