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.
Files changed (155) hide show
  1. toil/__init__.py +5 -9
  2. toil/batchSystems/abstractBatchSystem.py +23 -22
  3. toil/batchSystems/abstractGridEngineBatchSystem.py +17 -12
  4. toil/batchSystems/awsBatch.py +8 -8
  5. toil/batchSystems/cleanup_support.py +4 -4
  6. toil/batchSystems/contained_executor.py +3 -3
  7. toil/batchSystems/gridengine.py +3 -4
  8. toil/batchSystems/htcondor.py +5 -5
  9. toil/batchSystems/kubernetes.py +65 -63
  10. toil/batchSystems/local_support.py +2 -3
  11. toil/batchSystems/lsf.py +6 -7
  12. toil/batchSystems/mesos/batchSystem.py +11 -7
  13. toil/batchSystems/mesos/test/__init__.py +1 -2
  14. toil/batchSystems/options.py +9 -10
  15. toil/batchSystems/registry.py +3 -7
  16. toil/batchSystems/singleMachine.py +8 -11
  17. toil/batchSystems/slurm.py +49 -38
  18. toil/batchSystems/torque.py +3 -4
  19. toil/bus.py +36 -34
  20. toil/common.py +129 -89
  21. toil/cwl/cwltoil.py +857 -729
  22. toil/cwl/utils.py +44 -35
  23. toil/fileStores/__init__.py +3 -1
  24. toil/fileStores/abstractFileStore.py +28 -30
  25. toil/fileStores/cachingFileStore.py +8 -8
  26. toil/fileStores/nonCachingFileStore.py +10 -21
  27. toil/job.py +159 -158
  28. toil/jobStores/abstractJobStore.py +68 -69
  29. toil/jobStores/aws/jobStore.py +249 -213
  30. toil/jobStores/aws/utils.py +13 -24
  31. toil/jobStores/fileJobStore.py +28 -22
  32. toil/jobStores/googleJobStore.py +21 -17
  33. toil/jobStores/utils.py +3 -7
  34. toil/leader.py +17 -22
  35. toil/lib/accelerators.py +6 -4
  36. toil/lib/aws/__init__.py +9 -10
  37. toil/lib/aws/ami.py +33 -19
  38. toil/lib/aws/iam.py +6 -6
  39. toil/lib/aws/s3.py +259 -157
  40. toil/lib/aws/session.py +76 -76
  41. toil/lib/aws/utils.py +51 -43
  42. toil/lib/checksum.py +19 -15
  43. toil/lib/compatibility.py +3 -2
  44. toil/lib/conversions.py +45 -18
  45. toil/lib/directory.py +29 -26
  46. toil/lib/docker.py +93 -99
  47. toil/lib/dockstore.py +77 -50
  48. toil/lib/ec2.py +39 -38
  49. toil/lib/ec2nodes.py +11 -4
  50. toil/lib/exceptions.py +8 -5
  51. toil/lib/ftp_utils.py +9 -14
  52. toil/lib/generatedEC2Lists.py +161 -20
  53. toil/lib/history.py +141 -97
  54. toil/lib/history_submission.py +163 -72
  55. toil/lib/io.py +27 -17
  56. toil/lib/memoize.py +2 -1
  57. toil/lib/misc.py +15 -11
  58. toil/lib/pipes.py +40 -25
  59. toil/lib/plugins.py +12 -8
  60. toil/lib/resources.py +1 -0
  61. toil/lib/retry.py +32 -38
  62. toil/lib/threading.py +12 -12
  63. toil/lib/throttle.py +1 -2
  64. toil/lib/trs.py +113 -51
  65. toil/lib/url.py +14 -23
  66. toil/lib/web.py +7 -2
  67. toil/options/common.py +18 -15
  68. toil/options/cwl.py +2 -2
  69. toil/options/runner.py +9 -5
  70. toil/options/wdl.py +1 -3
  71. toil/provisioners/__init__.py +9 -9
  72. toil/provisioners/abstractProvisioner.py +22 -20
  73. toil/provisioners/aws/__init__.py +20 -14
  74. toil/provisioners/aws/awsProvisioner.py +10 -8
  75. toil/provisioners/clusterScaler.py +19 -18
  76. toil/provisioners/gceProvisioner.py +2 -3
  77. toil/provisioners/node.py +11 -13
  78. toil/realtimeLogger.py +4 -4
  79. toil/resource.py +5 -5
  80. toil/server/app.py +2 -2
  81. toil/server/cli/wes_cwl_runner.py +11 -11
  82. toil/server/utils.py +18 -21
  83. toil/server/wes/abstract_backend.py +9 -8
  84. toil/server/wes/amazon_wes_utils.py +3 -3
  85. toil/server/wes/tasks.py +3 -5
  86. toil/server/wes/toil_backend.py +17 -21
  87. toil/server/wsgi_app.py +3 -3
  88. toil/serviceManager.py +3 -4
  89. toil/statsAndLogging.py +12 -13
  90. toil/test/__init__.py +33 -24
  91. toil/test/batchSystems/batchSystemTest.py +12 -11
  92. toil/test/batchSystems/batch_system_plugin_test.py +3 -5
  93. toil/test/batchSystems/test_slurm.py +38 -24
  94. toil/test/cwl/conftest.py +5 -6
  95. toil/test/cwl/cwlTest.py +194 -78
  96. toil/test/cwl/download_file_uri.json +6 -0
  97. toil/test/cwl/download_file_uri_no_hostname.json +6 -0
  98. toil/test/docs/scripts/tutorial_staging.py +1 -0
  99. toil/test/jobStores/jobStoreTest.py +9 -7
  100. toil/test/lib/aws/test_iam.py +1 -3
  101. toil/test/lib/aws/test_s3.py +1 -1
  102. toil/test/lib/dockerTest.py +9 -9
  103. toil/test/lib/test_ec2.py +12 -11
  104. toil/test/lib/test_history.py +4 -4
  105. toil/test/lib/test_trs.py +16 -14
  106. toil/test/lib/test_url.py +7 -6
  107. toil/test/lib/url_plugin_test.py +12 -18
  108. toil/test/provisioners/aws/awsProvisionerTest.py +10 -8
  109. toil/test/provisioners/clusterScalerTest.py +2 -5
  110. toil/test/provisioners/clusterTest.py +1 -3
  111. toil/test/server/serverTest.py +13 -4
  112. toil/test/sort/restart_sort.py +2 -6
  113. toil/test/sort/sort.py +3 -8
  114. toil/test/src/deferredFunctionTest.py +7 -7
  115. toil/test/src/environmentTest.py +1 -2
  116. toil/test/src/fileStoreTest.py +5 -5
  117. toil/test/src/importExportFileTest.py +5 -6
  118. toil/test/src/jobServiceTest.py +22 -14
  119. toil/test/src/jobTest.py +121 -25
  120. toil/test/src/miscTests.py +5 -7
  121. toil/test/src/promisedRequirementTest.py +8 -7
  122. toil/test/src/regularLogTest.py +2 -3
  123. toil/test/src/resourceTest.py +5 -8
  124. toil/test/src/restartDAGTest.py +5 -6
  125. toil/test/src/resumabilityTest.py +2 -2
  126. toil/test/src/retainTempDirTest.py +3 -3
  127. toil/test/src/systemTest.py +3 -3
  128. toil/test/src/threadingTest.py +1 -1
  129. toil/test/src/workerTest.py +1 -2
  130. toil/test/utils/toilDebugTest.py +6 -4
  131. toil/test/utils/toilKillTest.py +1 -1
  132. toil/test/utils/utilsTest.py +15 -14
  133. toil/test/wdl/wdltoil_test.py +247 -124
  134. toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
  135. toil/toilState.py +2 -3
  136. toil/utils/toilDebugFile.py +3 -8
  137. toil/utils/toilDebugJob.py +1 -2
  138. toil/utils/toilLaunchCluster.py +1 -2
  139. toil/utils/toilSshCluster.py +2 -0
  140. toil/utils/toilStats.py +19 -24
  141. toil/utils/toilStatus.py +11 -14
  142. toil/version.py +10 -10
  143. toil/wdl/wdltoil.py +313 -209
  144. toil/worker.py +18 -12
  145. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/METADATA +11 -14
  146. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/RECORD +150 -153
  147. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/WHEEL +1 -1
  148. toil/test/cwl/staging_cat.cwl +0 -27
  149. toil/test/cwl/staging_make_file.cwl +0 -25
  150. toil/test/cwl/staging_workflow.cwl +0 -43
  151. toil/test/cwl/zero_default.cwl +0 -61
  152. toil/test/utils/ABCWorkflowDebug/ABC.txt +0 -1
  153. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/entry_points.txt +0 -0
  154. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/licenses/LICENSE +0 -0
  155. {toil-9.1.1.dist-info → toil-9.2.0.dist-info}/top_level.txt +0 -0
