44import socket
55from functools import lru_cache
66from pathlib import Path
7- from typing import Dict , List , Literal , Optional , Union
7+ from typing import Literal , Optional , Union
88
99import yaml
1010from backports .entry_points_selectable import entry_points
1111from pydantic import BaseModel , BaseSettings , Extra , validator
1212
1313
14- class MachineConfig (BaseModel , extra = Extra .allow ): # type: ignore
15- acquisition_software : List [str ]
16- calibrations : Dict [str , Dict [str , Union [dict , float ]]]
17- data_directories : List [Path ]
18- rsync_basepath : Path
19- default_model : Path
14+ class MachineConfig (BaseModel ): # type: ignore
15+ """
16+ Keys that describe the type of workflow conducted on the client side, and how
17+ Murfey will handle its data transfer and processing
18+ """
19+
20+ # General info --------------------------------------------------------------------
2021 display_name : str = ""
2122 instrument_name : str = ""
2223 image_path : Optional [Path ] = None
23- software_versions : Dict [str , str ] = {}
24- external_executables : Dict [str , str ] = {}
25- external_executables_eer : Dict [str , str ] = {}
26- external_environment : Dict [str , str ] = {}
27- rsync_module : str = ""
24+ machine_override : str = ""
25+
26+ # Hardware and software -----------------------------------------------------------
27+ camera : str = "FALCON"
28+ superres : bool = False
29+ calibrations : dict [str , dict [str , Union [dict , float ]]]
30+ acquisition_software : list [str ]
31+ software_versions : dict [str , str ] = {}
32+ software_settings_output_directories : dict [str , list [str ]] = {}
33+ data_required_substrings : dict [str , dict [str , list [str ]]] = {}
34+
35+ # Client side directory setup -----------------------------------------------------
36+ data_directories : list [Path ]
2837 create_directories : list [str ] = ["atlas" ]
29- analyse_created_directories : List [str ] = []
38+ analyse_created_directories : list [str ] = []
3039 gain_reference_directory : Optional [Path ] = None
3140 eer_fractionation_file_template : str = ""
32- processed_directory_name : str = "processed"
33- gain_directory_name : str = "processing"
34- node_creator_queue : str = "node_creator"
35- superres : bool = False
36- camera : str = "FALCON"
37- data_required_substrings : Dict [str , Dict [str , List [str ]]] = {}
38- allow_removal : bool = False
41+
42+ # Data transfer setup -------------------------------------------------------------
43+ # Rsync setup
3944 data_transfer_enabled : bool = True
45+ rsync_url : str = ""
46+ rsync_module : str = ""
47+ rsync_basepath : Path
48+ allow_removal : bool = False
49+
50+ # Upstream data download setup
51+ upstream_data_directories : list [Path ] = [] # Previous sessions
52+ upstream_data_download_directory : Optional [Path ] = None # Set by microscope config
53+ upstream_data_tiff_locations : list [str ] = ["processed" ] # Location of CLEM TIFFs
54+
55+ # Data processing setup -----------------------------------------------------------
56+ # General processing setup
4057 processing_enabled : bool = True
41- machine_override : str = ""
42- processed_extra_directory : str = ""
43- plugin_packages : Dict [str , Path ] = {}
44- software_settings_output_directories : Dict [str , List [str ]] = {}
4558 process_by_default : bool = True
46- recipes : Dict [str , str ] = {
59+ gain_directory_name : str = "processing"
60+ processed_directory_name : str = "processed"
61+ processed_extra_directory : str = ""
62+ recipes : dict [str , str ] = {
4763 "em-spa-bfactor" : "em-spa-bfactor" ,
4864 "em-spa-class2d" : "em-spa-class2d" ,
4965 "em-spa-class3d" : "em-spa-class3d" ,
@@ -53,26 +69,41 @@ class MachineConfig(BaseModel, extra=Extra.allow): # type: ignore
5369 "em-tomo-align" : "em-tomo-align" ,
5470 }
5571
56- # Find and download upstream directories
57- upstream_data_directories : List [Path ] = [] # Previous sessions
58- upstream_data_download_directory : Optional [Path ] = None # Set by microscope config
59- upstream_data_tiff_locations : List [str ] = ["processed" ] # Location of CLEM TIFFs
60-
72+ # Particle picking setup
73+ default_model : Path
6174 model_search_directory : str = "processing"
6275 initial_model_search_directory : str = "processing/initial_model"
6376
64- failure_queue : str = ""
65- instrument_server_url : str = "http://localhost:8001"
66- frontend_url : str = "http://localhost:3000"
67- murfey_url : str = "http://localhost:8000"
68- rsync_url : str = ""
77+ # Data analysis plugins
78+ external_executables : dict [ str , str ] = {}
79+ external_executables_eer : dict [ str , str ] = {}
80+ external_environment : dict [ str , str ] = {}
81+ plugin_packages : dict [ str , Path ] = {}
6982
83+ # Server and network setup --------------------------------------------------------
84+ # Configurations and URLs
7085 security_configuration_path : Optional [Path ] = None
86+ murfey_url : str = "http://localhost:8000"
87+ frontend_url : str = "http://localhost:3000"
88+ instrument_server_url : str = "http://localhost:8001"
7189
90+ # Messaging queues
91+ failure_queue : str = ""
92+ node_creator_queue : str = "node_creator"
7293 notifications_queue : str = "pato_notification"
7394
95+ class Config :
96+ """
97+ Inner class that defines this model's parsing and serialising behaviour
98+ """
7499
75- def from_file (config_file_path : Path , instrument : str = "" ) -> Dict [str , MachineConfig ]:
100+ extra = Extra .allow
101+ json_encoders = {
102+ Path : str ,
103+ }
104+
105+
106+ def from_file (config_file_path : Path , instrument : str = "" ) -> dict [str , MachineConfig ]:
76107 with open (config_file_path , "r" ) as config_stream :
77108 config = yaml .safe_load (config_stream )
78109 return {
@@ -83,22 +114,36 @@ def from_file(config_file_path: Path, instrument: str = "") -> Dict[str, Machine
83114
84115
85116class Security (BaseModel ):
117+ # Murfey database settings
86118 murfey_db_credentials : Path
87119 crypto_key : str
88- auth_key : str = ""
120+ sqlalchemy_pooling : bool = True
121+
122+ # ISPyB settings
123+ ispyb_credentials : Optional [Path ] = None
124+
125+ # Murfey server connection settings
89126 auth_algorithm : str = ""
127+ auth_key : str = ""
128+ auth_type : Literal ["password" , "cookie" ] = "password"
90129 auth_url : str = ""
91- sqlalchemy_pooling : bool = True
92- allow_origins : List [str ] = ["*" ]
130+ cookie_key : str = ""
93131 session_validation : str = ""
94132 session_token_timeout : Optional [int ] = None
95- auth_type : Literal ["password" , "cookie" ] = "password"
96- cookie_key : str = ""
133+ allow_origins : list [str ] = ["*" ]
134+
135+ # RabbitMQ settings
97136 rabbitmq_credentials : Path
98137 feedback_queue : str = "murfey_feedback"
138+
139+ # Graylog settings
99140 graylog_host : str = ""
100141 graylog_port : Optional [int ] = None
101- ispyb_credentials : Optional [Path ] = None
142+
143+ class Config :
144+ json_encoders = {
145+ Path : str ,
146+ }
102147
103148 @validator ("graylog_port" )
104149 def check_port_present_if_host_is (
@@ -158,7 +203,7 @@ def get_security_config() -> Security:
158203
159204
160205@lru_cache (maxsize = 1 )
161- def get_machine_config (instrument_name : str = "" ) -> Dict [str , MachineConfig ]:
206+ def get_machine_config (instrument_name : str = "" ) -> dict [str , MachineConfig ]:
162207 machine_config = {
163208 "" : MachineConfig (
164209 acquisition_software = [],
0 commit comments