toil 6.1.0a1__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 (193) hide show
  1. toil/__init__.py +122 -315
  2. toil/batchSystems/__init__.py +1 -0
  3. toil/batchSystems/abstractBatchSystem.py +173 -89
  4. toil/batchSystems/abstractGridEngineBatchSystem.py +272 -148
  5. toil/batchSystems/awsBatch.py +244 -135
  6. toil/batchSystems/cleanup_support.py +26 -16
  7. toil/batchSystems/contained_executor.py +31 -28
  8. toil/batchSystems/gridengine.py +86 -50
  9. toil/batchSystems/htcondor.py +166 -89
  10. toil/batchSystems/kubernetes.py +632 -382
  11. toil/batchSystems/local_support.py +20 -15
  12. toil/batchSystems/lsf.py +134 -81
  13. toil/batchSystems/lsfHelper.py +13 -11
  14. toil/batchSystems/mesos/__init__.py +41 -29
  15. toil/batchSystems/mesos/batchSystem.py +290 -151
  16. toil/batchSystems/mesos/executor.py +79 -50
  17. toil/batchSystems/mesos/test/__init__.py +31 -23
  18. toil/batchSystems/options.py +46 -28
  19. toil/batchSystems/registry.py +53 -19
  20. toil/batchSystems/singleMachine.py +296 -125
  21. toil/batchSystems/slurm.py +603 -138
  22. toil/batchSystems/torque.py +47 -33
  23. toil/bus.py +186 -76
  24. toil/common.py +664 -368
  25. toil/cwl/__init__.py +1 -1
  26. toil/cwl/cwltoil.py +1136 -483
  27. toil/cwl/utils.py +17 -22
  28. toil/deferred.py +63 -42
  29. toil/exceptions.py +5 -3
  30. toil/fileStores/__init__.py +5 -5
  31. toil/fileStores/abstractFileStore.py +140 -60
  32. toil/fileStores/cachingFileStore.py +717 -269
  33. toil/fileStores/nonCachingFileStore.py +116 -87
  34. toil/job.py +1225 -368
  35. toil/jobStores/abstractJobStore.py +416 -266
  36. toil/jobStores/aws/jobStore.py +863 -477
  37. toil/jobStores/aws/utils.py +201 -120
  38. toil/jobStores/conftest.py +3 -2
  39. toil/jobStores/fileJobStore.py +292 -154
  40. toil/jobStores/googleJobStore.py +140 -74
  41. toil/jobStores/utils.py +36 -15
  42. toil/leader.py +668 -272
  43. toil/lib/accelerators.py +115 -18
  44. toil/lib/aws/__init__.py +74 -31
  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 +214 -39
  49. toil/lib/aws/utils.py +287 -231
  50. toil/lib/bioio.py +13 -5
  51. toil/lib/compatibility.py +11 -6
  52. toil/lib/conversions.py +104 -47
  53. toil/lib/docker.py +131 -103
  54. toil/lib/ec2.py +361 -199
  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 +5 -3
  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 +141 -15
  66. toil/lib/iterables.py +4 -2
  67. toil/lib/memoize.py +12 -8
  68. toil/lib/misc.py +66 -21
  69. toil/lib/objects.py +2 -2
  70. toil/lib/resources.py +68 -15
  71. toil/lib/retry.py +126 -81
  72. toil/lib/threading.py +299 -82
  73. toil/lib/throttle.py +16 -15
  74. toil/options/common.py +843 -409
  75. toil/options/cwl.py +175 -90
  76. toil/options/runner.py +50 -0
  77. toil/options/wdl.py +73 -17
  78. toil/provisioners/__init__.py +117 -46
  79. toil/provisioners/abstractProvisioner.py +332 -157
  80. toil/provisioners/aws/__init__.py +70 -33
  81. toil/provisioners/aws/awsProvisioner.py +1145 -715
  82. toil/provisioners/clusterScaler.py +541 -279
  83. toil/provisioners/gceProvisioner.py +282 -179
  84. toil/provisioners/node.py +155 -79
  85. toil/realtimeLogger.py +34 -22
  86. toil/resource.py +137 -75
  87. toil/server/app.py +128 -62
  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 +224 -70
  98. toil/test/__init__.py +282 -183
  99. toil/test/batchSystems/batchSystemTest.py +460 -210
  100. toil/test/batchSystems/batch_system_plugin_test.py +90 -0
  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 +110 -49
  104. toil/test/cactus/__init__.py +0 -0
  105. toil/test/cactus/test_cactus_integration.py +56 -0
  106. toil/test/cwl/cwlTest.py +496 -287
  107. toil/test/cwl/measure_default_memory.cwl +12 -0
  108. toil/test/cwl/not_run_required_input.cwl +29 -0
  109. toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
  110. toil/test/cwl/seqtk_seq.cwl +1 -1
  111. toil/test/docs/scriptsTest.py +69 -46
  112. toil/test/jobStores/jobStoreTest.py +427 -264
  113. toil/test/lib/aws/test_iam.py +118 -50
  114. toil/test/lib/aws/test_s3.py +16 -9
  115. toil/test/lib/aws/test_utils.py +5 -6
  116. toil/test/lib/dockerTest.py +118 -141
  117. toil/test/lib/test_conversions.py +113 -115
  118. toil/test/lib/test_ec2.py +58 -50
  119. toil/test/lib/test_integration.py +104 -0
  120. toil/test/lib/test_misc.py +12 -5
  121. toil/test/mesos/MesosDataStructuresTest.py +23 -10
  122. toil/test/mesos/helloWorld.py +7 -6
  123. toil/test/mesos/stress.py +25 -20
  124. toil/test/options/__init__.py +13 -0
  125. toil/test/options/options.py +42 -0
  126. toil/test/provisioners/aws/awsProvisionerTest.py +320 -150
  127. toil/test/provisioners/clusterScalerTest.py +440 -250
  128. toil/test/provisioners/clusterTest.py +166 -44
  129. toil/test/provisioners/gceProvisionerTest.py +174 -100
  130. toil/test/provisioners/provisionerTest.py +25 -13
  131. toil/test/provisioners/restartScript.py +5 -4
  132. toil/test/server/serverTest.py +188 -141
  133. toil/test/sort/restart_sort.py +137 -68
  134. toil/test/sort/sort.py +134 -66
  135. toil/test/sort/sortTest.py +91 -49
  136. toil/test/src/autoDeploymentTest.py +141 -101
  137. toil/test/src/busTest.py +20 -18
  138. toil/test/src/checkpointTest.py +8 -2
  139. toil/test/src/deferredFunctionTest.py +49 -35
  140. toil/test/src/dockerCheckTest.py +32 -24
  141. toil/test/src/environmentTest.py +135 -0
  142. toil/test/src/fileStoreTest.py +539 -272
  143. toil/test/src/helloWorldTest.py +7 -4
  144. toil/test/src/importExportFileTest.py +61 -31
  145. toil/test/src/jobDescriptionTest.py +46 -21
  146. toil/test/src/jobEncapsulationTest.py +2 -0
  147. toil/test/src/jobFileStoreTest.py +74 -50
  148. toil/test/src/jobServiceTest.py +187 -73
  149. toil/test/src/jobTest.py +121 -71
  150. toil/test/src/miscTests.py +19 -18
  151. toil/test/src/promisedRequirementTest.py +82 -36
  152. toil/test/src/promisesTest.py +7 -6
  153. toil/test/src/realtimeLoggerTest.py +10 -6
  154. toil/test/src/regularLogTest.py +71 -37
  155. toil/test/src/resourceTest.py +80 -49
  156. toil/test/src/restartDAGTest.py +36 -22
  157. toil/test/src/resumabilityTest.py +9 -2
  158. toil/test/src/retainTempDirTest.py +45 -14
  159. toil/test/src/systemTest.py +12 -8
  160. toil/test/src/threadingTest.py +44 -25
  161. toil/test/src/toilContextManagerTest.py +10 -7
  162. toil/test/src/userDefinedJobArgTypeTest.py +8 -5
  163. toil/test/src/workerTest.py +73 -23
  164. toil/test/utils/toilDebugTest.py +103 -33
  165. toil/test/utils/toilKillTest.py +4 -5
  166. toil/test/utils/utilsTest.py +245 -106
  167. toil/test/wdl/wdltoil_test.py +818 -149
  168. toil/test/wdl/wdltoil_test_kubernetes.py +91 -0
  169. toil/toilState.py +120 -35
  170. toil/utils/toilConfig.py +13 -4
  171. toil/utils/toilDebugFile.py +44 -27
  172. toil/utils/toilDebugJob.py +214 -27
  173. toil/utils/toilDestroyCluster.py +11 -6
  174. toil/utils/toilKill.py +8 -3
  175. toil/utils/toilLaunchCluster.py +256 -140
  176. toil/utils/toilMain.py +37 -16
  177. toil/utils/toilRsyncCluster.py +32 -14
  178. toil/utils/toilSshCluster.py +49 -22
  179. toil/utils/toilStats.py +356 -273
  180. toil/utils/toilStatus.py +292 -139
  181. toil/utils/toilUpdateEC2Instances.py +3 -1
  182. toil/version.py +12 -12
  183. toil/wdl/utils.py +5 -5
  184. toil/wdl/wdltoil.py +3913 -1033
  185. toil/worker.py +367 -184
  186. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/LICENSE +25 -0
  187. toil-8.0.0.dist-info/METADATA +173 -0
  188. toil-8.0.0.dist-info/RECORD +253 -0
  189. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
  190. toil-6.1.0a1.dist-info/METADATA +0 -125
  191. toil-6.1.0a1.dist-info/RECORD +0 -237
  192. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
  193. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
