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.
Files changed (190) hide show
  1. toil/__init__.py +121 -83
  2. toil/batchSystems/__init__.py +1 -0
  3. toil/batchSystems/abstractBatchSystem.py +137 -77
  4. toil/batchSystems/abstractGridEngineBatchSystem.py +211 -101
  5. toil/batchSystems/awsBatch.py +237 -128
  6. toil/batchSystems/cleanup_support.py +22 -16
  7. toil/batchSystems/contained_executor.py +30 -26
  8. toil/batchSystems/gridengine.py +85 -49
  9. toil/batchSystems/htcondor.py +164 -87
  10. toil/batchSystems/kubernetes.py +622 -386
  11. toil/batchSystems/local_support.py +17 -12
  12. toil/batchSystems/lsf.py +132 -79
  13. toil/batchSystems/lsfHelper.py +13 -11
  14. toil/batchSystems/mesos/__init__.py +41 -29
  15. toil/batchSystems/mesos/batchSystem.py +288 -149
  16. toil/batchSystems/mesos/executor.py +77 -49
  17. toil/batchSystems/mesos/test/__init__.py +31 -23
  18. toil/batchSystems/options.py +38 -29
  19. toil/batchSystems/registry.py +53 -19
  20. toil/batchSystems/singleMachine.py +293 -123
  21. toil/batchSystems/slurm.py +489 -137
  22. toil/batchSystems/torque.py +46 -32
  23. toil/bus.py +141 -73
  24. toil/common.py +630 -359
  25. toil/cwl/__init__.py +1 -1
  26. toil/cwl/cwltoil.py +1114 -532
  27. toil/cwl/utils.py +17 -22
  28. toil/deferred.py +62 -41
  29. toil/exceptions.py +5 -3
  30. toil/fileStores/__init__.py +5 -5
  31. toil/fileStores/abstractFileStore.py +88 -57
  32. toil/fileStores/cachingFileStore.py +711 -247
  33. toil/fileStores/nonCachingFileStore.py +113 -75
  34. toil/job.py +988 -315
  35. toil/jobStores/abstractJobStore.py +387 -243
  36. toil/jobStores/aws/jobStore.py +727 -403
  37. toil/jobStores/aws/utils.py +161 -109
  38. toil/jobStores/conftest.py +1 -0
  39. toil/jobStores/fileJobStore.py +289 -151
  40. toil/jobStores/googleJobStore.py +137 -70
  41. toil/jobStores/utils.py +36 -15
  42. toil/leader.py +614 -269
  43. toil/lib/accelerators.py +115 -18
  44. toil/lib/aws/__init__.py +55 -28
  45. toil/lib/aws/ami.py +122 -87
  46. toil/lib/aws/iam.py +284 -108
  47. toil/lib/aws/s3.py +31 -0
  48. toil/lib/aws/session.py +193 -58
  49. toil/lib/aws/utils.py +238 -218
  50. toil/lib/bioio.py +13 -5
  51. toil/lib/compatibility.py +11 -6
  52. toil/lib/conversions.py +83 -49
  53. toil/lib/docker.py +131 -103
  54. toil/lib/ec2.py +322 -209
  55. toil/lib/ec2nodes.py +174 -106
  56. toil/lib/encryption/_dummy.py +5 -3
  57. toil/lib/encryption/_nacl.py +10 -6
  58. toil/lib/encryption/conftest.py +1 -0
  59. toil/lib/exceptions.py +26 -7
  60. toil/lib/expando.py +4 -2
  61. toil/lib/ftp_utils.py +217 -0
  62. toil/lib/generatedEC2Lists.py +127 -19
  63. toil/lib/humanize.py +6 -2
  64. toil/lib/integration.py +341 -0
  65. toil/lib/io.py +99 -11
  66. toil/lib/iterables.py +4 -2
  67. toil/lib/memoize.py +12 -8
  68. toil/lib/misc.py +65 -18
  69. toil/lib/objects.py +2 -2
  70. toil/lib/resources.py +19 -7
  71. toil/lib/retry.py +115 -77
  72. toil/lib/threading.py +282 -80
  73. toil/lib/throttle.py +15 -14
  74. toil/options/common.py +834 -401
  75. toil/options/cwl.py +175 -90
  76. toil/options/runner.py +50 -0
  77. toil/options/wdl.py +70 -19
  78. toil/provisioners/__init__.py +111 -46
  79. toil/provisioners/abstractProvisioner.py +322 -157
  80. toil/provisioners/aws/__init__.py +62 -30
  81. toil/provisioners/aws/awsProvisioner.py +980 -627
  82. toil/provisioners/clusterScaler.py +541 -279
  83. toil/provisioners/gceProvisioner.py +282 -179
  84. toil/provisioners/node.py +147 -79
  85. toil/realtimeLogger.py +34 -22
  86. toil/resource.py +137 -75
  87. toil/server/app.py +127 -61
  88. toil/server/celery_app.py +3 -1
  89. toil/server/cli/wes_cwl_runner.py +82 -53
  90. toil/server/utils.py +54 -28
  91. toil/server/wes/abstract_backend.py +64 -26
  92. toil/server/wes/amazon_wes_utils.py +21 -15
  93. toil/server/wes/tasks.py +121 -63
  94. toil/server/wes/toil_backend.py +142 -107
  95. toil/server/wsgi_app.py +4 -3
  96. toil/serviceManager.py +58 -22
  97. toil/statsAndLogging.py +148 -64
  98. toil/test/__init__.py +263 -179
  99. toil/test/batchSystems/batchSystemTest.py +438 -195
  100. toil/test/batchSystems/batch_system_plugin_test.py +18 -7
  101. toil/test/batchSystems/test_gridengine.py +173 -0
  102. toil/test/batchSystems/test_lsf_helper.py +67 -58
  103. toil/test/batchSystems/test_slurm.py +93 -47
  104. toil/test/cactus/test_cactus_integration.py +20 -22
  105. toil/test/cwl/cwlTest.py +271 -71
  106. toil/test/cwl/measure_default_memory.cwl +12 -0
  107. toil/test/cwl/not_run_required_input.cwl +29 -0
  108. toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
  109. toil/test/docs/scriptsTest.py +60 -34
  110. toil/test/jobStores/jobStoreTest.py +412 -235
  111. toil/test/lib/aws/test_iam.py +116 -48
  112. toil/test/lib/aws/test_s3.py +16 -9
  113. toil/test/lib/aws/test_utils.py +5 -6
  114. toil/test/lib/dockerTest.py +118 -141
  115. toil/test/lib/test_conversions.py +113 -115
  116. toil/test/lib/test_ec2.py +57 -49
  117. toil/test/lib/test_integration.py +104 -0
  118. toil/test/lib/test_misc.py +12 -5
  119. toil/test/mesos/MesosDataStructuresTest.py +23 -10
  120. toil/test/mesos/helloWorld.py +7 -6
  121. toil/test/mesos/stress.py +25 -20
  122. toil/test/options/options.py +7 -2
  123. toil/test/provisioners/aws/awsProvisionerTest.py +293 -140
  124. toil/test/provisioners/clusterScalerTest.py +440 -250
  125. toil/test/provisioners/clusterTest.py +81 -42
  126. toil/test/provisioners/gceProvisionerTest.py +174 -100
  127. toil/test/provisioners/provisionerTest.py +25 -13
  128. toil/test/provisioners/restartScript.py +5 -4
  129. toil/test/server/serverTest.py +188 -141
  130. toil/test/sort/restart_sort.py +137 -68
  131. toil/test/sort/sort.py +134 -66
  132. toil/test/sort/sortTest.py +91 -49
  133. toil/test/src/autoDeploymentTest.py +140 -100
  134. toil/test/src/busTest.py +20 -18
  135. toil/test/src/checkpointTest.py +8 -2
  136. toil/test/src/deferredFunctionTest.py +49 -35
  137. toil/test/src/dockerCheckTest.py +33 -26
  138. toil/test/src/environmentTest.py +20 -10
  139. toil/test/src/fileStoreTest.py +538 -271
  140. toil/test/src/helloWorldTest.py +7 -4
  141. toil/test/src/importExportFileTest.py +61 -31
  142. toil/test/src/jobDescriptionTest.py +32 -17
  143. toil/test/src/jobEncapsulationTest.py +2 -0
  144. toil/test/src/jobFileStoreTest.py +74 -50
  145. toil/test/src/jobServiceTest.py +187 -73
  146. toil/test/src/jobTest.py +120 -70
  147. toil/test/src/miscTests.py +19 -18
  148. toil/test/src/promisedRequirementTest.py +82 -36
  149. toil/test/src/promisesTest.py +7 -6
  150. toil/test/src/realtimeLoggerTest.py +6 -6
  151. toil/test/src/regularLogTest.py +71 -37
  152. toil/test/src/resourceTest.py +80 -49
  153. toil/test/src/restartDAGTest.py +36 -22
  154. toil/test/src/resumabilityTest.py +9 -2
  155. toil/test/src/retainTempDirTest.py +45 -14
  156. toil/test/src/systemTest.py +12 -8
  157. toil/test/src/threadingTest.py +44 -25
  158. toil/test/src/toilContextManagerTest.py +10 -7
  159. toil/test/src/userDefinedJobArgTypeTest.py +8 -5
  160. toil/test/src/workerTest.py +33 -16
  161. toil/test/utils/toilDebugTest.py +70 -58
  162. toil/test/utils/toilKillTest.py +4 -5
  163. toil/test/utils/utilsTest.py +239 -102
  164. toil/test/wdl/wdltoil_test.py +789 -148
  165. toil/test/wdl/wdltoil_test_kubernetes.py +37 -23
  166. toil/toilState.py +52 -26
  167. toil/utils/toilConfig.py +13 -4
  168. toil/utils/toilDebugFile.py +44 -27
  169. toil/utils/toilDebugJob.py +85 -25
  170. toil/utils/toilDestroyCluster.py +11 -6
  171. toil/utils/toilKill.py +8 -3
  172. toil/utils/toilLaunchCluster.py +251 -145
  173. toil/utils/toilMain.py +37 -16
  174. toil/utils/toilRsyncCluster.py +27 -14
  175. toil/utils/toilSshCluster.py +45 -22
  176. toil/utils/toilStats.py +75 -36
  177. toil/utils/toilStatus.py +226 -119
  178. toil/utils/toilUpdateEC2Instances.py +3 -1
  179. toil/version.py +11 -11
  180. toil/wdl/utils.py +5 -5
  181. toil/wdl/wdltoil.py +3513 -1052
  182. toil/worker.py +269 -128
  183. toil-8.0.0.dist-info/METADATA +173 -0
  184. toil-8.0.0.dist-info/RECORD +253 -0
  185. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
  186. toil-7.0.0.dist-info/METADATA +0 -158
  187. toil-7.0.0.dist-info/RECORD +0 -244
  188. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/LICENSE +0 -0
  189. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
  190. {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 List, Optional
19
+ from typing import Optional
20
20
 
21
21
  from botocore.client import BaseClient
22
22
 
23
- from toil.lib.aws import (get_aws_zone_from_boto,
24
- get_aws_zone_from_environment,
25
- get_aws_zone_from_environment_region,
26
- get_aws_zone_from_metadata)
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('ZoneTuple', ['name', 'price_deviation'])
32
+ ZoneTuple = namedtuple("ZoneTuple", ["name", "price_deviation"])
31
33
 
32
34
 
33
- def get_aws_zone_from_spot_market(spotBid: Optional[float], nodeType: Optional[str],
34
- boto3_ec2: Optional[BaseClient], zone_options: Optional[List[str]]) -> \
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(boto3_ec2, instance_type=nodeType, spot_bid=float(spotBid), zone_options=zone_options)
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(spotBid: Optional[float] = None, nodeType: Optional[str] = None,
61
- boto3_ec2: Optional[BaseClient] = None,
62
- zone_options: Optional[List[str]] = None) -> Optional[str]:
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 get_aws_zone_from_environment() or \
88
- get_aws_zone_from_metadata() or \
89
- get_aws_zone_from_spot_market(spotBid, nodeType, boto3_ec2, zone_options) or \
90
- get_aws_zone_from_environment_region() or \
91
- get_aws_zone_from_boto()
92
-
93
-
94
- def choose_spot_zone(zones: List[str], bid: float,
95
- spot_history: List['boto.ec2.spotpricehistory.SpotPriceHistory']) -> str:
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 = [zone_history for zone_history in spot_history if zone_history.availability_zone == zone]
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(markets_under_bid or markets_over_bid, key=attrgetter('price_deviation')).name
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(boto3_ec2: BaseClient, instance_type: str, spot_bid: float, zone_options: List[str]):
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("Your bid $ %f is more than double this instance type's average "
192
- "spot price ($ %f) over the last week", spot_bid, average)
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(StartTime=one_week_ago.isoformat(),
204
- InstanceTypes=[instance_type],
205
- ProductDescriptions=["Linux/UNIX"])
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