Skip to content

Commit 8d1f2d1

Browse files
Drew KaulDrew Kaul
authored andcommitted
nits
1 parent 576c02e commit 8d1f2d1

File tree

6 files changed

+32
-61
lines changed

6 files changed

+32
-61
lines changed

nucleus/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
)
136136
from .slice import Slice
137137
from .upload_response import UploadResponse
138-
from .scene import Scene, LidarScene
138+
from .scene import Scene, LidarScene, Frame, SceneDatasetItem, CameraParams
139139

140140
# pylint: disable=E1101
141141
# TODO: refactor to reduce this file to under 1000 lines.

nucleus/annotation.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -310,15 +310,6 @@ def to_payload(self) -> dict:
310310
}
311311

312312

313-
def check_all_frame_paths_remote(frames: List[str]):
314-
for frame_url in frames:
315-
if is_local_path(frame_url):
316-
raise ValueError(
317-
f"All paths must be remote, but {frame_url} is either "
318-
"local, or a remote URL type that is not supported."
319-
)
320-
321-
322313
def check_all_mask_paths_remote(
323314
annotations: Sequence[Union[Annotation]],
324315
):

nucleus/dataset.py

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from .annotation import (
1414
Annotation,
1515
check_all_mask_paths_remote,
16-
check_all_frame_paths_remote,
1716
)
1817
from .constants import (
1918
DATASET_ITEM_IDS_KEY,
@@ -23,13 +22,10 @@
2322
DATASET_SLICES_KEY,
2423
DEFAULT_ANNOTATION_UPDATE_MODE,
2524
EXPORTED_ROWS,
26-
FRAMES_KEY,
2725
NAME_KEY,
2826
REFERENCE_IDS_KEY,
2927
REQUEST_ID_KEY,
30-
SCENES_KEY,
3128
UPDATE_KEY,
32-
URL_KEY,
3329
)
3430
from .dataset_item import (
3531
DatasetItem,
@@ -43,6 +39,7 @@
4339
)
4440

4541
WARN_FOR_LARGE_UPLOAD = 50000
42+
WARN_FOR_LARGE_SCENES_UPLOAD = 5
4643

4744

4845
class Dataset:
@@ -268,62 +265,46 @@ def append_scenes(
268265
scenes: List[LidarScene],
269266
update: Optional[bool] = False,
270267
asynchronous: Optional[bool] = False,
271-
) -> Union[dict, AsyncJob]:
272-
"""TODO: Add updated docstring here"""
273-
for scene in scenes:
274-
scene.validate()
275-
276-
if asynchronous:
277-
check_all_scene_paths_remote(scenes)
278-
request_id = serialize_and_write_to_presigned_url(
279-
scenes, self.id, self._client
280-
)
281-
response = self._client.make_request(
282-
payload={REQUEST_ID_KEY: request_id, UPDATE_KEY: update},
283-
route=f"{self.id}/upload_scenes?async=1",
284-
)
285-
return AsyncJob.from_json(response, self._client)
286-
287-
payload = construct_append_scenes_payload(scenes, update)
288-
response = self._client.make_request(
289-
payload=payload,
290-
route=f"{self.id}/upload_scenes",
291-
)
292-
return response
293-
294-
def upload_scenes(
295-
self,
296-
payload: dict,
297-
update: Optional[bool] = False,
298-
asynchronous: bool = False,
299268
) -> Union[dict, AsyncJob]:
300269
"""
301-
Uploads scenes with given frames to the dataset
270+
Appends scenes with given frames (containing pointclouds and optional images) to the dataset
302271
303272
Parameters:
304-
:param payload: dictionary containing scenes to be uploaded
273+
:param scenes: scenes to upload
305274
:param update: if True, overwrite scene on collision
306-
:param aynchronous: if True, return a job object representing asynchronous ingestion job
275+
:param asynchronous: if True, return a job object representing asynchronous ingestion job
307276
:return:
308277
{
309278
'dataset_id': str,
310279
'new_scenes': int,
280+
'ignored_scenes': int,
281+
'scenes_errored': int,
282+
'errors': List[str],
311283
}
312284
"""
285+
for scene in scenes:
286+
scene.validate()
287+
288+
if len(scenes) > WARN_FOR_LARGE_SCENES_UPLOAD and not asynchronous:
289+
print(
290+
"Tip: for large uploads, get faster performance by importing your data "
291+
"into Nucleus directly from a cloud storage provider. See "
292+
"https://dashboard.scale.com/nucleus/docs/api?language=python#guide-for-large-ingestions"
293+
" for details."
294+
)
295+
313296
if asynchronous:
314-
for scene in payload[SCENES_KEY]:
315-
for frame in scene[FRAMES_KEY]:
316-
check_all_frame_paths_remote(frame[URL_KEY])
297+
check_all_scene_paths_remote(scenes)
317298
request_id = serialize_and_write_to_presigned_url(
318-
[payload], self.id, self._client
299+
scenes, self.id, self._client
319300
)
320301
response = self._client.make_request(
321302
payload={REQUEST_ID_KEY: request_id, UPDATE_KEY: update},
322303
route=f"{self.id}/upload_scenes?async=1",
323304
)
324305
return AsyncJob.from_json(response, self._client)
325306

