toil 7.0.0__py3-none-any.whl → 8.0.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 +121 -83
- toil/batchSystems/__init__.py +1 -0
- toil/batchSystems/abstractBatchSystem.py +137 -77
- toil/batchSystems/abstractGridEngineBatchSystem.py +211 -101
- toil/batchSystems/awsBatch.py +237 -128
- toil/batchSystems/cleanup_support.py +22 -16
- toil/batchSystems/contained_executor.py +30 -26
- toil/batchSystems/gridengine.py +85 -49
- toil/batchSystems/htcondor.py +164 -87
- toil/batchSystems/kubernetes.py +622 -386
- toil/batchSystems/local_support.py +17 -12
- toil/batchSystems/lsf.py +132 -79
- toil/batchSystems/lsfHelper.py +13 -11
- toil/batchSystems/mesos/__init__.py +41 -29
- toil/batchSystems/mesos/batchSystem.py +288 -149
- toil/batchSystems/mesos/executor.py +77 -49
- toil/batchSystems/mesos/test/__init__.py +31 -23
- toil/batchSystems/options.py +38 -29
- toil/batchSystems/registry.py +53 -19
- toil/batchSystems/singleMachine.py +293 -123
- toil/batchSystems/slurm.py +489 -137
- toil/batchSystems/torque.py +46 -32
- toil/bus.py +141 -73
- toil/common.py +630 -359
- toil/cwl/__init__.py +1 -1
- toil/cwl/cwltoil.py +1114 -532
- toil/cwl/utils.py +17 -22
- toil/deferred.py +62 -41
- toil/exceptions.py +5 -3
- toil/fileStores/__init__.py +5 -5
- toil/fileStores/abstractFileStore.py +88 -57
- toil/fileStores/cachingFileStore.py +711 -247
- toil/fileStores/nonCachingFileStore.py +113 -75
- toil/job.py +988 -315
- toil/jobStores/abstractJobStore.py +387 -243
- toil/jobStores/aws/jobStore.py +727 -403
- toil/jobStores/aws/utils.py +161 -109
- toil/jobStores/conftest.py +1 -0
- toil/jobStores/fileJobStore.py +289 -151
- toil/jobStores/googleJobStore.py +137 -70
- toil/jobStores/utils.py +36 -15
- toil/leader.py +614 -269
- toil/lib/accelerators.py +115 -18
- toil/lib/aws/__init__.py +55 -28
- toil/lib/aws/ami.py +122 -87
- toil/lib/aws/iam.py +284 -108
- toil/lib/aws/s3.py +31 -0
- toil/lib/aws/session.py +193 -58
- toil/lib/aws/utils.py +238 -218
- toil/lib/bioio.py +13 -5
- toil/lib/compatibility.py +11 -6
- toil/lib/conversions.py +83 -49
- toil/lib/docker.py +131 -103
- toil/lib/ec2.py +322 -209
- toil/lib/ec2nodes.py +174 -106
- toil/lib/encryption/_dummy.py +5 -3
- toil/lib/encryption/_nacl.py +10 -6
- toil/lib/encryption/conftest.py +1 -0
- toil/lib/exceptions.py +26 -7
- toil/lib/expando.py +4 -2
- toil/lib/ftp_utils.py +217 -0
- toil/lib/generatedEC2Lists.py +127 -19
- toil/lib/humanize.py +6 -2
- toil/lib/integration.py +341 -0
- toil/lib/io.py +99 -11
- toil/lib/iterables.py +4 -2
- toil/lib/memoize.py +12 -8
- toil/lib/misc.py +65 -18
- toil/lib/objects.py +2 -2
- toil/lib/resources.py +19 -7
- toil/lib/retry.py +115 -77
- toil/lib/threading.py +282 -80
- toil/lib/throttle.py +15 -14
- toil/options/common.py +834 -401
- toil/options/cwl.py +175 -90
- toil/options/runner.py +50 -0
- toil/options/wdl.py +70 -19
- toil/provisioners/__init__.py +111 -46
- toil/provisioners/abstractProvisioner.py +322 -157
- toil/provisioners/aws/__init__.py +62 -30
- toil/provisioners/aws/awsProvisioner.py +980 -627
- toil/provisioners/clusterScaler.py +541 -279
- toil/provisioners/gceProvisioner.py +282 -179
- toil/provisioners/node.py +147 -79
- toil/realtimeLogger.py +34 -22
- toil/resource.py +137 -75
- toil/server/app.py +127 -61
- toil/server/celery_app.py +3 -1
- toil/server/cli/wes_cwl_runner.py +82 -53
- toil/server/utils.py +54 -28
- toil/server/wes/abstract_backend.py +64 -26
- toil/server/wes/amazon_wes_utils.py +21 -15
- toil/server/wes/tasks.py +121 -63
- toil/server/wes/toil_backend.py +142 -107
- toil/server/wsgi_app.py +4 -3
- toil/serviceManager.py +58 -22
- toil/statsAndLogging.py +148 -64
- toil/test/__init__.py +263 -179
- toil/test/batchSystems/batchSystemTest.py +438 -195
- toil/test/batchSystems/batch_system_plugin_test.py +18 -7
- toil/test/batchSystems/test_gridengine.py +173 -0
- toil/test/batchSystems/test_lsf_helper.py +67 -58
- toil/test/batchSystems/test_slurm.py +93 -47
- toil/test/cactus/test_cactus_integration.py +20 -22
- toil/test/cwl/cwlTest.py +271 -71
- toil/test/cwl/measure_default_memory.cwl +12 -0
- toil/test/cwl/not_run_required_input.cwl +29 -0
- toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
- toil/test/docs/scriptsTest.py +60 -34
- toil/test/jobStores/jobStoreTest.py +412 -235
- toil/test/lib/aws/test_iam.py +116 -48
- toil/test/lib/aws/test_s3.py +16 -9
- toil/test/lib/aws/test_utils.py +5 -6
- toil/test/lib/dockerTest.py +118 -141
- toil/test/lib/test_conversions.py +113 -115
- toil/test/lib/test_ec2.py +57 -49
- toil/test/lib/test_integration.py +104 -0
- toil/test/lib/test_misc.py +12 -5
- toil/test/mesos/MesosDataStructuresTest.py +23 -10
- toil/test/mesos/helloWorld.py +7 -6
- toil/test/mesos/stress.py +25 -20
- toil/test/options/options.py +7 -2
- toil/test/provisioners/aws/awsProvisionerTest.py +293 -140
- toil/test/provisioners/clusterScalerTest.py +440 -250
- toil/test/provisioners/clusterTest.py +81 -42
- toil/test/provisioners/gceProvisionerTest.py +174 -100
- toil/test/provisioners/provisionerTest.py +25 -13
- toil/test/provisioners/restartScript.py +5 -4
- toil/test/server/serverTest.py +188 -141
- toil/test/sort/restart_sort.py +137 -68
- toil/test/sort/sort.py +134 -66
- toil/test/sort/sortTest.py +91 -49
- toil/test/src/autoDeploymentTest.py +140 -100
- toil/test/src/busTest.py +20 -18
- toil/test/src/checkpointTest.py +8 -2
- toil/test/src/deferredFunctionTest.py +49 -35
- toil/test/src/dockerCheckTest.py +33 -26
- toil/test/src/environmentTest.py +20 -10
- toil/test/src/fileStoreTest.py +538 -271
- toil/test/src/helloWorldTest.py +7 -4
- toil/test/src/importExportFileTest.py +61 -31
- toil/test/src/jobDescriptionTest.py +32 -17
- toil/test/src/jobEncapsulationTest.py +2 -0
- toil/test/src/jobFileStoreTest.py +74 -50
- toil/test/src/jobServiceTest.py +187 -73
- toil/test/src/jobTest.py +120 -70
- toil/test/src/miscTests.py +19 -18
- toil/test/src/promisedRequirementTest.py +82 -36
- toil/test/src/promisesTest.py +7 -6
- toil/test/src/realtimeLoggerTest.py +6 -6
- toil/test/src/regularLogTest.py +71 -37
- toil/test/src/resourceTest.py +80 -49
- toil/test/src/restartDAGTest.py +36 -22
- toil/test/src/resumabilityTest.py +9 -2
- toil/test/src/retainTempDirTest.py +45 -14
- toil/test/src/systemTest.py +12 -8
- toil/test/src/threadingTest.py +44 -25
- toil/test/src/toilContextManagerTest.py +10 -7
- toil/test/src/userDefinedJobArgTypeTest.py +8 -5
- toil/test/src/workerTest.py +33 -16
- toil/test/utils/toilDebugTest.py +70 -58
- toil/test/utils/toilKillTest.py +4 -5
- toil/test/utils/utilsTest.py +239 -102
- toil/test/wdl/wdltoil_test.py +789 -148
- toil/test/wdl/wdltoil_test_kubernetes.py +37 -23
- toil/toilState.py +52 -26
- toil/utils/toilConfig.py +13 -4
- toil/utils/toilDebugFile.py +44 -27
- toil/utils/toilDebugJob.py +85 -25
- toil/utils/toilDestroyCluster.py +11 -6
- toil/utils/toilKill.py +8 -3
- toil/utils/toilLaunchCluster.py +251 -145
- toil/utils/toilMain.py +37 -16
- toil/utils/toilRsyncCluster.py +27 -14
- toil/utils/toilSshCluster.py +45 -22
- toil/utils/toilStats.py +75 -36
- toil/utils/toilStatus.py +226 -119
- toil/utils/toilUpdateEC2Instances.py +3 -1
- toil/version.py +11 -11
- toil/wdl/utils.py +5 -5
- toil/wdl/wdltoil.py +3513 -1052
- toil/worker.py +269 -128
- toil-8.0.0.dist-info/METADATA +173 -0
- toil-8.0.0.dist-info/RECORD +253 -0
- {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
- toil-7.0.0.dist-info/METADATA +0 -158
- toil-7.0.0.dist-info/RECORD +0 -244
- {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/LICENSE +0 -0
- {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
- {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
|
@@ -16,23 +16,28 @@ import logging
|
|
|
16
16
|
from collections import namedtuple
|
|
17
17
|
from operator import attrgetter
|
|
18
18
|
from statistics import mean, stdev
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import Optional
|
|
20
20
|
|
|
21
21
|
from botocore.client import BaseClient
|
|
22
22
|
|
|
23
|
-
from toil.lib.aws import (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
from toil.lib.aws import (
|
|
24
|
+
get_aws_zone_from_boto,
|
|
25
|
+
get_aws_zone_from_environment,
|
|
26
|
+
get_aws_zone_from_environment_region,
|
|
27
|
+
get_aws_zone_from_metadata,
|
|
28
|
+
)
|
|
27
29
|
|
|
28
30
|
logger = logging.getLogger(__name__)
|
|
29
31
|
|
|
30
|
-
ZoneTuple = namedtuple(
|
|
32
|
+
ZoneTuple = namedtuple("ZoneTuple", ["name", "price_deviation"])
|
|
31
33
|
|
|
32
34
|
|
|
33
|
-
def get_aws_zone_from_spot_market(
|
|
34
|
-
|
|
35
|
-
Optional[str]
|
|
35
|
+
def get_aws_zone_from_spot_market(
|
|
36
|
+
spotBid: Optional[float],
|
|
37
|
+
nodeType: Optional[str],
|
|
38
|
+
boto3_ec2: Optional[BaseClient],
|
|
39
|
+
zone_options: Optional[list[str]],
|
|
40
|
+
) -> Optional[str]:
|
|
36
41
|
"""
|
|
37
42
|
If a spot bid, node type, and Boto2 EC2 connection are specified, picks a
|
|
38
43
|
zone where instances are easy to buy from the zones in the region of the
|
|
@@ -52,14 +57,22 @@ Optional[str]:
|
|
|
52
57
|
# We can use all the zones in the region
|
|
53
58
|
zone_options = [z.name for z in boto3_ec2.describe_availability_zones()]
|
|
54
59
|
|
|
55
|
-
return optimize_spot_bid(
|
|
60
|
+
return optimize_spot_bid(
|
|
61
|
+
boto3_ec2,
|
|
62
|
+
instance_type=nodeType,
|
|
63
|
+
spot_bid=float(spotBid),
|
|
64
|
+
zone_options=zone_options,
|
|
65
|
+
)
|
|
56
66
|
else:
|
|
57
67
|
return None
|
|
58
68
|
|
|
59
69
|
|
|
60
|
-
def get_best_aws_zone(
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
def get_best_aws_zone(
|
|
71
|
+
spotBid: Optional[float] = None,
|
|
72
|
+
nodeType: Optional[str] = None,
|
|
73
|
+
boto3_ec2: Optional[BaseClient] = None,
|
|
74
|
+
zone_options: Optional[list[str]] = None,
|
|
75
|
+
) -> Optional[str]:
|
|
63
76
|
"""
|
|
64
77
|
Get the right AWS zone to use.
|
|
65
78
|
|
|
@@ -84,15 +97,20 @@ def get_best_aws_zone(spotBid: Optional[float] = None, nodeType: Optional[str] =
|
|
|
84
97
|
|
|
85
98
|
Returns None if no method can produce a zone to use.
|
|
86
99
|
"""
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
return (
|
|
101
|
+
get_aws_zone_from_environment()
|
|
102
|
+
or get_aws_zone_from_metadata()
|
|
103
|
+
or get_aws_zone_from_spot_market(spotBid, nodeType, boto3_ec2, zone_options)
|
|
104
|
+
or get_aws_zone_from_environment_region()
|
|
105
|
+
or get_aws_zone_from_boto()
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def choose_spot_zone(
|
|
110
|
+
zones: list[str],
|
|
111
|
+
bid: float,
|
|
112
|
+
spot_history: list["boto.ec2.spotpricehistory.SpotPriceHistory"],
|
|
113
|
+
) -> str:
|
|
96
114
|
"""
|
|
97
115
|
Returns the zone to put the spot request based on, in order of priority:
|
|
98
116
|
|
|
@@ -131,7 +149,11 @@ def choose_spot_zone(zones: List[str], bid: float,
|
|
|
131
149
|
# standard deviation values.
|
|
132
150
|
markets_under_bid, markets_over_bid = [], []
|
|
133
151
|
for zone in zones:
|
|
134
|
-
zone_histories = [
|
|
152
|
+
zone_histories = [
|
|
153
|
+
zone_history
|
|
154
|
+
for zone_history in spot_history
|
|
155
|
+
if zone_history.availability_zone == zone
|
|
156
|
+
]
|
|
135
157
|
if zone_histories:
|
|
136
158
|
price_deviation = stdev([history.price for history in zone_histories])
|
|
137
159
|
recent_price = zone_histories[0].price
|
|
@@ -140,10 +162,14 @@ def choose_spot_zone(zones: List[str], bid: float,
|
|
|
140
162
|
zone_tuple = ZoneTuple(name=zone, price_deviation=price_deviation)
|
|
141
163
|
(markets_over_bid, markets_under_bid)[recent_price < bid].append(zone_tuple)
|
|
142
164
|
|
|
143
|
-
return min(
|
|
165
|
+
return min(
|
|
166
|
+
markets_under_bid or markets_over_bid, key=attrgetter("price_deviation")
|
|
167
|
+
).name
|
|
144
168
|
|
|
145
169
|
|
|
146
|
-
def optimize_spot_bid(
|
|
170
|
+
def optimize_spot_bid(
|
|
171
|
+
boto3_ec2: BaseClient, instance_type: str, spot_bid: float, zone_options: list[str]
|
|
172
|
+
):
|
|
147
173
|
"""
|
|
148
174
|
Check whether the bid is in line with history and makes an effort to place
|
|
149
175
|
the instance in a sensible zone.
|
|
@@ -188,8 +214,12 @@ def _check_spot_bid(spot_bid, spot_history):
|
|
|
188
214
|
"""
|
|
189
215
|
average = mean([datum.price for datum in spot_history])
|
|
190
216
|
if spot_bid > average * 2:
|
|
191
|
-
logger.warning(
|
|
192
|
-
|
|
217
|
+
logger.warning(
|
|
218
|
+
"Your bid $ %f is more than double this instance type's average "
|
|
219
|
+
"spot price ($ %f) over the last week",
|
|
220
|
+
spot_bid,
|
|
221
|
+
average,
|
|
222
|
+
)
|
|
193
223
|
|
|
194
224
|
|
|
195
225
|
def _get_spot_history(boto3_ec2: BaseClient, instance_type: str):
|
|
@@ -200,8 +230,10 @@ def _get_spot_history(boto3_ec2: BaseClient, instance_type: str):
|
|
|
200
230
|
:rtype: list[SpotPriceHistory]
|
|
201
231
|
"""
|
|
202
232
|
one_week_ago = datetime.datetime.now() - datetime.timedelta(days=7)
|
|
203
|
-
spot_data = boto3_ec2.describe_spot_price_history(
|
|
204
|
-
|
|
205
|
-
|
|
233
|
+
spot_data = boto3_ec2.describe_spot_price_history(
|
|
234
|
+
StartTime=one_week_ago.isoformat(),
|
|
235
|
+
InstanceTypes=[instance_type],
|
|
236
|
+
ProductDescriptions=["Linux/UNIX"],
|
|
237
|
+
)
|
|
206
238
|
spot_data.sort(key=attrgetter("timestamp"), reverse=True)
|
|
207
239
|
return spot_data
|