@@ -16,19 +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
- from toil.lib.aws import (get_aws_zone_from_boto,
22
- get_aws_zone_from_environment,
23
- get_aws_zone_from_environment_region,
24
- get_aws_zone_from_metadata)
21
+ from botocore.client import BaseClient
22
+
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
+ )
25
29
 
26
30
  logger = logging.getLogger(__name__)
27
31
 
28
- ZoneTuple = namedtuple('ZoneTuple', ['name', 'price_deviation'])
32
+ ZoneTuple = namedtuple("ZoneTuple", ["name", "price_deviation"])
33
+
29
34
 
30
- def get_aws_zone_from_spot_market(spotBid: Optional[float], nodeType: Optional[str],
31
- boto2_ec2: Optional["boto.connection.AWSAuthConnection"], zone_options: Optional[List[str]]) -> 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]:
32
41
  """
33
42
  If a spot bid, node type, and Boto2 EC2 connection are specified, picks a
34
43
  zone where instances are easy to buy from the zones in the region of the
@@ -40,21 +49,30 @@ def get_aws_zone_from_spot_market(spotBid: Optional[float], nodeType: Optional[s
40
49
  """
41
50
  if spotBid:
42
51
  # if spot bid is present, all the other parameters must be as well
43
- assert bool(spotBid) == bool(nodeType) == bool(boto2_ec2)
52
+ assert bool(spotBid) == bool(nodeType) == bool(boto3_ec2)
44
53
  # if the zone is unset and we are using the spot market, optimize our
