toil 8.1.0b1__py3-none-any.whl → 9.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 +0 -35
- toil/batchSystems/abstractBatchSystem.py +1 -1
- toil/batchSystems/abstractGridEngineBatchSystem.py +1 -1
- toil/batchSystems/awsBatch.py +1 -1
- toil/batchSystems/cleanup_support.py +1 -1
- toil/batchSystems/kubernetes.py +53 -7
- toil/batchSystems/local_support.py +1 -1
- toil/batchSystems/mesos/batchSystem.py +13 -8
- toil/batchSystems/mesos/test/__init__.py +3 -2
- toil/batchSystems/registry.py +15 -118
- toil/batchSystems/singleMachine.py +1 -1
- toil/batchSystems/slurm.py +27 -26
- toil/bus.py +5 -3
- toil/common.py +59 -12
- toil/cwl/cwltoil.py +81 -38
- toil/cwl/utils.py +103 -3
- toil/job.py +64 -49
- toil/jobStores/abstractJobStore.py +35 -239
- toil/jobStores/aws/jobStore.py +2 -1
- toil/jobStores/fileJobStore.py +27 -2
- toil/jobStores/googleJobStore.py +110 -33
- toil/leader.py +9 -0
- toil/lib/accelerators.py +4 -2
- toil/lib/aws/utils.py.orig +504 -0
- toil/lib/bioio.py +1 -1
- toil/lib/docker.py +252 -91
- toil/lib/dockstore.py +11 -3
- toil/lib/exceptions.py +5 -3
- toil/lib/generatedEC2Lists.py +81 -19
- toil/lib/history.py +87 -13
- toil/lib/history_submission.py +23 -9
- toil/lib/io.py +34 -22
- toil/lib/misc.py +8 -2
- toil/lib/plugins.py +106 -0
- toil/lib/resources.py +2 -1
- toil/lib/threading.py +11 -10
- toil/lib/url.py +320 -0
- toil/options/common.py +8 -0
- toil/options/cwl.py +13 -1
- toil/options/runner.py +17 -10
- toil/options/wdl.py +22 -0
- toil/provisioners/aws/awsProvisioner.py +25 -2
- toil/server/api_spec/LICENSE +201 -0
- toil/server/api_spec/README.rst +5 -0
- toil/server/app.py +12 -6
- toil/server/cli/wes_cwl_runner.py +3 -2
- toil/server/wes/abstract_backend.py +21 -43
- toil/server/wes/toil_backend.py +2 -2
- toil/test/__init__.py +275 -115
- toil/test/batchSystems/batchSystemTest.py +228 -213
- toil/test/batchSystems/batch_system_plugin_test.py +7 -0
- toil/test/batchSystems/test_slurm.py +27 -0
- toil/test/cactus/pestis.tar.gz +0 -0
- toil/test/conftest.py +7 -0
- toil/test/cwl/2.fasta +11 -0
- toil/test/cwl/2.fastq +12 -0
- toil/test/cwl/conftest.py +1 -1
- toil/test/cwl/cwlTest.py +1175 -870
- toil/test/cwl/directory/directory/file.txt +15 -0
- toil/test/cwl/download_directory_file.json +4 -0
- toil/test/cwl/download_directory_s3.json +4 -0
- toil/test/cwl/download_file.json +6 -0
- toil/test/cwl/download_http.json +6 -0
- toil/test/cwl/download_https.json +6 -0
- toil/test/cwl/download_s3.json +6 -0
- toil/test/cwl/download_subdirectory_file.json +5 -0
- toil/test/cwl/download_subdirectory_s3.json +5 -0
- toil/test/cwl/empty.json +1 -0
- toil/test/cwl/mock_mpi/fake_mpi.yml +8 -0
- toil/test/cwl/mock_mpi/fake_mpi_run.py +42 -0
- toil/test/cwl/optional-file-exists.json +6 -0
- toil/test/cwl/optional-file-missing.json +6 -0
- toil/test/cwl/preemptible_expression.json +1 -0
- toil/test/cwl/revsort-job-missing.json +6 -0
- toil/test/cwl/revsort-job.json +6 -0
- toil/test/cwl/s3_secondary_file.json +16 -0
- toil/test/cwl/seqtk_seq_job.json +6 -0
- toil/test/cwl/stream.json +6 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.dat +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f1 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f1i +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f2 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f2_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f3 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f3_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f4 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f4_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f5 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.info +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.lock +0 -0
- toil/test/cwl/whale.txt +16 -0
- toil/test/docs/scripts/example_alwaysfail.py +38 -0
- toil/test/docs/scripts/example_alwaysfail_with_files.wdl +33 -0
- toil/test/docs/scripts/example_cachingbenchmark.py +117 -0
- toil/test/docs/scripts/stagingExampleFiles/in.txt +1 -0
- toil/test/docs/scripts/stagingExampleFiles/out.txt +2 -0
- toil/test/docs/scripts/tutorial_arguments.py +23 -0
- toil/test/docs/scripts/tutorial_debugging.patch +12 -0
- toil/test/docs/scripts/tutorial_debugging_hangs.wdl +126 -0
- toil/test/docs/scripts/tutorial_debugging_works.wdl +129 -0
- toil/test/docs/scripts/tutorial_docker.py +20 -0
- toil/test/docs/scripts/tutorial_dynamic.py +24 -0
- toil/test/docs/scripts/tutorial_encapsulation.py +28 -0
- toil/test/docs/scripts/tutorial_encapsulation2.py +29 -0
- toil/test/docs/scripts/tutorial_helloworld.py +15 -0
- toil/test/docs/scripts/tutorial_invokeworkflow.py +27 -0
- toil/test/docs/scripts/tutorial_invokeworkflow2.py +30 -0
- toil/test/docs/scripts/tutorial_jobfunctions.py +22 -0
- toil/test/docs/scripts/tutorial_managing.py +29 -0
- toil/test/docs/scripts/tutorial_managing2.py +56 -0
- toil/test/docs/scripts/tutorial_multiplejobs.py +25 -0
- toil/test/docs/scripts/tutorial_multiplejobs2.py +21 -0
- toil/test/docs/scripts/tutorial_multiplejobs3.py +22 -0
- toil/test/docs/scripts/tutorial_promises.py +25 -0
- toil/test/docs/scripts/tutorial_promises2.py +30 -0
- toil/test/docs/scripts/tutorial_quickstart.py +22 -0
- toil/test/docs/scripts/tutorial_requirements.py +44 -0
- toil/test/docs/scripts/tutorial_services.py +45 -0
- toil/test/docs/scripts/tutorial_staging.py +45 -0
- toil/test/docs/scripts/tutorial_stats.py +64 -0
- toil/test/docs/scriptsTest.py +2 -1
- toil/test/lib/aws/test_iam.py +3 -1
- toil/test/lib/dockerTest.py +205 -122
- toil/test/lib/test_history.py +101 -77
- toil/test/lib/test_url.py +69 -0
- toil/test/lib/url_plugin_test.py +105 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +13 -10
- toil/test/provisioners/clusterTest.py +17 -4
- toil/test/provisioners/gceProvisionerTest.py +17 -15
- toil/test/server/serverTest.py +78 -36
- toil/test/sort/sort.py +4 -1
- toil/test/src/busTest.py +17 -17
- toil/test/src/deferredFunctionTest.py +145 -132
- toil/test/src/importExportFileTest.py +71 -63
- toil/test/src/jobEncapsulationTest.py +27 -28
- toil/test/src/jobServiceTest.py +149 -133
- toil/test/src/jobTest.py +219 -211
- toil/test/src/miscTests.py +66 -60
- toil/test/src/promisedRequirementTest.py +163 -169
- toil/test/src/regularLogTest.py +24 -24
- toil/test/src/resourceTest.py +82 -76
- toil/test/src/restartDAGTest.py +51 -47
- toil/test/src/resumabilityTest.py +24 -19
- toil/test/src/retainTempDirTest.py +60 -57
- toil/test/src/systemTest.py +17 -13
- toil/test/src/threadingTest.py +29 -32
- toil/test/utils/ABCWorkflowDebug/B_file.txt +1 -0
- toil/test/utils/ABCWorkflowDebug/debugWorkflow.py +204 -0
- toil/test/utils/ABCWorkflowDebug/mkFile.py +16 -0
- toil/test/utils/ABCWorkflowDebug/sleep.cwl +12 -0
- toil/test/utils/ABCWorkflowDebug/sleep.yaml +1 -0
- toil/test/utils/toilDebugTest.py +117 -102
- toil/test/utils/toilKillTest.py +54 -53
- toil/test/utils/utilsTest.py +303 -229
- toil/test/wdl/lint_error.wdl +9 -0
- toil/test/wdl/md5sum/empty_file.json +1 -0
- toil/test/wdl/md5sum/md5sum-gs.json +1 -0
- toil/test/wdl/md5sum/md5sum.1.0.wdl +32 -0
- toil/test/wdl/md5sum/md5sum.input +1 -0
- toil/test/wdl/md5sum/md5sum.json +1 -0
- toil/test/wdl/md5sum/md5sum.wdl +25 -0
- toil/test/wdl/miniwdl_self_test/inputs-namespaced.json +1 -0
- toil/test/wdl/miniwdl_self_test/inputs.json +1 -0
- toil/test/wdl/miniwdl_self_test/self_test.wdl +40 -0
- toil/test/wdl/standard_library/as_map.json +16 -0
- toil/test/wdl/standard_library/as_map_as_input.wdl +23 -0
- toil/test/wdl/standard_library/as_pairs.json +7 -0
- toil/test/wdl/standard_library/as_pairs_as_input.wdl +23 -0
- toil/test/wdl/standard_library/ceil.json +3 -0
- toil/test/wdl/standard_library/ceil_as_command.wdl +16 -0
- toil/test/wdl/standard_library/ceil_as_input.wdl +16 -0
- toil/test/wdl/standard_library/collect_by_key.json +1 -0
- toil/test/wdl/standard_library/collect_by_key_as_input.wdl +23 -0
- toil/test/wdl/standard_library/cross.json +11 -0
- toil/test/wdl/standard_library/cross_as_input.wdl +19 -0
- toil/test/wdl/standard_library/flatten.json +7 -0
- toil/test/wdl/standard_library/flatten_as_input.wdl +18 -0
- toil/test/wdl/standard_library/floor.json +3 -0
- toil/test/wdl/standard_library/floor_as_command.wdl +16 -0
- toil/test/wdl/standard_library/floor_as_input.wdl +16 -0
- toil/test/wdl/standard_library/keys.json +8 -0
- toil/test/wdl/standard_library/keys_as_input.wdl +24 -0
- toil/test/wdl/standard_library/length.json +7 -0
- toil/test/wdl/standard_library/length_as_input.wdl +16 -0
- toil/test/wdl/standard_library/length_as_input_with_map.json +7 -0
- toil/test/wdl/standard_library/length_as_input_with_map.wdl +17 -0
- toil/test/wdl/standard_library/length_invalid.json +3 -0
- toil/test/wdl/standard_library/range.json +3 -0
- toil/test/wdl/standard_library/range_0.json +3 -0
- toil/test/wdl/standard_library/range_as_input.wdl +17 -0
- toil/test/wdl/standard_library/range_invalid.json +3 -0
- toil/test/wdl/standard_library/read_boolean.json +3 -0
- toil/test/wdl/standard_library/read_boolean_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_float.json +3 -0
- toil/test/wdl/standard_library/read_float_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_int.json +3 -0
- toil/test/wdl/standard_library/read_int_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_json.json +3 -0
- toil/test/wdl/standard_library/read_json_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_lines.json +3 -0
- toil/test/wdl/standard_library/read_lines_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_map.json +3 -0
- toil/test/wdl/standard_library/read_map_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_string.json +3 -0
- toil/test/wdl/standard_library/read_string_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_tsv.json +3 -0
- toil/test/wdl/standard_library/read_tsv_as_output.wdl +31 -0
- toil/test/wdl/standard_library/round.json +3 -0
- toil/test/wdl/standard_library/round_as_command.wdl +16 -0
- toil/test/wdl/standard_library/round_as_input.wdl +16 -0
- toil/test/wdl/standard_library/size.json +3 -0
- toil/test/wdl/standard_library/size_as_command.wdl +17 -0
- toil/test/wdl/standard_library/size_as_output.wdl +36 -0
- toil/test/wdl/standard_library/stderr.json +3 -0
- toil/test/wdl/standard_library/stderr_as_output.wdl +30 -0
- toil/test/wdl/standard_library/stdout.json +3 -0
- toil/test/wdl/standard_library/stdout_as_output.wdl +30 -0
- toil/test/wdl/standard_library/sub.json +3 -0
- toil/test/wdl/standard_library/sub_as_input.wdl +17 -0
- toil/test/wdl/standard_library/sub_as_input_with_file.wdl +17 -0
- toil/test/wdl/standard_library/transpose.json +6 -0
- toil/test/wdl/standard_library/transpose_as_input.wdl +18 -0
- toil/test/wdl/standard_library/write_json.json +6 -0
- toil/test/wdl/standard_library/write_json_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_lines.json +7 -0
- toil/test/wdl/standard_library/write_lines_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_map.json +6 -0
- toil/test/wdl/standard_library/write_map_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_tsv.json +6 -0
- toil/test/wdl/standard_library/write_tsv_as_command.wdl +17 -0
- toil/test/wdl/standard_library/zip.json +12 -0
- toil/test/wdl/standard_library/zip_as_input.wdl +19 -0
- toil/test/wdl/test.csv +3 -0
- toil/test/wdl/test.tsv +3 -0
- toil/test/wdl/testfiles/croo.wdl +38 -0
- toil/test/wdl/testfiles/drop_files.wdl +62 -0
- toil/test/wdl/testfiles/drop_files_subworkflow.wdl +13 -0
- toil/test/wdl/testfiles/empty.txt +0 -0
- toil/test/wdl/testfiles/not_enough_outputs.wdl +33 -0
- toil/test/wdl/testfiles/random.wdl +66 -0
- toil/test/wdl/testfiles/read_file.wdl +18 -0
- toil/test/wdl/testfiles/string_file_coercion.json +1 -0
- toil/test/wdl/testfiles/string_file_coercion.wdl +35 -0
- toil/test/wdl/testfiles/test.json +4 -0
- toil/test/wdl/testfiles/test_boolean.txt +1 -0
- toil/test/wdl/testfiles/test_float.txt +1 -0
- toil/test/wdl/testfiles/test_int.txt +1 -0
- toil/test/wdl/testfiles/test_lines.txt +5 -0
- toil/test/wdl/testfiles/test_map.txt +2 -0
- toil/test/wdl/testfiles/test_string.txt +1 -0
- toil/test/wdl/testfiles/url_to_file.wdl +13 -0
- toil/test/wdl/testfiles/url_to_optional_file.wdl +14 -0
- toil/test/wdl/testfiles/vocab.json +1 -0
- toil/test/wdl/testfiles/vocab.wdl +66 -0
- toil/test/wdl/testfiles/wait.wdl +34 -0
- toil/test/wdl/wdl_specification/type_pair.json +23 -0
- toil/test/wdl/wdl_specification/type_pair_basic.wdl +36 -0
- toil/test/wdl/wdl_specification/type_pair_with_files.wdl +36 -0
- toil/test/wdl/wdl_specification/v1_spec.json +1 -0
- toil/test/wdl/wdl_specification/v1_spec_declaration.wdl +39 -0
- toil/test/wdl/wdltoil_test.py +751 -529
- toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
- toil/utils/toilSshCluster.py +23 -0
- toil/utils/toilUpdateEC2Instances.py +1 -0
- toil/version.py +5 -5
- toil/wdl/wdltoil.py +518 -437
- toil/worker.py +11 -6
- {toil-8.1.0b1.dist-info → toil-9.0.0.dist-info}/METADATA +25 -24
- toil-9.0.0.dist-info/RECORD +444 -0
- {toil-8.1.0b1.dist-info → toil-9.0.0.dist-info}/WHEEL +1 -1
- toil-8.1.0b1.dist-info/RECORD +0 -259
- {toil-8.1.0b1.dist-info → toil-9.0.0.dist-info}/entry_points.txt +0 -0
- {toil-8.1.0b1.dist-info → toil-9.0.0.dist-info/licenses}/LICENSE +0 -0
- {toil-8.1.0b1.dist-info → toil-9.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
version 1.1
|
|
2
|
+
|
|
3
|
+
workflow TutorialDebugging {
|
|
4
|
+
|
|
5
|
+
input {
|
|
6
|
+
Array[String] messages = ["Uh-oh!", "Oh dear", "Oops"]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
scatter(message in messages) {
|
|
10
|
+
|
|
11
|
+
call WhaleSay {
|
|
12
|
+
input:
|
|
13
|
+
message = message
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
call CountLines {
|
|
17
|
+
input:
|
|
18
|
+
to_count = WhaleSay.result
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Array[File] to_compress = flatten([CountLines.result, WhaleSay.result])
|
|
23
|
+
|
|
24
|
+
call CompressFiles {
|
|
25
|
+
input:
|
|
26
|
+
files = to_compress
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
output {
|
|
30
|
+
File compressed = CompressFiles.result
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Draw ASCII art
|
|
36
|
+
task WhaleSay {
|
|
37
|
+
input {
|
|
38
|
+
String message
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
command <<<
|
|
42
|
+
cowsay "~{message}"
|
|
43
|
+
>>>
|
|
44
|
+
|
|
45
|
+
output {
|
|
46
|
+
File result = stdout()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
runtime {
|
|
50
|
+
container: "docker/whalesay"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Count the lines in a file
|
|
55
|
+
task CountLines {
|
|
56
|
+
input {
|
|
57
|
+
File to_count
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
command <<<
|
|
61
|
+
wc -l ~{to_count}
|
|
62
|
+
>>>
|
|
63
|
+
|
|
64
|
+
output {
|
|
65
|
+
File result = stdout()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
runtime {
|
|
69
|
+
container: ["ubuntu:latest", "https://gcr.io/standard-images/ubuntu:latest"]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Compress files into a ZIP
|
|
74
|
+
task CompressFiles {
|
|
75
|
+
input {
|
|
76
|
+
Array[File] files
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
command <<<
|
|
80
|
+
set -e
|
|
81
|
+
cat >script.py <<'EOF'
|
|
82
|
+
import sys
|
|
83
|
+
from zipfile import ZipFile
|
|
84
|
+
import os
|
|
85
|
+
|
|
86
|
+
# Interpret command line arguments
|
|
87
|
+
to_compress = list(reversed(sys.argv[1:]))
|
|
88
|
+
|
|
89
|
+
with ZipFile("compressed.zip", "w") as z:
|
|
90
|
+
while to_compress != []:
|
|
91
|
+
# Grab the file to add off the end of the list
|
|
92
|
+
input_filename = to_compress[-1]
|
|
93
|
+
# Now we need to write this to the zip file.
|
|
94
|
+
# What internal filename should we use?
|
|
95
|
+
basename = os.path.basename(input_filename)
|
|
96
|
+
disambiguation_number = 0
|
|
97
|
+
while True:
|
|
98
|
+
target_filename = str(disambiguation_number) + basename
|
|
99
|
+
try:
|
|
100
|
+
z.getinfo(target_filename)
|
|
101
|
+
except KeyError:
|
|
102
|
+
# Filename is free
|
|
103
|
+
break
|
|
104
|
+
# Otherwise try another name
|
|
105
|
+
disambiguation_number += 1
|
|
106
|
+
# Now we can actually make the compressed file
|
|
107
|
+
with z.open(target_filename, 'w') as out_stream:
|
|
108
|
+
with open(input_filename) as in_stream:
|
|
109
|
+
for line in in_stream:
|
|
110
|
+
# Prefix each line of text with the original input file
|
|
111
|
+
# it came from.
|
|
112
|
+
# Also remember to encode the text as the zip file
|
|
113
|
+
# stream is in binary mode.
|
|
114
|
+
out_stream.write(f"{basename}: {line}".encode("utf-8"))
|
|
115
|
+
# Even though we got distracted by zip file manipulation, remember
|
|
116
|
+
# to pop off the file we just did.
|
|
117
|
+
to_compress.pop()
|
|
118
|
+
EOF
|
|
119
|
+
python script.py ~{sep(" ", files)}
|
|
120
|
+
>>>
|
|
121
|
+
|
|
122
|
+
output {
|
|
123
|
+
File result = "compressed.zip"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
runtime {
|
|
127
|
+
container: "python:3.11"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.docker import apiDockerCall
|
|
6
|
+
from toil.lib.io import mkdtemp
|
|
7
|
+
|
|
8
|
+
align = Job.wrapJobFn(
|
|
9
|
+
apiDockerCall, image="ubuntu", working_dir=os.getcwd(), parameters=["ls", "-lha"]
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
jobstore: str = mkdtemp("tutorial_docker")
|
|
14
|
+
os.rmdir(jobstore)
|
|
15
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
16
|
+
options.logLevel = "INFO"
|
|
17
|
+
options.clean = "always"
|
|
18
|
+
|
|
19
|
+
with Toil(options) as toil:
|
|
20
|
+
toil.start(align)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def binaryStringFn(job, depth, message=""):
|
|
9
|
+
if depth > 0:
|
|
10
|
+
job.addChildJobFn(binaryStringFn, depth - 1, message + "0")
|
|
11
|
+
job.addChildJobFn(binaryStringFn, depth - 1, message + "1")
|
|
12
|
+
else:
|
|
13
|
+
job.log(f"Binary string: {message}")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
jobstore: str = mkdtemp("tutorial_dynamic")
|
|
18
|
+
os.rmdir(jobstore)
|
|
19
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
20
|
+
options.logLevel = "INFO"
|
|
21
|
+
options.clean = "always"
|
|
22
|
+
|
|
23
|
+
with Toil(options) as toil:
|
|
24
|
+
toil.start(Job.wrapJobFn(binaryStringFn, depth=5))
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
# A is a job with children and follow-ons, for example:
|
|
9
|
+
A = Job()
|
|
10
|
+
A.addChild(Job())
|
|
11
|
+
A.addFollowOn(Job())
|
|
12
|
+
|
|
13
|
+
# B is a job which needs to run after A and its successors
|
|
14
|
+
B = Job()
|
|
15
|
+
|
|
16
|
+
# The way to do this without encapsulation is to make a parent of A, Ap, and make B a follow-on of Ap.
|
|
17
|
+
Ap = Job()
|
|
18
|
+
Ap.addChild(A)
|
|
19
|
+
Ap.addFollowOn(B)
|
|
20
|
+
|
|
21
|
+
jobstore: str = mkdtemp("tutorial_encapsulations")
|
|
22
|
+
os.rmdir(jobstore)
|
|
23
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
24
|
+
options.logLevel = "INFO"
|
|
25
|
+
options.clean = "always"
|
|
26
|
+
|
|
27
|
+
with Toil(options) as toil:
|
|
28
|
+
print(toil.start(Ap))
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
# A
|
|
9
|
+
A = Job()
|
|
10
|
+
A.addChild(Job())
|
|
11
|
+
A.addFollowOn(Job())
|
|
12
|
+
|
|
13
|
+
# Encapsulate A
|
|
14
|
+
A = A.encapsulate()
|
|
15
|
+
|
|
16
|
+
# B is a job which needs to run after A and its successors
|
|
17
|
+
B = Job()
|
|
18
|
+
|
|
19
|
+
# With encapsulation A and its successor subgraph appear to be a single job, hence:
|
|
20
|
+
A.addChild(B)
|
|
21
|
+
|
|
22
|
+
jobstore: str = mkdtemp("tutorial_encapsulations2")
|
|
23
|
+
os.rmdir(jobstore)
|
|
24
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
25
|
+
options.logLevel = "INFO"
|
|
26
|
+
options.clean = "always"
|
|
27
|
+
|
|
28
|
+
with Toil(options) as toil:
|
|
29
|
+
print(toil.start(A))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from toil.common import Toil
|
|
2
|
+
from toil.job import Job
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def helloWorld(message, memory="1G", cores=1, disk="1G"):
|
|
6
|
+
return f"Hello, world!, here's a message: {message}"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
parser = Job.Runner.getDefaultArgumentParser()
|
|
11
|
+
options = parser.parse_args()
|
|
12
|
+
options.clean = "always"
|
|
13
|
+
with Toil(options) as toil:
|
|
14
|
+
output = toil.start(Job.wrapFn(helloWorld, "You did it!"))
|
|
15
|
+
print(output)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HelloWorld(Job):
|
|
9
|
+
def __init__(self, message):
|
|
10
|
+
Job.__init__(self)
|
|
11
|
+
self.message = message
|
|
12
|
+
|
|
13
|
+
def run(self, fileStore):
|
|
14
|
+
return f"Hello, world!, here's a message: {self.message}"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
jobstore: str = mkdtemp("tutorial_invokeworkflow")
|
|
19
|
+
os.rmdir(jobstore)
|
|
20
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
21
|
+
options.logLevel = "OFF"
|
|
22
|
+
options.clean = "always"
|
|
23
|
+
|
|
24
|
+
hello_job = HelloWorld("Woot")
|
|
25
|
+
|
|
26
|
+
with Toil(options) as toil:
|
|
27
|
+
print(toil.start(hello_job))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HelloWorld(Job):
|
|
9
|
+
def __init__(self, message):
|
|
10
|
+
Job.__init__(self)
|
|
11
|
+
self.message = message
|
|
12
|
+
|
|
13
|
+
def run(self, fileStore):
|
|
14
|
+
return f"Hello, world!, I have a message: {self.message}"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
jobstore: str = mkdtemp("tutorial_invokeworkflow2")
|
|
19
|
+
os.rmdir(jobstore)
|
|
20
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
21
|
+
options.logLevel = "INFO"
|
|
22
|
+
options.clean = "always"
|
|
23
|
+
|
|
24
|
+
with Toil(options) as toil:
|
|
25
|
+
if not toil.options.restart:
|
|
26
|
+
job = HelloWorld("Woot!")
|
|
27
|
+
output = toil.start(job)
|
|
28
|
+
else:
|
|
29
|
+
output = toil.restart()
|
|
30
|
+
print(output)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def helloWorld(job, message):
|
|
9
|
+
job.log(f"Hello world, I have a message: {message}")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
jobstore: str = mkdtemp("tutorial_jobfunctions")
|
|
14
|
+
os.rmdir(jobstore)
|
|
15
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
16
|
+
options.logLevel = "INFO"
|
|
17
|
+
options.clean = "always"
|
|
18
|
+
|
|
19
|
+
hello_job = Job.wrapJobFn(helloWorld, "Woot!")
|
|
20
|
+
|
|
21
|
+
with Toil(options) as toil:
|
|
22
|
+
toil.start(hello_job)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LocalFileStoreJob(Job):
|
|
9
|
+
def run(self, fileStore):
|
|
10
|
+
# self.tempDir will always contain the name of a directory within the allocated disk space reserved for the job
|
|
11
|
+
scratchDir = self.tempDir
|
|
12
|
+
|
|
13
|
+
# Similarly create a temporary file.
|
|
14
|
+
scratchFile = fileStore.getLocalTempFile()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
jobstore: str = mkdtemp("tutorial_managing")
|
|
19
|
+
os.rmdir(jobstore)
|
|
20
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
21
|
+
options.logLevel = "INFO"
|
|
22
|
+
options.clean = "always"
|
|
23
|
+
|
|
24
|
+
# Create an instance of FooJob which will have at least 2 gigabytes of storage space.
|
|
25
|
+
j = LocalFileStoreJob(disk="2G")
|
|
26
|
+
|
|
27
|
+
# Run the workflow
|
|
28
|
+
with Toil(options) as toil:
|
|
29
|
+
toil.start(j)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def globalFileStoreJobFn(job):
|
|
9
|
+
job.log(
|
|
10
|
+
"The following example exercises all the methods provided "
|
|
11
|
+
"by the toil.fileStores.abstractFileStore.AbstractFileStore class"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Create a local temporary file.
|
|
15
|
+
scratchFile = job.fileStore.getLocalTempFile()
|
|
16
|
+
|
|
17
|
+
# Write something in the scratch file.
|
|
18
|
+
with open(scratchFile, "w") as fH:
|
|
19
|
+
fH.write("What a tangled web we weave")
|
|
20
|
+
|
|
21
|
+
# Write a copy of the file into the file-store; fileID is the key that can be used to retrieve the file.
|
|
22
|
+
# This write is asynchronous by default
|
|
23
|
+
fileID = job.fileStore.writeGlobalFile(scratchFile)
|
|
24
|
+
|
|
25
|
+
# Write another file using a stream; fileID2 is the
|
|
26
|
+
# key for this second file.
|
|
27
|
+
with job.fileStore.writeGlobalFileStream(cleanup=True) as (fH, fileID2):
|
|
28
|
+
fH.write(b"Out brief candle")
|
|
29
|
+
|
|
30
|
+
# Now read the first file; scratchFile2 is a local copy of the file that is read-only by default.
|
|
31
|
+
scratchFile2 = job.fileStore.readGlobalFile(fileID)
|
|
32
|
+
|
|
33
|
+
# Read the second file to a desired location: scratchFile3.
|
|
34
|
+
scratchFile3 = os.path.join(job.tempDir, "foo.txt")
|
|
35
|
+
job.fileStore.readGlobalFile(fileID2, userPath=scratchFile3)
|
|
36
|
+
|
|
37
|
+
# Read the second file again using a stream.
|
|
38
|
+
with job.fileStore.readGlobalFileStream(fileID2) as fH:
|
|
39
|
+
print(fH.read()) # This prints "Out brief candle"
|
|
40
|
+
|
|
41
|
+
# Delete the first file from the global file-store.
|
|
42
|
+
job.fileStore.deleteGlobalFile(fileID)
|
|
43
|
+
|
|
44
|
+
# It is unnecessary to delete the file keyed by fileID2 because we used the cleanup flag,
|
|
45
|
+
# which removes the file after this job and all its successors have run (if the file still exists)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
jobstore: str = mkdtemp("tutorial_managing2")
|
|
50
|
+
os.rmdir(jobstore)
|
|
51
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
52
|
+
options.logLevel = "INFO"
|
|
53
|
+
options.clean = "always"
|
|
54
|
+
|
|
55
|
+
with Toil(options) as toil:
|
|
56
|
+
toil.start(Job.wrapJobFn(globalFileStoreJobFn))
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from toil.common import Toil
|
|
2
|
+
from toil.job import Job
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def helloWorld(job, message):
|
|
6
|
+
job.log(f"Hello world, I have a message: {message}")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
parser = Job.Runner.getDefaultArgumentParser()
|
|
11
|
+
options = parser.parse_args()
|
|
12
|
+
options.logLevel = "INFO"
|
|
13
|
+
options.clean = "always"
|
|
14
|
+
|
|
15
|
+
j1 = Job.wrapJobFn(helloWorld, "first")
|
|
16
|
+
j2 = Job.wrapJobFn(helloWorld, "second or third")
|
|
17
|
+
j3 = Job.wrapJobFn(helloWorld, "second or third")
|
|
18
|
+
j4 = Job.wrapJobFn(helloWorld, "last")
|
|
19
|
+
|
|
20
|
+
j1.addChild(j2)
|
|
21
|
+
j1.addChild(j3)
|
|
22
|
+
j1.addFollowOn(j4)
|
|
23
|
+
|
|
24
|
+
with Toil(options) as toil:
|
|
25
|
+
toil.start(j1)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from toil.common import Toil
|
|
2
|
+
from toil.job import Job
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def helloWorld(job, message):
|
|
6
|
+
job.log(f"Hello world, I have a message: {message}")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
parser = Job.Runner.getDefaultArgumentParser()
|
|
11
|
+
options = parser.parse_args()
|
|
12
|
+
options.logLevel = "INFO"
|
|
13
|
+
options.clean = "always"
|
|
14
|
+
|
|
15
|
+
j1 = Job.wrapJobFn(helloWorld, "first")
|
|
16
|
+
j2 = j1.addChildJobFn(helloWorld, "second or third")
|
|
17
|
+
j3 = j1.addChildJobFn(helloWorld, "second or third")
|
|
18
|
+
j4 = j1.addFollowOnJobFn(helloWorld, "last")
|
|
19
|
+
|
|
20
|
+
with Toil(options) as toil:
|
|
21
|
+
toil.start(j1)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from toil.common import Toil
|
|
2
|
+
from toil.job import Job
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def helloWorld(job, message):
|
|
6
|
+
job.log(f"Hello world, I have a message: {message}")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
parser = Job.Runner.getDefaultArgumentParser()
|
|
11
|
+
options = parser.parse_args()
|
|
12
|
+
options.logLevel = "INFO"
|
|
13
|
+
options.clean = "always"
|
|
14
|
+
|
|
15
|
+
j1 = Job.wrapJobFn(helloWorld, "first")
|
|
16
|
+
j2 = j1.addChildJobFn(helloWorld, "second or third")
|
|
17
|
+
j3 = j1.addChildJobFn(helloWorld, "second or third")
|
|
18
|
+
j4 = j2.addChildJobFn(helloWorld, "last")
|
|
19
|
+
j3.addChild(j4)
|
|
20
|
+
|
|
21
|
+
with Toil(options) as toil:
|
|
22
|
+
toil.start(j1)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def fn(job, i):
|
|
9
|
+
job.log("i is: %s" % i, level=100)
|
|
10
|
+
return i + 1
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
jobstore: str = mkdtemp("tutorial_promises")
|
|
15
|
+
os.rmdir(jobstore)
|
|
16
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
17
|
+
options.logLevel = "INFO"
|
|
18
|
+
options.clean = "always"
|
|
19
|
+
|
|
20
|
+
j1 = Job.wrapJobFn(fn, 1)
|
|
21
|
+
j2 = j1.addChildJobFn(fn, j1.rv())
|
|
22
|
+
j3 = j1.addFollowOnJobFn(fn, j2.rv())
|
|
23
|
+
|
|
24
|
+
with Toil(options) as toil:
|
|
25
|
+
toil.start(j1)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def binaryStrings(job, depth, message=""):
|
|
9
|
+
if depth > 0:
|
|
10
|
+
s = [
|
|
11
|
+
job.addChildJobFn(binaryStrings, depth - 1, message + "0").rv(),
|
|
12
|
+
job.addChildJobFn(binaryStrings, depth - 1, message + "1").rv(),
|
|
13
|
+
]
|
|
14
|
+
return job.addFollowOnFn(merge, s).rv()
|
|
15
|
+
return [message]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def merge(strings):
|
|
19
|
+
return strings[0] + strings[1]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
jobstore: str = mkdtemp("tutorial_promises2")
|
|
24
|
+
os.rmdir(jobstore)
|
|
25
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
26
|
+
options.loglevel = "OFF"
|
|
27
|
+
options.clean = "always"
|
|
28
|
+
|
|
29
|
+
with Toil(options) as toil:
|
|
30
|
+
print(toil.start(Job.wrapJobFn(binaryStrings, depth=5)))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def helloWorld(message):
|
|
9
|
+
return f"Hello, world!, here's a message: {message}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
jobstore: str = mkdtemp("tutorial_quickstart")
|
|
14
|
+
os.rmdir(jobstore)
|
|
15
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
16
|
+
options.logLevel = "OFF"
|
|
17
|
+
options.clean = "always"
|
|
18
|
+
|
|
19
|
+
hello_job = Job.wrapFn(helloWorld, "Woot")
|
|
20
|
+
|
|
21
|
+
with Toil(options) as toil:
|
|
22
|
+
print(toil.start(hello_job)) # prints "Hello, world!, ..."
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job, PromisedRequirement
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def parentJob(job):
|
|
9
|
+
downloadJob = Job.wrapJobFn(
|
|
10
|
+
stageFn,
|
|
11
|
+
"file://" + os.path.realpath(__file__),
|
|
12
|
+
cores=0.1,
|
|
13
|
+
memory="32M",
|
|
14
|
+
disk="1M",
|
|
15
|
+
)
|
|
16
|
+
job.addChild(downloadJob)
|
|
17
|
+
|
|
18
|
+
analysis = Job.wrapJobFn(
|
|
19
|
+
analysisJob,
|
|
20
|
+
fileStoreID=downloadJob.rv(0),
|
|
21
|
+
disk=PromisedRequirement(downloadJob.rv(1)),
|
|
22
|
+
)
|
|
23
|
+
job.addFollowOn(analysis)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def stageFn(job, url):
|
|
27
|
+
importedFile = job.fileStore.import_file(url)
|
|
28
|
+
return importedFile, importedFile.size
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def analysisJob(job, fileStoreID):
|
|
32
|
+
# now do some analysis on the file
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
jobstore: str = mkdtemp("tutorial_requirements")
|
|
38
|
+
os.rmdir(jobstore)
|
|
39
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
40
|
+
options.logLevel = "INFO"
|
|
41
|
+
options.clean = "always"
|
|
42
|
+
|
|
43
|
+
with Toil(options) as toil:
|
|
44
|
+
toil.start(Job.wrapJobFn(parentJob))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from toil.common import Toil
|
|
4
|
+
from toil.job import Job
|
|
5
|
+
from toil.lib.io import mkdtemp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DemoService(Job.Service):
|
|
9
|
+
def start(self, fileStore):
|
|
10
|
+
# Start up a database/service here
|
|
11
|
+
# Return a value that enables another process to connect to the database
|
|
12
|
+
return "loginCredentials"
|
|
13
|
+
|
|
14
|
+
def check(self):
|
|
15
|
+
# A function that if it returns False causes the service to quit
|
|
16
|
+
# If it raises an exception the service is killed and an error is reported
|
|
17
|
+
return True
|
|
18
|
+
|
|
19
|
+
def stop(self, fileStore):
|
|
20
|
+
# Cleanup the database here
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
j = Job()
|
|
25
|
+
s = DemoService()
|
|
26
|
+
loginCredentialsPromise = j.addService(s)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def dbFn(loginCredentials):
|
|
30
|
+
# Use the login credentials returned from the service's start method to connect to the service
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
j.addChildFn(dbFn, loginCredentialsPromise)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
jobstore: str = mkdtemp("tutorial_services")
|
|
39
|
+
os.rmdir(jobstore)
|
|
40
|
+
options = Job.Runner.getDefaultOptions(jobstore)
|
|
41
|
+
options.logLevel = "INFO"
|
|
42
|
+
options.clean = "always"
|
|
43
|
+
|
|
44
|
+
with Toil(options) as toil:
|
|
45
|
+
toil.start(j)
|