unitlab 3.0.4__tar.gz → 3.0.5__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.
- {unitlab-3.0.4 → unitlab-3.0.5}/PKG-INFO +82 -2
- {unitlab-3.0.4 → unitlab-3.0.5}/README.md +81 -1
- {unitlab-3.0.4 → unitlab-3.0.5}/pyproject.toml +1 -1
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/__init__.py +2 -0
- unitlab-3.0.5/src/unitlab/_nuscenes.py +531 -0
- unitlab-3.0.5/src/unitlab/_scene_uploader.py +604 -0
- unitlab-3.0.5/src/unitlab/_scenes.py +833 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_uploader.py +152 -17
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/cli.py +198 -1
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/assets.py +69 -17
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/projects.py +63 -13
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/types.py +9 -0
- unitlab-3.0.5/tests/test_nuscenes.py +484 -0
- unitlab-3.0.5/tests/test_scene_cli.py +250 -0
- unitlab-3.0.5/tests/test_scene_uploads.py +565 -0
- unitlab-3.0.5/tests/test_scenes.py +650 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/.gitignore +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/LICENSE.md +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/__main__.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_config.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_downloader.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_grouping.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_http.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_waiter.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/client.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/exceptions.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/ontology.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/py.typed +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/__init__.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/_base.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/cloud.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/datasets.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/embeddings.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/ontologies.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/releases.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/workflow.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_cli.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_client.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_downloader.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_embeddings.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_http.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_tiled_uploads.py +0 -0
- {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_uploader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: unitlab
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.5
|
|
4
4
|
Summary: Python SDK for the Unitlab.ai data annotation platform
|
|
5
5
|
Project-URL: Homepage, https://unitlab.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.unitlab.ai
|
|
@@ -113,7 +113,8 @@ print(batch.uploaded, batch.batch_queue_id)
|
|
|
113
113
|
|
|
114
114
|
The directory may mix images, video, audio, text, PDFs, DICOM, NIfTI, and NRRD.
|
|
115
115
|
One call creates one Batch Queue. Call `batch.wait()` when the next operation
|
|
116
|
-
depends on server-side processing.
|
|
116
|
+
depends on server-side processing. Lidar scenes are uploaded with
|
|
117
|
+
`generic_type="pointcloud"`; see [Lidar scenes](#lidar-scenes).
|
|
117
118
|
|
|
118
119
|
### 2. Curate in Assets, publish a dataset, and attach it
|
|
119
120
|
|
|
@@ -234,6 +235,76 @@ upload directly to storage in bounded parts. Tiled processing can take hours,
|
|
|
234
235
|
so use a longer timeout such as `batch.wait(timeout=25200)` when the next
|
|
235
236
|
operation depends on the generated COG/DZI derivative.
|
|
236
237
|
|
|
238
|
+
Video, medical (NIfTI, NRRD, DICOM), audio and PDF files larger than 64 MiB
|
|
239
|
+
also upload directly to storage, up to 500 MiB each; smaller ones keep the
|
|
240
|
+
ordinary upload. A large medical file becomes one volume on its own and is not
|
|
241
|
+
grouped with other files of the batch into a series.
|
|
242
|
+
|
|
243
|
+
DICOM files named without a usable extension (`IM00001`, or a UID) are found by
|
|
244
|
+
their content when a folder is uploaded and are sent as medical; nothing needs
|
|
245
|
+
to be renamed.
|
|
246
|
+
|
|
247
|
+
### Lidar scenes
|
|
248
|
+
|
|
249
|
+
A lidar scene is one item whatever it is made of. It is uploaded only when the
|
|
250
|
+
type is named; without it `.pcd`, `.ply`, `.bin` and scene `.zip` files are
|
|
251
|
+
skipped. The workspace needs lidar scenes enabled.
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from unitlab import detect_scenes
|
|
255
|
+
|
|
256
|
+
# Look first: what would be uploaded, nothing is sent.
|
|
257
|
+
for scene in detect_scenes("./recordings").scenes:
|
|
258
|
+
print(scene.name, scene.frame_count, scene.point_sensors, scene.cameras)
|
|
259
|
+
|
|
260
|
+
batch = project.upload("./recordings", generic_type="pointcloud")
|
|
261
|
+
batch.wait()
|
|
262
|
+
|
|
263
|
+
for item_id in batch.data_item_ids:
|
|
264
|
+
status = project.scene_status(item_id)
|
|
265
|
+
print(status.status, status.frame_count, status.error)
|
|
266
|
+
|
|
267
|
+
project.retry_scene(item_id) # a failed scene, about a minute after it failed
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
What `source` may be:
|
|
271
|
+
|
|
272
|
+
- One file: a `.pcd`, `.ply` or `.bin` cloud, or a `.zip` that contains such
|
|
273
|
+
frames or a `scene.json`. Any other `.zip` is refused.
|
|
274
|
+
- A folder with a `scene.json`, or with the point clouds of one sensor
|
|
275
|
+
(`drive_01/lidar/000.pcd`, ...). Image folders whose file names match the
|
|
276
|
+
frames become its cameras (`drive_01/cam_front/000.jpg`).
|
|
277
|
+
- A folder with one subfolder per sensor that share file names. This is read as
|
|
278
|
+
one scene with several sensors; pass `split_sensor_folders=True` when each
|
|
279
|
+
folder is a recording of its own.
|
|
280
|
+
- A folder that holds several such scenes: each one is uploaded as its own
|
|
281
|
+
item. Scene files left over in the folder are one scene each.
|
|
282
|
+
- A nuScenes dataset (the folder with `samples/` and `v1.0-*/`): one scene per
|
|
283
|
+
recording, key frames only, with the calibration taken from its tables.
|
|
284
|
+
|
|
285
|
+
Other files in the folder are not uploaded by this call; upload the folder once
|
|
286
|
+
more without the type for ordinary media. A scene is limited to 20 GiB and
|
|
287
|
+
1,000 frames, and one data unit is used per frame.
|
|
288
|
+
|
|
289
|
+
`batch.wait()` covers scenes like any other upload. A failed scene is not in
|
|
290
|
+
`project.data_units()`; find it in the Batch Queue (`queue.data()`) and ask
|
|
291
|
+
`project.scene_status(item_id)` for the reason.
|
|
292
|
+
|
|
293
|
+
Scenes go into Assets the same way, and the existing Asset methods apply:
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
result = client.assets.upload(
|
|
297
|
+
"./recordings", generic_type="pointcloud", folder="Lidar"
|
|
298
|
+
)
|
|
299
|
+
asset = result.assets[0]
|
|
300
|
+
status = asset.wait() # status.frame_count, status.error
|
|
301
|
+
asset.retry() # a failed scene
|
|
302
|
+
asset = client.assets.asset("ASSET_ID") # a handle by ID, for status and retry
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`release.download_files()` writes a scene that was uploaded as a folder under
|
|
306
|
+
`<item file name>/` with the paths it was uploaded with.
|
|
307
|
+
|
|
237
308
|
### Data Units and project lifecycle
|
|
238
309
|
|
|
239
310
|
```python
|
|
@@ -423,6 +494,12 @@ unitlab project sources PROJECT_ID
|
|
|
423
494
|
unitlab project detach-source PROJECT_ID SOURCE_LINK_ID --preview
|
|
424
495
|
unitlab project upload PROJECT_ID --source ./data
|
|
425
496
|
unitlab project upload PROJECT_ID --source ./maps
|
|
497
|
+
unitlab project upload PROJECT_ID --source ./recordings --type pointcloud --dry-run
|
|
498
|
+
unitlab project upload PROJECT_ID --source ./recordings --type pointcloud
|
|
499
|
+
unitlab project upload PROJECT_ID --source ./rig --type pointcloud \
|
|
500
|
+
--split-sensor-folders
|
|
501
|
+
unitlab project scene-status PROJECT_ID ITEM_ID
|
|
502
|
+
unitlab project scene-retry PROJECT_ID ITEM_ID
|
|
426
503
|
unitlab batch-queue list PROJECT_ID
|
|
427
504
|
unitlab batch-queue detail PROJECT_ID BATCH_QUEUE_ID
|
|
428
505
|
unitlab batch-queue status PROJECT_ID BATCH_QUEUE_ID
|
|
@@ -438,6 +515,9 @@ unitlab project attach PROJECT_ID --dataset-version DATASET_ID:2
|
|
|
438
515
|
# Assets
|
|
439
516
|
unitlab assets upload ./data --folder "Raw data" --tag incoming
|
|
440
517
|
unitlab assets upload ./slides --folder "Slides"
|
|
518
|
+
unitlab assets upload ./recordings --folder "Lidar" --type pointcloud
|
|
519
|
+
unitlab assets status ASSET_ID
|
|
520
|
+
unitlab assets retry ASSET_ID
|
|
441
521
|
|
|
442
522
|
# Folders
|
|
443
523
|
unitlab folders create "Raw data"
|
|
@@ -80,7 +80,8 @@ print(batch.uploaded, batch.batch_queue_id)
|
|
|
80
80
|
|
|
81
81
|
The directory may mix images, video, audio, text, PDFs, DICOM, NIfTI, and NRRD.
|
|
82
82
|
One call creates one Batch Queue. Call `batch.wait()` when the next operation
|
|
83
|
-
depends on server-side processing.
|
|
83
|
+
depends on server-side processing. Lidar scenes are uploaded with
|
|
84
|
+
`generic_type="pointcloud"`; see [Lidar scenes](#lidar-scenes).
|
|
84
85
|
|
|
85
86
|
### 2. Curate in Assets, publish a dataset, and attach it
|
|
86
87
|
|
|
@@ -201,6 +202,76 @@ upload directly to storage in bounded parts. Tiled processing can take hours,
|
|
|
201
202
|
so use a longer timeout such as `batch.wait(timeout=25200)` when the next
|
|
202
203
|
operation depends on the generated COG/DZI derivative.
|
|
203
204
|
|
|
205
|
+
Video, medical (NIfTI, NRRD, DICOM), audio and PDF files larger than 64 MiB
|
|
206
|
+
also upload directly to storage, up to 500 MiB each; smaller ones keep the
|
|
207
|
+
ordinary upload. A large medical file becomes one volume on its own and is not
|
|
208
|
+
grouped with other files of the batch into a series.
|
|
209
|
+
|
|
210
|
+
DICOM files named without a usable extension (`IM00001`, or a UID) are found by
|
|
211
|
+
their content when a folder is uploaded and are sent as medical; nothing needs
|
|
212
|
+
to be renamed.
|
|
213
|
+
|
|
214
|
+
### Lidar scenes
|
|
215
|
+
|
|
216
|
+
A lidar scene is one item whatever it is made of. It is uploaded only when the
|
|
217
|
+
type is named; without it `.pcd`, `.ply`, `.bin` and scene `.zip` files are
|
|
218
|
+
skipped. The workspace needs lidar scenes enabled.
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from unitlab import detect_scenes
|
|
222
|
+
|
|
223
|
+
# Look first: what would be uploaded, nothing is sent.
|
|
224
|
+
for scene in detect_scenes("./recordings").scenes:
|
|
225
|
+
print(scene.name, scene.frame_count, scene.point_sensors, scene.cameras)
|
|
226
|
+
|
|
227
|
+
batch = project.upload("./recordings", generic_type="pointcloud")
|
|
228
|
+
batch.wait()
|
|
229
|
+
|
|
230
|
+
for item_id in batch.data_item_ids:
|
|
231
|
+
status = project.scene_status(item_id)
|
|
232
|
+
print(status.status, status.frame_count, status.error)
|
|
233
|
+
|
|
234
|
+
project.retry_scene(item_id) # a failed scene, about a minute after it failed
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
What `source` may be:
|
|
238
|
+
|
|
239
|
+
- One file: a `.pcd`, `.ply` or `.bin` cloud, or a `.zip` that contains such
|
|
240
|
+
frames or a `scene.json`. Any other `.zip` is refused.
|
|
241
|
+
- A folder with a `scene.json`, or with the point clouds of one sensor
|
|
242
|
+
(`drive_01/lidar/000.pcd`, ...). Image folders whose file names match the
|
|
243
|
+
frames become its cameras (`drive_01/cam_front/000.jpg`).
|
|
244
|
+
- A folder with one subfolder per sensor that share file names. This is read as
|
|
245
|
+
one scene with several sensors; pass `split_sensor_folders=True` when each
|
|
246
|
+
folder is a recording of its own.
|
|
247
|
+
- A folder that holds several such scenes: each one is uploaded as its own
|
|
248
|
+
item. Scene files left over in the folder are one scene each.
|
|
249
|
+
- A nuScenes dataset (the folder with `samples/` and `v1.0-*/`): one scene per
|
|
250
|
+
recording, key frames only, with the calibration taken from its tables.
|
|
251
|
+
|
|
252
|
+
Other files in the folder are not uploaded by this call; upload the folder once
|
|
253
|
+
more without the type for ordinary media. A scene is limited to 20 GiB and
|
|
254
|
+
1,000 frames, and one data unit is used per frame.
|
|
255
|
+
|
|
256
|
+
`batch.wait()` covers scenes like any other upload. A failed scene is not in
|
|
257
|
+
`project.data_units()`; find it in the Batch Queue (`queue.data()`) and ask
|
|
258
|
+
`project.scene_status(item_id)` for the reason.
|
|
259
|
+
|
|
260
|
+
Scenes go into Assets the same way, and the existing Asset methods apply:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
result = client.assets.upload(
|
|
264
|
+
"./recordings", generic_type="pointcloud", folder="Lidar"
|
|
265
|
+
)
|
|
266
|
+
asset = result.assets[0]
|
|
267
|
+
status = asset.wait() # status.frame_count, status.error
|
|
268
|
+
asset.retry() # a failed scene
|
|
269
|
+
asset = client.assets.asset("ASSET_ID") # a handle by ID, for status and retry
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`release.download_files()` writes a scene that was uploaded as a folder under
|
|
273
|
+
`<item file name>/` with the paths it was uploaded with.
|
|
274
|
+
|
|
204
275
|
### Data Units and project lifecycle
|
|
205
276
|
|
|
206
277
|
```python
|
|
@@ -390,6 +461,12 @@ unitlab project sources PROJECT_ID
|
|
|
390
461
|
unitlab project detach-source PROJECT_ID SOURCE_LINK_ID --preview
|
|
391
462
|
unitlab project upload PROJECT_ID --source ./data
|
|
392
463
|
unitlab project upload PROJECT_ID --source ./maps
|
|
464
|
+
unitlab project upload PROJECT_ID --source ./recordings --type pointcloud --dry-run
|
|
465
|
+
unitlab project upload PROJECT_ID --source ./recordings --type pointcloud
|
|
466
|
+
unitlab project upload PROJECT_ID --source ./rig --type pointcloud \
|
|
467
|
+
--split-sensor-folders
|
|
468
|
+
unitlab project scene-status PROJECT_ID ITEM_ID
|
|
469
|
+
unitlab project scene-retry PROJECT_ID ITEM_ID
|
|
393
470
|
unitlab batch-queue list PROJECT_ID
|
|
394
471
|
unitlab batch-queue detail PROJECT_ID BATCH_QUEUE_ID
|
|
395
472
|
unitlab batch-queue status PROJECT_ID BATCH_QUEUE_ID
|
|
@@ -405,6 +482,9 @@ unitlab project attach PROJECT_ID --dataset-version DATASET_ID:2
|
|
|
405
482
|
# Assets
|
|
406
483
|
unitlab assets upload ./data --folder "Raw data" --tag incoming
|
|
407
484
|
unitlab assets upload ./slides --folder "Slides"
|
|
485
|
+
unitlab assets upload ./recordings --folder "Lidar" --type pointcloud
|
|
486
|
+
unitlab assets status ASSET_ID
|
|
487
|
+
unitlab assets retry ASSET_ID
|
|
408
488
|
|
|
409
489
|
# Folders
|
|
410
490
|
unitlab folders create "Raw data"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from importlib.metadata import version
|
|
2
2
|
|
|
3
3
|
from ._grouping import tiles_from_template
|
|
4
|
+
from ._scene_uploader import detect_scenes
|
|
4
5
|
from .client import UnitlabClient
|
|
5
6
|
from .exceptions import (
|
|
6
7
|
AmbiguousUploadCompletionError,
|
|
@@ -102,5 +103,6 @@ __all__ = [
|
|
|
102
103
|
"WorkflowStage",
|
|
103
104
|
"WorkflowTask",
|
|
104
105
|
"__version__",
|
|
106
|
+
"detect_scenes",
|
|
105
107
|
"tiles_from_template",
|
|
106
108
|
]
|