Skip to content

Commit 83fa6c1

Browse files
committed
FIX: recursion
1 parent 7b97b22 commit 83fa6c1

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

bluesky-tiled-plugins/bluesky_tiled_plugins/bluesky_event_stream.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,12 @@ def from_stream_client(cls, stream_client, metadata=None):
174174

175175
@functools.cached_property
176176
def descriptors(self):
177-
# Go back to the BlueskyRun node and requests the documents
178-
bs_run_node = self["data"].parent.parent # the path is: bs_run_node/streams/current_stream
177+
# Go back to the BlueskyRun node and request the documents
178+
# the path is: bs_run_node/streams/current_stream (old) or bs_run_node/current_stream (new)
179+
bs_run_node = self["data"].parent
180+
if bs_run_node.item["id"] == "streams" and ("BlueskyRun" not in {s.name for s in bs_run_node.specs}):
181+
# The parent is the old "streams" node, go up one more level
182+
bs_run_node = bs_run_node.parent
179183
stream_name = self.metadata.get("stream_name") or self["data"].item["id"]
180184
return [
181185
doc for name, doc in bs_run_node.documents() if name == "descriptor" and doc["name"] == stream_name
@@ -236,10 +240,10 @@ def __repr__(self):
236240
return node_repr(self, self._keys).replace(type(self).__name__, "DatasetClient")
237241

238242
def _keys_slice(self, start, stop, direction, page_size: Optional[int] = None, **kwargs):
239-
yield from self._keys[start : stop : -1 if direction < 0 else 1] # noqa: #203
243+
yield from self._keys[start : stop : -1 if direction < 0 else 1] # noqa: 203
240244

241245
def _items_slice(self, start, stop, direction, page_size: Optional[int] = None, **kwargs):
242-
for key in self._keys[start : stop : -1 if direction < 0 else 1]: # noqa: #203
246+
for key in self._keys[start : stop : -1 if direction < 0 else 1]: # noqa: 203
243247
yield key, self[key]
244248

245249
def __iter__(self):
@@ -343,7 +347,11 @@ def read(self, variables=(DATAVALUES,), dim0=None):
343347
def descriptors(self):
344348
# Go back to the BlueskyRun node and requests the documents
345349
stream_name = self.metadata.get("stream_name") or self.item["id"]
346-
bs_run_node = self.parent.parent # the path is: bs_run_node/streams/current_stream
350+
# the path is: bs_run_node/streams/current_stream (old) or bs_run_node/current_stream (new)
351+
bs_run_node = self.parent
352+
if bs_run_node.item["id"] == "streams" and ("BlueskyRun" not in {s.name for s in bs_run_node.specs}):
353+
# The parent is the old "streams" node, go up one more level
354+
bs_run_node = bs_run_node.parent
347355
return [
348356
doc for name, doc in bs_run_node.documents() if name == "descriptor" and doc["name"] == stream_name
349357
]

bluesky-tiled-plugins/bluesky_tiled_plugins/bluesky_run.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,22 @@ def __getitem__(self, key):
239239

240240
return super().__getitem__(key)
241241

242+
@functools.cached_property
243+
def _has_streams_namespace(self):
244+
return ("streams" in self) and ("BlueskyEventStream" not in {s.name for s in self["streams"].specs})
245+
246+
@functools.cached_property
247+
def _streams_node(self):
248+
# Access to the "streams" namespace (possibly a separate container)
249+
if self._has_streams_namespace:
250+
return self["streams"]
251+
else:
252+
# No intermediate "streams" node, use the top-level node
253+
return self
254+
242255
@functools.cached_property
243256
def _stream_names(self):
244-
return sorted(self.get("streams", ()))
257+
return sorted(k for k in self._streams_node)
245258

246259
def documents(self, fill=False):
247260
with io.BytesIO() as buffer:
@@ -254,22 +267,30 @@ def documents(self, fill=False):
254267

255268
class BlueskyRunV2SQL(BlueskyRunV2, _BlueskyRunSQL):
256269
def _keys_slice(self, start, stop, direction, page_size: Optional[int] = None, **kwargs):
257-
keys = reversed(self._stream_names) if direction < 0 else self._stream_names
258-
return (yield from keys[start:stop])
270+
if self._has_streams_namespace:
271+
keys = reversed(self._stream_names) if direction < 0 else self._stream_names
272+
return (yield from keys[start:stop])
273+
else:
274+
return (yield from super()._keys_slice(start, stop, direction, page_size=page_size, **kwargs))
259275

260276
def _items_slice(self, start, stop, direction, page_size: Optional[int] = None, **kwargs):
261-
_streams_node = super().get("streams", {})
262-
for key in reversed(self._stream_names) if direction < 0 else self._stream_names:
263-
yield key, _streams_node.get(key)
264-
return
277+
if self._has_streams_namespace:
278+
_streams_node = super().get("streams", {})
279+
for key in reversed(self._stream_names) if direction < 0 else self._stream_names:
280+
yield key, _streams_node.get(key)
281+
return
282+
else:
283+
return (yield from super()._items_slice(start, stop, direction, page_size=page_size, **kwargs))
265284

266285
def __getitem__(self, key):
267286
# For v3, we need to handle the streams and configs keys
268287
if key in RESERVED_V3_KEYS:
269288
return super().__getitem__(key)
270289

271290
if key in self._stream_names:
272-
stream_container = super().get("streams", {}).get(key)
291+
stream_container = (
292+
super().get("streams", {}).get(key) if self._has_streams_namespace else super().get(key)
293+
)
273294
return BlueskyEventStreamV2SQL.from_stream_client(stream_container)
274295

275296
return super().__getitem__(key)
@@ -293,7 +314,7 @@ def __new__(cls, context, *, item, structure_clients, **kwargs):
293314
def __getattr__(self, key):
294315
if key in self._stream_names:
295316
# A shortcut to the stream data
296-
return self["streams"][key]
317+
return self["streams"][key] if self._has_streams_namespace else self[key]
297318

298319
return super().__getattr__(key)
299320

bluesky-tiled-plugins/bluesky_tiled_plugins/exporters.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,16 @@ async def json_seq_exporter(mimetype, adapter, metadata, filter_for_access):
2424
result = []
2525

2626
# Generate descriptors
27-
stream_names = await (await adapter.lookup_adapter(["streams"])).keys_range(offset=0, limit=None)
27+
stream_names = await adapter.keys_range(offset=0, limit=None)
28+
if "streams" in stream_names:
29+
# Check for backward compatibility with the old layout (with an intermediate "streams" node)
30+
streams_adapter = await adapter.lookup_adapter(["streams"])
31+
if "BlueskyEventStream" not in {s.name for s in streams_adapter.specs}:
32+
adapter = streams_adapter
33+
stream_names = await adapter.keys_range(offset=0, limit=None)
34+
2835
for desc_name in stream_names:
29-
desc_node = await adapter.lookup_adapter(["streams", desc_name])
36+
desc_node = await adapter.lookup_adapter([desc_name])
3037
desc_meta = desc_node.metadata()
3138
part_names = set(await desc_node.keys_range(offset=0, limit=None)) # Composite parts
3239

0 commit comments

Comments
 (0)