bec-server 2.5.0__tar.gz → 2.7.0__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 (121) hide show
  1. {bec_server-2.5.0 → bec_server-2.7.0}/PKG-INFO +1 -2
  2. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/bec_server_utils/subprocess_launch.py +1 -8
  3. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/devices/devicemanager.py +3 -31
  4. bec_server-2.7.0/bec_server/device_server/tests/utils.py +55 -0
  5. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer/__init__.py +1 -1
  6. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer/cli/launch.py +0 -3
  7. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer/file_writer.py +12 -105
  8. bec_server-2.7.0/bec_server/file_writer_plugins/__init__.py +1 -0
  9. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_guard.py +2 -6
  10. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_manager.py +11 -30
  11. bec_server-2.7.0/bec_server/scan_server/scan_plugins/__init__.py +1 -0
  12. bec_server-2.7.0/bec_server/scan_server/tests/__init__.py +0 -0
  13. bec_server-2.7.0/bec_server/scan_server/tests/fixtures.py +14 -0
  14. {bec_server-2.5.0/tests/tests_scan_server → bec_server-2.7.0/bec_server/scan_server/tests}/utils.py +1 -59
  15. bec_server-2.7.0/bec_server/scihub/cli/__init__.py +0 -0
  16. {bec_server-2.5.0 → bec_server-2.7.0}/pyproject.toml +1 -2
  17. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_file_writer/test_file_writer.py +1 -1
  18. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scan_guard.py +1 -1
  19. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scan_server_queue.py +1 -1
  20. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scan_worker.py +1 -1
  21. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scans.py +1 -472
  22. bec_server-2.5.0/bec_server/file_writer_plugins/__init__.py +0 -2
  23. bec_server-2.5.0/bec_server/scan_server/scan_plugins/LamNIFermatScan.py +0 -489
  24. bec_server-2.5.0/bec_server/scan_server/scan_plugins/__init__.py +0 -3
  25. bec_server-2.5.0/bec_server/scan_server/scan_plugins/flomni_fermat_scan.py +0 -329
  26. bec_server-2.5.0/bec_server/scan_server/scan_plugins/owis_grid.py +0 -309
  27. bec_server-2.5.0/bec_server/scan_server/scan_plugins/sgalil_grid.py +0 -216
  28. bec_server-2.5.0/tests/tests_scan_server/test_flomni_fermat_scan.py +0 -61
  29. {bec_server-2.5.0 → bec_server-2.7.0}/.gitignore +0 -0
  30. {bec_server-2.5.0 → bec_server-2.7.0}/README.md +0 -0
  31. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/__init__.py +0 -0
  32. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/bec_server_utils/__init__.py +0 -0
  33. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/bec_server_utils/launch.py +0 -0
  34. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/bec_server_utils/service_handler.py +0 -0
  35. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/bec_server_utils/tmux_launch.py +0 -0
  36. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/__init__.py +0 -0
  37. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/cli/__init__.py +0 -0
  38. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/cli/launch.py +0 -0
  39. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/dap_server.py +0 -0
  40. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/dap_service.py +0 -0
  41. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/dap_service_manager.py +0 -0
  42. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/data_processing/lmfit1d_service.py +0 -0
  43. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/__init__.py +0 -0
  44. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/cli/__init__.py +0 -0
  45. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/cli/launch.py +0 -0
  46. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/device_server.py +0 -0
  47. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/devices/__init__.py +0 -0
  48. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/devices/config_update_handler.py +0 -0
  49. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/devices/device_serializer.py +0 -0
  50. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/device_server/rpc_mixin.py +0 -0
  51. {bec_server-2.5.0/bec_server/file_writer/cli → bec_server-2.7.0/bec_server/device_server/tests}/__init__.py +0 -0
  52. {bec_server-2.5.0/bec_server/scan_bundler → bec_server-2.7.0/bec_server/file_writer}/cli/__init__.py +0 -0
  53. {bec_server-2.5.0/bec_server/file_writer_plugins → bec_server-2.7.0/bec_server/file_writer}/default_writer.py +0 -0
  54. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer/file_writer_manager.py +0 -0
  55. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer/merged_dicts.py +0 -0
  56. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/file_writer_plugins/cSAXS.py +0 -0
  57. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/__init__.py +0 -0
  58. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/bec_emitter.py +0 -0
  59. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/bluesky_emitter.py +0 -0
  60. {bec_server-2.5.0/bec_server/scan_server → bec_server-2.7.0/bec_server/scan_bundler}/cli/__init__.py +0 -0
  61. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/cli/launch.py +0 -0
  62. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/emitter.py +0 -0
  63. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_bundler/scan_bundler.py +0 -0
  64. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/__init__.py +0 -0
  65. {bec_server-2.5.0/bec_server/scihub → bec_server-2.7.0/bec_server/scan_server}/cli/__init__.py +0 -0
  66. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/cli/launch.py +0 -0
  67. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/device_validation.py +0 -0
  68. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/errors.py +0 -0
  69. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/path_optimization.py +0 -0
  70. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_assembler.py +0 -0
  71. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_plugins/otf_scan.py +0 -0
  72. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_queue.py +0 -0
  73. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_server.py +0 -0
  74. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_stubs.py +0 -0
  75. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scan_worker.py +0 -0
  76. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scan_server/scans.py +0 -0
  77. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/__init__.py +0 -0
  78. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/cli/launch.py +0 -0
  79. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/repeated_timer.py +0 -0
  80. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scibec/__init__.py +0 -0
  81. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scibec/config_handler.py +0 -0
  82. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scibec/scibec_connector.py +0 -0
  83. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scibec/scibec_metadata_handler.py +0 -0
  84. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scihub.py +0 -0
  85. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scilog/__init__.py +0 -0
  86. {bec_server-2.5.0 → bec_server-2.7.0}/bec_server/scihub/scilog/scilog.py +0 -0
  87. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_bec_server_utils/test_main.py +0 -0
  88. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_bec_server_utils/test_service_handler.py +0 -0
  89. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_bec_server_utils/test_tmux_launch.py +0 -0
  90. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_data_processing/conftest.py +0 -0
  91. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_data_processing/test_dap_cli_launch.py +0 -0
  92. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_data_processing/test_dap_server.py +0 -0
  93. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_data_processing/test_dap_service_manager.py +0 -0
  94. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_data_processing/test_lmfit1d_service.py +0 -0
  95. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/conftest.py +0 -0
  96. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_config_handler.py +0 -0
  97. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_device_manager_ds.py +0 -0
  98. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_device_serializer.py +0 -0
  99. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_device_server.py +0 -0
  100. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_device_server_cli_launch.py +0 -0
  101. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_device_server/test_rpc_mixin.py +0 -0
  102. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_file_writer/conftest.py +0 -0
  103. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_file_writer/test_file_writer_cli_launch.py +0 -0
  104. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_file_writer/test_file_writer_manager.py +0 -0
  105. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/conftest.py +0 -0
  106. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/test_bec_emitter.py +0 -0
  107. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/test_bluesky_emitter.py +0 -0
  108. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/test_emitter.py +0 -0
  109. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/test_scan_bundler.py +0 -0
  110. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_bundler/test_scan_bundler_cli_launch.py +0 -0
  111. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/conftest.py +0 -0
  112. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_path_optimization.py +0 -0
  113. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scan_server_cli_launch.py +0 -0
  114. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scan_server/test_scan_stubs.py +0 -0
  115. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/conftest.py +0 -0
  116. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_repeated_timer.py +0 -0
  117. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_scibec_config_handler.py +0 -0
  118. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_scibec_connector.py +0 -0
  119. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_scibec_metadata_handler.py +0 -0
  120. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_scihub_cli_launch.py +0 -0
  121. {bec_server-2.5.0 → bec_server-2.7.0}/tests/tests_scihub/test_scilog_connector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec-server
