blissdata 2.4.2__tar.gz → 2.4.3__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 (101) hide show
  1. {blissdata-2.4.2/src/blissdata.egg-info → blissdata-2.4.3}/PKG-INFO +1 -1
  2. {blissdata-2.4.2 → blissdata-2.4.3}/pyproject.toml +1 -1
  3. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/redis_hdf5.py +18 -8
  4. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/store.py +1 -1
  5. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/__init__.py +1 -1
  6. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/plugins/test_plugin_base.py +44 -32
  7. {blissdata-2.4.2 → blissdata-2.4.3/src/blissdata.egg-info}/PKG-INFO +1 -1
  8. {blissdata-2.4.2 → blissdata-2.4.3}/LICENSE +0 -0
  9. {blissdata-2.4.2 → blissdata-2.4.3}/README.md +0 -0
  10. {blissdata-2.4.2 → blissdata-2.4.3}/setup.cfg +0 -0
  11. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/__init__.py +0 -0
  12. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/__init__.py +0 -0
  13. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/_base.py +0 -0
  14. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/_utils.py +0 -0
  15. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/config.py +0 -0
  16. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/data.py +0 -0
  17. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/beacon/files.py +0 -0
  18. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/deprecation.py +0 -0
  19. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/exceptions.py +0 -0
  20. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/__init__.py +0 -0
  21. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/abstract.py +0 -0
  22. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/dynamic_hdf5.py +0 -0
  23. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/file_arguments.py +0 -0
  24. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/h5_scan_map.py +0 -0
  25. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/static_hdf5.py +0 -0
  26. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/__init__.py +0 -0
  27. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/bliss.py +0 -0
  28. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/hdf5.py +0 -0
  29. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/hdf5_retry.py +0 -0
  30. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/lima.py +0 -0
  31. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5api/utils/types.py +0 -0
  32. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5map/__init__.py +0 -0
  33. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5map/data_items.py +0 -0
  34. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/h5map/hdf5_items.py +0 -0
  35. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/lima/__init__.py +0 -0
  36. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/lima/client.py +0 -0
  37. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/lima/image_utils.py +0 -0
  38. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/py.typed +0 -0
  39. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/__init__.py +0 -0
  40. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/encoding/__init__.py +0 -0
  41. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/encoding/json.py +0 -0
  42. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/encoding/numeric.py +0 -0
  43. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/event_stream.py +0 -0
  44. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/exceptions.py +0 -0
  45. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/identities.py +0 -0
  46. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/memory_tracker.py +0 -0
  47. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/redis_engine/scan.py +0 -0
  48. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/scan.py +0 -0
  49. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/schemas/__init__.py +0 -0
  50. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/schemas/scan_info.py +0 -0
  51. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/schemas/scan_info_display.py +0 -0
  52. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/base.py +0 -0
  53. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/default.py +0 -0
  54. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/encoding/__init__.py +0 -0
  55. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/encoding/json.py +0 -0
  56. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/encoding/numeric.py +0 -0
  57. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/event_stream.py +0 -0
  58. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/hdf5_fallback/__init__.py +0 -0
  59. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/hdf5_fallback/stream.py +0 -0
  60. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/lima/__init__.py +0 -0
  61. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/lima/stream.py +0 -0
  62. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/scan_sequence/__init__.py +0 -0
  63. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/scan_sequence/stream.py +0 -0
  64. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/streams/sink.py +0 -0
  65. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/__init__.py +0 -0
  66. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/beacon/__init__.py +0 -0
  67. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/beacon/test_config.py +0 -0
  68. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/beacon/test_data.py +0 -0
  69. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/beacon/test_files.py +0 -0
  70. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/conftest.py +0 -0
  71. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/__init__.py +0 -0
  72. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/scanner.py +0 -0
  73. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/test_dynamic_files.py +0 -0
  74. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/test_h5api_lima_utils.py +0 -0
  75. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/test_hdf5_handlers.py +0 -0
  76. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/test_redis_files.py +0 -0
  77. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5api/test_static_files.py +0 -0
  78. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5map/__init__.py +0 -0
  79. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5map/test_data_items.py +0 -0
  80. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/h5map/test_hdf5_items.py +0 -0
  81. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/lima/__init__.py +0 -0
  82. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/lima/test_image_utils.py +0 -0
  83. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/__init__.py +0 -0
  84. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/conftest.py +0 -0
  85. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/test_cursor.py +0 -0
  86. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/test_memory_tracker.py +0 -0
  87. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/test_scan.py +0 -0
  88. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/test_search.py +0 -0
  89. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/redis_engine/utils.py +0 -0
  90. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/encoding/__init__.py +0 -0
  91. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/encoding/test_json.py +0 -0
  92. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/encoding/test_numeric.py +0 -0
  93. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/plugins/__init__.py +0 -0
  94. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/plugins/test_file_backed_stream.py +0 -0
  95. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/plugins/test_lima_stream.py +0 -0
  96. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata/tests/streams/test_event_stream.py +0 -0
  97. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata.egg-info/SOURCES.txt +0 -0
  98. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata.egg-info/dependency_links.txt +0 -0
  99. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata.egg-info/entry_points.txt +0 -0
  100. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata.egg-info/requires.txt +0 -0
  101. {blissdata-2.4.2 → blissdata-2.4.3}/src/blissdata.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blissdata