45
54
  # choice based on the spot history
46
55
 
47
56
  if zone_options is None:
48
57
  # We can use all the zones in the region
49
- zone_options = [z.name for z in boto2_ec2.get_all_zones()]
50
-
51
- return optimize_spot_bid(boto2_ec2, instance_type=nodeType, spot_bid=float(spotBid), zone_options=zone_options)
58
+ zone_options = [z.name for z in boto3_ec2.describe_availability_zones()]
59
+
60
+ return optimize_spot_bid(
61
+ boto3_ec2,
62
+ instance_type=nodeType,
63
+ spot_bid=float(spotBid),
64
+ zone_options=zone_options,
65
+ )
52
66
  else:
53
67
  return None
54
68
 
55
69
 
56
- def get_best_aws_zone(spotBid: Optional[float] = None, nodeType: Optional[str] = None,
57
- boto2_ec2: Optional["boto.connection.AWSAuthConnection"] = None, 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]:
58
76
  """
59
77
  Get the right AWS zone to use.
60
78
 
@@ -79,14 +97,20 @@ def get_best_aws_zone(spotBid: Optional[float] = None, nodeType: Optional[str] =
79
97
 
80
98
  Returns None if no method can produce a zone to use.
81
99
  """
82
- return get_aws_zone_from_environment() or \
83
- get_aws_zone_from_metadata() or \
84
- get_aws_zone_from_spot_market(spotBid, nodeType, boto2_ec2, zone_options) or \
85
- get_aws_zone_from_environment_region() or \
86
- get_aws_zone_from_boto()
87
-
88
-
89
- def choose_spot_zone(zones: List[str], bid: float, 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:
90
114
  """
91
115
  Returns the zone to put the spot request based on, in order of priority:
92
116
 
@@ -125,7 +149,11 @@ def choose_spot_zone(zones: List[str], bid: float, spot_history: List['boto.ec2.
125
149
  # standard deviation values.
126
150
  markets_under_bid, markets_over_bid = [], []
127
151
  for zone in zones:
128
- 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
+ ]
129
157
  if zone_histories:
130
158
  price_deviation = stdev([history.price for history in zone_histories])
131
159
  recent_price = zone_histories[0].price
@@ -134,10 +162,14 @@ def choose_spot_zone(zones: List[str], bid: float, spot_history: List['boto.ec2.
134
162
  zone_tuple = ZoneTuple(name=zone, price_deviation=price_deviation)
135
163
  (markets_over_bid, markets_under_bid)[recent_price < bid].append(zone_tuple)
136
164
 
137
- 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
138
168
 
139
169
 
140
- def optimize_spot_bid(boto2_ec2, instance_type, spot_bid, zone_options: List[str]):
170
+ def optimize_spot_bid(
171
+ boto3_ec2: BaseClient, instance_type: str, spot_bid: float, zone_options: list[str]
172
+ ):
141
173
  """
142
174
  Check whether the bid is in line with history and makes an effort to place
143
175
  the instance in a sensible zone.
@@ -145,7 +177,7 @@ def optimize_spot_bid(boto2_ec2, instance_type, spot_bid, zone_options: List[str
145
177
  :param zone_options: The collection of allowed zones to consider, within
146
178
  the region associated with the Boto2 connection.
147
179
  """
148
- spot_history = _get_spot_history(boto2_ec2, instance_type)
180
+ spot_history = _get_spot_history(boto3_ec2, instance_type)
149
181
  if spot_history:
150
182
  _check_spot_bid(spot_bid, spot_history)
151
183
  most_stable_zone = choose_spot_zone(zone_options, spot_bid, spot_history)
@@ -182,21 +214,26 @@ def _check_spot_bid(spot_bid, spot_history):
182
214
  """
183
215
  average = mean([datum.price for datum in spot_history])
184
216
  if spot_bid > average * 2:
185
- logger.warning("Your bid $ %f is more than double this instance type's average "
186
- "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
+ )
187
223
 
188
224
 
189
- def _get_spot_history(boto2_ec2, instance_type):
225
+ def _get_spot_history(boto3_ec2: BaseClient, instance_type: str):
190
226
  """
191
227
  Returns list of 1,000 most recent spot market data points represented as SpotPriceHistory
192
228
  objects. Note: The most recent object/data point will be first in the list.
193
229
 
194
230
  :rtype: list[SpotPriceHistory]
195
231
  """
196
-
197
232
  one_week_ago = datetime.datetime.now() - datetime.timedelta(days=7)
198
- spot_data = boto2_ec2.get_spot_price_history(start_time=one_week_ago.isoformat(),
199
- instance_type=instance_type,
200
- product_description="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
+ )
201
238
  spot_data.sort(key=attrgetter("timestamp"), reverse=True)
202
239
  return spot_data