toil 8.2.0__py3-none-any.whl → 9.1.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/batchSystems/abstractBatchSystem.py +13 -5
- toil/batchSystems/abstractGridEngineBatchSystem.py +17 -5
- toil/batchSystems/kubernetes.py +13 -2
- toil/batchSystems/mesos/batchSystem.py +33 -2
- toil/batchSystems/registry.py +15 -118
- toil/batchSystems/slurm.py +191 -16
- toil/common.py +20 -1
- toil/cwl/cwltoil.py +97 -119
- toil/cwl/utils.py +103 -3
- toil/fileStores/__init__.py +1 -1
- toil/fileStores/abstractFileStore.py +5 -2
- toil/fileStores/cachingFileStore.py +1 -1
- toil/job.py +30 -14
- toil/jobStores/abstractJobStore.py +35 -255
- toil/jobStores/aws/jobStore.py +864 -1964
- toil/jobStores/aws/utils.py +24 -270
- toil/jobStores/fileJobStore.py +2 -1
- toil/jobStores/googleJobStore.py +32 -13
- toil/jobStores/utils.py +0 -327
- toil/leader.py +27 -22
- toil/lib/accelerators.py +1 -1
- toil/lib/aws/config.py +22 -0
- toil/lib/aws/s3.py +477 -9
- toil/lib/aws/utils.py +22 -33
- toil/lib/checksum.py +88 -0
- toil/lib/conversions.py +33 -31
- toil/lib/directory.py +217 -0
- toil/lib/ec2.py +97 -29
- toil/lib/exceptions.py +2 -1
- toil/lib/expando.py +2 -2
- toil/lib/generatedEC2Lists.py +138 -19
- toil/lib/io.py +33 -2
- toil/lib/memoize.py +21 -7
- toil/lib/misc.py +1 -1
- toil/lib/pipes.py +385 -0
- toil/lib/plugins.py +106 -0
- toil/lib/retry.py +1 -1
- toil/lib/threading.py +1 -1
- toil/lib/url.py +320 -0
- toil/lib/web.py +4 -5
- toil/options/cwl.py +13 -1
- toil/options/runner.py +17 -10
- toil/options/wdl.py +12 -1
- toil/provisioners/__init__.py +5 -2
- toil/provisioners/aws/__init__.py +43 -36
- toil/provisioners/aws/awsProvisioner.py +47 -15
- toil/provisioners/node.py +60 -12
- toil/resource.py +3 -13
- toil/server/app.py +12 -6
- toil/server/cli/wes_cwl_runner.py +2 -2
- toil/server/wes/abstract_backend.py +21 -43
- toil/server/wes/toil_backend.py +2 -2
- toil/test/__init__.py +16 -18
- toil/test/batchSystems/batchSystemTest.py +2 -9
- toil/test/batchSystems/batch_system_plugin_test.py +7 -0
- toil/test/batchSystems/test_slurm.py +103 -14
- toil/test/cwl/cwlTest.py +181 -8
- toil/test/cwl/staging_cat.cwl +27 -0
- toil/test/cwl/staging_make_file.cwl +25 -0
- toil/test/cwl/staging_workflow.cwl +43 -0
- toil/test/cwl/zero_default.cwl +61 -0
- toil/test/docs/scripts/tutorial_staging.py +17 -8
- toil/test/docs/scriptsTest.py +2 -1
- toil/test/jobStores/jobStoreTest.py +23 -133
- toil/test/lib/aws/test_iam.py +7 -7
- toil/test/lib/aws/test_s3.py +30 -33
- toil/test/lib/aws/test_utils.py +9 -9
- toil/test/lib/test_url.py +69 -0
- toil/test/lib/url_plugin_test.py +105 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +60 -7
- toil/test/provisioners/clusterTest.py +15 -2
- toil/test/provisioners/gceProvisionerTest.py +1 -1
- toil/test/server/serverTest.py +78 -36
- toil/test/src/autoDeploymentTest.py +2 -3
- toil/test/src/fileStoreTest.py +89 -87
- toil/test/utils/ABCWorkflowDebug/ABC.txt +1 -0
- toil/test/utils/ABCWorkflowDebug/debugWorkflow.py +4 -4
- toil/test/utils/toilKillTest.py +35 -28
- toil/test/wdl/md5sum/md5sum-gs.json +1 -1
- toil/test/wdl/md5sum/md5sum.json +1 -1
- toil/test/wdl/testfiles/read_file.wdl +18 -0
- toil/test/wdl/testfiles/url_to_optional_file.wdl +2 -1
- toil/test/wdl/wdltoil_test.py +171 -162
- toil/test/wdl/wdltoil_test_kubernetes.py +9 -0
- toil/utils/toilDebugFile.py +6 -3
- toil/utils/toilSshCluster.py +23 -0
- toil/utils/toilStats.py +17 -2
- toil/utils/toilUpdateEC2Instances.py +1 -0
- toil/version.py +10 -10
- toil/wdl/wdltoil.py +1179 -825
- toil/worker.py +16 -8
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/METADATA +32 -32
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/RECORD +97 -85
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/WHEEL +1 -1
- toil/lib/iterables.py +0 -112
- toil/test/docs/scripts/stagingExampleFiles/in.txt +0 -1
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/entry_points.txt +0 -0
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/licenses/LICENSE +0 -0
- {toil-8.2.0.dist-info → toil-9.1.0.dist-info}/top_level.txt +0 -0
|
@@ -32,6 +32,7 @@ from typing import (
|
|
|
32
32
|
Union,
|
|
33
33
|
cast,
|
|
34
34
|
overload,
|
|
35
|
+
Type,
|
|
35
36
|
)
|
|
36
37
|
from urllib.error import HTTPError
|
|
37
38
|
from urllib.parse import ParseResult, urlparse
|
|
@@ -52,6 +53,7 @@ from toil.lib.exceptions import UnimplementedURLException
|
|
|
52
53
|
from toil.lib.io import WriteWatchingStream
|
|
53
54
|
from toil.lib.memoize import memoize
|
|
54
55
|
from toil.lib.retry import ErrorCondition, retry
|
|
56
|
+
from toil.lib.url import URLAccess
|
|
55
57
|
|
|
56
58
|
if TYPE_CHECKING:
|
|
57
59
|
from toil.job import TemporaryID
|
|
@@ -88,7 +90,7 @@ class InvalidImportExportUrlException(Exception):
|
|
|
88
90
|
class NoSuchJobException(Exception):
|
|
89
91
|
"""Indicates that the specified job does not exist."""
|
|
90
92
|
|
|
91
|
-
def __init__(self, jobStoreID: FileID):
|
|
93
|
+
def __init__(self, jobStoreID: Union[FileID, str]):
|
|
92
94
|
"""
|
|
93
95
|
:param str jobStoreID: the jobStoreID that was mistakenly assumed to exist
|
|
94
96
|
"""
|
|
@@ -98,7 +100,7 @@ class NoSuchJobException(Exception):
|
|
|
98
100
|
class ConcurrentFileModificationException(Exception):
|
|
99
101
|
"""Indicates that the file was attempted to be modified by multiple processes at once."""
|
|
100
102
|
|
|
101
|
-
def __init__(self, jobStoreFileID: FileID):
|
|
103
|
+
def __init__(self, jobStoreFileID: Union[FileID, str]):
|
|
102
104
|
"""
|
|
103
105
|
:param jobStoreFileID: the ID of the file that was modified by multiple workers
|
|
104
106
|
or processes concurrently
|
|
@@ -110,7 +112,7 @@ class NoSuchFileException(Exception):
|
|
|
110
112
|
"""Indicates that the specified file does not exist."""
|
|
111
113
|
|
|
112
114
|
def __init__(
|
|
113
|
-
self, jobStoreFileID: FileID, customName: Optional[str] = None, *extra: Any
|
|
115
|
+
self, jobStoreFileID: Union[FileID, str], customName: Optional[str] = None, *extra: Any
|
|
114
116
|
):
|
|
115
117
|
"""
|
|
116
118
|
:param jobStoreFileID: the ID of the file that was mistakenly assumed to exist
|
|
@@ -138,11 +140,12 @@ class NoSuchJobStoreException(LocatorException):
|
|
|
138
140
|
def __init__(self, locator: str, prefix: str):
|
|
139
141
|
"""
|
|
140
142
|
:param str locator: The location of the job store
|
|
143
|
+
:param str prefix: The type of job store
|
|
141
144
|
"""
|
|
142
145
|
super().__init__(
|
|
143
146
|
"The job store '%s' does not exist, so there is nothing to restart.",
|
|
144
147
|
locator,
|
|
145
|
-
prefix
|
|
148
|
+
prefix
|
|
146
149
|
)
|
|
147
150
|
|
|
148
151
|
|
|
@@ -157,7 +160,7 @@ class JobStoreExistsException(LocatorException):
|
|
|
157
160
|
"The job store '%s' already exists. Use --restart to resume the workflow, or remove "
|
|
158
161
|
"the job store with 'toil clean' to start the workflow from scratch.",
|
|
159
162
|
locator,
|
|
160
|
-
prefix
|
|
163
|
+
prefix
|
|
161
164
|
)
|
|
162
165
|
|
|
163
166
|
|
|
@@ -238,7 +241,12 @@ class AbstractJobStore(ABC):
|
|
|
238
241
|
|
|
239
242
|
@property
|
|
240
243
|
def config(self) -> Config:
|
|
241
|
-
"""
|
|
244
|
+
"""
|
|
245
|
+
Return the Toil configuration associated with this job store.
|
|
246
|
+
|
|
247
|
+
:raises AttributeError: if the config has not yet been assigned (i.e.
|
|
248
|
+
during :meth:`resume`).
|
|
249
|
+
"""
|
|
242
250
|
return self.__config
|
|
243
251
|
|
|
244
252
|
@property
|
|
@@ -354,23 +362,6 @@ class AbstractJobStore(ABC):
|
|
|
354
362
|
jobStoreClasses.append(jobStoreClass)
|
|
355
363
|
return jobStoreClasses
|
|
356
364
|
|
|
357
|
-
@classmethod
|
|
358
|
-
def _findJobStoreForUrl(
|
|
359
|
-
cls, url: ParseResult, export: bool = False
|
|
360
|
-
) -> "AbstractJobStore":
|
|
361
|
-
"""
|
|
362
|
-
Returns the AbstractJobStore subclass that supports the given URL.
|
|
363
|
-
|
|
364
|
-
:param ParseResult url: The given URL
|
|
365
|
-
|
|
366
|
-
:param bool export: Determines if the url is supported for exporting
|
|
367
|
-
|
|
368
|
-
:rtype: toil.jobStore.AbstractJobStore
|
|
369
|
-
"""
|
|
370
|
-
for implementation in cls._get_job_store_classes():
|
|
371
|
-
if implementation._supports_url(url, export):
|
|
372
|
-
return implementation
|
|
373
|
-
raise UnimplementedURLException(url, "export" if export else "import")
|
|
374
365
|
|
|
375
366
|
# Importing a file with a shared file name returns None, but without one it
|
|
376
367
|
# returns a file ID. Explain this to MyPy.
|
|
@@ -464,7 +455,7 @@ class AbstractJobStore(ABC):
|
|
|
464
455
|
# optimizations that circumvent this, the _import_file method should be overridden by
|
|
465
456
|
# subclasses of AbstractJobStore.
|
|
466
457
|
parseResult = urlparse(src_uri)
|
|
467
|
-
otherCls =
|
|
458
|
+
otherCls = URLAccess._find_url_implementation(parseResult)
|
|
468
459
|
logger.info("Importing input %s...", src_uri)
|
|
469
460
|
return self._import_file(
|
|
470
461
|
otherCls,
|
|
@@ -476,7 +467,7 @@ class AbstractJobStore(ABC):
|
|
|
476
467
|
|
|
477
468
|
def _import_file(
|
|
478
469
|
self,
|
|
479
|
-
otherCls: "
|
|
470
|
+
otherCls: Type["URLAccess"],
|
|
480
471
|
uri: ParseResult,
|
|
481
472
|
shared_file_name: Optional[str] = None,
|
|
482
473
|
hardlink: bool = False,
|
|
@@ -490,7 +481,7 @@ class AbstractJobStore(ABC):
|
|
|
490
481
|
|
|
491
482
|
Raises FileNotFoundError if the file does not exist.
|
|
492
483
|
|
|
493
|
-
:param
|
|
484
|
+
:param URLAccess otherCls: The class of URLAccess that supports
|
|
494
485
|
reading from the given URL and getting the file size from the URL.
|
|
495
486
|
|
|
496
487
|
:param ParseResult uri: The location of the file to import.
|
|
@@ -535,16 +526,16 @@ class AbstractJobStore(ABC):
|
|
|
535
526
|
from toil.common import Toil
|
|
536
527
|
dst_uri = Toil.normalize_uri(dst_uri)
|
|
537
528
|
parseResult = urlparse(dst_uri)
|
|
538
|
-
otherCls =
|
|
529
|
+
otherCls = URLAccess._find_url_implementation(parseResult, export=True)
|
|
539
530
|
self._export_file(otherCls, file_id, parseResult)
|
|
540
531
|
|
|
541
532
|
def _export_file(
|
|
542
|
-
self, otherCls: "
|
|
533
|
+
self, otherCls: Type["URLAccess"], jobStoreFileID: FileID, url: ParseResult
|
|
543
534
|
) -> None:
|
|
544
535
|
"""
|
|
545
536
|
Refer to exportFile docstring for information about this method.
|
|
546
537
|
|
|
547
|
-
:param
|
|
538
|
+
:param URLAccess otherCls: The class of URLAccess that supports
|
|
548
539
|
exporting to the given URL. Note that the type annotation here is not completely
|
|
549
540
|
accurate. This is not an instance, it's a class, but there is no way to reflect
|
|
550
541
|
that in :pep:`484` type hints.
|
|
@@ -556,12 +547,12 @@ class AbstractJobStore(ABC):
|
|
|
556
547
|
self._default_export_file(otherCls, jobStoreFileID, url)
|
|
557
548
|
|
|
558
549
|
def _default_export_file(
|
|
559
|
-
self, otherCls: "
|
|
550
|
+
self, otherCls: Type["URLAccess"], jobStoreFileID: FileID, url: ParseResult
|
|
560
551
|
) -> None:
|
|
561
552
|
"""
|
|
562
553
|
Refer to exportFile docstring for information about this method.
|
|
563
554
|
|
|
564
|
-
:param
|
|
555
|
+
:param URLAccess otherCls: The class of URLAccess that supports
|
|
565
556
|
exporting to the given URL. Note that the type annotation here is not completely
|
|
566
557
|
accurate. This is not an instance, it's a class, but there is no way to reflect
|
|
567
558
|
that in :pep:`484` type hints.
|
|
@@ -576,217 +567,6 @@ class AbstractJobStore(ABC):
|
|
|
576
567
|
executable = jobStoreFileID.executable
|
|
577
568
|
otherCls._write_to_url(readable, url, executable)
|
|
578
569
|
|
|
579
|
-
@classmethod
|
|
580
|
-
def url_exists(cls, src_uri: str) -> bool:
|
|
581
|
-
"""
|
|
582
|
-
Return True if the file at the given URI exists, and False otherwise.
|
|
583
|
-
|
|
584
|
-
May raise an error if file existence cannot be determined.
|
|
585
|
-
|
|
586
|
-
:param src_uri: URL that points to a file or object in the storage
|
|
587
|
-
mechanism of a supported URL scheme e.g. a blob in an AWS s3 bucket.
|
|
588
|
-
"""
|
|
589
|
-
parseResult = urlparse(src_uri)
|
|
590
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
591
|
-
return otherCls._url_exists(parseResult)
|
|
592
|
-
|
|
593
|
-
@classmethod
|
|
594
|
-
def get_size(cls, src_uri: str) -> Optional[int]:
|
|
595
|
-
"""
|
|
596
|
-
Get the size in bytes of the file at the given URL, or None if it cannot be obtained.
|
|
597
|
-
|
|
598
|
-
:param src_uri: URL that points to a file or object in the storage
|
|
599
|
-
mechanism of a supported URL scheme e.g. a blob in an AWS s3 bucket.
|
|
600
|
-
"""
|
|
601
|
-
parseResult = urlparse(src_uri)
|
|
602
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
603
|
-
return otherCls._get_size(parseResult)
|
|
604
|
-
|
|
605
|
-
@classmethod
|
|
606
|
-
def get_is_directory(cls, src_uri: str) -> bool:
|
|
607
|
-
"""
|
|
608
|
-
Return True if the thing at the given URL is a directory, and False if
|
|
609
|
-
it is a file. The URL may or may not end in '/'.
|
|
610
|
-
"""
|
|
611
|
-
parseResult = urlparse(src_uri)
|
|
612
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
613
|
-
return otherCls._get_is_directory(parseResult)
|
|
614
|
-
|
|
615
|
-
@classmethod
|
|
616
|
-
def list_url(cls, src_uri: str) -> list[str]:
|
|
617
|
-
"""
|
|
618
|
-
List the directory at the given URL. Returned path components can be
|
|
619
|
-
joined with '/' onto the passed URL to form new URLs. Those that end in
|
|
620
|
-
'/' correspond to directories. The provided URL may or may not end with
|
|
621
|
-
'/'.
|
|
622
|
-
|
|
623
|
-
Currently supported schemes are:
|
|
624
|
-
|
|
625
|
-
- 's3' for objects in Amazon S3
|
|
626
|
-
e.g. s3://bucket/prefix/
|
|
627
|
-
|
|
628
|
-
- 'file' for local files
|
|
629
|
-
e.g. file:///local/dir/path/
|
|
630
|
-
|
|
631
|
-
:param str src_uri: URL that points to a directory or prefix in the storage mechanism of a
|
|
632
|
-
supported URL scheme e.g. a prefix in an AWS s3 bucket.
|
|
633
|
-
|
|
634
|
-
:return: A list of URL components in the given directory, already URL-encoded.
|
|
635
|
-
"""
|
|
636
|
-
parseResult = urlparse(src_uri)
|
|
637
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
638
|
-
return otherCls._list_url(parseResult)
|
|
639
|
-
|
|
640
|
-
@classmethod
|
|
641
|
-
def read_from_url(cls, src_uri: str, writable: IO[bytes]) -> tuple[int, bool]:
|
|
642
|
-
"""
|
|
643
|
-
Read the given URL and write its content into the given writable stream.
|
|
644
|
-
|
|
645
|
-
Raises FileNotFoundError if the URL doesn't exist.
|
|
646
|
-
|
|
647
|
-
:return: The size of the file in bytes and whether the executable permission bit is set
|
|
648
|
-
"""
|
|
649
|
-
parseResult = urlparse(src_uri)
|
|
650
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
651
|
-
return otherCls._read_from_url(parseResult, writable)
|
|
652
|
-
|
|
653
|
-
@classmethod
|
|
654
|
-
def open_url(cls, src_uri: str) -> IO[bytes]:
|
|
655
|
-
"""
|
|
656
|
-
Read from the given URI.
|
|
657
|
-
|
|
658
|
-
Raises FileNotFoundError if the URL doesn't exist.
|
|
659
|
-
|
|
660
|
-
Has a readable stream interface, unlike :meth:`read_from_url` which
|
|
661
|
-
takes a writable stream.
|
|
662
|
-
"""
|
|
663
|
-
parseResult = urlparse(src_uri)
|
|
664
|
-
otherCls = cls._findJobStoreForUrl(parseResult)
|
|
665
|
-
return otherCls._open_url(parseResult)
|
|
666
|
-
|
|
667
|
-
@classmethod
|
|
668
|
-
@abstractmethod
|
|
669
|
-
def _url_exists(cls, url: ParseResult) -> bool:
|
|
670
|
-
"""
|
|
671
|
-
Return True if the item at the given URL exists, and Flase otherwise.
|
|
672
|
-
|
|
673
|
-
May raise an error if file existence cannot be determined.
|
|
674
|
-
"""
|
|
675
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
676
|
-
|
|
677
|
-
@classmethod
|
|
678
|
-
@abstractmethod
|
|
679
|
-
def _get_size(cls, url: ParseResult) -> Optional[int]:
|
|
680
|
-
"""
|
|
681
|
-
Get the size of the object at the given URL, or None if it cannot be obtained.
|
|
682
|
-
"""
|
|
683
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
684
|
-
|
|
685
|
-
@classmethod
|
|
686
|
-
@abstractmethod
|
|
687
|
-
def _get_is_directory(cls, url: ParseResult) -> bool:
|
|
688
|
-
"""
|
|
689
|
-
Return True if the thing at the given URL is a directory, and False if
|
|
690
|
-
it is a file or it is known not to exist. The URL may or may not end in
|
|
691
|
-
'/'.
|
|
692
|
-
|
|
693
|
-
:param url: URL that points to a file or object, or directory or prefix,
|
|
694
|
-
in the storage mechanism of a supported URL scheme e.g. a blob
|
|
695
|
-
in an AWS s3 bucket.
|
|
696
|
-
"""
|
|
697
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
698
|
-
|
|
699
|
-
@classmethod
|
|
700
|
-
@abstractmethod
|
|
701
|
-
def _read_from_url(cls, url: ParseResult, writable: IO[bytes]) -> tuple[int, bool]:
|
|
702
|
-
"""
|
|
703
|
-
Reads the contents of the object at the specified location and writes it to the given
|
|
704
|
-
writable stream.
|
|
705
|
-
|
|
706
|
-
Refer to :func:`~AbstractJobStore.importFile` documentation for currently supported URL schemes.
|
|
707
|
-
|
|
708
|
-
Raises FileNotFoundError if the thing at the URL is not found.
|
|
709
|
-
|
|
710
|
-
:param ParseResult url: URL that points to a file or object in the storage
|
|
711
|
-
mechanism of a supported URL scheme e.g. a blob in an AWS s3 bucket.
|
|
712
|
-
|
|
713
|
-
:param IO[bytes] writable: a writable stream
|
|
714
|
-
|
|
715
|
-
:return: The size of the file in bytes and whether the executable permission bit is set
|
|
716
|
-
"""
|
|
717
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
718
|
-
|
|
719
|
-
@classmethod
|
|
720
|
-
@abstractmethod
|
|
721
|
-
def _list_url(cls, url: ParseResult) -> list[str]:
|
|
722
|
-
"""
|
|
723
|
-
List the contents of the given URL, which may or may not end in '/'
|
|
724
|
-
|
|
725
|
-
Returns a list of URL components. Those that end in '/' are meant to be
|
|
726
|
-
directories, while those that do not are meant to be files.
|
|
727
|
-
|
|
728
|
-
Refer to :func:`~AbstractJobStore.importFile` documentation for currently supported URL schemes.
|
|
729
|
-
|
|
730
|
-
:param ParseResult url: URL that points to a directory or prefix in the
|
|
731
|
-
storage mechanism of a supported URL scheme e.g. a prefix in an AWS s3
|
|
732
|
-
bucket.
|
|
733
|
-
|
|
734
|
-
:return: The children of the given URL, already URL-encoded if
|
|
735
|
-
appropriate. (If the URL is a bare path, no encoding is done.)
|
|
736
|
-
"""
|
|
737
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
738
|
-
|
|
739
|
-
@classmethod
|
|
740
|
-
@abstractmethod
|
|
741
|
-
def _open_url(cls, url: ParseResult) -> IO[bytes]:
|
|
742
|
-
"""
|
|
743
|
-
Get a stream of the object at the specified location.
|
|
744
|
-
|
|
745
|
-
Refer to :func:`~AbstractJobStore.importFile` documentation for currently supported URL schemes.
|
|
746
|
-
|
|
747
|
-
Raises FileNotFoundError if the thing at the URL is not found.
|
|
748
|
-
"""
|
|
749
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
750
|
-
|
|
751
|
-
@classmethod
|
|
752
|
-
@abstractmethod
|
|
753
|
-
def _write_to_url(
|
|
754
|
-
cls,
|
|
755
|
-
readable: Union[IO[bytes], IO[str]],
|
|
756
|
-
url: ParseResult,
|
|
757
|
-
executable: bool = False,
|
|
758
|
-
) -> None:
|
|
759
|
-
"""
|
|
760
|
-
Reads the contents of the given readable stream and writes it to the object at the
|
|
761
|
-
specified location. Raises FileNotFoundError if the URL doesn't exist..
|
|
762
|
-
|
|
763
|
-
Refer to AbstractJobStore.importFile documentation for currently supported URL schemes.
|
|
764
|
-
|
|
765
|
-
:param Union[IO[bytes], IO[str]] readable: a readable stream
|
|
766
|
-
|
|
767
|
-
:param ParseResult url: URL that points to a file or object in the storage
|
|
768
|
-
mechanism of a supported URL scheme e.g. a blob in an AWS s3 bucket.
|
|
769
|
-
|
|
770
|
-
:param bool executable: determines if the file has executable permissions
|
|
771
|
-
"""
|
|
772
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
773
|
-
|
|
774
|
-
@classmethod
|
|
775
|
-
@abstractmethod
|
|
776
|
-
def _supports_url(cls, url: ParseResult, export: bool = False) -> bool:
|
|
777
|
-
"""
|
|
778
|
-
Returns True if the job store supports the URL's scheme.
|
|
779
|
-
|
|
780
|
-
Refer to AbstractJobStore.importFile documentation for currently supported URL schemes.
|
|
781
|
-
|
|
782
|
-
:param ParseResult url: a parsed URL that may be supported
|
|
783
|
-
|
|
784
|
-
:param bool export: Determines if the url is supported for exported
|
|
785
|
-
|
|
786
|
-
:return bool: returns true if the cls supports the URL
|
|
787
|
-
"""
|
|
788
|
-
raise NotImplementedError(f"No implementation for {url}")
|
|
789
|
-
|
|
790
570
|
@abstractmethod
|
|
791
571
|
def destroy(self) -> None:
|
|
792
572
|
"""
|
|
@@ -1155,15 +935,6 @@ class AbstractJobStore(ABC):
|
|
|
1155
935
|
"""
|
|
1156
936
|
raise NotImplementedError()
|
|
1157
937
|
|
|
1158
|
-
@contextmanager
|
|
1159
|
-
def batch(self) -> Iterator[None]:
|
|
1160
|
-
"""
|
|
1161
|
-
If supported by the batch system, calls to create() with this context
|
|
1162
|
-
manager active will be performed in a batch after the context manager
|
|
1163
|
-
is released.
|
|
1164
|
-
"""
|
|
1165
|
-
yield
|
|
1166
|
-
|
|
1167
938
|
@deprecated(new_function_name="create_job")
|
|
1168
939
|
def create(self, jobDescription: JobDescription) -> JobDescription:
|
|
1169
940
|
return self.create_job(jobDescription)
|
|
@@ -1261,6 +1032,15 @@ class AbstractJobStore(ABC):
|
|
|
1261
1032
|
def update(self, jobDescription: JobDescription) -> None:
|
|
1262
1033
|
return self.update_job(jobDescription)
|
|
1263
1034
|
|
|
1035
|
+
@contextmanager
|
|
1036
|
+
def batch(self) -> Iterator[None]:
|
|
1037
|
+
"""
|
|
1038
|
+
If supported by the batch system, calls to create() with this context
|
|
1039
|
+
manager active will be performed in a batch after the context manager
|
|
1040
|
+
is released.
|
|
1041
|
+
"""
|
|
1042
|
+
yield
|
|
1043
|
+
|
|
1264
1044
|
@abstractmethod
|
|
1265
1045
|
def update_job(self, job_description: JobDescription) -> None:
|
|
1266
1046
|
"""
|
|
@@ -1431,14 +1211,14 @@ class AbstractJobStore(ABC):
|
|
|
1431
1211
|
Creates an empty file in the job store and returns its ID.
|
|
1432
1212
|
Call to fileExists(getEmptyFileStoreID(jobStoreID)) will return True.
|
|
1433
1213
|
|
|
1434
|
-
:param
|
|
1214
|
+
:param job_id: the id of a job, or None. If specified, the may be associated
|
|
1435
1215
|
with that job in a job-store-specific way. This may influence the returned ID.
|
|
1436
1216
|
|
|
1437
|
-
:param
|
|
1217
|
+
:param cleanup: Whether to attempt to delete the file when the job
|
|
1438
1218
|
whose jobStoreID was given as jobStoreID is deleted with
|
|
1439
1219
|
jobStore.delete(job). If jobStoreID was not given, does nothing.
|
|
1440
1220
|
|
|
1441
|
-
:param
|
|
1221
|
+
:param basename: If supported by the implementation, use the given
|
|
1442
1222
|
file basename so that when searching the job store with a query
|
|
1443
1223
|
matching that basename, the file will be detected.
|
|
1444
1224
|
|
|
@@ -1872,7 +1652,7 @@ class AbstractJobStore(ABC):
|
|
|
1872
1652
|
raise ValueError("Not a valid shared file name: '%s'." % sharedFileName)
|
|
1873
1653
|
|
|
1874
1654
|
|
|
1875
|
-
class JobStoreSupport(AbstractJobStore, metaclass=ABCMeta):
|
|
1655
|
+
class JobStoreSupport(AbstractJobStore, URLAccess, metaclass=ABCMeta):
|
|
1876
1656
|
"""
|
|
1877
1657
|
A mostly fake JobStore to access URLs not really associated with real job
|
|
1878
1658
|
stores.
|