dexverse-cli 0.0.2__py3-none-any.whl
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/__init__.py +54 -0
- dexverse/cli.py +422 -0
- dexverse/client.py +128 -0
- dexverse/config.py +85 -0
- dexverse/convert/__init__.py +38 -0
- dexverse/convert/hdf5_to_raw.py +498 -0
- dexverse/convert/image_video_encode.py +449 -0
- dexverse/downloader/__init__.py +26 -0
- dexverse/downloader/base.py +101 -0
- dexverse/downloader/http_backend.py +508 -0
- dexverse/downloader/manager.py +365 -0
- dexverse/downloader/python_s3_backend.py +137 -0
- dexverse/downloader/s5cmd_backend.py +170 -0
- dexverse/downloader/state.py +263 -0
- dexverse/downloader/verify.py +114 -0
- dexverse/manifest.py +284 -0
- dexverse/mock/__init__.py +2 -0
- dexverse/mock/mock_tasks.json +22 -0
- dexverse/mock/server.py +211 -0
- dexverse_cli-0.0.2.dist-info/METADATA +198 -0
- dexverse_cli-0.0.2.dist-info/RECORD +23 -0
- dexverse_cli-0.0.2.dist-info/WHEEL +4 -0
- dexverse_cli-0.0.2.dist-info/entry_points.txt +3 -0
dexverse/mock/server.py
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Mock backend (doc §9) — simulates the platform so the CLI/SDK can run the
|
|
2
|
+
real flow without a production server.
|
|
3
|
+
|
|
4
|
+
GET /api/download-tasks/{task_id}/manifest (doc §9.3, §12.2)
|
|
5
|
+
POST /api/dev/download-tasks (doc §8.3 — create from files)
|
|
6
|
+
|
|
7
|
+
Env vars (doc §9.2):
|
|
8
|
+
|
|
9
|
+
DEXVERSE_DEV_TOKEN default "dev-token"
|
|
10
|
+
DEXVERSE_S3_ENDPOINT
|
|
11
|
+
DEXVERSE_S3_REGION default "us-east-1"
|
|
12
|
+
DEXVERSE_S3_ACCESS_KEY
|
|
13
|
+
DEXVERSE_S3_SECRET_KEY
|
|
14
|
+
DEXVERSE_S3_SESSION_TOKEN optional
|
|
15
|
+
DEXVERSE_MOCK_TASKS path to tasks json (default ./mock_tasks.json)
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
|
|
19
|
+
dexverse-mock-server --port 18080
|
|
20
|
+
# (binds 127.0.0.1 by default — dev endpoints must not be exposed publicly,
|
|
21
|
+
# doc §13.1 item 4. Use --host 0.0.0.0 only inside a trusted intranet.)
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
import os
|
|
27
|
+
import threading
|
|
28
|
+
from datetime import datetime, timedelta, timezone
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from typing import Any, Dict, List, Optional
|
|
31
|
+
|
|
32
|
+
from fastapi import FastAPI, Header, HTTPException
|
|
33
|
+
from pydantic import BaseModel
|
|
34
|
+
|
|
35
|
+
TASKS_PATH = Path(os.getenv("DEXVERSE_MOCK_TASKS", str(Path(__file__).parent / "mock_tasks.json")))
|
|
36
|
+
|
|
37
|
+
_lock = threading.Lock()
|
|
38
|
+
_tasks: Dict[str, Dict[str, Any]] = {}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _load_tasks() -> Dict[str, Dict[str, Any]]:
|
|
42
|
+
global _tasks
|
|
43
|
+
if not _tasks:
|
|
44
|
+
if TASKS_PATH.exists():
|
|
45
|
+
_tasks = json.loads(TASKS_PATH.read_text(encoding="utf-8"))
|
|
46
|
+
else:
|
|
47
|
+
_tasks = {}
|
|
48
|
+
return _tasks
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _check_auth(authorization: Optional[str]) -> None:
|
|
52
|
+
expected = os.getenv("DEXVERSE_DEV_TOKEN", "dev-token")
|
|
53
|
+
if not authorization:
|
|
54
|
+
raise HTTPException(status_code=401, detail="Missing Authorization header")
|
|
55
|
+
if authorization != f"Bearer {expected}":
|
|
56
|
+
raise HTTPException(status_code=403, detail="Invalid token")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _truthy(name: str) -> bool:
|
|
60
|
+
return os.getenv(name, "").lower() in ("1", "true", "yes", "on")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _presign_client():
|
|
64
|
+
"""A boto3 client for real presigning, or None if not configured."""
|
|
65
|
+
if not _truthy("DEXVERSE_MOCK_PRESIGN"):
|
|
66
|
+
return None
|
|
67
|
+
import boto3
|
|
68
|
+
from botocore.config import Config
|
|
69
|
+
endpoint = os.getenv("DEXVERSE_S3_ENDPOINT")
|
|
70
|
+
ak = os.getenv("DEXVERSE_S3_ACCESS_KEY")
|
|
71
|
+
sk = os.getenv("DEXVERSE_S3_SECRET_KEY")
|
|
72
|
+
if not (endpoint and ak and sk):
|
|
73
|
+
return None
|
|
74
|
+
return boto3.client(
|
|
75
|
+
"s3", endpoint_url=endpoint,
|
|
76
|
+
region_name=os.getenv("DEXVERSE_S3_REGION", "us-east-1"),
|
|
77
|
+
aws_access_key_id=ak, aws_secret_access_key=sk,
|
|
78
|
+
config=Config(signature_version="s3v4"),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _build_manifest(task_id: str, task: Dict[str, Any]) -> Dict[str, Any]:
|
|
83
|
+
endpoint = os.getenv("DEXVERSE_S3_ENDPOINT", "https://minio.dexverse.com")
|
|
84
|
+
region = os.getenv("DEXVERSE_S3_REGION", "us-east-1")
|
|
85
|
+
presign_expires = int(os.getenv("DEXVERSE_MOCK_PRESIGN_EXPIRES", "3600"))
|
|
86
|
+
presigner = _presign_client()
|
|
87
|
+
expires_at = datetime.now(timezone.utc) + timedelta(hours=12)
|
|
88
|
+
|
|
89
|
+
files: List[Dict[str, Any]] = []
|
|
90
|
+
for item in task.get("files", []):
|
|
91
|
+
bucket = item["bucket"]
|
|
92
|
+
object_key = item["objectKey"]
|
|
93
|
+
relative = item.get("relativePath") or item.get("originalPath") or object_key
|
|
94
|
+
entry = {
|
|
95
|
+
"fileId": item.get("fileId", object_key),
|
|
96
|
+
"uri": f"s3://{bucket}/{object_key}",
|
|
97
|
+
"bucket": bucket,
|
|
98
|
+
"objectKey": object_key,
|
|
99
|
+
"relativePath": relative,
|
|
100
|
+
"size": item.get("size"),
|
|
101
|
+
"sha256": item.get("sha256", ""),
|
|
102
|
+
}
|
|
103
|
+
# presignedUrl: explicit per-file value, or generated via boto3 if presign is on
|
|
104
|
+
if item.get("presignedUrl"):
|
|
105
|
+
entry["presignedUrl"] = item["presignedUrl"]
|
|
106
|
+
elif presigner is not None:
|
|
107
|
+
entry["presignedUrl"] = presigner.generate_presigned_url(
|
|
108
|
+
"get_object",
|
|
109
|
+
Params={"Bucket": bucket, "Key": object_key},
|
|
110
|
+
ExpiresIn=presign_expires,
|
|
111
|
+
)
|
|
112
|
+
files.append(entry)
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
"manifestVersion": "1.0",
|
|
116
|
+
"taskId": task_id,
|
|
117
|
+
"createdAt": datetime.now(timezone.utc).isoformat(),
|
|
118
|
+
"expiresAt": expires_at.isoformat(),
|
|
119
|
+
"storage": {
|
|
120
|
+
"type": "s3",
|
|
121
|
+
"endpoint": endpoint,
|
|
122
|
+
"region": region,
|
|
123
|
+
"addressingStyle": "path",
|
|
124
|
+
"credentials": {
|
|
125
|
+
"type": "dev",
|
|
126
|
+
"accessKey": os.getenv("DEXVERSE_S3_ACCESS_KEY"),
|
|
127
|
+
"secretKey": os.getenv("DEXVERSE_S3_SECRET_KEY"),
|
|
128
|
+
"sessionToken": os.getenv("DEXVERSE_S3_SESSION_TOKEN", ""),
|
|
129
|
+
"expiresAt": expires_at.isoformat(),
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
"download": {
|
|
133
|
+
"defaultParallel": 16,
|
|
134
|
+
"verify": "size",
|
|
135
|
+
"preserveOriginalPath": True,
|
|
136
|
+
},
|
|
137
|
+
"files": files,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
app = FastAPI(title="DexVerse Mock Backend")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@app.get("/api/download-tasks/{task_id}/manifest")
|
|
145
|
+
def get_manifest(task_id: str, authorization: Optional[str] = Header(default=None)) -> Dict[str, Any]:
|
|
146
|
+
_check_auth(authorization)
|
|
147
|
+
with _lock:
|
|
148
|
+
tasks = _load_tasks()
|
|
149
|
+
if task_id not in tasks:
|
|
150
|
+
raise HTTPException(status_code=404, detail="Task not found")
|
|
151
|
+
return _build_manifest(task_id, tasks[task_id])
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class DevFile(BaseModel):
|
|
155
|
+
fileId: Optional[str] = None
|
|
156
|
+
bucket: str
|
|
157
|
+
objectKey: str
|
|
158
|
+
relativePath: Optional[str] = None
|
|
159
|
+
size: Optional[int] = None
|
|
160
|
+
sha256: Optional[str] = None
|
|
161
|
+
presignedUrl: Optional[str] = None
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class DevTaskRequest(BaseModel):
|
|
165
|
+
files: List[DevFile]
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@app.post("/api/dev/download-tasks")
|
|
169
|
+
def create_dev_task(
|
|
170
|
+
req: DevTaskRequest,
|
|
171
|
+
authorization: Optional[str] = Header(default=None),
|
|
172
|
+
) -> Dict[str, Any]:
|
|
173
|
+
_check_auth(authorization)
|
|
174
|
+
task_id = f"dl_dev_{datetime.now(timezone.utc).strftime('%y%m%d%H%M%S')}"
|
|
175
|
+
with _lock:
|
|
176
|
+
tasks = _load_tasks()
|
|
177
|
+
tasks[task_id] = {
|
|
178
|
+
"files": [f.model_dump(exclude_none=True) for f in req.files],
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
"taskId": task_id,
|
|
182
|
+
"commandLinux": f"dexverse-dl download --task {task_id} --out /data/dexverse",
|
|
183
|
+
"commandWindows": f"dexverse-dl download --task {task_id} --out D:\\DexVerse",
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@app.get("/healthz")
|
|
188
|
+
def healthz() -> Dict[str, str]:
|
|
189
|
+
return {"status": "ok"}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def build_parser():
|
|
193
|
+
import argparse
|
|
194
|
+
|
|
195
|
+
parser = argparse.ArgumentParser(description="DexVerse mock backend")
|
|
196
|
+
parser.add_argument("--host", default="127.0.0.1",
|
|
197
|
+
help="bind host (default loopback; doc §13.1 item 4)")
|
|
198
|
+
parser.add_argument("--port", type=int, default=18080)
|
|
199
|
+
return parser
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def main(argv=None) -> None:
|
|
203
|
+
args = build_parser().parse_args(argv)
|
|
204
|
+
|
|
205
|
+
import uvicorn
|
|
206
|
+
|
|
207
|
+
uvicorn.run(app, host=args.host, port=args.port)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
main()
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dexverse-cli
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: DexVerse dataset downloader for S3-compatible robot training datasets
|
|
5
|
+
Author: DexVerse
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Keywords: dataset,dexverse,downloader,minio,robotics,s3,s5cmd
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Requires-Dist: av>=12
|
|
10
|
+
Requires-Dist: h5py>=3.10
|
|
11
|
+
Requires-Dist: httpx>=0.27
|
|
12
|
+
Requires-Dist: numpy>=1.26
|
|
13
|
+
Requires-Dist: pillow>=10
|
|
14
|
+
Requires-Dist: pydantic>=2.0
|
|
15
|
+
Requires-Dist: rich>=13.0
|
|
16
|
+
Requires-Dist: tomlkit>=0.12
|
|
17
|
+
Requires-Dist: typer>=0.12
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: boto3>=1.34; extra == 'dev'
|
|
20
|
+
Requires-Dist: fastapi>=0.110; extra == 'dev'
|
|
21
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
22
|
+
Requires-Dist: moto[s3]>=5.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
24
|
+
Provides-Extra: mock
|
|
25
|
+
Requires-Dist: fastapi>=0.110; extra == 'mock'
|
|
26
|
+
Requires-Dist: uvicorn>=0.27; extra == 'mock'
|
|
27
|
+
Provides-Extra: s3
|
|
28
|
+
Requires-Dist: boto3>=1.34; extra == 's3'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# DexVerse Downloader (`dexverse`)
|
|
32
|
+
|
|
33
|
+
Presigned-URL batch downloader for robot-training datasets.
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
manifest -> dexverse-dl -> httpx -> presigned URLs -> local file landing
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The primary input is the DexVerse backend's raw presigned-URL JSON. For those
|
|
40
|
+
payloads, `storage_path` is the remote object key and `file_name` is the local
|
|
41
|
+
landing path under `--out`.
|
|
42
|
+
|
|
43
|
+
Canonical manifests are still supported. Their local paths come from
|
|
44
|
+
`relativePath`, falling back to `originalPath`, then `objectKey`:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
localPath = out / (file.relativePath || file.originalPath || file.objectKey)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install "dexverse[s3,mock]" # boto3 + fastapi mock server
|
|
54
|
+
# optional legacy S3 backend:
|
|
55
|
+
# install s5cmd (https://github.com/peak/s5cmd) and put it on PATH
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Development:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
62
|
+
uv pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
If your backend issues short-lived presigned URLs per file, save that response
|
|
68
|
+
as `download.json` and run:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
dexverse-dl download --manifest ./download.json --out D:\DexVerse
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
No login, no `AWS_*` credentials, no s5cmd, no backend flag, and no TLS flag are
|
|
75
|
+
required for the common internal/self-signed endpoint case. The default backend
|
|
76
|
+
is `http`, and TLS verification is disabled by default for http/presigned
|
|
77
|
+
downloads. Use `--secure` when the endpoint has a valid certificate and you want
|
|
78
|
+
certificate validation.
|
|
79
|
+
|
|
80
|
+
Raw backend output is accepted directly:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
[{
|
|
84
|
+
"download_url": "https://host/bucket/datasets/.../20260429_180359.hdf5?X-Amz-Signature=...",
|
|
85
|
+
"storage_bucket": "dexverse",
|
|
86
|
+
"storage_path": "datasets/.../20260429_180359.hdf5",
|
|
87
|
+
"file_name": "20260429_180359.hdf5",
|
|
88
|
+
"file_size": 14994636,
|
|
89
|
+
"task_instruction": {
|
|
90
|
+
"aaa": "111",
|
|
91
|
+
"aaaa": 222,
|
|
92
|
+
"ewrwrwe": 1.1111111111111112e+54
|
|
93
|
+
}
|
|
94
|
+
}]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Result:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
D:\DexVerse\20260429_180359.hdf5
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`task_instruction` is optional and must be a JSON object. If multiple manifest
|
|
104
|
+
items resolve to the same local path (for example, repeated `file_name`
|
|
105
|
+
values), the first item wins and later duplicates are ignored.
|
|
106
|
+
|
|
107
|
+
Include `file_size` (and preferably `sha256`) for large files. The HTTP backend
|
|
108
|
+
also learns the total size from `Content-Length`/`Content-Range`, but manifest
|
|
109
|
+
metadata lets the CLI verify an existing local file before making a request.
|
|
110
|
+
|
|
111
|
+
Transient timeouts and HTTP 408/425/429/5xx responses are retried five times by
|
|
112
|
+
default. Bytes already received stay in a sibling `<file>.part`; retries and
|
|
113
|
+
later CLI runs request the remaining bytes with HTTP Range, while the final
|
|
114
|
+
destination path only appears after the size check succeeds. The object server
|
|
115
|
+
must support Range requests for efficient resume.
|
|
116
|
+
|
|
117
|
+
Presigned URLs expire, often after 1 hour. Have the backend regenerate the
|
|
118
|
+
manifest right before each download; expired URLs surface as per-file `HTTP 403`
|
|
119
|
+
errors. After generating a fresh `download.json`, run the same command with the
|
|
120
|
+
same `--out` path to continue from the retained `.part`.
|
|
121
|
+
|
|
122
|
+
## CLI
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
dexverse-dl login --server https://dexverse.xxx.com [--token TOKEN]
|
|
126
|
+
dexverse-dl download --manifest ./download.json --out /data/dexverse [--parallel 16] [--secure] [--backend http|python|s5cmd]
|
|
127
|
+
dexverse-dl download --manifest ./download.json --out /data/dexverse [--http-read-timeout 120] [--http-retries 5]
|
|
128
|
+
dexverse-dl download --task dl_xxx --out /data/dexverse [--server URL]
|
|
129
|
+
dexverse-dl verify --manifest PATH --out /data/dexverse [--deep]
|
|
130
|
+
dexverse-dl repair --manifest PATH --out /data/dexverse [--backend http|python|s5cmd]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 还原 HDF5 → 可训练数据
|
|
134
|
+
|
|
135
|
+
下载完成后,把落盘的 `.hdf5` 还原为原始录制结构(逐帧 JPEG + `pose_record_*.json`
|
|
136
|
+
+ `metadata.jsonl`)。如果对应 manifest 带有 `task_instruction`,还会自动生成
|
|
137
|
+
`task_instruction.json`:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 单文件
|
|
141
|
+
dexverse-dl convert -i /data/dexverse/20260429_180359.hdf5 -o /data/dexverse/restored
|
|
142
|
+
# 批量(递归处理目录下所有 *.hdf5,保持目录结构)
|
|
143
|
+
dexverse-dl convert --input-dir /data/dexverse -o /data/dexverse/restored
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
还原输出形如:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
/data/dexverse/restored/20260429_180359/
|
|
150
|
+
head/left/000000.jpg ...
|
|
151
|
+
head/right/000000.jpg ...
|
|
152
|
+
hand/left/000000.jpg ...
|
|
153
|
+
hand/right/000000.jpg ...
|
|
154
|
+
pose_record_20260429_180359.json
|
|
155
|
+
metadata.jsonl
|
|
156
|
+
task_instruction.json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`task_instruction.json` 的内容就是 manifest 中的对象本身,不增加外层包装。
|
|
160
|
+
下载器会把转换所需的映射保存在 `.dexverse/task-instructions/`,无需为
|
|
161
|
+
`convert` 增加额外参数。独立来源且没有该隐藏元数据的 HDF5 仍按原行为还原。
|
|
162
|
+
|
|
163
|
+
该命令依赖 `h5py` / `numpy` / `av` / `pillow`,已列入核心依赖,安装时随包装上。
|
|
164
|
+
|
|
165
|
+
## Python SDK
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from dexverse import DexVerseClient, download_manifest
|
|
169
|
+
|
|
170
|
+
client = DexVerseClient(server="https://dexverse.xxx.com", token="xxx")
|
|
171
|
+
local_root = client.download_task(task_id="dl_xxx", out="/data/dexverse", parallel=16)
|
|
172
|
+
|
|
173
|
+
# or from a local manifest file
|
|
174
|
+
download_manifest(manifest_path="./download.json", out="/data/dexverse")
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Layout
|
|
178
|
+
|
|
179
|
+
State files live under `<out>/.dexverse/` and never mix into the dataset tree:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
/data/dexverse/
|
|
183
|
+
.dexverse/task-instructions/
|
|
184
|
+
20260429_180359.hdf5.json
|
|
185
|
+
.dexverse/tasks/<taskId>/
|
|
186
|
+
manifest.json
|
|
187
|
+
download-state.json
|
|
188
|
+
download.log
|
|
189
|
+
20260429_180359.hdf5
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Backends
|
|
193
|
+
|
|
194
|
+
| backend | engine | notes |
|
|
195
|
+
|----------|-------------------|-----------------------------------------|
|
|
196
|
+
| `http` | httpx | default; presigned URLs, no creds/login |
|
|
197
|
+
| `python` | boto3 | legacy S3 fallback |
|
|
198
|
+
| `s5cmd` | peak/s5cmd binary | legacy S3 high-throughput backend |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
dexverse/__init__.py,sha256=Hf6AqC9YsxJFDCK2BvPpnJ4eKarOPHRb7I6V_n3CzFQ,1365
|
|
2
|
+
dexverse/cli.py,sha256=hWGYEB-tENPXw_CtxJzTJDVwmY7dNHdcmlv30JYd-yw,16802
|
|
3
|
+
dexverse/client.py,sha256=OCchd_x0T20TcegeRIns0SEl_5yb7AQ0POf1D1O3jjc,5073
|
|
4
|
+
dexverse/config.py,sha256=555RAAa5Nyj6E7Ym2m9sU57ndQJU8lanBsJROfTapsU,2368
|
|
5
|
+
dexverse/manifest.py,sha256=uw9V5_L5zf5b8vVa9ihpDmZPYVHepwJkAwiZdjPYz2E,11652
|
|
6
|
+
dexverse/convert/__init__.py,sha256=1O6XCtMzX6ITgXcAQWCntkaJieO2cDwuZzRF7wIDL0g,1001
|
|
7
|
+
dexverse/convert/hdf5_to_raw.py,sha256=GlHGA5C_i5f-hR9B8H_CKCcRfqSm2S20taDq9iXtf0c,19135
|
|
8
|
+
dexverse/convert/image_video_encode.py,sha256=KnYybo3F076HtMUj-3YuwP9kmQED5YBj5DiUxkiOvR4,14283
|
|
9
|
+
dexverse/downloader/__init__.py,sha256=66ATqgVaCd9VDKX7hs_4Bfi_yqLQd3fZjCaoZBuY9Po,723
|
|
10
|
+
dexverse/downloader/base.py,sha256=InH6n264HtmlpArPrlK-F3o2Crd8RDT0KVDPj3a-5pg,3004
|
|
11
|
+
dexverse/downloader/http_backend.py,sha256=ML2Cik4NSgiZQAcuwV1j9nGlthN8sNfekh7PowIczZ0,18666
|
|
12
|
+
dexverse/downloader/manager.py,sha256=ptGWx_f6Ay51FDTodY-jGivWebUazylRtB6VW_eg5k0,14293
|
|
13
|
+
dexverse/downloader/python_s3_backend.py,sha256=-LpvhLn6mer93UP80ugwh21aiKL8r1CWWXPmqwIphaY,5353
|
|
14
|
+
dexverse/downloader/s5cmd_backend.py,sha256=KP28uNRW3DLFGqyEvPlrhh0b8Irm4mCWF5v7sfGKlqs,5897
|
|
15
|
+
dexverse/downloader/state.py,sha256=1iMknv7-SdsAg3rj5_CENKPZACUWv4fS1IPm2Pbiotw,8874
|
|
16
|
+
dexverse/downloader/verify.py,sha256=6M8hZJoUov0Qbpr03B9jUfjObjLqMgE-u_YjWIvqpow,3337
|
|
17
|
+
dexverse/mock/__init__.py,sha256=PfJ4z1g0RHJMeTOAssfiHOIltaktsPIp5J-5pu3EkhA,89
|
|
18
|
+
dexverse/mock/mock_tasks.json,sha256=EyHnM1LOXG5JuP0SYI39R-52LUcXSKx4h34DySg5Iy4,618
|
|
19
|
+
dexverse/mock/server.py,sha256=JLiEEqt8r3DdEbASLn4KIcMQDB1vyBDqezHer3qHBLc,6862
|
|
20
|
+
dexverse_cli-0.0.2.dist-info/METADATA,sha256=0SORmrrWQ07XNPX-Gi-ilU2iiiETAJhPEZPcJy0LLwE,6744
|
|
21
|
+
dexverse_cli-0.0.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
22
|
+
dexverse_cli-0.0.2.dist-info/entry_points.txt,sha256=OYxj67T5AD2oVdDxcEOEkSPgy371GA7kWFTMtm74nyw,98
|
|
23
|
+
dexverse_cli-0.0.2.dist-info/RECORD,,
|