toil/lib/aws/ami.py CHANGED
@@ -14,10 +14,13 @@ from toil.lib.retry import retry
14
14
 
15
15
  logger = logging.getLogger(__name__)
16
16
 
17
+
17
18
  class ReleaseFeedUnavailableError(RuntimeError):
18
19
  """Raised when a Flatcar releases can't be located."""
20
+
19
21
  pass
20
22
 
23
+
21
24
  @retry(errors=[ReleaseFeedUnavailableError])
22
25
  def get_flatcar_ami(ec2_client: BaseClient, architecture: str = "amd64") -> str:
23
26
  """
@@ -92,14 +95,14 @@ def _fetch_flatcar_feed(architecture: str = "amd64", source: str = "stable") ->
92
95
  "stable": f"https://stable.release.flatcar-linux.net/{architecture}-usr/current/flatcar_production_ami_all.json",
93
96
  "beta": f"https://beta.release.flatcar-linux.net/{architecture}-usr/current/flatcar_production_ami_all.json",
94
97
  # "alpha": f"https://alpha.release.flatcar-linux.net/{architecture}-usr/current/flatcar_production_ami_all.json",
95
- "archive": f"https://web.archive.org/web/20220625112618if_/https://stable.release.flatcar-linux.net/{architecture}-usr/current/flatcar_production_ami_all.json"
98
+ "archive": f"https://web.archive.org/web/20220625112618if_/https://stable.release.flatcar-linux.net/{architecture}-usr/current/flatcar_production_ami_all.json",
96
99
  }[source]
97
100
  return cast(bytes, urllib.request.urlopen(JSON_FEED_URL).read())
98
101
 
99
102
 
100
103
  def flatcar_release_feed_ami(
101
104
  region: str, architecture: str = "amd64", source: str = "stable"
102
- ) -> Optional[str]:
105
+ ) -> str | None:
103
106
  """