3
- Version: 2.5.0
3
+ Version: 2.7.0
4
4
  Summary: BEC server
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec
@@ -22,7 +22,6 @@ Requires-Dist: pydantic
22
22
  Requires-Dist: python-dotenv
23
23
  Requires-Dist: pyyaml
24
24
  Requires-Dist: rich
25
- Requires-Dist: xmltodict
26
25
  Provides-Extra: dev
27
26
  Requires-Dist: black; extra == 'dev'
28
27
  Requires-Dist: coverage; extra == 'dev'
@@ -11,14 +11,7 @@ def subprocess_start(bec_path: str, config_path: str, services: dict):
11
11
  cwd = os.path.abspath(os.path.join(service_path, ".."))
12
12
  if config_path:
13
13
  processes.append(
14
- subprocess.Popen(
15
- (
16
- service_config["command"],
17
- "--config",
18
- config_path,
19
- ),
20
- cwd=cwd,
21
- )
14
+ subprocess.Popen((service_config["command"], "--config", config_path), cwd=cwd)
22
15
  )
23
16
  else:
24
17
  processes.append(subprocess.Popen((service_config["command"],), cwd=cwd))
@@ -13,7 +13,6 @@ from functools import reduce
13
13
 
14
14
  import numpy as np
15
15
  import ophyd
