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.
Files changed (43) hide show
  1. {unitlab-3.0.4 → unitlab-3.0.5}/PKG-INFO +82 -2
  2. {unitlab-3.0.4 → unitlab-3.0.5}/README.md +81 -1
  3. {unitlab-3.0.4 → unitlab-3.0.5}/pyproject.toml +1 -1
  4. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/__init__.py +2 -0
  5. unitlab-3.0.5/src/unitlab/_nuscenes.py +531 -0
  6. unitlab-3.0.5/src/unitlab/_scene_uploader.py +604 -0
  7. unitlab-3.0.5/src/unitlab/_scenes.py +833 -0
  8. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_uploader.py +152 -17
  9. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/cli.py +198 -1
  10. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/assets.py +69 -17
  11. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/projects.py +63 -13
  12. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/types.py +9 -0
  13. unitlab-3.0.5/tests/test_nuscenes.py +484 -0
  14. unitlab-3.0.5/tests/test_scene_cli.py +250 -0
  15. unitlab-3.0.5/tests/test_scene_uploads.py +565 -0
  16. unitlab-3.0.5/tests/test_scenes.py +650 -0
  17. {unitlab-3.0.4 → unitlab-3.0.5}/.gitignore +0 -0
  18. {unitlab-3.0.4 → unitlab-3.0.5}/LICENSE.md +0 -0
  19. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/__main__.py +0 -0
  20. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_config.py +0 -0
  21. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_downloader.py +0 -0
  22. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_grouping.py +0 -0
  23. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_http.py +0 -0
  24. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/_waiter.py +0 -0
  25. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/client.py +0 -0
  26. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/exceptions.py +0 -0
  27. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/ontology.py +0 -0
  28. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/py.typed +0 -0
  29. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/__init__.py +0 -0
  30. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/_base.py +0 -0
  31. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/cloud.py +0 -0
  32. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/datasets.py +0 -0
  33. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/embeddings.py +0 -0
  34. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/ontologies.py +0 -0
  35. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/releases.py +0 -0
  36. {unitlab-3.0.4 → unitlab-3.0.5}/src/unitlab/resources/workflow.py +0 -0
  37. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_cli.py +0 -0
  38. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_client.py +0 -0
  39. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_downloader.py +0 -0
  40. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_embeddings.py +0 -0
  41. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_http.py +0 -0
  42. {unitlab-3.0.4 → unitlab-3.0.5}/tests/test_tiled_uploads.py +0 -0
  43. {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.4
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"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "unitlab"
7
- version = "3.0.4"
7
+ version = "3.0.5"
8
8
  description = "Python SDK for the Unitlab.ai data annotation platform"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -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
  ]