bec-ipython-client 3.152.0__tar.gz → 3.153.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 (44) hide show
  1. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/PKG-INFO +1 -1
  2. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/pyproject.toml +1 -1
  3. bec_ipython_client-3.153.0/tests/end-2-end/test_acl_e2e.py +140 -0
  4. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/.gitignore +0 -0
  5. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/__init__.py +0 -0
  6. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/beamline_mixin.py +0 -0
  7. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/bec_magics.py +0 -0
  8. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/bec_startup.py +0 -0
  9. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/__init__.py +0 -0
  10. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/device_progress.py +0 -0
  11. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/ipython_live_updates.py +0 -0
  12. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/live_table.py +0 -0
  13. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/move_device.py +0 -0
  14. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/callbacks/utils.py +0 -0
  15. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/high_level_interfaces/__init__.py +0 -0
  16. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/high_level_interfaces/bec_hli.py +0 -0
  17. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/high_level_interfaces/spec_hli.py +0 -0
  18. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/main.py +0 -0
  19. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/SLS/__init__.py +0 -0
  20. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/SLS/sls_info.py +0 -0
  21. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/XTreme/__init__.py +0 -0
  22. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/XTreme/x-treme.py +0 -0
  23. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/__init__.py +0 -0
  24. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/plugins/flomni/flomni_config.yaml +0 -0
  25. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/prettytable.py +0 -0
  26. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/progressbar.py +0 -0
  27. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/bec_ipython_client/signals.py +0 -0
  28. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/demo.py +0 -0
  29. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/conftest.py +0 -0
  30. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_beamline_mixins.py +0 -0
  31. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_bec_client.py +0 -0
  32. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_device_progress.py +0 -0
  33. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_ipython_live_updates.py +0 -0
  34. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_live_table.py +0 -0
  35. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_move_callback.py +0 -0
  36. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_pretty_table.py +0 -0
  37. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/client_tests/test_signals.py +0 -0
  38. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/conftest.py +0 -0
  39. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/_ensure_requirements_container.py +0 -0
  40. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/test_actors_e2e.py +0 -0
  41. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/test_procedures_e2e.py +0 -0
  42. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/test_scans_e2e.py +0 -0
  43. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/test_scans_lib_e2e.py +0 -0
  44. {bec_ipython_client-3.152.0 → bec_ipython_client-3.153.0}/tests/end-2-end/test_scans_v4_lib_e2e.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_ipython_client
3
- Version: 3.152.0
3
+ Version: 3.153.0
4
4
  Summary: BEC IPython client
5
5
  Project-URL: Bug Tracker, https://github.com/bec-project/bec/issues
6
6
  Project-URL: Homepage, https://github.com/bec-project/bec
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_ipython_client"
7
- version = "3.152.0"
7
+ version = "3.153.0"
8
8
  description = "BEC IPython client"
9
9
  requires-python = ">=3.11"