104
107
  Yield AMI IDs for the given architecture from the Flatcar release feed.
105
108
 
@@ -150,12 +153,14 @@ def flatcar_release_feed_ami(
150
153
  if ami_record.get("name") == region:
151
154
  return str(ami_record.get("hvm")) if ami_record.get("hvm") else None
152
155
  # We didn't find our region
153
- logger.warning(f"Flatcar {source} release feed does not have an image for region {region}")
156
+ logger.warning(
157
+ f"Flatcar {source} release feed does not have an image for region {region}"
158
+ )
154
159
 
155
160
 
156
161
  def feed_flatcar_ami_release(
157
162
  ec2_client: BaseClient, architecture: str = "amd64", source: str = "stable"
158
- ) -> Optional[str]:
163
+ ) -> str | None:
159
164
  """
160
165
  Check a Flatcar release feed for the latest flatcar AMI.
161
166
 
@@ -175,27 +180,36 @@ def feed_flatcar_ami_release(
175
180
 
176
181
  region = ec2_client._client_config.region_name # type: ignore
177
182
 
178
- ami = flatcar_release_feed_ami(region, architecture, source)
179
- # verify it exists on AWS
180
- try:
181
- response = ec2_client.describe_images(Filters=[{"Name": "image-id", "Values": [ami]}]) # type: ignore
182
- if (len(response["Images"]) == 1 and response["Images"][0]["State"] == "available"):
183
+ if ami := flatcar_release_feed_ami(region, architecture, source):
184
+ # verify it exists on AWS
185
+ try:
186
+ response = ec2_client.describe_images(Filters=[{"Name": "image-id", "Values": [ami]}]) # type: ignore
187
+ if (
188
+ len(response["Images"]) == 1
189
+ and response["Images"][0]["State"] == "available"
190
+ ):
191
+ return ami
192
+ else:
193
+ logger.warning(
194
+ f"Flatcar release feed suggests image {ami} which does not exist on AWS in {region}"
195
+ )
196
+ except (ClientError, EndpointConnectionError):
197
+ # Sometimes we get back nonsense like:
198
+ # botocore.exceptions.ClientError: An error occurred (AuthFailure) when calling the DescribeImages operation: AWS was not able to validate the provided access credentials
199
+ # Don't hold that against the AMI.
200
+ logger.exception(
201
+ f"Unable to check if AMI {ami} exists on AWS in {region}; assuming it does"
202
+ )
183
203
  return ami
184
- else:
185
- logger.warning(f"Flatcar release feed suggests image {ami} which does not exist on AWS in {region}")
186
- except (ClientError, EndpointConnectionError):
187
- # Sometimes we get back nonsense like:
188
- # botocore.exceptions.ClientError: An error occurred (AuthFailure) when calling the DescribeImages operation: AWS was not able to validate the provided access credentials
189
- # Don't hold that against the AMI.
190
- logger.exception(f"Unable to check if AMI {ami} exists on AWS in {region}; assuming it does")
191
- return ami
192
204
  # We didn't find it
193
- logger.warning(f"Flatcar release feed does not have an image for region {region} that exists on AWS")
205
+ logger.warning(
206
+ f"Flatcar release feed does not have an image for region {region} that exists on AWS"
207
+ )
194
208
 
195
209
 
196
210
  def aws_marketplace_flatcar_ami_search(
197
211
  ec2_client: BaseClient, architecture: str = "amd64"
198
- ) -> Optional[str]:
212
+ ) -> str | None:
199
213
  """
