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.
Files changed (54) hide show
  1. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/PKG-INFO +3 -2
  2. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/README.md +2 -1
  3. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/hdf5_to_raw.py +7 -1
  4. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/manager.py +2 -2
  5. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/manifest.py +7 -0
  6. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/pyproject.toml +1 -1
  7. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_convert_additional_info.py +14 -2
  8. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_http_backend.py +29 -3
  9. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/.dockerignore +0 -0
  10. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/.gitignore +0 -0
  11. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/Dockerfile +0 -0
  12. {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
  13. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/__init__.py +0 -0
  14. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/cli.py +0 -0
  15. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/client.py +0 -0
  16. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/config.py +0 -0
  17. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/__init__.py +0 -0
  18. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/convert/image_video_encode.py +0 -0
  19. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/__init__.py +0 -0
  20. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/base.py +0 -0
  21. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/http_backend.py +0 -0
  22. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/python_s3_backend.py +0 -0
  23. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/s5cmd_backend.py +0 -0
  24. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/state.py +0 -0
  25. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/downloader/verify.py +0 -0
  26. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/__init__.py +0 -0
  27. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/mock_tasks.json +0 -0
  28. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/dexverse/mock/server.py +0 -0
  29. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docker_run.sh +0 -0
  30. {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
  31. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/docs/PROMPT_copy_and_download_command.md +0 -0
  32. {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
  33. {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
  34. {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
  35. {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
  36. {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
  37. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/download (7).json +0 -0
  38. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/local_demo.py +0 -0
  39. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/manifest.json +0 -0
  40. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/examples/manifest_presigned.json +0 -0
  41. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/set-creds.ps1 +0 -0
  42. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/conftest.py +0 -0
  43. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_cli.py +0 -0
  44. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_http_resilience.py +0 -0
  45. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manager_integration.py +0 -0
  46. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manifest.py +0 -0
  47. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_manifest_aliases.py +0 -0
  48. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_mock_server.py +0 -0
  49. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_presigned_fixes.py +0 -0
  50. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_review_fixes.py +0 -0
  51. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_s5cmd_generation.py +0 -0
  52. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_state.py +0 -0
  53. {dexverse_cli-0.0.4.post1 → dexverse_cli-0.0.4.post2}/tests/test_verify.py +0 -0
  54. {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.post1
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` 增加额外参数。独立来源且没有该隐藏元数据的 HDF5 仍按原行为还原。
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` 增加额外参数。独立来源且没有该隐藏元数据的 HDF5 仍按原行为还原。
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(task_instruction, ensure_ascii=False, indent=2) + "\n",
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
  # --------------------------------------------------------------------------- #
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dexverse-cli"
7
- version = "0.0.4.post1"
7
+ version = "0.0.4.post2"
8
8
  description = "DexVerse dataset downloader for S3-compatible robot training datasets"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -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": {"source": "第一条", "value": 1.1111111111111112e+54},
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")) == payload[0]["additional_info"]
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"