16
- import ophyd.sim as ops
17
16
  import ophyd_devices as opd
18
17
  from ophyd.ophydobj import OphydObject
19
18
  from ophyd.signal import EpicsSignalBase
@@ -27,16 +26,11 @@ from bec_lib import (
27
26
  MessageEndpoints,
28
27
  bec_logger,
29
28
  messages,
29
+ plugin_helper,
30
30
  )
31
31
  from bec_server.device_server.devices.config_update_handler import ConfigUpdateHandler
32
32
  from bec_server.device_server.devices.device_serializer import get_device_info
33
33
 
34
- try:
35
- from bec_plugins import devices as plugin_devices
36
- except ImportError:
37
- plugin_devices = None
38
-
39
-
40
34
  logger = bec_logger.logger
41
35
 
42
36
 
@@ -118,30 +112,8 @@ class DeviceManagerDS(DeviceManagerBase):
118
112
 
119
113
  @staticmethod
120
114
  def _get_device_class(dev_type: str) -> type:
121
- """
122
- Return the class object from 'dev_type' string in the form '[module:][submodule:]class_name'
123
- The class is looked after in ophyd devices[.module][.submodule] first, if it is not
124
- present plugin_devices, ophyd, ophyd_devices.sim are searched too
125
-
126
- Args:
127
- dev_type (str): device type string
128
-
129
- Returns:
130
- type: class object
131
- """
132
- submodule, _, class_name = dev_type.rpartition(":")
133
- if submodule:
134
- submodule = f".{submodule.replace(':', '.')}"
135
- for parent_module in (opd, plugin_devices, ophyd, ops):
136
- try:
137
- module = __import__(f"{parent_module.__name__}{submodule}", fromlist=[""])
138
- except ModuleNotFoundError:
139
- continue
140
- else:
141
- break
142
- else:
143
- raise TypeError(f"Unknown device class {dev_type}")
144
- return getattr(module, class_name)
115
+ """Get the device class from the device type"""
116
+ return plugin_helper.get_plugin_class(dev_type, [opd, ophyd])
145
117
 
146
118
  def _load_session(self, *_args, **_kwargs):
147
119
  delayed_init = []
@@ -0,0 +1,55 @@
1
+ from bec_lib.devicemanager import DeviceContainer
2
+ from bec_lib.tests.utils import ConnectorMock
3
+
4
+
5
+ # pylint: disable=missing-function-docstring
6
+ # pylint: disable=protected-access
7
+ class DeviceMock:
8
+ def __init__(self, name: str, value=None):
9
+ self.name = name
10
+ self.read_buffer = {self.name: {"value": value}} if value is not None else None
11
+ self._config = {"deviceConfig": {"limits": [-50, 50]}, "userParameter": None}
12
+ self._read_only = False
13
+ self._enabled = True
14
+
15
+ def read(self):
16
+ return self.read_buffer
17
+
18
+ def readback(self):
19
+ return self.read_buffer
20
+
21
+ @property
22
+ def obj(self):
23
+ return self
24
+
25
+ @property
26
+ def limits(self):
27
+ return self._config["deviceConfig"]["limits"]
28
+
29
+ @property
30
+ def read_only(self) -> bool:
31
+ return self._read_only
32
+
33
+ @read_only.setter
34
+ def read_only(self, val: bool):
35
+ self._read_only = val
36
+
37
+ @property
38
+ def enabled(self) -> bool:
39
+ return self._enabled
40
+
41
+ @enabled.setter
42
+ def enabled(self, val: bool):
43
+ self._enabled = val
44
+
45
+ @property
46
+ def user_parameter(self):
47
+ return self._config["userParameter"]
48
+
49
+
50
+ class DMMock:
51
+ devices = DeviceContainer()
52
+ connector = ConnectorMock()
53
+
54
+ def add_device(self, name, value=None):
55
+ self.devices[name] = DeviceMock(name, value=value)
@@ -1,3 +1,3 @@
1
1
  from .cli.launch import main
