sl-shared-assets 1.0.0rc14__py3-none-any.whl → 1.0.0rc15__py3-none-any.whl

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.

Potentially problematic release.


This version of sl-shared-assets might be problematic. Click here for more details.

Files changed (42) hide show
  1. sl_shared_assets/__init__.py +21 -9
  2. sl_shared_assets/__init__.pyi +26 -6
  3. sl_shared_assets/cli.py +1 -1
  4. sl_shared_assets/cli.pyi +1 -1
  5. sl_shared_assets/data_classes/__init__.py +63 -0
  6. sl_shared_assets/data_classes/__init__.pyi +61 -0
  7. sl_shared_assets/data_classes/configuration_data.py +64 -0
  8. sl_shared_assets/data_classes/configuration_data.pyi +37 -0
  9. sl_shared_assets/data_classes/runtime_data.py +233 -0
  10. sl_shared_assets/data_classes/runtime_data.pyi +145 -0
  11. sl_shared_assets/{data_classes.py → data_classes/session_data.py} +47 -472
  12. sl_shared_assets/{data_classes.pyi → data_classes/session_data.pyi} +10 -282
  13. sl_shared_assets/data_classes/surgery_data.py +152 -0
  14. sl_shared_assets/data_classes/surgery_data.pyi +89 -0
  15. sl_shared_assets/server/__init__.py +8 -0
  16. sl_shared_assets/server/__init__.pyi +8 -0
  17. sl_shared_assets/server/job.py +140 -0
  18. sl_shared_assets/server/job.pyi +94 -0
  19. sl_shared_assets/server/server.py +213 -0
  20. sl_shared_assets/server/server.pyi +95 -0
  21. sl_shared_assets/suite2p/__init__.py +8 -0
  22. sl_shared_assets/suite2p/__init__.pyi +4 -0
  23. sl_shared_assets/suite2p/multi_day.py +193 -0
  24. sl_shared_assets/suite2p/multi_day.pyi +99 -0
  25. sl_shared_assets/{suite2p.py → suite2p/single_day.py} +55 -32
  26. sl_shared_assets/{suite2p.pyi → suite2p/single_day.pyi} +23 -19
  27. sl_shared_assets/tools/__init__.py +8 -0
  28. sl_shared_assets/tools/__init__.pyi +5 -0
  29. sl_shared_assets/{ascension_tools.py → tools/ascension_tools.py} +3 -2
  30. sl_shared_assets/{ascension_tools.pyi → tools/ascension_tools.pyi} +1 -1
  31. {sl_shared_assets-1.0.0rc14.dist-info → sl_shared_assets-1.0.0rc15.dist-info}/METADATA +1 -1
  32. sl_shared_assets-1.0.0rc15.dist-info/RECORD +40 -0
  33. sl_shared_assets/server.py +0 -300
  34. sl_shared_assets/server.pyi +0 -117
  35. sl_shared_assets-1.0.0rc14.dist-info/RECORD +0 -22
  36. /sl_shared_assets/{packaging_tools.py → tools/packaging_tools.py} +0 -0
  37. /sl_shared_assets/{packaging_tools.pyi → tools/packaging_tools.pyi} +0 -0
  38. /sl_shared_assets/{transfer_tools.py → tools/transfer_tools.py} +0 -0
  39. /sl_shared_assets/{transfer_tools.pyi → tools/transfer_tools.pyi} +0 -0
  40. {sl_shared_assets-1.0.0rc14.dist-info → sl_shared_assets-1.0.0rc15.dist-info}/WHEEL +0 -0
  41. {sl_shared_assets-1.0.0rc14.dist-info → sl_shared_assets-1.0.0rc15.dist-info}/entry_points.txt +0 -0
  42. {sl_shared_assets-1.0.0rc14.dist-info → sl_shared_assets-1.0.0rc15.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,140 @@
1
+ """This module provides the core Job class, used as the starting point for all SLURM-managed job executed on lab compute
2
+ server(s). Specifically, the Job class acts as a wrapper around the SLURM configuration and specific logic of each
3
+ job. During runtime, Server class interacts with input job objects to manage their transfer and execution on the
4
+ remote servers."""
5
+
6
+ # noinspection PyProtectedMember
7
+ from pathlib import Path
8
+ import datetime
9
+
10
+ from simple_slurm import Slurm # type: ignore
11
+
12
+
13
+ class Job:
14
+ """Aggregates the data of a single SLURM-managed job to be executed on the Sun lab BioHPC cluster.
15
+
16
+ This class provides the API for constructing any server-side job in the Sun lab. Internally, it wraps an instance
17
+ of a Slurm class to package the job data into the format expected by the SLURM job manager. All jobs managed by this
18
+ class instance should be submitted to an initialized Server class 'submit_job' method to be executed on the server.
19
+
20
+ Notes:
21
+ The initialization method of the class contains the arguments for configuring the SLURM and Conda environments
22
+ used by the job. Do not submit additional SLURM or Conda commands via the 'add_command' method, as this may
23
+ produce unexpected behavior.
24
+
25
+ Each job can be conceptualized as a sequence of shell instructions to execute on the remote compute server. For
26
+ the lab, that means that the bulk of the command consists of calling various CLIs exposed by data processing or
27
+ analysis pipelines, installed in the Conda environment on the server. Other than that, the job contains commands
28
+ for activating the target conda environment and, in some cases, doing other preparatory or cleanup work. The
29
+ source code of a 'remote' job is typically identical to what a human operator would type in a 'local' terminal
30
+ to run the same job on their PC.
31
+
32
+ A key feature of server-side jobs is that they are executed on virtual machines managed by SLURM. Since the
33
+ server has a lot more compute and memory resources than likely needed by individual jobs, each job typically
34
+ requests a subset of these resources. Upon being executed, SLURM creates an isolated environment with the
35
+ requested resources and runs the job in that environment.
36
+
37
+ Since all jobs are expected to use the CLIs from python packages (pre)installed on the BioHPC server, make sure
38
+ that the target environment is installed and configured before submitting jobs to the server. See notes in
39
+ ReadMe to learn more about configuring server-side conda environments.
40
+
41
+ Args:
42
+ job_name: The descriptive name of the SLURM job to be created. Primarily, this name is used in terminal
43
+ printouts to identify the job to human operators.
44
+ output_log: The absolute path to the .txt file on the processing server, where to store the standard output
45
+ data of the job.
46
+ error_log: The absolute path to the .txt file on the processing server, where to store the standard error
47
+ data of the job.
48
+ working_directory: The absolute path to the directory where temporary job files will be stored. During runtime,
49
+ classes from this library use that directory to store files such as the job's shell script. All such files
50
+ are automatically removed from the directory at the end of a non-errors runtime.
51
+ conda_environment: The name of the conda environment to activate on the server before running the job logic. The
52
+ environment should contain the necessary Python packages and CLIs to support running the job's logic.
53
+ cpus_to_use: The number of CPUs to use for the job.
54
+ ram_gb: The amount of RAM to allocate for the job, in Gigabytes.
55
+ time_limit: The maximum time limit for the job, in minutes. If the job is still running at the end of this time
56
+ period, it will be forcibly terminated. It is highly advised to always set adequate maximum runtime limits
57
+ to prevent jobs from hogging the server in case of runtime or algorithm errors.
58
+
59
+ Attributes:
60
+ remote_script_path: Stores the path to the script file relative to the root of the remote server that runs the
61
+ command.
62
+ job_id: Stores the unique job identifier assigned by the SLURM manager to this job, when it is accepted for
63
+ execution. This field initialized to None and is overwritten by the Server class that submits the job.
64
+ job_name: Stores the descriptive name of the SLURM job.
65
+ _command: Stores the managed SLURM command object.
66
+ """
67
+
68
+ def __init__(
69
+ self,
70
+ job_name: str,
71
+ output_log: Path,
72
+ error_log: Path,
73
+ working_directory: Path,
74
+ conda_environment: str,
75
+ cpus_to_use: int = 10,
76
+ ram_gb: int = 10,
77
+ time_limit: int = 60,
78
+ ) -> None:
79
+ # Resolves the paths to the remote (server-side) .sh script file. This is the path where the job script
80
+ # will be stored on the server, once it is transferred by the Server class instance.
81
+ self.remote_script_path = str(working_directory.joinpath(f"{job_name}.sh"))
82
+
83
+ # Defines additional arguments used by the Server class that executed the job.
84
+ self.job_id: str | None = None # This is set by the Server that submits the job.
85
+ self.job_name: str = job_name # Also stores the job name to support more informative terminal prints
86
+
87
+ # Builds the slurm command object filled with configuration information
88
+ self._command: Slurm = Slurm(
89
+ cpus_per_task=cpus_to_use,
90
+ job_name=job_name,
91
+ output=str(output_log),
92
+ error=str(error_log),
93
+ mem=f"{ram_gb}G",
94
+ time=datetime.timedelta(minutes=time_limit),
95
+ )
96
+
97
+ # Conda shell initialization commands
98
+ self._command.add_cmd("eval $(conda shell.bash hook)")
99
+ self._command.add_cmd("conda init bash")
100
+
101
+ # Activates the target conda environment for the command.
102
+ self._command.add_cmd(f"conda activate {conda_environment}")
103
+
104
+ def __repr__(self) -> str:
105
+ """Returns the string representation of the Job instance."""
106
+ return f"Job(name={self.job_name}, id={self.job_id})"
107
+
108
+ def add_command(self, command: str) -> None:
109
+ """Adds the input command string to the end of the managed SLURM job command list.
110
+
111
+ This method is a wrapper around simple_slurm's 'add_cmd' method. It is used to iteratively build the shell
112
+ command sequence of the job.
113
+
114
+ Args:
115
+ command: The command string to add to the command list, e.g.: 'python main.py --input 1'.
116
+ """
117
+
118
+ self._command.add_cmd(command)
119
+
120
+ @property
121
+ def command_script(self) -> str:
122
+ """Translates the managed job data into a shell-script-writable string and returns it to caller.
123
+
124
+ This method is used by the Server class to translate the job into the format that can be submitted to and
125
+ executed on the remote compute server. Do not call this method manually unless you know what you are doing.
126
+ The returned string is safe to dump into a .sh (shell script) file and move to the BioHPC server for execution.
127
+ """
128
+
129
+ # Appends the command to clean up (remove) the temporary script file after processing runtime is over
130
+ self._command.add_cmd(f"rm -f {self.remote_script_path}")
131
+
132
+ # Translates the command to string format
133
+ script_content = str(self._command)
134
+
135
+ # Replaces escaped $ (/$) with $. This is essential, as without this correction, things like conda
136
+ # initialization would not work as expected.
137
+ fixed_script_content = script_content.replace("\\$", "$")
138
+
139
+ # Returns the script content to caller as a string
140
+ return fixed_script_content
@@ -0,0 +1,94 @@
1
+ from pathlib import Path
2
+
3
+ from _typeshed import Incomplete
4
+ from simple_slurm import Slurm
5
+
6
+ class Job:
7
+ """Aggregates the data of a single SLURM-managed job to be executed on the Sun lab BioHPC cluster.
8
+
9
+ This class provides the API for constructing any server-side job in the Sun lab. Internally, it wraps an instance
10
+ of a Slurm class to package the job data into the format expected by the SLURM job manager. All jobs managed by this
11
+ class instance should be submitted to an initialized Server class 'submit_job' method to be executed on the server.
12
+
13
+ Notes:
14
+ The initialization method of the class contains the arguments for configuring the SLURM and Conda environments
15
+ used by the job. Do not submit additional SLURM or Conda commands via the 'add_command' method, as this may
16
+ produce unexpected behavior.
17
+
18
+ Each job can be conceptualized as a sequence of shell instructions to execute on the remote compute server. For
19
+ the lab, that means that the bulk of the command consists of calling various CLIs exposed by data processing or
20
+ analysis pipelines, installed in the Conda environment on the server. Other than that, the job contains commands
21
+ for activating the target conda environment and, in some cases, doing other preparatory or cleanup work. The
22
+ source code of a 'remote' job is typically identical to what a human operator would type in a 'local' terminal
23
+ to run the same job on their PC.
24
+
25
+ A key feature of server-side jobs is that they are executed on virtual machines managed by SLURM. Since the
26
+ server has a lot more compute and memory resources than likely needed by individual jobs, each job typically
27
+ requests a subset of these resources. Upon being executed, SLURM creates an isolated environment with the
28
+ requested resources and runs the job in that environment.
29
+
30
+ Since all jobs are expected to use the CLIs from python packages (pre)installed on the BioHPC server, make sure
31
+ that the target environment is installed and configured before submitting jobs to the server. See notes in
32
+ ReadMe to learn more about configuring server-side conda environments.
33
+
34
+ Args:
35
+ job_name: The descriptive name of the SLURM job to be created. Primarily, this name is used in terminal
36
+ printouts to identify the job to human operators.
37
+ output_log: The absolute path to the .txt file on the processing server, where to store the standard output
38
+ data of the job.
39
+ error_log: The absolute path to the .txt file on the processing server, where to store the standard error
40
+ data of the job.
41
+ working_directory: The absolute path to the directory where temporary job files will be stored. During runtime,
42
+ classes from this library use that directory to store files such as the job's shell script. All such files
43
+ are automatically removed from the directory at the end of a non-errors runtime.
44
+ conda_environment: The name of the conda environment to activate on the server before running the job logic. The
45
+ environment should contain the necessary Python packages and CLIs to support running the job's logic.
46
+ cpus_to_use: The number of CPUs to use for the job.
47
+ ram_gb: The amount of RAM to allocate for the job, in Gigabytes.
48
+ time_limit: The maximum time limit for the job, in minutes. If the job is still running at the end of this time
49
+ period, it will be forcibly terminated. It is highly advised to always set adequate maximum runtime limits
50
+ to prevent jobs from hogging the server in case of runtime or algorithm errors.
51
+
52
+ Attributes:
53
+ remote_script_path: Stores the path to the script file relative to the root of the remote server that runs the
54
+ command.
55
+ job_id: Stores the unique job identifier assigned by the SLURM manager to this job, when it is accepted for
56
+ execution. This field initialized to None and is overwritten by the Server class that submits the job.
57
+ job_name: Stores the descriptive name of the SLURM job.
58
+ _command: Stores the managed SLURM command object.
59
+ """
60
+
61
+ remote_script_path: Incomplete
62
+ job_id: str | None
63
+ job_name: str
64
+ _command: Slurm
65
+ def __init__(
66
+ self,
67
+ job_name: str,
68
+ output_log: Path,
69
+ error_log: Path,
70
+ working_directory: Path,
71
+ conda_environment: str,
72
+ cpus_to_use: int = 10,
73
+ ram_gb: int = 10,
74
+ time_limit: int = 60,
75
+ ) -> None: ...
76
+ def __repr__(self) -> str:
77
+ """Returns the string representation of the Job instance."""
78
+ def add_command(self, command: str) -> None:
79
+ """Adds the input command string to the end of the managed SLURM job command list.
80
+
81
+ This method is a wrapper around simple_slurm's 'add_cmd' method. It is used to iteratively build the shell
82
+ command sequence of the job.
83
+
84
+ Args:
85
+ command: The command string to add to the command list, e.g.: 'python main.py --input 1'.
86
+ """
87
+ @property
88
+ def command_script(self) -> str:
89
+ """Translates the managed job data into a shell-script-writable string and returns it to caller.
90
+
91
+ This method is used by the Server class to translate the job into the format that can be submitted to and
92
+ executed on the remote compute server. Do not call this method manually unless you know what you are doing.
93
+ The returned string is safe to dump into a .sh (shell script) file and move to the BioHPC server for execution.
94
+ """
@@ -0,0 +1,213 @@
1
+ """This module provides the tools for working with the Sun lab BioHPC cluster. Specifically, the classes from this
2
+ module establish an API for submitting jobs to the shared data processing cluster (managed via SLURM) and monitoring
3
+ the running job status. All lab processing and analysis pipelines use this interface for accessing shared compute
4
+ resources.
5
+ """
6
+
7
+ import time
8
+ from pathlib import Path
9
+ import tempfile
10
+ from dataclasses import dataclass
11
+
12
+ import paramiko
13
+
14
+ # noinspection PyProtectedMember
15
+ from simple_slurm import Slurm # type: ignore
16
+ from paramiko.client import SSHClient
17
+ from ataraxis_base_utilities import LogLevel, console
18
+ from ataraxis_data_structures import YamlConfig
19
+
20
+ from .job import Job
21
+
22
+
23
+ def generate_server_credentials(
24
+ output_directory: Path, username: str, password: str, host: str = "cbsuwsun.biohpc.cornell.edu"
25
+ ) -> None:
26
+ """Generates a new server_credentials.yaml file under the specified directory, using input information.
27
+
28
+ This function provides a convenience interface for generating new BioHPC server credential files. Generally, this is
29
+ only used when setting up new host-computers in the lab.
30
+ """
31
+ ServerCredentials(username=username, password=password, host=host).to_yaml(
32
+ file_path=output_directory.joinpath("server_credentials.yaml")
33
+ )
34
+
35
+
36
+ @dataclass()
37
+ class ServerCredentials(YamlConfig):
38
+ """This class stores the hostname and credentials used to log into the BioHPC cluster to run Sun lab processing
39
+ pipelines.
40
+
41
+ Primarily, this is used as part of the sl-experiment library runtime to start data processing once it is
42
+ transferred to the BioHPC server during preprocessing. However, the same file can be used together with the Server
43
+ class API to run any computation jobs on the lab's BioHPC server.
44
+ """
45
+
46
+ username: str = "YourNetID"
47
+ """The username to use for server authentication."""
48
+ password: str = "YourPassword"
49
+ """The password to use for server authentication."""
50
+ host: str = "cbsuwsun.biohpc.cornell.edu"
51
+ """The hostname or IP address of the server to connect to."""
52
+
53
+
54
+ class Server:
55
+ """Encapsulates access to the Sun lab BioHPC processing server.
56
+
57
+ This class provides the API that allows accessing the BioHPC server to create and submit various SLURM-managed jobs
58
+ to the server. It functions as the central interface used by all processing pipelines in the lab to execute costly
59
+ data processing on the server.
60
+
61
+ Notes:
62
+ All lab processing pipelines expect the data to be stored on the server and all processing logic to be packaged
63
+ and installed into dedicated conda environments on the server.
64
+
65
+ This class assumes that the target server has SLURM job manager installed and accessible to the user whose
66
+ credentials are used to connect to the server as part of this class instantiation.
67
+
68
+ Args:
69
+ credentials_path: The path to the locally stored .yaml file that contains the server hostname and access
70
+ credentials.
71
+
72
+ Attributes:
73
+ _open: Tracks whether the connection to the server is open or not.
74
+ _client: Stores the initialized SSHClient instance used to interface with the server.
75
+ """
76
+
77
+ def __init__(self, credentials_path: Path) -> None:
78
+ # Tracker used to prevent __del__ from classing stop() for a partially initialized class.
79
+ self._open: bool = False
80
+
81
+ # Loads the credentials from the provided .yaml file
82
+ self._credentials: ServerCredentials = ServerCredentials.from_yaml(credentials_path) # type: ignore
83
+
84
+ # Establishes the SSH connection to the specified processing server. At most, attempts to connect to the server
85
+ # 30 times before terminating with an error
86
+ attempt = 0
87
+ while True:
88
+ console.echo(
89
+ f"Trying to connect to {self._credentials.host} (attempt {attempt}/30)...", level=LogLevel.INFO
90
+ )
91
+ try:
92
+ self._client: SSHClient = paramiko.SSHClient()
93
+ self._client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
94
+ self._client.connect(
95
+ self._credentials.host, username=self._credentials.username, password=self._credentials.password
96
+ )
97
+ console.echo(f"Connected to {self._credentials.host}", level=LogLevel.SUCCESS)
98
+ break
99
+ except paramiko.AuthenticationException:
100
+ message = (
101
+ f"Authentication failed when connecting to {self._credentials.host} using "
102
+ f"{self._credentials.username} user."
103
+ )
104
+ console.error(message, RuntimeError)
105
+ raise RuntimeError
106
+ except:
107
+ if attempt == 30:
108
+ message = f"Could not connect to {self._credentials.host} after 30 attempts. Aborting runtime."
109
+ console.error(message, RuntimeError)
110
+ raise RuntimeError
111
+
112
+ console.echo(
113
+ f"Could not SSH to {self._credentials.host}, retrying after a 2-second delay...",
114
+ level=LogLevel.WARNING,
115
+ )
116
+ attempt += 1
117
+ time.sleep(2)
118
+
119
+ def __del__(self) -> None:
120
+ """If the instance is connected to the server, terminates the connection before the instance is destroyed."""
121
+ self.close()
122
+
123
+ def submit_job(self, job: Job) -> Job:
124
+ """Submits the input job to the managed BioHPC server via SLURM job manager.
125
+
126
+ This method submits various jobs for execution via SLURM-managed BioHPC cluster. As part of its runtime, the
127
+ method translates the Job object into the shell script, moves the script to the target working directory on
128
+ the server, and instructs the server to execute the shell script (via SLURM).
129
+
130
+ Args:
131
+ job: The Job object that contains all job data.
132
+
133
+ Returns:
134
+ The job object whose 'job_id' attribute had been modified with the job ID, if the job was successfully
135
+ submitted.
136
+
137
+ Raises:
138
+ RuntimeError: If job submission to the server fails.
139
+ """
140
+
141
+ # Generates a temporary shell script on the local machine. Uses tempfile to automatically remove the
142
+ # local script as soon as it is uploaded to the server.
143
+ with tempfile.TemporaryDirectory() as temp_dir:
144
+ local_script_path = Path(temp_dir).joinpath(f"{job.job_name}.sh")
145
+ fixed_script_content = job.command_script
146
+
147
+ # Creates a temporary script file locally and dumps translated command data into the file
148
+ with open(local_script_path, "w") as f:
149
+ f.write(fixed_script_content)
150
+
151
+ # Uploads the command script to the server
152
+ sftp = self._client.open_sftp()
153
+ sftp.put(localpath=local_script_path, remotepath=job.remote_script_path)
154
+ sftp.close()
155
+
156
+ # Makes the server-side script executable
157
+ self._client.exec_command(f"chmod +x {job.remote_script_path}")
158
+
159
+ # Submits the job to SLURM with sbatch and verifies submission state
160
+ job_output = self._client.exec_command(f"sbatch {job.remote_script_path}")[1].read().strip().decode()
161
+
162
+ # If batch_job is not in the output received from SLURM in response to issuing the submission command, raises an
163
+ # error.
164
+ if "Submitted batch job" not in job_output:
165
+ message = f"Failed to submit the {job.job_name} job to the BioHPC cluster."
166
+ console.error(message, RuntimeError)
167
+
168
+ # Fallback to appease mypy, should not be reachable
169
+ raise RuntimeError(message)
170
+
171
+ # Otherwise, extracts the job id assigned to the job by SLURM from the response and writes it to the processed
172
+ # Job object
173
+ job_id = job_output.split()[-1]
174
+ job.job_id = job_id
175
+ return job
176
+
177
+ def job_complete(self, job: Job) -> bool:
178
+ """Returns True if the job managed by the input Job instance has been completed or terminated its runtime due
179
+ to an error.
180
+
181
+ If the job is still running or is waiting inside the execution queue, returns False.
182
+
183
+ Args:
184
+ job: The Job object whose status needs to be checked.
185
+
186
+ Raises:
187
+ ValueError: If the input Job object does not contain a valid job_id, suggesting that it has not been
188
+ submitted to the server.
189
+ """
190
+
191
+ if job.job_id is None:
192
+ message = (
193
+ f"The input Job object for the job {job.job_name} does not contain a valid job_id. This indicates that "
194
+ f"the job has not been submitted to the server."
195
+ )
196
+ console.error(message, ValueError)
197
+
198
+ # This is here to appease mypy, it should not be reachable
199
+ raise ValueError(message)
200
+
201
+ if job.job_id not in self._client.exec_command(f"squeue -j {job.job_id}")[1].read().decode().strip():
202
+ return True
203
+ else:
204
+ return False
205
+
206
+ def close(self) -> None:
207
+ """Closes the SSH connection to the server.
208
+
209
+ This method has to be called before destroying the class instance to ensure proper resource cleanup.
210
+ """
211
+ # Prevents closing already closed connections
212
+ if self._open:
213
+ self._client.close()
@@ -0,0 +1,95 @@
1
+ from pathlib import Path
2
+ from dataclasses import dataclass
3
+
4
+ from simple_slurm import Slurm as Slurm
5
+ from paramiko.client import SSHClient as SSHClient
6
+ from ataraxis_data_structures import YamlConfig
7
+
8
+ from .job import Job as Job
9
+
10
+ def generate_server_credentials(
11
+ output_directory: Path, username: str, password: str, host: str = "cbsuwsun.biohpc.cornell.edu"
12
+ ) -> None:
13
+ """Generates a new server_credentials.yaml file under the specified directory, using input information.
14
+
15
+ This function provides a convenience interface for generating new BioHPC server credential files. Generally, this is
16
+ only used when setting up new host-computers in the lab.
17
+ """
18
+ @dataclass()
19
+ class ServerCredentials(YamlConfig):
20
+ """This class stores the hostname and credentials used to log into the BioHPC cluster to run Sun lab processing
21
+ pipelines.
22
+
23
+ Primarily, this is used as part of the sl-experiment library runtime to start data processing once it is
24
+ transferred to the BioHPC server during preprocessing. However, the same file can be used together with the Server
25
+ class API to run any computation jobs on the lab's BioHPC server.
26
+ """
27
+
28
+ username: str = ...
29
+ password: str = ...
30
+ host: str = ...
31
+
32
+ class Server:
33
+ """Encapsulates access to the Sun lab BioHPC processing server.
34
+
35
+ This class provides the API that allows accessing the BioHPC server to create and submit various SLURM-managed jobs
36
+ to the server. It functions as the central interface used by all processing pipelines in the lab to execute costly
37
+ data processing on the server.
38
+
39
+ Notes:
40
+ All lab processing pipelines expect the data to be stored on the server and all processing logic to be packaged
41
+ and installed into dedicated conda environments on the server.
42
+
43
+ This class assumes that the target server has SLURM job manager installed and accessible to the user whose
44
+ credentials are used to connect to the server as part of this class instantiation.
45
+
46
+ Args:
47
+ credentials_path: The path to the locally stored .yaml file that contains the server hostname and access
48
+ credentials.
49
+
50
+ Attributes:
51
+ _open: Tracks whether the connection to the server is open or not.
52
+ _client: Stores the initialized SSHClient instance used to interface with the server.
53
+ """
54
+
55
+ _open: bool
56
+ _credentials: ServerCredentials
57
+ _client: SSHClient
58
+ def __init__(self, credentials_path: Path) -> None: ...
59
+ def __del__(self) -> None:
60
+ """If the instance is connected to the server, terminates the connection before the instance is destroyed."""
61
+ def submit_job(self, job: Job) -> Job:
62
+ """Submits the input job to the managed BioHPC server via SLURM job manager.
63
+
64
+ This method submits various jobs for execution via SLURM-managed BioHPC cluster. As part of its runtime, the
65
+ method translates the Job object into the shell script, moves the script to the target working directory on
66
+ the server, and instructs the server to execute the shell script (via SLURM).
67
+
68
+ Args:
69
+ job: The Job object that contains all job data.
70
+
71
+ Returns:
72
+ The job object whose 'job_id' attribute had been modified with the job ID, if the job was successfully
73
+ submitted.
74
+
75
+ Raises:
76
+ RuntimeError: If job submission to the server fails.
77
+ """
78
+ def job_complete(self, job: Job) -> bool:
79
+ """Returns True if the job managed by the input Job instance has been completed or terminated its runtime due
80
+ to an error.
81
+
82
+ If the job is still running or is waiting inside the execution queue, returns False.
83
+
84
+ Args:
85
+ job: The Job object whose status needs to be checked.
86
+
87
+ Raises:
88
+ ValueError: If the input Job object does not contain a valid job_id, suggesting that it has not been
89
+ submitted to the server.
90
+ """
91
+ def close(self) -> None:
92
+ """Closes the SSH connection to the server.
93
+
94
+ This method has to be called before destroying the class instance to ensure proper resource cleanup.
95
+ """
@@ -0,0 +1,8 @@
1
+ """This package provides the configuration classes used by the Sun lab maintained version of the suite2p library
2
+ (sl-suite2p package, https://github.com/Sun-Lab-NBB/suite2p) to process brain activity data within and across sessions
3
+ (days)."""
4
+
5
+ from .multi_day import MultiDayS2PConfiguration
6
+ from .single_day import SingleDayS2PConfiguration
7
+
8
+ __all__ = ["MultiDayS2PConfiguration", "SingleDayS2PConfiguration"]
@@ -0,0 +1,4 @@
1
+ from .multi_day import MultiDayS2PConfiguration as MultiDayS2PConfiguration
2
+ from .single_day import SingleDayS2PConfiguration as SingleDayS2PConfiguration
3
+
4
+ __all__ = ["MultiDayS2PConfiguration", "SingleDayS2PConfiguration"]