Skip to content

Commit dcf59ac

Browse files
committed
Appending works
1 parent 3901f7b commit dcf59ac

File tree

4 files changed

+39
-25
lines changed

4 files changed

+39
-25
lines changed

tiled/adapters/zarr.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ async def write_block(
182182
async def patch(
183183
self,
184184
data: NDArray[Any],
185-
slice: NDSlice,
185+
slice: Tuple[slice | int, ...],
186186
grow: bool = False,
187-
) -> Tuple[int, ...]:
187+
) -> Tuple[Tuple[int, ...], Tuple[Tuple[int, ...], ...]]:
188188
"""
189189
Write data into a slice of the array, maybe growing it.
190190
@@ -207,7 +207,16 @@ async def patch(
207207
else:
208208
raise ValueError(f"Slice does not fit into array shape {current_shape}")
209209
self._array[slice] = data
210-
return new_shape_tuple
210+
new_chunks = []
211+
# Zarr has regularly-sized chunks, so no user input is required to
212+
# simply extend the existing pattern.
213+
for chunk_size, size in zip(self._array.chunks, new_shape_tuple):
214+
dim = [chunk_size] * (size // chunk_size)
215+
if size % chunk_size:
216+
dim.append(size % chunk_size)
217+
new_chunks.append(tuple(dim))
218+
new_chunks_tuple = tuple(new_chunks)
219+
return new_shape_tuple, new_chunks_tuple
211220

212221

213222
if sys.version_info < (3, 9):

tiled/catalog/adapter.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,28 +1044,30 @@ async def write_block(self, *args, **kwargs):
10441044
async def patch(self, *args, **kwargs):
10451045
# assumes a single DataSource (currently only supporting zarr)
10461046
async with self.context.session() as db:
1047-
try:
1048-
new_shape = await ensure_awaitable(
1049-
(await self.get_adapter()).patch, *args, **kwargs
1050-
)
1051-
node = await db.get(orm.Node, self.node.id)
1052-
data_source = node.data_sources[0]
1053-
structure_row = await db.get(orm.Structure, data_source.structure_id)
1054-
# Get the current structure row, update the shape, and write it back
1055-
structure_dict = copy.deepcopy(structure_row.structure)
1056-
structure_dict["shape"] = new_shape
1057-
structure_id = compute_structure_id(structure_dict)
1058-
statement = self.insert(orm.Structure).values(
1059-
id=structure_id,
1047+
new_shape_and_chunks = await ensure_awaitable(
1048+
(await self.get_adapter()).patch, *args, **kwargs
1049+
)
1050+
node = await db.get(orm.Node, self.node.id)
1051+
data_source = node.data_sources[0]
1052+
structure_row = await db.get(orm.Structure, data_source.structure_id)
1053+
# Get the current structure row, update the shape, and write it back
1054+
structure_dict = copy.deepcopy(structure_row.structure)
1055+
structure_dict["shape"], structure_dict["chunks"] = new_shape_and_chunks
1056+
new_structure_id = compute_structure_id(structure_dict)
1057+
statement = (
1058+
self.insert(orm.Structure)
1059+
.values(
1060+
id=new_structure_id,
10601061
structure=structure_dict,
10611062
)
1062-
await db.execute(statement)
1063-
new_structure = await db.get(orm.Structure, structure_id)
1064-
data_source.structure = new_structure
1065-
db.add(data_source)
1066-
await db.commit()
1067-
except Exception as e:
1068-
raise RuntimeError(f"Could not retrieve node: {e}")
1063+
.on_conflict_do_nothing(index_elements=["id"])
1064+
)
1065+
await db.execute(statement)
1066+
new_structure = await db.get(orm.Structure, new_structure_id)
1067+
data_source.structure = new_structure
1068+
data_source.structure_id = new_structure_id
1069+
db.add(data_source)
1070+
await db.commit()
10691071

10701072

10711073
class CatalogAwkwardAdapter(CatalogNodeAdapter):

tiled/client/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ def refresh(self):
184184
)
185185
).json()
186186
self._item = content["data"]
187+
attributes = self._item["attributes"]
188+
structure_type = STRUCTURE_TYPES[attributes["structure_family"]]
189+
self._structure = structure_type.from_json(attributes["structure"])
187190
return self
188191

189192
@property

tiled/server/dependencies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from functools import lru_cache
2-
from typing import Optional
2+
from typing import Optional, Tuple
33

44
import pydantic_settings
55
from fastapi import Depends, HTTPException, Query, Request, Security
@@ -182,7 +182,7 @@ def parse_slice_str(dim: str):
182182

183183
def slice_(
184184
slice: Optional[str] = Query(None, pattern=SLICE_REGEX),
185-
):
185+
) -> Tuple[slice | int, ...]:
186186
"Specify and parse a block index parameter."
187187

188188
return tuple(parse_slice_str(dim) for dim in (slice or "").split(",") if dim)

0 commit comments

Comments
 (0)