2
- from .file_writer import NexusFileWriter, NeXusFileXMLWriter
2
+ from .file_writer import NexusFileWriter
3
3
  from .file_writer_manager import FileWriterManager
@@ -23,9 +23,6 @@ def main():
23
23
  config = ServiceConfig(config_path)
24
24
 
25
25
  file_writer_manager = file_writer.FileWriterManager(config, RedisConnector)
26
- file_writer_manager.file_writer.configure(
27
- layout_file=os.path.abspath("./layout_cSAXS_NXsas.xml")
28
- )
29
26
  try:
30
27
  event = threading.Event()
31
28
  logger.success("Started FileWriter")
@@ -8,11 +8,10 @@ import traceback
8
8
  import typing
9
9
 
10
10
  import h5py
11
- import xmltodict
12
11
 
13
- import bec_server.file_writer_plugins as fwp
14
- from bec_lib import MessageEndpoints, bec_logger, messages
12
+ from bec_lib import MessageEndpoints, bec_logger, messages, plugin_helper
15
13
 
14
+ from .default_writer import NeXus_format as default_NeXus_format
16
15
  from .merged_dicts import merge_dicts
17
16
 
18
17
  logger = bec_logger.logger
@@ -49,107 +48,6 @@ class FileWriter(abc.ABC):
49
48
  return device_storage
50
49
 
51
50
 
52
- class XMLWriter:
53
- @staticmethod
54
- def get_type(type_string: str):
55
- if type_string == "float":
56
- return float
57
- if type_string == "string":
58
- return str
59
- if type_string == "int":
60
- return int
61
- raise NeXusLayoutError(f"Unsupported data type {type_string}.")
62
-
63
- def get_value(self, value, entry, source, data_type):
64
- if source == "constant":
65
- if data_type:
66
- return self.get_type(data_type)(value)
67
- return value
68
- return entry
69
-
70
- def add_group(self, container, val):
71
- name = val.pop("@name")
72
- group = container.create_group(name)
73
- self.add_content(group, val)
74
-
75
- def add_dataset(self, container, val):
76
- name = val.pop("@name")
77
- source = val.pop("@source")
78
- value = val.pop("@value", None)
79
- data_type = val.pop("@type", None)
80
- entry = val.pop("@entry", None)
81
-
82
- data = self.get_value(value=value, entry=entry, source=source, data_type=data_type)
83
- if data is None:
84
- return
85
- dataset = container.create_dataset(name, data=data)
86
- self.add_content(dataset, val)
87
- return
88
-
89
- def add_attribute(self, container, val):
90
- name = val.pop("@name")
91
- source = val.pop("@source")
92
- value = val.pop("@value", None)
93
- data_type = val.pop("@type", None)
94
- entry = val.pop("@entry", None)
95
-
96
- data = self.get_value(value=value, entry=entry, source=source, data_type=data_type)
97
- setattr(container.attrs, name, data)
98
-
99
- def add_hardlink(self, container, val):
100
- pass
101
-
102
- def add_softlink(self, container, val):
103
- pass
104
-
105
- def add_content(self, container, layout):
106
- for key, values in layout.items():
107
- if not isinstance(values, list):
108
- values = [values]
109
- for val in values:
110
- if key == "group":
111
- self.add_group(container, val)
112
- elif key == "hdf5_layout":
113
- self.add_base_entry(container, val)
114
- elif key == "attribute":
115
- self.add_attribute(container, val)
116
- elif key == "dataset":
117
- self.add_dataset(container, val)
118
- elif key == "hardlink":
119
- self.add_hardlink(container, val)
120
- elif key == "softlink":
121
- self.add_softlink(container, val)
122
- else:
123
- pass
124
- # raise NeXusLayoutError()
125
-
126
- def add_base_entry(self, container, val):
127
- self.add_group(container, val["group"])
128
-
129
-
130
- class NeXusFileXMLWriter(FileWriter, XMLWriter):
131
- def configure(self, layout_file, **kwargs):
132
- self.layout_file = layout_file
133
- with open(self.layout_file, "br") as f:
134
- self.layout = xmltodict.parse(f)
135
-
136
- def get_value(self, value, entry, source, data_type):
137
- if source == "constant":
138
- if data_type:
139
- return self.get_type(data_type)(value)
140
- return value
141
- if source == "bec":
142
- return self.data.get(entry)
143
- return entry
144
-
145
- def write(self, file_path: str, data):
146
- print(f"writing file to {file_path}")
147
- self.data = self._create_device_data_storage(data)
148
-
149
- with h5py.File(file_path, "w") as file:
150
- self.add_content(file, self.layout)
151
-
152
-
153
51
  class HDF5Storage:
