Skip to content

Commit a132b86

Browse files
committed
Merged recent changes from 'main' branch
2 parents ecf6d38 + 3be8e09 commit a132b86

37 files changed

+1442
-852
lines changed

.bumpclient.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.bumpversion]
2-
current_version = "0.14.0"
2+
current_version = "0.15.3"
33
commit = true
44
tag = false
55

.bumpversion.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.bumpversion]
2-
current_version = "0.14.0"
2+
current_version = "0.15.3"
33
commit = true
44
tag = true
55

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A transporter for data from Diamond eBIC microscope and detector machines onto the Diamond network.
44

5-
### Who is Murfey?
5+
## Who is Murfey?
66

77
Murfey, the package, is named after [Eliza Murfey, the inventor](https://nationalrrmuseum.org/blog/mother-of-invention-women-railroad-innovators/):
88

@@ -11,38 +11,38 @@ Murfey, the package, is named after [Eliza Murfey, the inventor](https://nationa
1111
> it was Murfey who designed the packings that would lubricate the axles with oil, aiding
1212
> in the reduction of derailments caused by seized axles and bearings.
1313
14-
### How do I set up a development environment?
14+
## How do I set up a development environment?
1515

1616
We suggest you start with your favourite virtual environment (mamba/conda/python virtualenv/...),
1717
then install using the following command.
1818

19-
#### From Git
20-
21-
```bash
19+
```text
2220
$ git clone [email protected]:DiamondLightSource/python-murfey.git
2321
$ cd python-murfey
2422
$ pip install -e .[client,server,developer]
2523
```
2624

2725
The packages included under the `[developer]` installation key contain some helpful tools to aid you with developing Murfey further:
2826

27+
- `bump-my-version` - Simplifies version control.
2928
- `ipykernel` - Enables interactive code development via Jupyter Notebooks.
3029
- `pre-commit` - Allows for the installation and running of hooks to help with linting, formatting, and type checking your code.
3130
- `pytest` - Used in conjunction with test functions to evaluate the reliability of your code.
32-
- `bump2version` - A nice little script to simplify version control.
31+
32+
Instructions for setting up the database for Murfey to register files to can be found [here](src/murfey/server/MURFEY_DB.md).
3333

3434
Finally, you may want to set up an ISPyB mock database server and a Zocalo
3535
development environment. The instructions for this are out of scope here.
3636

3737
You can then start the Murfey server with
3838

39-
```bash
39+
```text
4040
$ murfey.server
4141
```
4242

4343
and connect the client with
4444

45-
```bash
45+
```text
4646
$ murfey --server http://127.0.0.1:8000
4747
```
4848

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ requires = [
77

88
[project]
99
name = "murfey"
10-
version = "0.14.0"
10+
version = "0.15.3"
1111
description = "Client-Server architecture hauling Cryo-EM data"
1212
readme = "README.md"
1313
keywords = [
@@ -83,6 +83,7 @@ murfey = "murfey.client:run"
8383
"murfey.create_db" = "murfey.cli.create_db:run"
8484
"murfey.db_sql" = "murfey.cli.murfey_db_sql:run"
8585
"murfey.decrypt_password" = "murfey.cli.decrypt_db_password:run"
86+
"murfey.dlq_murfey" = "murfey.cli.dlq_resubmit:run"
8687
"murfey.generate_key" = "murfey.cli.generate_crypto_key:run"
8788
"murfey.generate_password" = "murfey.cli.generate_db_password:run"
8889
"murfey.instrument_server" = "murfey.instrument_server:run"
@@ -94,6 +95,8 @@ murfey = "murfey.client:run"
9495
"murfey.transfer" = "murfey.cli.transfer:run"
9596
[project.entry-points."murfey.auth.token_validation"]
9697
"password" = "murfey.server.api.auth:password_token_validation"
98+
[project.entry-points."murfey.config.extraction"]
99+
"murfey_machine" = "murfey.util.config:get_extended_machine_config"
97100
[project.entry-points."murfey.workflows.clem"]
98101
"lif_to_stack" = "murfey.workflows.clem.lif_to_stack:zocalo_cluster_request"
99102
"register_lif_preprocessing_result" = "murfey.workflows.clem.register_results:register_lif_preprocessing_result"

src/murfey/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from __future__ import annotations
22

3-
__version__ = "0.14.0"
4-
__supported_client_version__ = "0.14.0"
3+
__version__ = "0.15.3"
4+
__supported_client_version__ = "0.15.3"

src/murfey/cli/dlq_resubmit.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import argparse
2+
import json
3+
import subprocess
4+
from pathlib import Path
5+
6+
import requests
7+
8+
9+
def handle_failed_posts(json_folder: Path, token: str):
10+
"""Deal with any messages that have been sent as failed client posts"""
11+
for json_file in json_folder.glob("*"):
12+
with open(json_file, "r") as json_data:
13+
message = json.load(json_data)
14+
15+
if not message.get("message") or not message["message"].get("url"):
16+
print(f"{json_file} is not a failed client post")
17+
continue
18+
dest = message["message"]["url"]
19+
message_json = message["message"]["json"]
20+
21+
response = requests.post(
22+
dest, json=message_json, headers={"Authorization": f"Bearer {token}"}
23+
)
24+
if response.status_code != 200:
25+
print(f"Failed to repost {json_file}")
26+
else:
27+
print(f"Reposted {json_file}")
28+
json_file.unlink()
29+
30+
31+
def handle_dlq_messages(json_folder: Path):
32+
"""Reinjected to the queue"""
33+
for json_file in json_folder.glob("*"):
34+
reinject_result = subprocess.run(
35+
["zocalo.dlq_reinject", "-e", "devrmq", str(json_file)],
36+
capture_output=True,
37+
)
38+
if reinject_result.returncode == 0:
39+
print(f"Reinjected {json_file}")
40+
json_file.unlink()
41+
else:
42+
print(f"Failed to reinject {json_file}")
43+
44+
45+
def run():
46+
"""
47+
Method of checking and purging murfey queues on rabbitmq
48+
Two types of messages are possible:
49+
- failed client posts which need reposting to the murfey server API
50+
- feedback messages that can be sent back to rabbitmq
51+
"""
52+
parser = argparse.ArgumentParser(
53+
description="Purge and reinject failed murfey messages"
54+
)
55+
parser.add_argument(
56+
"--queue",
57+
help="Queue to check and purge",
58+
required=True,
59+
)
60+
parser.add_argument(
61+
"--token",
62+
help="Murfey token",
63+
required=True,
64+
)
65+
args = parser.parse_args()
66+
67+
purge_result = subprocess.run(
68+
["zocalo.dlq_purge", "-e", "devrmq", args.queue],
69+
capture_output=True,
70+
)
71+
if purge_result.returncode != 0:
72+
print(f"Failed to purge {args.queue}")
73+
return
74+
purge_stdout = purge_result.stdout.decode("utf8")
75+
export_directories = []
76+
if "exported" in purge_stdout:
77+
for line in purge_stdout.split("\n"):
78+
if line.strip().startswith("DLQ/"):
79+
dlq_dir = "DLQ/" + line.split("/")[1]
80+
if dlq_dir not in export_directories:
81+
print(f"Found messages in {dlq_dir}")
82+
export_directories.append(dlq_dir)
83+
84+
if not export_directories:
85+
print("No exported messages found")
86+
return
87+
88+
for json_dir in export_directories:
89+
handle_failed_posts(Path(json_dir), args.token)
90+
handle_dlq_messages(Path(json_dir))
91+
print("Done")
92+
93+
94+
if __name__ == "__main__":
95+
run()

src/murfey/cli/inject_spa_processing.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from murfey.server.ispyb import TransportManager
1212
from murfey.server.murfey_db import url
13-
from murfey.util.config import get_machine_config, get_microscope
13+
from murfey.util.config import get_machine_config, get_microscope, get_security_config
1414
from murfey.util.db import (
1515
AutoProcProgram,
1616
ClientEnvironment,
@@ -97,12 +97,13 @@ def run():
9797
os.environ["BEAMLINE"] = args.microscope
9898

9999
machine_config = get_machine_config()
100+
security_config = get_security_config()
100101
_url = url(machine_config)
101102
engine = create_engine(_url)
102103
murfey_db = Session(engine)
103104

104105
_transport_object = TransportManager(args.transport)
105-
_transport_object.feedback_queue = machine_config.feedback_queue
106+
_transport_object.feedback_queue = security_config.feedback_queue
106107

107108
query = (
108109
select(Movie)
@@ -182,7 +183,7 @@ def run():
182183
zocalo_message = {
183184
"recipes": ["em-spa-preprocess"],
184185
"parameters": {
185-
"feedback_queue": machine_config.feedback_queue,
186+
"feedback_queue": _transport_object.feedback_queue,
186187
"node_creator_queue": machine_config.node_creator_queue,
187188
"dcid": detached_ids[1],
188189
"kv": proc_params["voltage"],

src/murfey/cli/spa_ispyb_messages.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from murfey.server.ispyb import Session, TransportManager, get_session_id
2323
from murfey.server.murfey_db import url
2424
from murfey.util import db
25-
from murfey.util.config import get_machine_config, get_microscope
25+
from murfey.util.config import get_machine_config, get_microscope, get_security_config
2626

2727

2828
def run():
@@ -341,6 +341,7 @@ def run():
341341
.where(db.ProcessingJob.recipe == "em-spa-preprocess")
342342
).one()
343343
machine_config = get_machine_config()
344+
security_config = get_security_config()
344345
params = db.SPARelionParameters(
345346
pj_id=collected_ids[2].id,
346347
angpix=float(metadata["pixel_size_on_image"]) * 1e10,
@@ -377,7 +378,7 @@ def run():
377378

378379
if args.flush_preprocess:
379380
_transport_object = TransportManager(args.transport)
380-
_transport_object.feedback_queue = machine_config.feedback_queue
381+
_transport_object.feedback_queue = security_config.feedback_queue
381382
stashed_files = murfey_db.exec(
382383
select(db.PreprocessStash)
383384
.where(db.PreprocessStash.session_id == args.session_id)
@@ -407,7 +408,7 @@ def run():
407408
zocalo_message = {
408409
"recipes": ["em-spa-preprocess"],
409410
"parameters": {
410-
"feedback_queue": machine_config.feedback_queue,
411+
"feedback_queue": _transport_object.feedback_queue,
411412
"dcid": collected_ids[1].id,
412413
"kv": metadata["voltage"],
413414
"autoproc_program_id": collected_ids[3].id,

src/murfey/client/__init__.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,31 @@ def read_config() -> configparser.ConfigParser:
6565
requests.delete = partial(requests.delete, headers={"Authorization": f"Bearer {token}"})
6666

6767

68+
def write_config(config: configparser.ConfigParser):
69+
mcch = os.environ.get("MURFEY_CLIENT_CONFIG_HOME")
70+
murfey_client_config_home = Path(mcch) if mcch else Path.home()
71+
with open(murfey_client_config_home / ".murfey", "w") as configfile:
72+
config.write(configfile)
73+
74+
75+
def main_loop(
76+
source_watchers: List[murfey.client.watchdir.DirWatcher],
77+
appearance_time: float,
78+
transfer_all: bool,
79+
):
80+
log.info(
81+
f"Murfey {murfey.__version__} on Python {'.'.join(map(str, sys.version_info[0:3]))} entering main loop"
82+
)
83+
if appearance_time > 0:
84+
modification_time: float | None = time.time() - appearance_time * 3600
85+
else:
86+
modification_time = None
87+
while True:
88+
for sw in source_watchers:
89+
sw.scan(modification_time=modification_time, transfer_all=transfer_all)
90+
time.sleep(15)
91+
92+
6893
def _enable_webbrowser_in_cygwin():
6994
"""Helper function to make webbrowser.open() work in CygWin"""
7095
if "cygwin" in platform.system().lower() and shutil.which("cygstart"):
@@ -288,7 +313,9 @@ def run():
288313

289314
status_bar = StatusBar()
290315

291-
machine_data = requests.get(f"{murfey_url.geturl()}/machine").json()
316+
machine_data = requests.get(
317+
f"{murfey_url.geturl()}/instruments/{instrument_name}/machine"
318+
).json()
292319
gain_ref: Path | None = None
293320

294321
instance_environment = MurfeyInstanceEnvironment(
@@ -323,28 +350,3 @@ def run():
323350
)
324351
app.run()
325352
rich_handler.redirect = False
326-
327-
328-
def main_loop(
329-
source_watchers: List[murfey.client.watchdir.DirWatcher],
330-
appearance_time: float,
331-
transfer_all: bool,
332-
):
333-
log.info(
334-
f"Murfey {murfey.__version__} on Python {'.'.join(map(str, sys.version_info[0:3]))} entering main loop"
335-
)
336-
if appearance_time > 0:
337-
modification_time: float | None = time.time() - appearance_time * 3600
338-
else:
339-
modification_time = None
340-
while True:
341-
for sw in source_watchers:
342-
sw.scan(modification_time=modification_time, transfer_all=transfer_all)
343-
time.sleep(15)
344-
345-
346-
def write_config(config: configparser.ConfigParser):
347-
mcch = os.environ.get("MURFEY_CLIENT_CONFIG_HOME")
348-
murfey_client_config_home = Path(mcch) if mcch else Path.home()
349-
with open(murfey_client_config_home / ".murfey", "w") as configfile:
350-
config.write(configfile)

0 commit comments

Comments
 (0)