3
- Version: 2.4.2
3
+ Version: 2.4.3
4
4
  Summary: Bliss data streaming client
5
5
  Maintainer: BCU (ESRF)
6
6
  License-Expression: LGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "blissdata"
3
- version = "2.4.2"
3
+ version = "2.4.3"
4
4
  description = "Bliss data streaming client"
5
5
  readme = "README.md"
6
6
  license = "LGPL-3.0-or-later"
@@ -15,21 +15,31 @@ from blissdata.h5api.h5_scan_map import H5ScanMap
15
15
 
16
16
 
17
17
  class Attributes(abstract.Attributes):
18
- def __init__(self, dct):
19
- self.dct = dct
18
+ def __init__(self, attrs: dict[str : h5m.DataItemType]):
19
+ self._attrs: dict[str : h5m.DataItemType] = attrs
20
20
  super().__init__()
21
21
 
22
22
  def __repr__(self):
23
- return f"<Attributes of Redis-HDF5 object at {hex(id(self))}>"
23
+ return f"<Attributes of Live-HDF5 object at {hex(id(self))}>"
24
24
 
25
25
  def __getitem__(self, key: str):
26
- return self.dct[key]
26
+ value = self._attrs[key].decode()
27
+ # h5map decoded values are always numpy arrays, "O" type is used for
28
+ # strings. In h5py the same value will be returned as 'bytes' when in a
29
+ # dataset, but as 'str' when in an attribute.
30
+ if value.dtype == np.dtype("O"):
31
+ # Decode 'bytes' into 'str' to reproduce h5py attribute's behavior
32
+ value = np.vectorize(lambda x: x.decode(), otypes=[np.dtype("O")])(value)
33
+ if value.shape == ():
34
+ # extract value when array is a scalar
35
+ value = value[()]
36
+ return value
27
37
 
28
38
  def __iter__(self):
29
- yield from self.dct
39
+ yield from self._attrs
30
40
 
31
41
  def __len__(self):
32
- return len(self.dct)
42
+ return len(self._attrs)
33
43
 
34
44
 
35
45
  class File(abstract.File):
@@ -68,7 +78,7 @@ class File(abstract.File):
68
78
 
69
79
  @property
70
80
  def attrs(self) -> abstract.Attributes:
71
- return Attributes({"NX_class": "NXroot"})
81
+ return Attributes({"NX_class": h5m.InlineRaw("NXroot")})
72
82
 
73
83
  @property
74
84
  def file(self) -> "File":
@@ -541,4 +551,4 @@ def dataset_factory(parent: File, path: str, item: h5m.HDF5ItemType, scan) -> Da
541
551
  # TODO
542
552
  raise NotImplementedError
543
553
 