154
52
  """
155
53
  The HDF5Storage class is a container used by the HDF5 writer plugins to store data in the correct NeXus format.
@@ -310,7 +208,16 @@ class NexusFileWriter(FileWriter):
310
208
  ).isoformat()
311
209
  if data.end_time is not None:
312
210
  device_storage["end_time"] = datetime.datetime.fromtimestamp(data.end_time).isoformat()
313
- writer_format = getattr(fwp, self.file_writer_manager.file_writer_config.get("plugin"))
211
+
212
+ requested_plugin = self.file_writer_manager.file_writer_config.get("plugin")
213
+ if requested_plugin == "default_NeXus_format":
214
+ writer_format = default_NeXus_format
215
+ else:
216
+ plugins = plugin_helper.get_file_writer_plugins()
217
+ if requested_plugin not in plugins:
218
+ logger.error(f"Plugin {requested_plugin} not found. Using default plugin.")
219
+ writer_format = default_NeXus_format
220
+
314
221
  for file_ref in data.file_references.values():
315
222
  rel_path = os.path.relpath(file_ref["path"], os.path.dirname(file_path))
316
223
  file_ref["path"] = rel_path
@@ -0,0 +1 @@
1
+ from .cSAXS import NeXus_format as cSAXS_NeXus_format
@@ -26,9 +26,7 @@ class ScanGuard:
26
26
  self.connector = self.parent.connector
27
27
 
28
28
  self.connector.register(
29
- MessageEndpoints.scan_queue_request(),
30
- cb=self._scan_queue_request_callback,
31
- parent=self,
29
+ MessageEndpoints.scan_queue_request(), cb=self._scan_queue_request_callback, parent=self
32
30
  )
33
31
 
34
32
  self.connector.register(
@@ -127,9 +125,7 @@ class ScanGuard:
127
125
  """
128
126
  sqrr = MessageEndpoints.scan_queue_request_response()
129
127
  rrm = messages.RequestResponseMessage(
130
- accepted=scan_status.accepted,
131
- message=scan_status.message,
132
- metadata=metadata,
128
+ accepted=scan_status.accepted, message=scan_status.message, metadata=metadata
133
129
  )
134
130
  self.device_manager.connector.send(sqrr, rrm)
135
131
 
@@ -1,11 +1,6 @@
1
- import glob
2
- import importlib
3
- import importlib.util
4
1
  import inspect
5
- import os
6
- from pathlib import Path
7
2
 
8
- from bec_lib import MessageEndpoints, bec_logger
3
+ from bec_lib import MessageEndpoints, bec_logger, plugin_helper
9
4
  from bec_lib.messages import AvailableResourceMessage
10
5
  from bec_lib.signature_serializer import signature_to_dict
11
6
 
@@ -15,7 +10,6 @@ logger = bec_logger.logger
15
10
 
16
11
 
17
12
  class ScanManager:
18
- DEFAULT_PLUGIN_PATH = Path(os.path.dirname(os.path.abspath(__file__)) + "/../../").resolve()
19
13
 
20
14
  def __init__(self, *, parent):