10
10
  classifiers = [
@@ -0,0 +1,140 @@
1
+ import shutil
2
+
3
+ import pytest
4
+ import redis.exceptions
5
+
6
+ from bec_lib import messages
7
+ from bec_lib.client import BECClient
8
+ from bec_lib.endpoints import MessageEndpoints
9
+ from bec_lib.redis_connector import RedisConnector
10
+ from bec_lib.service_config import ServiceConfig, ServiceConfigModel
11
+ from bec_lib.tests.utils import wait_for_empty_queue
12
+ from bec_lib.utils.user_acls_test import BECAccessDemo
13
+ from bec_server.bec_server_utils.service_handler import ServiceHandler
14
+
15
+
16
+ @pytest.fixture
17
+ def acl_enabled_bec_services(
18
+ request,
19
+ bec_files_path,
20
+ bec_services_config_file_path,
21
+ bec_test_config_file_path,
22
+ bec_redis_host_port,
23
+ test_config_yaml_file_path,
24
+ ):
25
+ if not request.config.getoption("--start-servers") or not request.config.getoption(
26
+ "--flush-redis"
27
+ ):
28
+ pytest.skip("ACL e2e test mutates Redis ACLs and requires isolated pytest BEC services.")
29
+
30
+ redis_host, redis_port = bec_redis_host_port
31
+ redis_url = f"{redis_host}:{redis_port}"
32
+ acl_env_file = bec_services_config_file_path.parent / ".bec_acl.env"
33
+ acl_env_file.write_text("REDIS_USER=admin\nREDIS_PASSWORD=admin\n", encoding="utf-8")
34
+ shutil.copyfile(test_config_yaml_file_path, bec_test_config_file_path)
35
+
36
+ service_config = ServiceConfigModel(
37
+ redis={"host": redis_host, "port": redis_port},
38
+ file_writer={"base_path": str(bec_services_config_file_path.parent)},
39
+ acl={"env_file": str(acl_env_file)},
40
+ )
41
+ bec_services_config_file_path.write_text(
42
+ service_config.model_dump_json(indent=4), encoding="utf-8"
43
+ )
44
+
45
+ service_handler = ServiceHandler(
46
+ bec_path=bec_files_path, config_path=bec_services_config_file_path, interface="subprocess"
47
+ )
48
+ processes = None
49
+ try:
50
+ acl_connector = RedisConnector(redis_url)
51
+ try:
52
+ access_control = BECAccessDemo(acl_connector)
53
+ access_control.reset()
54
+ access_control.add_user()
55
+ access_control.add_admin()
56
+ access_control.set_default_non_admin()
57
+ finally:
58
+ acl_connector.shutdown()
59
+
60
+ processes = service_handler.start()
61
+ yield bec_services_config_file_path
62
+ finally:
63
+ if processes is not None:
64
+ service_handler.stop(processes)
65
+ restore_connector = RedisConnector(redis_url)
66
+ try:
67
+ BECAccessDemo(restore_connector).reset()
68
+ finally:
69
+ restore_connector.shutdown()
70
+
71
+
72
+ @pytest.mark.timeout(120)
73
+ def test_acl_admin_server_allows_default_user_scan(acl_enabled_bec_services):
74
+ admin_config = ServiceConfig(acl_enabled_bec_services)
75
+ admin_client = BECClient(admin_config, RedisConnector, forced=True, wait_for_server=True)
76
+ admin_client.start()
77
+ try:
78
+ admin_client.config.load_demo_config(force=True)
79
+ finally:
80
+ admin_client.shutdown()
81
+ admin_client._client._reset_singleton()
82
+
83
+ user_config = ServiceConfig(acl_enabled_bec_services, acl={"env_file": "", "user": "user"})
84
+ user_client = BECClient(user_config, RedisConnector, forced=True, wait_for_server=True)
85
+ user_client.start()
86
+ try:
87
+ user_client.queue.request_queue_reset()
88
+ user_client.queue.request_scan_continuation()
89
+ wait_for_empty_queue(user_client)
90
+ assert user_client.username == "user"
91
+
92
+ dev = user_client.device_manager.devices
93
+ status = user_client.scans.line_scan(
94
+ dev.samx, -0.1, 0.1, steps=3, exp_time=0.01, relative=False
95
+ )
96
+ status.wait(num_points=True, file_written=True)
97
+
98
+ assert status.scan.num_points == 3
99
+ finally:
100
+ user_client.shutdown()
101
+ user_client._client._reset_singleton()
102
+
103
+
104
+ @pytest.mark.timeout(120)
105
+ def test_acl_account_endpoint_allows_user_read_but_admin_only_write(acl_enabled_bec_services):
106
+ account_endpoint = MessageEndpoints.account()
107
+ initial_account_msg = messages.VariableMessage(value="initial-admin-account")
108
+ updated_account_msg = messages.VariableMessage(value="updated-admin-account")
109
+
110
+ user_config = ServiceConfig(acl_enabled_bec_services, acl={"env_file": "", "user": "user"})
111
+ user_client = BECClient(user_config, RedisConnector, forced=True, wait_for_server=True)
112
+ user_client.start()
113
+ try:
114
+ assert user_client.username == "user"
115
+ with user_client.acl.temporary_user(username="admin", token="admin"):
116
+ user_client._update_username()
117
+ assert user_client.username == "admin"
118
+ user_client.connector.xadd(account_endpoint, {"data": initial_account_msg})
119
+ assert user_client.connector.get_last(account_endpoint, "data") == initial_account_msg
120
+
121
+ user_client._update_username()
122
+ assert user_client.username == "user"
123
+ assert user_client.connector.get_last(account_endpoint, "data") == initial_account_msg
124
+ with pytest.raises(redis.exceptions.NoPermissionError):
125
+ user_client.connector.xadd(
126
+ account_endpoint, {"data": messages.VariableMessage(value="user-account")}
127
+ )
128
+
129
+ with user_client.acl.temporary_user(username="admin", token="admin"):
130
+ user_client._update_username()
131
+ assert user_client.username == "admin"
132
+ user_client.connector.xadd(account_endpoint, {"data": updated_account_msg})
133
+ assert user_client.connector.get_last(account_endpoint, "data") == updated_account_msg
134
+
135
+ user_client._update_username()
136
+ assert user_client.username == "user"
137
+ assert user_client.connector.get_last(account_endpoint, "data") == updated_account_msg
138
+ finally:
139
+ user_client.shutdown()
140
+ user_client._client._reset_singleton()