toil 9.1.1__py3-none-any.whl → 9.2.0__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.
- toil/__init__.py +5 -9
- toil/batchSystems/abstractBatchSystem.py +23 -22
- toil/batchSystems/abstractGridEngineBatchSystem.py +17 -12
- toil/batchSystems/awsBatch.py +8 -8
- toil/batchSystems/cleanup_support.py +4 -4
- toil/batchSystems/contained_executor.py +3 -3
- toil/batchSystems/gridengine.py +3 -4
- toil/batchSystems/htcondor.py +5 -5
- toil/batchSystems/kubernetes.py +65 -63
- toil/batchSystems/local_support.py +2 -3
- toil/batchSystems/lsf.py +6 -7
- toil/batchSystems/mesos/batchSystem.py +11 -7
- toil/batchSystems/mesos/test/__init__.py +1 -2
- toil/batchSystems/options.py +9 -10
- toil/batchSystems/registry.py +3 -7
- toil/batchSystems/singleMachine.py +8 -11
- toil/batchSystems/slurm.py +49 -38
- toil/batchSystems/torque.py +3 -4
- toil/bus.py +36 -34
- toil/common.py +129 -89
- toil/cwl/cwltoil.py +857 -729
- toil/cwl/utils.py +44 -35
- toil/fileStores/__init__.py +3 -1
- toil/fileStores/abstractFileStore.py +28 -30
- toil/fileStores/cachingFileStore.py +8 -8
- toil/fileStores/nonCachingFileStore.py +10 -21
- toil/job.py +159 -158
- toil/jobStores/abstractJobStore.py +68 -69
- toil/jobStores/aws/jobStore.py +249 -213
- toil/jobStores/aws/utils.py +13 -24
- toil/jobStores/fileJobStore.py +28 -22
- toil/jobStores/googleJobStore.py +21 -17
- toil/jobStores/utils.py +3 -7
- toil/leader.py +17 -22
- toil/lib/accelerators.py +6 -4
- toil/lib/aws/__init__.py +9 -10
- toil/lib/aws/ami.py +33 -19
- toil/lib/aws/iam.py +6 -6
- toil/lib/aws/s3.py +259 -157
- toil/lib/aws/session.py +76 -76
- toil/lib/aws/utils.py +51 -43
- toil/lib/checksum.py +19 -15
- toil/lib/compatibility.py +3 -2
- toil/lib/conversions.py +45 -18
- toil/lib/directory.py +29 -26
- toil/lib/docker.py +93 -99
- toil/lib/dockstore.py +77 -50
- toil/lib/ec2.py +39 -38
- toil/lib/ec2nodes.py +11 -4
- toil/lib/exceptions.py +8 -5
- toil/lib/ftp_utils.py +9 -14
- toil/lib/generatedEC2Lists.py +161 -20
- toil/lib/history.py +141 -97
- toil/lib/history_submission.py +163 -72
- toil/lib/io.py +27 -17
- toil/lib/memoize.py +2 -1
- toil/lib/misc.py +15 -11
- toil/lib/pipes.py +40 -25
- toil/lib/plugins.py +12 -8
- toil/lib/resources.py +1 -0
- toil/lib/retry.py +32 -38
- toil/lib/threading.py +12 -12
- toil/lib/throttle.py +1 -2
- toil/lib/trs.py +113 -51
- toil/lib/url.py +14 -23
- toil/lib/web.py +7 -2
- toil/options/common.py +18 -15
- toil/options/cwl.py +2 -2
- toil/options/runner.py +9 -5
- toil/options/wdl.py +1 -3
- toil/provisioners/__init__.py +9 -9
- toil/provisioners/abstractProvisioner.py +22 -20
- toil/provisioners/aws/__init__.py +20 -14
- toil/provisioners/aws/awsProvisioner.py +10 -8
- toil/provisioners/clusterScaler.py +19 -18
- toil/provisioners/gceProvisioner.py +2 -3
- toil/provisioners/node.py +11 -13
- toil/realtimeLogger.py +4 -4
- toil/resource.py +5 -5
- toil/server/app.py +2 -2
- toil/server/cli/wes_cwl_runner.py +11 -11
- toil/server/utils.py +18 -21
- toil/server/wes/abstract_backend.py +9 -8
- toil/server/wes/amazon_wes_utils.py +3 -3
- toil/server/wes/tasks.py +3 -5
- toil/server/wes/toil_backend.py +17 -21
- toil/server/wsgi_app.py +3 -3
- toil/serviceManager.py +3 -4
- toil/statsAndLogging.py +12 -13
- toil/test/__init__.py +33 -24
- toil/test/batchSystems/batchSystemTest.py +12 -11
- toil/test/batchSystems/batch_system_plugin_test.py +3 -5
- toil/test/batchSystems/test_slurm.py +38 -24
- toil/test/cwl/conftest.py +5 -6
- toil/test/cwl/cwlTest.py +194 -78
- toil/test/cwl/download_file_uri.json +6 -0
- toil/test/cwl/download_file_uri_no_hostname.json +6 -0
- toil/test/docs/scripts/tutorial_staging.py +1 -0
- toil/test/jobStores/jobStoreTest.py +9 -7
- toil/test/lib/aws/test_iam.py +1 -3
- toil/test/lib/aws/test_s3.py +1 -1
- toil/test/lib/dockerTest.py +9 -9
- toil/test/lib/test_ec2.py +12 -11
- toil/test/lib/test_history.py +4 -4
- toil/test/lib/test_trs.py +16 -14
- toil/test/lib/test_url.py +7 -6
- toil/test/lib/url_plugin_test.py +12 -18
- toil/test/provisioners/aws/awsProvisionerTest.py +10 -8
- toil/test/provisioners/clusterScalerTest.py +2 -5
- toil/test/provisioners/clusterTest.py +1 -3
- toil/test/server/serverTest.py +13 -4
- toil/test/sort/restart_sort.py +2 -6
- toil/test/sort/sort.py +3 -8
- toil/test/src/deferredFunctionTest.py +7 -7
- toil/test/src/environmentTest.py +1 -2
- toil/test/src/fileStoreTest.py +5 -5
- toil/test/src/importExportFileTest.py +5 -6
- toil/test/src/jobServiceTest.py +22 -14
- toil/test/src/jobTest.py +121 -25
- toil/test/src/miscTests.py +5 -7
- toil/test/src/promisedRequirementTest.py +8 -7
- toil/test/src/regularLogTest.py +2 -3
- toil/test/src/resourceTest.py +5 -8
- toil/test/src/restartDAGTest.py +5 -6
- toil/test/src/resumabilityTest.py +2 -2
- toil/test/src/retainTempDirTest.py +3 -3
- toil/test/src/systemTest.py +3 -3
- toil/test/src/threadingTest.py +1 -1
- toil/test/src/workerTest.py +1 -2
- toil/test/utils/toilDebugTest.py +6 -4
- toil/test/utils/toilKillTest.py +1 -1
- toil/test/utils/utilsTest.py +15 -14
- toil/test/wdl/wdltoil_test.py +247 -124
- toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
- toil/toilState.py +2 -3
- toil/utils/toilDebugFile.py +3 -8
- toil/utils/toilDebugJob.py +1 -2
- toil/utils/toilLaunchCluster.py +1 -2
- toil/utils/toilSshCluster.py +2 -0
- toil/utils/toilStats.py +19 -24
- toil/utils/toilStatus.py +11 -14
- toil/version.py +10 -10
- toil/wdl/wdltoil.py +313 -209
- toil/worker.py +18 -12
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/METADATA +11 -14
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/RECORD +150 -153
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/WHEEL +1 -1
- toil/test/cwl/staging_cat.cwl +0 -27
- toil/test/cwl/staging_make_file.cwl +0 -25
- toil/test/cwl/staging_workflow.cwl +0 -43
- toil/test/cwl/zero_default.cwl +0 -61
- toil/test/utils/ABCWorkflowDebug/ABC.txt +0 -1
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/entry_points.txt +0 -0
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/licenses/LICENSE +0 -0
- {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/top_level.txt +0 -0
toil/__init__.py
CHANGED
|
@@ -16,14 +16,11 @@ import os
|
|
|
16
16
|
import re
|
|
17
17
|
import socket
|
|
18
18
|
import sys
|
|
19
|
-
from
|
|
20
|
-
from typing import TYPE_CHECKING, Optional
|
|
21
|
-
|
|
22
|
-
from toil.lib.web import web_session
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
23
20
|
|
|
24
21
|
from docker.errors import ImageNotFound
|
|
25
22
|
from toil.lib.memoize import memoize
|
|
26
|
-
from toil.lib.
|
|
23
|
+
from toil.lib.web import web_session
|
|
27
24
|
from toil.version import currentCommit
|
|
28
25
|
|
|
29
26
|
if TYPE_CHECKING:
|
|
@@ -32,7 +29,7 @@ if TYPE_CHECKING:
|
|
|
32
29
|
log = logging.getLogger(__name__)
|
|
33
30
|
|
|
34
31
|
|
|
35
|
-
def which(cmd, mode=os.F_OK | os.X_OK, path=None) ->
|
|
32
|
+
def which(cmd, mode=os.F_OK | os.X_OK, path=None) -> str | None:
|
|
36
33
|
"""
|
|
37
34
|
Return the path with conforms to the given mode on the Path.
|
|
38
35
|
|
|
@@ -355,11 +352,11 @@ def parseDockerAppliance(appliance: str) -> tuple[str, str, str]:
|
|
|
355
352
|
def checkDockerSchema(appliance):
|
|
356
353
|
if not appliance:
|
|
357
354
|
raise ImageNotFound("No docker image specified.")
|
|
358
|
-
|
|
355
|
+
if "://" in appliance:
|
|
359
356
|
raise ImageNotFound(
|
|
360
357
|
"Docker images cannot contain a schema (such as '://'): %s" "" % appliance
|
|
361
358
|
)
|
|
362
|
-
|
|
359
|
+
if len(appliance) > 256:
|
|
363
360
|
raise ImageNotFound(
|
|
364
361
|
"Docker image must be less than 256 chars: %s" "" % appliance
|
|
365
362
|
)
|
|
@@ -479,4 +476,3 @@ def logProcessContext(config: "Config") -> None:
|
|
|
479
476
|
|
|
480
477
|
log.info("Running Toil version %s on host %s.", version, socket.gethostname())
|
|
481
478
|
log.debug("Configuration: %s", config.__dict__)
|
|
482
|
-
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
from dataclasses import dataclass
|
|
15
14
|
import enum
|
|
16
15
|
import logging
|
|
17
16
|
import os
|
|
@@ -21,8 +20,9 @@ from abc import ABC, abstractmethod
|
|
|
21
20
|
from argparse import ArgumentParser, _ArgumentGroup
|
|
22
21
|
from collections.abc import Iterator
|
|
23
22
|
from contextlib import contextmanager
|
|
23
|
+
from dataclasses import dataclass
|
|
24
24
|
from threading import Condition
|
|
25
|
-
from typing import Any, ContextManager, NamedTuple,
|
|
25
|
+
from typing import Any, ContextManager, NamedTuple, cast
|
|
26
26
|
|
|
27
27
|
from toil.batchSystems.options import OptionSetter
|
|
28
28
|
from toil.bus import MessageBus, MessageOutbox
|
|
@@ -73,6 +73,7 @@ class BatchJobExitReason(enum.IntEnum):
|
|
|
73
73
|
except ValueError:
|
|
74
74
|
return str(value)
|
|
75
75
|
|
|
76
|
+
|
|
76
77
|
@dataclass
|
|
77
78
|
class UpdatedBatchJobInfo:
|
|
78
79
|
jobID: int
|
|
@@ -87,9 +88,9 @@ class UpdatedBatchJobInfo:
|
|
|
87
88
|
(e.g. job is lost, or otherwise died but actual exit code was not reported).
|
|
88
89
|
"""
|
|
89
90
|
|
|
90
|
-
exitReason:
|
|
91
|
-
wallTime:
|
|
92
|
-
backing_id:
|
|
91
|
+
exitReason: BatchJobExitReason | None = None
|
|
92
|
+
wallTime: float | int | None = None
|
|
93
|
+
backing_id: str | None = None
|
|
93
94
|
"""
|
|
94
95
|
The identifier for the job in the backing scheduler, if available.
|
|
95
96
|
"""
|
|
@@ -97,10 +98,10 @@ class UpdatedBatchJobInfo:
|
|
|
97
98
|
|
|
98
99
|
# Information required for worker cleanup on shutdown of the batch system.
|
|
99
100
|
class WorkerCleanupInfo(NamedTuple):
|
|
100
|
-
work_dir:
|
|
101
|
+
work_dir: str | None
|
|
101
102
|
"""Work directory path (where the cache would go) if specified by user"""
|
|
102
103
|
|
|
103
|
-
coordination_dir:
|
|
104
|
+
coordination_dir: str | None
|
|
104
105
|
"""Coordination directory path (where lock files would go) if specified by user"""
|
|
105
106
|
|
|
106
107
|
workflow_id: str
|
|
@@ -171,7 +172,7 @@ class AbstractBatchSystem(ABC):
|
|
|
171
172
|
self,
|
|
172
173
|
command: str,
|
|
173
174
|
job_desc: JobDescription,
|
|
174
|
-
job_environment:
|
|
175
|
+
job_environment: dict[str, str] | None = None,
|
|
175
176
|
) -> int:
|
|
176
177
|
"""
|
|
177
178
|
Issues a job with the specified command to the batch system and returns
|
|
@@ -224,7 +225,7 @@ class AbstractBatchSystem(ABC):
|
|
|
224
225
|
raise NotImplementedError()
|
|
225
226
|
|
|
226
227
|
@abstractmethod
|
|
227
|
-
def getUpdatedBatchJob(self, maxWait: int) ->
|
|
228
|
+
def getUpdatedBatchJob(self, maxWait: int) -> UpdatedBatchJobInfo | None:
|
|
228
229
|
"""
|
|
229
230
|
Returns information about job that has updated its status (i.e. ceased
|
|
230
231
|
running, either successfully or with an error). Each such job will be
|
|
@@ -242,7 +243,7 @@ class AbstractBatchSystem(ABC):
|
|
|
242
243
|
"""
|
|
243
244
|
raise NotImplementedError()
|
|
244
245
|
|
|
245
|
-
def getSchedulingStatusMessage(self) ->
|
|
246
|
+
def getSchedulingStatusMessage(self) -> str | None:
|
|
246
247
|
"""
|
|
247
248
|
Get a log message fragment for the user about anything that might be
|
|
248
249
|
going wrong in the batch system, if available.
|
|
@@ -269,7 +270,7 @@ class AbstractBatchSystem(ABC):
|
|
|
269
270
|
"""
|
|
270
271
|
raise NotImplementedError()
|
|
271
272
|
|
|
272
|
-
def setEnv(self, name: str, value:
|
|
273
|
+
def setEnv(self, name: str, value: str | None = None) -> None:
|
|
273
274
|
"""
|
|
274
275
|
Set an environment variable for the worker process before it is launched.
|
|
275
276
|
|
|
@@ -286,7 +287,7 @@ class AbstractBatchSystem(ABC):
|
|
|
286
287
|
raise NotImplementedError()
|
|
287
288
|
|
|
288
289
|
@classmethod
|
|
289
|
-
def add_options(cls, parser:
|
|
290
|
+
def add_options(cls, parser: ArgumentParser | _ArgumentGroup) -> None:
|
|
290
291
|
"""
|
|
291
292
|
If this batch system provides any command line options, add them to the given parser.
|
|
292
293
|
"""
|
|
@@ -351,7 +352,7 @@ class BatchSystemSupport(AbstractBatchSystem):
|
|
|
351
352
|
workflow_id=config.workflowID,
|
|
352
353
|
clean_work_dir=config.cleanWorkDir,
|
|
353
354
|
)
|
|
354
|
-
self._outbox:
|
|
355
|
+
self._outbox: MessageOutbox | None = None
|
|
355
356
|
|
|
356
357
|
def check_resource_request(self, requirer: Requirer) -> None:
|
|
357
358
|
"""
|
|
@@ -400,7 +401,7 @@ class BatchSystemSupport(AbstractBatchSystem):
|
|
|
400
401
|
details=["The batch system does not support any accelerators."],
|
|
401
402
|
)
|
|
402
403
|
|
|
403
|
-
def setEnv(self, name: str, value:
|
|
404
|
+
def setEnv(self, name: str, value: str | None = None) -> None:
|
|
404
405
|
"""
|
|
405
406
|
Set an environment variable for the worker process before it is launched. The worker
|
|
406
407
|
process will typically inherit the environment of the machine it is running on but this
|
|
@@ -572,7 +573,7 @@ class AbstractScalableBatchSystem(AbstractBatchSystem):
|
|
|
572
573
|
|
|
573
574
|
@abstractmethod
|
|
574
575
|
def getNodes(
|
|
575
|
-
self, preemptible:
|
|
576
|
+
self, preemptible: bool | None = None, timeout: int = 600
|
|
576
577
|
) -> dict[str, NodeInfo]:
|
|
577
578
|
"""
|
|
578
579
|
Returns a dictionary mapping node identifiers of preemptible or non-preemptible nodes to
|
|
@@ -622,9 +623,9 @@ class InsufficientSystemResources(Exception):
|
|
|
622
623
|
self,
|
|
623
624
|
requirer: Requirer,
|
|
624
625
|
resource: str,
|
|
625
|
-
available:
|
|
626
|
-
batch_system:
|
|
627
|
-
source:
|
|
626
|
+
available: ParsedRequirement | None = None,
|
|
627
|
+
batch_system: str | None = None,
|
|
628
|
+
source: str | None = None,
|
|
628
629
|
details: list[str] = [],
|
|
629
630
|
) -> None:
|
|
630
631
|
"""
|
|
@@ -639,7 +640,7 @@ class InsufficientSystemResources(Exception):
|
|
|
639
640
|
:param details: Any extra details about the problem that can be attached to the error.
|
|
640
641
|
"""
|
|
641
642
|
|
|
642
|
-
self.job_name:
|
|
643
|
+
self.job_name: str | None = str(requirer)
|
|
643
644
|
self.resource = resource
|
|
644
645
|
self.requested = cast(ParsedRequirement, getattr(requirer, resource))
|
|
645
646
|
self.available = available
|
|
@@ -655,7 +656,7 @@ class InsufficientSystemResources(Exception):
|
|
|
655
656
|
unit = "bytes of " if self.resource in ("disk", "memory") else ""
|
|
656
657
|
purpose = " for temporary space" if self.resource == "disk" else ""
|
|
657
658
|
qualifier = (
|
|
658
|
-
" free on {self.source}"
|
|
659
|
+
f" free on {self.source}"
|
|
659
660
|
if self.resource == "disk" and self.source is not None
|
|
660
661
|
else ""
|
|
661
662
|
)
|
|
@@ -695,8 +696,8 @@ class AcquisitionTimeoutException(Exception):
|
|
|
695
696
|
def __init__(
|
|
696
697
|
self,
|
|
697
698
|
resource: str,
|
|
698
|
-
requested:
|
|
699
|
-
available:
|
|
699
|
+
requested: int | float | set[int],
|
|
700
|
+
available: int | float | set[int],
|
|
700
701
|
) -> None:
|
|
701
702
|
"""
|
|
702
703
|
Creates an instance of this exception that indicates which resource is insufficient for
|
|
@@ -17,7 +17,6 @@ from abc import ABCMeta, abstractmethod
|
|
|
17
17
|
from datetime import datetime
|
|
18
18
|
from queue import Empty, Queue
|
|
19
19
|
from threading import Lock, Thread
|
|
20
|
-
from typing import Optional, Union
|
|
21
20
|
|
|
22
21
|
from toil.batchSystems.abstractBatchSystem import (
|
|
23
22
|
BatchJobExitReason,
|
|
@@ -27,9 +26,9 @@ from toil.batchSystems.cleanup_support import BatchSystemCleanupSupport
|
|
|
27
26
|
from toil.bus import ExternalBatchIdMessage, get_job_kind
|
|
28
27
|
from toil.common import Config
|
|
29
28
|
from toil.job import AcceleratorRequirement, JobDescription
|
|
30
|
-
from toil.statsAndLogging import TRACE
|
|
31
29
|
from toil.lib.misc import CalledProcessErrorStderr
|
|
32
30
|
from toil.lib.retry import DEFAULT_DELAYS, old_retry
|
|
31
|
+
from toil.statsAndLogging import TRACE
|
|
33
32
|
|
|
34
33
|
logger = logging.getLogger(__name__)
|
|
35
34
|
|
|
@@ -172,7 +171,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
172
171
|
"Job %s with batch system ID %s queued as job %s",
|
|
173
172
|
jobName,
|
|
174
173
|
jobID,
|
|
175
|
-
str(batchJobID)
|
|
174
|
+
str(batchJobID),
|
|
176
175
|
)
|
|
177
176
|
|
|
178
177
|
# Store dict for mapping Toil job ID to batch job ID
|
|
@@ -258,8 +257,12 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
258
257
|
self.coalesce_job_exit_codes, batch_job_id_list
|
|
259
258
|
)
|
|
260
259
|
# We got the statuses as a batch
|
|
261
|
-
for running_job_id, status, backing_id in zip(
|
|
262
|
-
|
|
260
|
+
for running_job_id, status, backing_id in zip(
|
|
261
|
+
running_job_list, statuses, batch_job_id_list
|
|
262
|
+
):
|
|
263
|
+
activity = self._handle_job_status(
|
|
264
|
+
running_job_id, status, activity, backing_id
|
|
265
|
+
)
|
|
263
266
|
|
|
264
267
|
self._checkOnJobsCache = activity
|
|
265
268
|
self._checkOnJobsTimestamp = datetime.now()
|
|
@@ -268,7 +271,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
268
271
|
def _handle_job_status(
|
|
269
272
|
self,
|
|
270
273
|
job_id: int,
|
|
271
|
-
status:
|
|
274
|
+
status: int | tuple[int, BatchJobExitReason | None] | None,
|
|
272
275
|
activity: bool,
|
|
273
276
|
backing_id: str,
|
|
274
277
|
) -> bool:
|
|
@@ -313,7 +316,9 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
313
316
|
if self.checkOnJobs():
|
|
314
317
|
activity = True
|
|
315
318
|
if not activity:
|
|
316
|
-
logger.log(
|
|
319
|
+
logger.log(
|
|
320
|
+
TRACE, "No activity, sleeping for %is", self.boss.sleepSeconds()
|
|
321
|
+
)
|
|
317
322
|
return True
|
|
318
323
|
|
|
319
324
|
def run(self):
|
|
@@ -332,7 +337,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
332
337
|
|
|
333
338
|
def coalesce_job_exit_codes(
|
|
334
339
|
self, batch_job_id_list: list
|
|
335
|
-
) -> list[
|
|
340
|
+
) -> list[int | tuple[int, BatchJobExitReason | None] | None]:
|
|
336
341
|
"""
|
|
337
342
|
Returns exit codes and possibly exit reasons for a list of jobs, or None if they are running.
|
|
338
343
|
|
|
@@ -362,8 +367,8 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
362
367
|
jobID: int,
|
|
363
368
|
command: str,
|
|
364
369
|
jobName: str,
|
|
365
|
-
job_environment:
|
|
366
|
-
gpus:
|
|
370
|
+
job_environment: dict[str, str] | None = None,
|
|
371
|
+
gpus: int | None = None,
|
|
367
372
|
) -> list[str]:
|
|
368
373
|
"""
|
|
369
374
|
Preparation in putting together a command-line string
|
|
@@ -416,7 +421,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
416
421
|
@abstractmethod
|
|
417
422
|
def getJobExitCode(
|
|
418
423
|
self, batchJobID
|
|
419
|
-
) ->
|
|
424
|
+
) -> int | tuple[int, BatchJobExitReason | None] | None:
|
|
420
425
|
"""
|
|
421
426
|
Returns job exit code and possibly an instance of abstractBatchSystem.BatchJobExitReason.
|
|
422
427
|
|
|
@@ -478,7 +483,7 @@ class AbstractGridEngineBatchSystem(BatchSystemCleanupSupport):
|
|
|
478
483
|
self,
|
|
479
484
|
command: str,
|
|
480
485
|
job_desc: JobDescription,
|
|
481
|
-
job_environment:
|
|
486
|
+
job_environment: dict[str, str] | None = None,
|
|
482
487
|
):
|
|
483
488
|
# Avoid submitting internal jobs to the batch queue, handle locally
|
|
484
489
|
local_id = self.handleLocalJob(command, job_desc)
|
toil/batchSystems/awsBatch.py
CHANGED
|
@@ -35,7 +35,7 @@ import time
|
|
|
35
35
|
import uuid
|
|
36
36
|
from argparse import ArgumentParser, _ArgumentGroup
|
|
37
37
|
from collections.abc import Iterator
|
|
38
|
-
from typing import Any
|
|
38
|
+
from typing import Any
|
|
39
39
|
|
|
40
40
|
from botocore.exceptions import ClientError
|
|
41
41
|
|
|
@@ -137,7 +137,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
137
137
|
# is managed by the BatchSystemLocalSupport.
|
|
138
138
|
|
|
139
139
|
# Here is where we will store the user script resource object if we get one.
|
|
140
|
-
self.user_script:
|
|
140
|
+
self.user_script: Resource | None = None
|
|
141
141
|
|
|
142
142
|
# Get the image to deploy from Toil's configuration
|
|
143
143
|
self.docker_image = applianceSelf()
|
|
@@ -145,7 +145,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
145
145
|
# We can't use AWS Batch without a job definition. But we can use one
|
|
146
146
|
# of them for all the jobs. We want to lazily initialize it. This will
|
|
147
147
|
# be an ARN.
|
|
148
|
-
self.job_definition:
|
|
148
|
+
self.job_definition: str | None = None
|
|
149
149
|
|
|
150
150
|
# We need a way to map between our batch system ID numbers, and AWS Batch job IDs from the server.
|
|
151
151
|
self.bs_id_to_aws_id: dict[int, str] = {}
|
|
@@ -179,7 +179,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
179
179
|
self,
|
|
180
180
|
command: str,
|
|
181
181
|
job_desc: JobDescription,
|
|
182
|
-
job_environment:
|
|
182
|
+
job_environment: dict[str, str] | None = None,
|
|
183
183
|
) -> int:
|
|
184
184
|
# Try the job as local
|
|
185
185
|
local_id = self.handleLocalJob(command, job_desc)
|
|
@@ -298,7 +298,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
298
298
|
# And re-compose them into a string
|
|
299
299
|
return "".join(kept_chars)
|
|
300
300
|
|
|
301
|
-
def _get_runtime(self, job_detail: dict[str, Any]) ->
|
|
301
|
+
def _get_runtime(self, job_detail: dict[str, Any]) -> float | None:
|
|
302
302
|
"""
|
|
303
303
|
Internal function. Should not be called outside this class.
|
|
304
304
|
|
|
@@ -349,7 +349,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
349
349
|
)
|
|
350
350
|
)
|
|
351
351
|
|
|
352
|
-
def getUpdatedBatchJob(self, maxWait: int) ->
|
|
352
|
+
def getUpdatedBatchJob(self, maxWait: int) -> UpdatedBatchJobInfo | None:
|
|
353
353
|
# Remember when we started, for respecting the timeout
|
|
354
354
|
entry = datetime.datetime.now()
|
|
355
355
|
while (
|
|
@@ -494,7 +494,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
494
494
|
if self.job_definition is None:
|
|
495
495
|
# First work out what volume mounts to make, because the type
|
|
496
496
|
# system is happiest this way
|
|
497
|
-
volumes: list[dict[str,
|
|
497
|
+
volumes: list[dict[str, str | dict[str, str]]] = []
|
|
498
498
|
mount_points: list[dict[str, str]] = []
|
|
499
499
|
for i, shared_path in enumerate(
|
|
500
500
|
{
|
|
@@ -650,7 +650,7 @@ class AWSBatchBatchSystem(BatchSystemCleanupSupport):
|
|
|
650
650
|
self._wait_until_stopped(self.bs_id_to_aws_id[bs_id])
|
|
651
651
|
|
|
652
652
|
@classmethod
|
|
653
|
-
def add_options(cls, parser:
|
|
653
|
+
def add_options(cls, parser: ArgumentParser | _ArgumentGroup) -> None:
|
|
654
654
|
parser.add_argument(
|
|
655
655
|
"--awsBatchRegion",
|
|
656
656
|
dest="aws_batch_region",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import logging
|
|
15
15
|
from types import TracebackType
|
|
16
|
-
from typing import Any, ContextManager
|
|
16
|
+
from typing import Any, ContextManager
|
|
17
17
|
|
|
18
18
|
from toil.batchSystems.abstractBatchSystem import BatchSystemSupport, WorkerCleanupInfo
|
|
19
19
|
from toil.batchSystems.local_support import BatchSystemLocalSupport
|
|
@@ -89,9 +89,9 @@ class WorkerCleanupContext:
|
|
|
89
89
|
# that is always falsey but claims to return a bool is an error.
|
|
90
90
|
def __exit__(
|
|
91
91
|
self,
|
|
92
|
-
type:
|
|
93
|
-
value:
|
|
94
|
-
traceback:
|
|
92
|
+
type: type[BaseException] | None,
|
|
93
|
+
value: BaseException | None,
|
|
94
|
+
traceback: TracebackType | None,
|
|
95
95
|
) -> None:
|
|
96
96
|
logger.debug("Leaving cleanup arena")
|
|
97
97
|
for _ in self.arena.leave():
|
|
@@ -22,7 +22,7 @@ import os
|
|
|
22
22
|
import pickle
|
|
23
23
|
import subprocess
|
|
24
24
|
import sys
|
|
25
|
-
from typing import Any
|
|
25
|
+
from typing import Any
|
|
26
26
|
|
|
27
27
|
from toil.batchSystems.abstractBatchSystem import EXIT_STATUS_UNAVAILABLE_VALUE
|
|
28
28
|
from toil.resource import Resource
|
|
@@ -33,8 +33,8 @@ logger = logging.getLogger(__name__)
|
|
|
33
33
|
|
|
34
34
|
def pack_job(
|
|
35
35
|
command: str,
|
|
36
|
-
user_script:
|
|
37
|
-
environment:
|
|
36
|
+
user_script: Resource | None = None,
|
|
37
|
+
environment: dict[str, str] | None = None,
|
|
38
38
|
) -> list[str]:
|
|
39
39
|
"""
|
|
40
40
|
Create a command that runs the given command in an environment.
|
toil/batchSystems/gridengine.py
CHANGED
|
@@ -17,7 +17,6 @@ import os
|
|
|
17
17
|
import shlex
|
|
18
18
|
import time
|
|
19
19
|
from shlex import quote
|
|
20
|
-
from typing import Optional
|
|
21
20
|
|
|
22
21
|
from toil.batchSystems.abstractGridEngineBatchSystem import (
|
|
23
22
|
AbstractGridEngineBatchSystem,
|
|
@@ -62,8 +61,8 @@ class GridEngineBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
62
61
|
jobID: int,
|
|
63
62
|
command: str,
|
|
64
63
|
jobName: str,
|
|
65
|
-
job_environment:
|
|
66
|
-
gpus:
|
|
64
|
+
job_environment: dict[str, str] | None = None,
|
|
65
|
+
gpus: int | None = None,
|
|
67
66
|
):
|
|
68
67
|
# POSIX qsub
|
|
69
68
|
# <https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/qsub.html>
|
|
@@ -126,7 +125,7 @@ class GridEngineBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
126
125
|
cpu: int,
|
|
127
126
|
mem: int,
|
|
128
127
|
jobID: int,
|
|
129
|
-
job_environment:
|
|
128
|
+
job_environment: dict[str, str] | None = None,
|
|
130
129
|
) -> list[str]:
|
|
131
130
|
qsubline = [
|
|
132
131
|
"qsub",
|
toil/batchSystems/htcondor.py
CHANGED
|
@@ -18,7 +18,7 @@ import os
|
|
|
18
18
|
import time
|
|
19
19
|
from contextlib import contextmanager
|
|
20
20
|
from threading import Lock
|
|
21
|
-
from typing import Any
|
|
21
|
+
from typing import Any
|
|
22
22
|
|
|
23
23
|
import htcondor
|
|
24
24
|
|
|
@@ -355,7 +355,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
355
355
|
schedd.xquery(limit=0)
|
|
356
356
|
|
|
357
357
|
@retry(errors=[htcondor.HTCondorIOError])
|
|
358
|
-
def _get_schedd_address(self) ->
|
|
358
|
+
def _get_schedd_address(self) -> str | None:
|
|
359
359
|
"""
|
|
360
360
|
Get the HTCondor scheduler to connect to, or None for the local machine.
|
|
361
361
|
|
|
@@ -367,7 +367,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
367
367
|
schedd_name = os.getenv("TOIL_HTCONDOR_SCHEDD")
|
|
368
368
|
|
|
369
369
|
# Get the scheduler's address, if not local
|
|
370
|
-
schedd_ad:
|
|
370
|
+
schedd_ad: str | None = None
|
|
371
371
|
|
|
372
372
|
# If TOIL_HTCONDOR_ variables are set, use them to find the Schedd
|
|
373
373
|
if condor_host and schedd_name:
|
|
@@ -397,7 +397,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
397
397
|
return schedd_ad
|
|
398
398
|
|
|
399
399
|
@retry(errors=[htcondor.HTCondorIOError])
|
|
400
|
-
def _open_schedd_connection(self, schedd_ad:
|
|
400
|
+
def _open_schedd_connection(self, schedd_ad: str | None = None) -> Any:
|
|
401
401
|
"""
|
|
402
402
|
Open a connection to the htcondor schedd.
|
|
403
403
|
|
|
@@ -451,7 +451,7 @@ class HTCondorBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
451
451
|
|
|
452
452
|
# Override the issueBatchJob method so HTCondor can be given the disk request
|
|
453
453
|
def issueBatchJob(
|
|
454
|
-
self, command: str, jobNode, job_environment:
|
|
454
|
+
self, command: str, jobNode, job_environment: dict[str, str] | None = None
|
|
455
455
|
):
|
|
456
456
|
# Avoid submitting internal jobs to the batch queue, handle locally
|
|
457
457
|
localID = self.handleLocalJob(command, jobNode)
|