dexverse-cli 0.0.4.post1__tar.gz → 0.0.4.post2__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.
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/PKG-INFO +3 -2
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/README.md +2 -1
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/hdf5_to_raw.py +7 -1
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/manager.py +2 -2
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/manifest.py +7 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/pyproject.toml +1 -1
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_convert_additional_info.py +14 -2
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_http_backend.py +29 -3
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/.dockerignore +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/.gitignore +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/Dockerfile +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/decision-traces/2026-08-12_1613_pypi_0_0_4_release_trace.md +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/__init__.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/cli.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/client.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/config.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/__init__.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/image_video_encode.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/__init__.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/base.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/http_backend.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/python_s3_backend.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/s5cmd_backend.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/state.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/verify.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/__init__.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/mock_tasks.json +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/server.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docker_run.sh +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/DexVerse_Downloader_S3_Final_/345/256/236/346/226/275/346/226/271/346/241/210_/345/216/237/350/267/257/345/276/204/350/220/275/347/233/230/347/211/210.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/PROMPT_copy_and_download_command.md +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/Python_vs_Node_CLI/345/257/271/346/257/224/345/210/206/346/236/220.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/Python_vs_Node_/346/216/245/345/205/245C++/345/257/271/346/257/224/345/210/206/346/236/220.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs//345/210/206/345/217/221/347/273/231/347/256/227/346/263/225/345/233/242/351/230/237_/346/225/231/347/250/213.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs//346/223/215/344/275/234/346/214/207/345/215/227--/345/234/250Dexechain/344/270/255/350/277/233/350/241/214/346/250/241/344/273/277/345/255/246/344/271/240.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs//346/234/215/345/212/241/345/231/250/344/275/277/347/224/250/346/211/213/345/206/214.md" +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/download (7).json +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/local_demo.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/manifest.json +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/manifest_presigned.json +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/set-creds.ps1 +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/conftest.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_cli.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_http_resilience.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manager_integration.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manifest.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manifest_aliases.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_mock_server.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_presigned_fixes.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_review_fixes.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_s5cmd_generation.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_state.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_verify.py +0 -0
- {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dexverse-cli
|
|
3
|
-
Version: 0.0.4.
|
|
3
|
+
Version: 0.0.4.post2
|
|
4
4
|
Summary: DexVerse dataset downloader for S3-compatible robot training datasets
|
|
5
5
|
Author: DexVerse
|
|
6
6
|
License: Apache-2.0
|
|
@@ -161,7 +161,8 @@ dexverse-dl convert --input-dir /data/dexverse -o /data/dexverse/restored
|
|
|
161
161
|
|
|
162
162
|
`task_instruction.json` 的内容就是 manifest 中的对象本身,不增加外层包装。
|
|
163
163
|
下载器会把转换所需的映射保存在 `.dexverse/task-instructions/`,无需为
|
|
164
|
-
`convert`
|
|
164
|
+
`convert` 增加额外参数。设备侧 `data_protocol` 不会写入算法侧
|
|
165
|
+
`task_instruction.json`;独立来源且没有该隐藏元数据的 HDF5 仍按原行为还原。
|
|
165
166
|
|
|
166
167
|
该命令依赖 `h5py` / `numpy` / `av` / `pillow`,已列入核心依赖,安装时随包装上。
|
|
167
168
|
|
|
@@ -131,7 +131,8 @@ dexverse-dl convert --input-dir /data/dexverse -o /data/dexverse/restored
|
|
|
131
131
|
|
|
132
132
|
`task_instruction.json` 的内容就是 manifest 中的对象本身,不增加外层包装。
|
|
133
133
|
下载器会把转换所需的映射保存在 `.dexverse/task-instructions/`,无需为
|
|
134
|
-
`convert`
|
|
134
|
+
`convert` 增加额外参数。设备侧 `data_protocol` 不会写入算法侧
|
|
135
|
+
`task_instruction.json`;独立来源且没有该隐藏元数据的 HDF5 仍按原行为还原。
|
|
135
136
|
|
|
136
137
|
该命令依赖 `h5py` / `numpy` / `av` / `pillow`,已列入核心依赖,安装时随包装上。
|
|
137
138
|
|
|
@@ -31,6 +31,7 @@ import h5py
|
|
|
31
31
|
import numpy as np
|
|
32
32
|
|
|
33
33
|
from ..downloader import state as download_state
|
|
34
|
+
from ..manifest import algorithm_task_instruction
|
|
34
35
|
# 复用同包子模块的解码能力
|
|
35
36
|
from .image_video_encode import decode_mp4_bytes_to_rgb_images
|
|
36
37
|
|
|
@@ -68,7 +69,12 @@ def _sync_restored_task_instruction(
|
|
|
68
69
|
if not isinstance(task_instruction, dict):
|
|
69
70
|
raise ValueError(f"task instruction must be a JSON object: {source}")
|
|
70
71
|
destination.write_text(
|
|
71
|
-
json.dumps(
|
|
72
|
+
json.dumps(
|
|
73
|
+
algorithm_task_instruction(task_instruction),
|
|
74
|
+
ensure_ascii=False,
|
|
75
|
+
indent=2,
|
|
76
|
+
)
|
|
77
|
+
+ "\n",
|
|
72
78
|
encoding="utf-8",
|
|
73
79
|
)
|
|
74
80
|
else:
|
|
@@ -20,7 +20,7 @@ from dataclasses import dataclass, field
|
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
from typing import Dict, List, Optional, Union
|
|
22
22
|
|
|
23
|
-
from ..manifest import FileSpec, Manifest, resolve_dest
|
|
23
|
+
from ..manifest import FileSpec, Manifest, algorithm_task_instruction, resolve_dest
|
|
24
24
|
from . import state as st
|
|
25
25
|
from .base import Backend, ProgressReporter
|
|
26
26
|
from .http_backend import HttpBackend, _HTTP_BACKEND_NAMES
|
|
@@ -62,7 +62,7 @@ def _sync_task_instructions(
|
|
|
62
62
|
instruction_path.parent.mkdir(parents=True, exist_ok=True)
|
|
63
63
|
instruction_path.write_text(
|
|
64
64
|
json.dumps(
|
|
65
|
-
file_spec.additionalInfo,
|
|
65
|
+
algorithm_task_instruction(file_spec.additionalInfo),
|
|
66
66
|
ensure_ascii=False,
|
|
67
67
|
indent=2,
|
|
68
68
|
)
|
|
@@ -22,6 +22,13 @@ from typing import Any, Dict, List, Optional
|
|
|
22
22
|
from pydantic import AliasChoices, BaseModel, ConfigDict, Field, model_validator
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def algorithm_task_instruction(additional_info: Dict[str, Any]) -> Dict[str, Any]:
|
|
26
|
+
"""Return algorithm-facing task metadata without device-only protocol data."""
|
|
27
|
+
task_instruction = dict(additional_info)
|
|
28
|
+
task_instruction.pop("data_protocol", None)
|
|
29
|
+
return task_instruction
|
|
30
|
+
|
|
31
|
+
|
|
25
32
|
# --------------------------------------------------------------------------- #
|
|
26
33
|
# Path helpers
|
|
27
34
|
# --------------------------------------------------------------------------- #
|
|
@@ -38,7 +38,7 @@ def test_convert_single_file_writes_and_updates_raw_task_instruction(tmp_path):
|
|
|
38
38
|
info_path = _write_hidden_task_instruction(
|
|
39
39
|
download_root,
|
|
40
40
|
"session.hdf5",
|
|
41
|
-
{"aaa": "中文", "number": 1.1111111111111112e+54},
|
|
41
|
+
{"aaa": "中文", "number": 1.1111111111111112e+54, "data_protocol": "W1"},
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
frames = convert_hdf5(source, restored)
|
|
@@ -92,10 +92,22 @@ def test_convert_bridges_additional_info_state_to_legacy_output(tmp_path):
|
|
|
92
92
|
_write_minimal_hdf5(source)
|
|
93
93
|
bridge_path = st.additional_info_path(download_root, "session.hdf5")
|
|
94
94
|
bridge_path.parent.mkdir(parents=True)
|
|
95
|
-
bridge_path.write_text('{"from": "32ffa8e"}\n', encoding="utf-8")
|
|
95
|
+
bridge_path.write_text('{"from": "32ffa8e", "data_protocol": "SIM"}\n', encoding="utf-8")
|
|
96
96
|
|
|
97
97
|
convert_hdf5(source, restored)
|
|
98
98
|
|
|
99
99
|
assert json.loads((restored / "task_instruction.json").read_text(encoding="utf-8")) == {
|
|
100
100
|
"from": "32ffa8e"
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_convert_data_protocol_only_writes_empty_task_instruction(tmp_path):
|
|
105
|
+
download_root = tmp_path / "download"
|
|
106
|
+
source = download_root / "session.hdf5"
|
|
107
|
+
restored = tmp_path / "restored" / "session"
|
|
108
|
+
_write_minimal_hdf5(source)
|
|
109
|
+
_write_hidden_task_instruction(download_root, "session.hdf5", {"data_protocol": "UMI"})
|
|
110
|
+
|
|
111
|
+
convert_hdf5(source, restored)
|
|
112
|
+
|
|
113
|
+
assert json.loads((restored / "task_instruction.json").read_text(encoding="utf-8")) == {}
|
|
@@ -273,7 +273,11 @@ def test_duplicate_filename_download_and_additional_info_keep_first(tmp_path, ht
|
|
|
273
273
|
{
|
|
274
274
|
"download_url": http_server.url("first.hdf5"),
|
|
275
275
|
"file_name": "same.hdf5",
|
|
276
|
-
"additional_info": {
|
|
276
|
+
"additional_info": {
|
|
277
|
+
"source": "第一条",
|
|
278
|
+
"value": 1.1111111111111112e+54,
|
|
279
|
+
"data_protocol": "W1",
|
|
280
|
+
},
|
|
277
281
|
},
|
|
278
282
|
{
|
|
279
283
|
"download_url": http_server.url("second.hdf5"),
|
|
@@ -291,7 +295,11 @@ def test_duplicate_filename_download_and_additional_info_keep_first(tmp_path, ht
|
|
|
291
295
|
assert report.downloaded == 1
|
|
292
296
|
assert (out / "same.hdf5").read_bytes() == first_body
|
|
293
297
|
instruction_path = st.task_instruction_path(out, "same.hdf5")
|
|
294
|
-
assert json.loads(instruction_path.read_text(encoding="utf-8")) ==
|
|
298
|
+
assert json.loads(instruction_path.read_text(encoding="utf-8")) == {
|
|
299
|
+
"source": "第一条",
|
|
300
|
+
"value": 1.1111111111111112e+54,
|
|
301
|
+
}
|
|
302
|
+
assert manifest.files[0].additionalInfo["data_protocol"] == "W1"
|
|
295
303
|
assert not st.additional_info_path(out, "same.hdf5").exists()
|
|
296
304
|
|
|
297
305
|
|
|
@@ -304,7 +312,7 @@ def test_legacy_manifest_metadata_still_syncs_to_legacy_path(tmp_path, http_serv
|
|
|
304
312
|
"download_url": http_server.url("unused.hdf5"),
|
|
305
313
|
"file_name": "ep.hdf5",
|
|
306
314
|
"file_size": len(body),
|
|
307
|
-
"task_instruction": {"mode": "legacy"},
|
|
315
|
+
"task_instruction": {"mode": "legacy", "data_protocol": "SIM"},
|
|
308
316
|
}])
|
|
309
317
|
|
|
310
318
|
report = DownloadManager(out, backend="http").run(manifest)
|
|
@@ -315,6 +323,24 @@ def test_legacy_manifest_metadata_still_syncs_to_legacy_path(tmp_path, http_serv
|
|
|
315
323
|
assert not st.additional_info_path(out, "ep.hdf5").exists()
|
|
316
324
|
|
|
317
325
|
|
|
326
|
+
def test_data_protocol_only_writes_an_empty_task_instruction(tmp_path, http_server):
|
|
327
|
+
body = b"already-downloaded"
|
|
328
|
+
out = tmp_path / "out"
|
|
329
|
+
out.mkdir()
|
|
330
|
+
(out / "ep.hdf5").write_bytes(body)
|
|
331
|
+
manifest = Manifest.from_payload([{
|
|
332
|
+
"download_url": http_server.url("unused.hdf5"),
|
|
333
|
+
"file_name": "ep.hdf5",
|
|
334
|
+
"file_size": len(body),
|
|
335
|
+
"additional_info": {"data_protocol": "UMI"},
|
|
336
|
+
}])
|
|
337
|
+
|
|
338
|
+
report = DownloadManager(out, backend="http").run(manifest)
|
|
339
|
+
|
|
340
|
+
assert report.ok
|
|
341
|
+
assert json.loads(st.task_instruction_path(out, "ep.hdf5").read_text(encoding="utf-8")) == {}
|
|
342
|
+
|
|
343
|
+
|
|
318
344
|
def test_skipped_file_still_syncs_additional_info(tmp_path, http_server):
|
|
319
345
|
body = b"already-downloaded"
|
|
320
346
|
out = tmp_path / "out"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/image_video_encode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/python_s3_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/PROMPT_copy_and_download_command.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|