326-
# TODO: create client method for sync scene upload
307+
payload = construct_append_scenes_payload(scenes, update)
327308
response = self._client.make_request(
328309
payload=payload,
329310
route=f"{self.id}/upload_scenes",

nucleus/scene.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ def to_json(self) -> str:
130130

131131
@dataclass
132132
class Frame:
133-
index: Union[int, None] = None
134133
items: Dict[str, SceneDatasetItem] = field(default_factory=dict)
134+
index: Union[int, None] = None
135135

136136
def __post_init__(self):
137137
for key, value in self.items.items():
@@ -197,7 +197,7 @@ def validate(self):
197197

198198
def add_item(self, index: int, sensor_name: str, item: SceneDatasetItem):
199199
if index not in self.frames_dict:
200-
new_frame = Frame(index, {sensor_name: item})
200+
new_frame = Frame(index=index, items={sensor_name: item})
201201
self.frames_dict[index] = new_frame
202202
else:
203203
self.frames_dict[index].items[sensor_name] = item
@@ -254,7 +254,6 @@ def to_json(self) -> str:
254254

255255
@dataclass
256256
class LidarScene(Scene):
257-
# TODO: call validate in scene upload
258257
def validate(self):
259258
super().validate()
260259
lidar_sources = flatten(

nucleus/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def convert_export_payload(api_payload):
122122

123123

124124
def serialize_and_write(
125-
upload_units: Sequence[Union[DatasetItem, Annotation, Dict, LidarScene]],
125+
upload_units: Sequence[Union[DatasetItem, Annotation, LidarScene]],
126126
file_pointer,
127127
):
128128
for unit in upload_units:
@@ -157,7 +157,7 @@ def upload_to_presigned_url(presigned_url: str, file_pointer: IO):
157157

158158

159159
def serialize_and_write_to_presigned_url(
160-
upload_units: Sequence[Union[DatasetItem, Annotation, Dict, LidarScene]],
160+
upload_units: Sequence[Union[DatasetItem, Annotation, LidarScene]],
161161
dataset_id: str,
162162
client,
163163
):

tests/test_scene.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
from nucleus.constants import SCENES_KEY, UPDATE_KEY
21
import pytest
2+
from nucleus.constants import SCENES_KEY, UPDATE_KEY
3+
4+
from nucleus import (
5+
CuboidAnnotation,
6+
LidarScene,
7+
)
38

49
from .helpers import (
510
TEST_DATASET_3D_NAME,
@@ -8,11 +13,6 @@
813
assert_cuboid_annotation_matches_dict,
914
)
1015

11-
from nucleus import (
12-
CuboidAnnotation,
13-
LidarScene,
14-
)
15-
1616

1717
@pytest.fixture()
1818
def dataset(CLIENT):

0 commit comments

Comments
 (0)