200
214
  Query AWS for all AMI names matching ``Flatcar-stable-*`` and return the most recent one.
201
215
 
toil/lib/aws/iam.py CHANGED
@@ -3,7 +3,7 @@ import json
3
3
  import logging
4
4
  from collections import defaultdict
5
5
  from functools import lru_cache
6
- from typing import TYPE_CHECKING, Any, Optional, Union
6
+ from typing import TYPE_CHECKING, Any, Union
7
7
 
8
8
  import boto3
9
9
  from botocore.exceptions import ClientError
@@ -64,7 +64,7 @@ AllowedActionCollection = dict[str, dict[str, list[str]]]
64
64
 
65
65
  @retry(errors=[AWSServerErrors])
66
66
  def delete_iam_instance_profile(
67
- instance_profile_name: str, region: Optional[str] = None, quiet: bool = True
67
+ instance_profile_name: str, region: str | None = None, quiet: bool = True
68
68
  ) -> None:
69
69
  iam_resource = session.resource("iam", region_name=region)
70
70
  instance_profile = iam_resource.InstanceProfile(instance_profile_name)
@@ -81,7 +81,7 @@ def delete_iam_instance_profile(
81
81
 
82
82
  @retry(errors=[AWSServerErrors])
83
83
  def delete_iam_role(
84
- role_name: str, region: Optional[str] = None, quiet: bool = True
84
+ role_name: str, region: str | None = None, quiet: bool = True
85
85
  ) -> None:
86
86
  """
87
87
  Deletes an AWS IAM role. Any separate policies are detached from the role, and any inline policies are deleted.
@@ -119,7 +119,7 @@ def create_iam_role(
119
119
  role_name: str,
120
120
  assume_role_policy_document: str,
121
121
  policies: dict[str, Any],
122
- region: Optional[str] = None,
122
+ region: str | None = None,
123
123
  ) -> str:
124
124
  """
125
125
  Creates an AWS IAM role. Any separate policies are detached from the role, and any inline policies are deleted.
@@ -336,7 +336,7 @@ def allowed_actions_roles(
336
336
 
337
337
 
338
338
  def collect_policy_actions(
339
- policy_documents: list[Union[str, "PolicyDocumentDictTypeDef"]]
339
+ policy_documents: list[Union[str, "PolicyDocumentDictTypeDef"]],
340
340
  ) -> AllowedActionCollection:
341
341
  """
342
342
  Collect all of the actions allowed by the given policy documents into one AllowedActionCollection.
@@ -478,7 +478,7 @@ def get_policy_permissions(region: str) -> AllowedActionCollection:
478
478
 
479
479
 
480
480
  @lru_cache
481
- def get_aws_account_num() -> Optional[str]:
481
+ def get_aws_account_num() -> str | None:
482
482
  """
483
483
  Returns AWS account num
484
484
  """