544
- return Dataset(parent, path, item, array, virtual, external)
554
+ return Dataset(parent, path, item.attributes, array, virtual, external)
@@ -350,7 +350,7 @@ redis.register_function('seal_stream', seal_stream)"""
350
350
  for stream_key in stream_keys:
351
351
  pipe.xrevrange(stream_key, count=1)
352
352
  raw = pipe.execute()
353
- scan_states = [ScanState(val[0][1][b"state"].decode()) for val in raw]
353
+ scan_states = [ScanState(int(val[0][1][b"state"].decode())) for val in raw]
354
354
 
355
355
  return {key: state for key, state in zip(scan_keys, scan_states)}
356
356
 
@@ -92,7 +92,7 @@ class BaseStream(ABC):
92
92
  except EndOfStream:
93
93
  return
94
94
  else:
95
- yield from view.get_data()
95
+ yield from view
96
96
 
97
97
  @abstractmethod
98
98
  def _need_last_only(self, last_only):
@@ -1,5 +1,6 @@
1
1
  import pytest
2
2
  import numpy as np
3
+ import gc
3
4
  from contextlib import contextmanager
4
5
  import blissdata.redis_engine.scan
5
6
  from blissdata.exceptions import MissingPluginException
@@ -12,11 +13,11 @@ from blissdata.streams.default import (
12
13
  )
13
14
 
14
15
 
15
- class FakePluginView(View):
16
+ class MockPluginView(View):
16
17
  pass
17
18
 
18
19
 
19
- class FakePluginStream(Stream):
20
+ class MockPluginStream(Stream):
20
21
  def __init__(self, event_stream):
21
22
  if event_stream.info.get("fail", False):
22
23
  raise Exception("Oops, broken plugin...")
@@ -25,56 +26,67 @@ class FakePluginStream(Stream):
25
26
  @staticmethod
26
27
  def make_definition(name, info={}) -> StreamDefinition:
27
28
  return Stream.make_definition(
28
- name, dtype=np.int64, info=info | {"plugin": "fake"}
29
+ name, dtype=np.int64, info=info | {"plugin": "mock"}
29
30
  )
30
31
 
31
32
  @property
32
33
  def kind(self):
33
- return "fake"
34
+ return "mock"
34
35
 
35
36
  @property
36
37
  def plugin(self):
37
- return "fake"
38
+ return "mock"
38
39
 
39
40
  def _build_view_from_events(self, index, events: EventRange, last_only):
40
- return FakePluginView(events)
41
+ return MockPluginView(events)
41
42
 
42
43
 
43
- @contextmanager
44
- def fake_plugin_available():
45
- """Emulate installation of 'fake' plugin module"""
44
+ @pytest.fixture
45
+ def mock_plugin(monkeypatch):
46
+ @contextmanager
47
+ def mock_plugin_ctx():
48
+ """Emulate installation of 'mock' plugin module"""
46
49
 
47
- class FakePluginModule:
48
- stream_cls = FakePluginStream
49
- view_cls = FakePluginView
50
+ class MockPluginModule:
51
+ stream_cls = MockPluginStream
52
+ view_cls = MockPluginView
50
53
 
51
- plugin_modules = blissdata.redis_engine.scan.loaded_plugins
52
- try:
53
- plugin_modules["fake"] = FakePluginModule
54
- yield
55
- finally:
56
- del plugin_modules["fake"]
54
+ try:
55
+ monkeypatch.setitem(
56
+ blissdata.redis_engine.scan.loaded_plugins, "mock", MockPluginModule
57
+ )
58
+ yield
59
+ finally:
60
+ monkeypatch.delitem(blissdata.redis_engine.scan.loaded_plugins, "mock")
57
61
 
62
+ return mock_plugin_ctx
58
63
 
59
- def test_plugin_load(dummy_scan):
60
- with fake_plugin_available():
61
- stream_definition = FakePluginStream.make_definition("mystream")
64
+
65
+ def test_plugin_load(dummy_scan, mock_plugin):
66
+ with mock_plugin():
67
+ stream_definition = MockPluginStream.make_definition("mystream")
62
68
  _ = dummy_scan.create_stream(stream_definition)
63
69
  dummy_scan.prepare()
64
70
 
65
71
  stream = dummy_scan.streams["mystream"]
66
- assert isinstance(stream, FakePluginStream)
72
+ assert isinstance(stream, MockPluginStream)
67
73
 
68
74
 
69
75
  def test_missing_plugin_create(dummy_scan):
70
- stream_definition = FakePluginStream.make_definition("mystream")
76
+ stream_definition = MockPluginStream.make_definition("mystream")
71
77
  with pytest.raises(MissingPluginException):
72
78
  _ = dummy_scan.create_stream(stream_definition)
73
79
 
80
+ # In this test an event stream was created and then abandoned. It owns a
81
+ # sink with a redis connection that will be returned to the pool at garbage
82
+ # collection. With gevent, this leads to frequent race conditions blocking
83
+ # tests. Forcing gc.collect here prevent this issue.
84
+ gc.collect()
85
+
74
86
 
75
- def test_missing_plugin_load(dummy_scan):
76
- with fake_plugin_available():
77
- stream_definition = FakePluginStream.make_definition("mystream")
87
+ def test_missing_plugin_load(dummy_scan, mock_plugin):
88
+ with mock_plugin():
89
+ stream_definition = MockPluginStream.make_definition("mystream")
78
90
  _ = dummy_scan.create_stream(stream_definition)
79
91
  dummy_scan.prepare()
80
92
  stream = dummy_scan.streams["mystream"]
@@ -83,9 +95,9 @@ def test_missing_plugin_load(dummy_scan):
83
95
  len(stream)
84
96
 
85
97
 
86
- def test_broken_plugin_create(data_store, dummy_scan):
87
- with fake_plugin_available():
88
- stream_definition = FakePluginStream.make_definition(
98
+ def test_broken_plugin_create(data_store, dummy_scan, mock_plugin):
99
+ with mock_plugin():
100
+ stream_definition = MockPluginStream.make_definition(
89
101
  "mystream", info={"fail": True}
90
102
  )
91
103
  with pytest.raises(Exception) as exc_info:
@@ -93,9 +105,9 @@ def test_broken_plugin_create(data_store, dummy_scan):
93
105
  assert "Oops, broken plugin..." in str(exc_info)
94
106
 
95
107
 
96
- def test_broken_plugin_load(data_store, dummy_scan):
97
- with fake_plugin_available():
98
- stream_definition = FakePluginStream.make_definition(
108
+ def test_broken_plugin_load(data_store, dummy_scan, mock_plugin):
109
+ with mock_plugin():
110
+ stream_definition = MockPluginStream.make_definition(
99
111
  "mystream", info={"fail": False}
100
112
  )
101
113
  rw_stream = dummy_scan.create_stream(stream_definition)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blissdata
3
- Version: 2.4.2
3
+ Version: 2.4.3
4
4
  Summary: Bliss data streaming client
5
5
  Maintainer: BCU (ESRF)
6
6
  License-Expression: LGPL-3.0-or-later
File without changes
File without changes
File without changes