21
15
  """
@@ -31,30 +25,17 @@ class ScanManager:
31
25
 
32
26
  def load_plugins(self):
33
27
  """load scan plugins"""
34
- plugin_path = os.environ.get("BEC_PLUGIN_PATH")
35
- if not plugin_path:
36
- logger.info("BEC_PLUGIN_PATH not set. Using default plugin path.")
37
- plugin_path = self.DEFAULT_PLUGIN_PATH
38
- else:
39
- logger.info(f"Using plugin path {plugin_path}")
40
- plugin_path = os.path.join(plugin_path, "scan_server/scan_plugins")
41
- files = glob.glob(os.path.join(plugin_path, "*.py"))
42
- for file in files:
43
- if file.endswith("__init__.py"):
28
+ plugins = plugin_helper.get_scan_plugins()
29
+ if not plugins:
30
+ return
31
+ for name, cls in plugins.items():
32
+ if not issubclass(cls, ScanServerScans.RequestBase):
33
+ logger.error(
34
+ f"Plugin {name} is not a valid scan plugin as it does not inherit from RequestBase. Skipping."
35
+ )
44
36
  continue
45
- module_spec = importlib.util.spec_from_file_location("scan_plugins", file)
46
- plugin_module = importlib.util.module_from_spec(module_spec)
47
- module_spec.loader.exec_module(plugin_module)
48
- module_members = inspect.getmembers(plugin_module)
49
- for name, cls in module_members:
50
- if not inspect.isclass(cls):
51
- continue
52
- # ignore imported classes
53
- if cls.__module__ != "scan_plugins":
54
- continue
55
- if issubclass(cls, ScanServerScans.RequestBase):
56
- self._plugins[name] = cls
57
- logger.info(f"Loading scan plugin {name}")
37
+ self._plugins[name] = cls
38
+ logger.info(f"Loading scan plugin {name}")
58
39
 
59
40
  def update_available_scans(self):
60
41
  """load all scans and plugin scans"""
@@ -0,0 +1 @@
1
+ from .otf_scan import OTFScan
@@ -0,0 +1,14 @@
1
+ import pytest
2
+
3
+ from bec_lib.logger import bec_logger
4
+ from bec_lib.tests.fixtures import dm_with_devices
5
+ from bec_server.scan_server.tests.utils import ScanServerMock
6
+
7
+
8
+ # pylint: disable=missing-function-docstring
9
+ # pylint: disable=protected-access
10
+ @pytest.fixture
11
+ def scan_server_mock(dm_with_devices):
12
+ server = ScanServerMock(dm_with_devices)
13
+ yield server
14
+ bec_logger.logger.remove()
@@ -1,8 +1,4 @@
1
- import pytest
2
-
3
1
  from bec_lib import ServiceConfig
4
- from bec_lib.devicemanager import DeviceContainer
5
- from bec_lib.logger import bec_logger
6
2
  from bec_lib.messages import BECStatus
7
3
  from bec_lib.tests.utils import ConnectorMock
8
4
  from bec_server.scan_server.scan_server import ScanServer
@@ -12,13 +8,6 @@ from bec_server.scan_server.scan_worker import InstructionQueueStatus
12
8
  # pylint: disable=protected-access
13
9
 
14
10
 
15
- @pytest.fixture
16
- def scan_server_mock(dm_with_devices):
17
- server = ScanServerMock(dm_with_devices, dm_with_devices.connector)
18
- yield server
19
- bec_logger.logger.remove()
20
-
21
-
22
11
  class WorkerMock:
23
12
  def __init__(self) -> None:
24
13
  self.scan_id = None
@@ -30,7 +19,7 @@ class WorkerMock:
30
19
 
31
20
 
32
21
  class ScanServerMock(ScanServer):
33
- def __init__(self, device_manager, connector) -> None:
22
+ def __init__(self, device_manager) -> None:
34
23
  self.device_manager = device_manager
35
24
  super().__init__(
36
25
  ServiceConfig(redis={"host": "dummy", "port": 6379}), connector_cls=ConnectorMock
@@ -69,50 +58,3 @@ class ScanServerMock(ScanServer):
69
58
  @dataset_number.setter
70
59
  def dataset_number(self, val: int):
71
60
  pass
72
-
73
-
74
- class DeviceMock:
75
- def __init__(self, name: str):
76
- self.name = name
77
- self.read_buffer = None
78
- self._config = {"deviceConfig": {"limits": [-50, 50]}, "userParameter": None}
79
- self._read_only = False
80
- self._enabled = True
81
-
82
- def read(self):
83
- return self.read_buffer
84
-
85
- def readback(self):
86
- return self.read_buffer
87
-
88
- @property
89
- def limits(self):
90
- return self._config["deviceConfig"]["limits"]
91
-
92
- @property
93
- def read_only(self) -> bool:
94
- return self._read_only
95
-
96
- @read_only.setter
97
- def read_only(self, val: bool):
98
- self._read_only = val
99
-
100
- @property
101
- def enabled(self) -> bool:
102
- return self._enabled
103
-
104
- @enabled.setter
105
- def enabled(self, val: bool):
106
- self._enabled = val
107
-
108
- @property
109
- def user_parameter(self):
110
- return self._config["userParameter"]
111
-
112
-
113
- class DMMock:
114
- devices = DeviceContainer()
115
- connector = ConnectorMock()
116
-
117
- def add_device(self, name):
118
- self.devices[name] = DeviceMock(name)
File without changes
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec-server"
7
- version = "2.5.0"
7
+ version = "2.7.0"
8
8
  description = "BEC server"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -27,7 +27,6 @@ dependencies = [
27
27
  "pyyaml",
28
28
  "python-dotenv",
29
29
  "rich",
30
- "xmltodict",
31
30
  ]
32
31
 
33
32
  [project.optional-dependencies]
@@ -9,7 +9,7 @@ from test_file_writer_manager import file_writer_manager_mock
9
9
 
10
10
  from bec_lib.tests.fixtures import dm_with_devices
11
11
  from bec_server import file_writer
12
- from bec_server.file_writer import NexusFileWriter, NeXusFileXMLWriter
12
+ from bec_server.file_writer import NexusFileWriter
13
13
  from bec_server.file_writer.file_writer import HDF5Storage
14
14
  from bec_server.file_writer.file_writer_manager import ScanStorage
15
15
  from bec_server.file_writer_plugins.cSAXS import NeXus_format as cSAXS_Nexus_format
@@ -1,11 +1,11 @@
1
1
  from unittest import mock
2
2
 
3
3
  import pytest
4
- from utils import scan_server_mock
5
4
 
6
5
  from bec_lib import MessageEndpoints, messages
7
6
  from bec_lib.redis_connector import MessageObject
8
7
  from bec_server.scan_server.scan_guard import ScanGuard, ScanRejection, ScanStatus
8
+ from bec_server.scan_server.tests.fixtures import scan_server_mock
9
9
 
10
10
 
11
11
  @pytest.fixture
@@ -2,7 +2,6 @@ import uuid
2
2
  from unittest import mock
3
3
 
4
4
  import pytest
5
- from utils import scan_server_mock
6
5
 
7
6
  from bec_lib import Alarms, MessageEndpoints, messages
8
7
  from bec_lib.redis_connector import MessageObject
@@ -17,6 +16,7 @@ from bec_server.scan_server.scan_queue import (
17
16
  ScanQueueStatus,
18
17
  )
19
18
  from bec_server.scan_server.scan_worker import ScanWorker
19
+ from bec_server.scan_server.tests.fixtures import scan_server_mock
20
20
 
21
21
  # pylint: disable=missing-function-docstring
22
22
  # pylint: disable=protected-access
@@ -3,7 +3,6 @@ import uuid
3
3
  from unittest import mock
4
4
 
5
5
  import pytest
6
- from utils import scan_server_mock
7
6
 
8
7
  from bec_lib import MessageEndpoints, messages
9
8
  from bec_lib.tests.utils import ConnectorMock
@@ -18,6 +17,7 @@ from bec_server.scan_server.scan_queue import (
18
17
  ScanQueue,
19
18
  )
20
19
  from bec_server.scan_server.scan_worker import ScanWorker
20
+ from bec_server.scan_server.tests.fixtures import scan_server_mock
21
21
 
22
22
 
23
23
  @pytest.fixture