eva-sub-cli 0.4.4__tar.gz → 0.4.7__tar.gz

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 (118) hide show
  1. eva_sub_cli-0.4.7/.github/workflows/publish.yml +51 -0
  2. {eva_sub_cli-0.4.4/eva_sub_cli.egg-info → eva_sub_cli-0.4.7}/PKG-INFO +62 -11
  3. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/README.md +53 -3
  4. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/__init__.py +1 -0
  5. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/_version.py +2 -2
  6. eva_sub_cli-0.4.7/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
  7. eva_sub_cli-0.4.7/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
  8. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva_schema.json +7 -5
  9. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/spreadsheet2json_conf.yaml +3 -2
  10. eva_sub_cli-0.4.7/eva_sub_cli/exceptions/metadata_template_version_exception.py +10 -0
  11. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/cli.py +18 -2
  12. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/trim_down.py +21 -11
  13. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/file_utils.py +3 -3
  14. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/nextflow/validation.nf +1 -0
  15. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/orchestrator.py +78 -6
  16. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/semantic_metadata.py +42 -5
  17. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/docker_validator.py +15 -11
  18. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/native_validator.py +11 -9
  19. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/validator.py +5 -2
  20. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7/eva_sub_cli.egg-info}/PKG-INFO +62 -11
  21. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/SOURCES.txt +9 -1
  22. eva_sub_cli-0.4.7/eva_sub_cli.egg-info/requires.txt +8 -0
  23. eva_sub_cli-0.4.7/requirements.txt +8 -0
  24. eva_sub_cli-0.4.7/tests/build_and_test_docker_locally.py +293 -0
  25. eva_sub_cli-0.4.7/tests/resources/EVA_Submission_Docker_Test.xlsx +0 -0
  26. eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test.xlsx +0 -0
  27. eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
  28. eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test_version_missing.xlsx +0 -0
  29. eva_sub_cli-0.4.7/tests/resources/fasta_files/multi_seq.fa +8 -0
  30. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/other_validations/metadata_validation.txt +2 -0
  31. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_cli.py +5 -0
  32. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_orchestrator.py +72 -10
  33. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_semantic_metadata.py +41 -17
  34. eva_sub_cli-0.4.7/tests/test_trim_down.py +108 -0
  35. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_validator.py +17 -8
  36. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_xlsx2json.py +27 -0
  37. eva_sub_cli-0.4.4/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
  38. eva_sub_cli-0.4.4/eva_sub_cli.egg-info/requires.txt +0 -7
  39. eva_sub_cli-0.4.4/requirements.txt +0 -7
  40. eva_sub_cli-0.4.4/tests/resources/EVA_Submission_test.xlsx +0 -0
  41. eva_sub_cli-0.4.4/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
  42. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.github/workflows/publish_packages.yml +0 -0
  43. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.github/workflows/tests.yml +0 -0
  44. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.gitignore +0 -0
  45. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/LICENSE +0 -0
  46. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/conda/build.sh +0 -0
  47. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/conda/meta.yaml +0 -0
  48. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/docker/Dockerfile +0 -0
  49. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7/docs}/Getting_Started_with_eva_sub_cli.md +0 -0
  50. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/auth.py +0 -0
  51. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/date_utils.py +0 -0
  52. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva-biosamples.json +0 -0
  53. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva_logo.png +0 -0
  54. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/__init__.py +0 -0
  55. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/invalid_file_type_exception.py +0 -0
  56. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/submission_not_found_exception.py +0 -0
  57. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/submission_status_exception.py +0 -0
  58. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/__init__.py +0 -0
  59. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/check_fasta_insdc.py +0 -0
  60. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/check_metadata_semantics.py +0 -0
  61. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/samples_checker.py +0 -0
  62. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/xlsx2json.py +0 -0
  63. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/fasta_check.html +0 -0
  64. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/file_validation.html +0 -0
  65. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/html_report.html +0 -0
  66. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/metadata_validation.html +0 -0
  67. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/project_details.html +0 -0
  68. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/sample_name_check.html +0 -0
  69. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/shallow_validation.html +0 -0
  70. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/metadata_utils.py +0 -0
  71. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/report.py +0 -0
  72. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/submission_ws.py +0 -0
  73. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/submit.py +0 -0
  74. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/__init__.py +0 -0
  75. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/validation_results_parsers.py +0 -0
  76. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/dependency_links.txt +0 -0
  77. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/entry_points.txt +0 -0
  78. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/top_level.txt +0 -0
  79. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/pyproject.toml +0 -0
  80. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/pytest.ini +0 -0
  81. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/setup.cfg +0 -0
  82. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/setup.py +0 -0
  83. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/ignore_test_nextflow_validation.yml +0 -0
  84. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/EVA_Submission_test.json +0 -0
  85. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/EVA_Submission_test_with_asm_report.json +0 -0
  86. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_check/invalid.vcf.assembly_check.log +0 -0
  87. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_check/invalid.vcf.text_assembly_report.txt +0 -0
  88. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_reports/input_passed.txt +0 -0
  89. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa +0 -0
  90. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/fasta_files/input_passed.fa +0 -0
  91. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example1.vcf.gz +0 -0
  92. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example2.vcf +0 -0
  93. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example3.vcf +0 -0
  94. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/metadata.json +0 -0
  95. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_report_metadata_json.html +0 -0
  96. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_report_metadata_xlsx.html +0 -0
  97. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.html +0 -0
  98. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.assembly_check.log +0 -0
  99. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.text_assembly_report.1680102476700.txt +0 -0
  100. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.valid_assembly_report.1680102476700.txt +0 -0
  101. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/other_validations/input_passed.fa_check.yml +0 -0
  102. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/other_validations/metadata_conversion_errors.yml +0 -0
  103. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/other_validations/metadata_semantic_check.yml +0 -0
  104. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/other_validations/sample_checker.yml +0 -0
  105. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.db +0 -0
  106. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.txt +0 -0
  107. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.vcf_format.log +0 -0
  108. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/vcf_files/example2.vcf.gz +0 -0
  109. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/vcf_files/input_passed.vcf +0 -0
  110. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_auth.py +0 -0
  111. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_check_fasta_insdc.py +0 -0
  112. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_docker_validator.py +0 -0
  113. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_file_utils.py +0 -0
  114. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_report.py +0 -0
  115. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_samples_checker.py +0 -0
  116. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_submit.py +0 -0
  117. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_utils.py +0 -0
  118. {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_validaton_results_parsers.py +0 -0
@@ -0,0 +1,51 @@
1
+ name: Publish Python Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - '**'
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.9"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ cache: pip
21
+ cache-dependency-path: '**/pyproject.toml'
22
+ - name: Install dependencies
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install pytest
26
+ python -m pip install .
27
+ - name: Run tests
28
+ run: |
29
+ PYTHONPATH=. pytest tests -k "not integration"
30
+ deploy:
31
+ runs-on: ubuntu-latest
32
+ needs: [test]
33
+ environment: release
34
+ permissions:
35
+ id-token: write
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+ - name: Set up Python
39
+ uses: actions/setup-python@v5
40
+ with:
41
+ python-version: '3.9'
42
+ cache: pip
43
+ cache-dependency-path: '**/pyproject.toml'
44
+ - name: Install dependencies
45
+ run: |
46
+ pip install setuptools wheel build
47
+ - name: Build
48
+ run: |
49
+ python -m build
50
+ - name: Publish
51
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eva_sub_cli
3
- Version: 0.4.4
3
+ Version: 0.4.7
4
4
  Summary: EBI EVA - validation and submission command line tool
5
5
  Classifier: Development Status :: 5 - Production/Stable
6
6
  Classifier: Environment :: Console
@@ -19,13 +19,14 @@ Classifier: License :: OSI Approved :: Apache Software License
19
19
  Requires-Python: >=3.6
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: ebi_eva_common_pyutils==0.6.11
23
- Requires-Dist: jinja2
24
- Requires-Dist: jsonschema
25
- Requires-Dist: openpyxl
26
- Requires-Dist: pyyaml
27
- Requires-Dist: requests
28
- Requires-Dist: retry
22
+ Requires-Dist: ebi_eva_common_pyutils==0.*,>=0.7.1
23
+ Requires-Dist: jinja2==3.*,>=3.0.0
24
+ Requires-Dist: jsonschema==4.*
25
+ Requires-Dist: openpyxl==3.*
26
+ Requires-Dist: pyyaml==6.*
27
+ Requires-Dist: requests==2.*
28
+ Requires-Dist: packaging==24.*
29
+ Requires-Dist: setuptools-scm
29
30
  Dynamic: license-file
30
31
 
31
32
  # eva-sub-cli
@@ -76,13 +77,13 @@ Install each of these and ensure they are included in your PATH. Then install th
76
77
 
77
78
  ## Getting started with the eva-sub-cli tool
78
79
 
79
- The ["Getting Started" guide](Getting_Started_with_eva_sub_cli.md) serves as an introduction for users of the eva-sub-cli tool. It includes instructions on how to prepare your data and metadata, ensuring that users are equipped with the necessary information to successfully submit variant data. This guide is essential for new users, offering practical advice and tips for a smooth onboarding experience with the eva-sub-cli tool.
80
+ The ["Getting Started" guide](docs/Getting_Started_with_eva_sub_cli.md) serves as an introduction for users of the eva-sub-cli tool. It includes instructions on how to prepare your data and metadata, ensuring that users are equipped with the necessary information to successfully submit variant data. This guide is essential for new users, offering practical advice and tips for a smooth onboarding experience with the eva-sub-cli tool.
80
81
 
81
82
  ## Options and parameters guide
82
83
 
83
84
  The eva-sub-cli tool provides several options and parameters that you can use to tailor its functionality to your needs.
84
85
  You can view all the available parameters with the command `eva-sub-cli.py -h` and view detailed explanations for the
85
- input file requirements in the ["Getting Started" guide](Getting_Started_with_eva_sub_cli.md).
86
+ input file requirements in the ["Getting Started" guide](docs/Getting_Started_with_eva_sub_cli.md).
86
87
  Below is an overview of the key parameters.
87
88
 
88
89
  ### Submission directory
@@ -128,7 +129,7 @@ eva-sub-cli.py --metadata_xlsx metadata_spreadsheet.xlsx --submission_dir submis
128
129
 
129
130
  Make sure that Docker is running in the background, e.g. by opening Docker Desktop.
130
131
  For each of the below commands, add the command line option `--executor docker`, which will
131
- fetch and manage the docker container for you.
132
+ fetch and manage the Docker container for you.
132
133
 
133
134
  ```shell
134
135
  eva-sub-cli.py --metadata_xlsx metadata_spreadsheet.xlsx --submission_dir submission_dir --tasks VALIDATE --executor docker
@@ -162,3 +163,53 @@ This will only submit the data and not validate.
162
163
  If you are working with large VCF files and find that validation takes a very long time, you can add the
163
164
  argument `--shallow` to the command, which will validate only the first 10,000 lines in each VCF. Note that running
164
165
  shallow validation will **not** be sufficient for actual submission.
166
+
167
+
168
+ ## Leveraging Nextflow to parallelize the validation process
169
+
170
+ Nextflow is a common workflow management system that helps orchestrate tasks and interface with the execution engine (like HPC or cloud). When running natively (i.e. not using Docker), eva-sub-cli will use Nextflow to run all the validation steps. In this section we'll see how it can be parameterised to work with your compute infrastructure.
171
+
172
+ When no options are provided, Nextflow will run as many tasks as there are available CPUs on the machine executing it. To modify how many tasks can start and how Nextflow will process each one, you can provide a Nextflow configuration file in several ways.
173
+
174
+ From the command line you can use `--nextflow_config <path>` to specify the Nextflow config file you want to apply. The configuration can also be picked up from other places directly by Nextflow. Please refer to [the nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more details.
175
+
176
+ ### Basic Nextflow configuration.
177
+
178
+ There are many options to configure Nextflow so we will not provide them all. Please refer to [the documentation](https://www.nextflow.io/docs/latest/reference/config.html) for advanced features.
179
+ Below is a very basic Nextflow configuration file that will request 2 cpus for each process, essentially limiting the number of process to half the number of available CPUs
180
+ ```
181
+ process {
182
+ executor="local"
183
+ cpus=2
184
+ }
185
+ ```
186
+ In this configuration, all the process will be running on the same machine where eva-sub-cli was started as described in the schema below.
187
+ ```
188
+ (Local machine)
189
+ eva-sub-cli
190
+ |_ nextflow
191
+ |_ task1
192
+ |_ task2
193
+ ```
194
+
195
+ ### Basic Nextflow configuration for HPC use.
196
+
197
+ If you have access to High Performance Compute (HPC) environment, Nextflow supports the main resource managers such as [SLURM](https://www.nextflow.io/docs/latest/executor.html#slurm), [SGE](https://www.nextflow.io/docs/latest/executor.html#sge), [LSF](https://www.nextflow.io/docs/latest/executor.html#lsf) and others.
198
+ In the configuration below, we're assuming that you are using SLURM. It would work similarly with other resource managers.
199
+ ```
200
+ process {
201
+ executor="slurm"
202
+ queue="my_production_queue"
203
+ }
204
+ ```
205
+
206
+ In this configuration, the subtasks will be performed in other machines as specified by your SLURM resource manager as described in the schema below.
207
+ ```
208
+ (Local machine)
209
+ eva-sub-cli
210
+ |_ nextflow
211
+ (Other compute node)
212
+ task1
213
+ (Other compute node)
214
+ task2
215
+ ```
@@ -46,13 +46,13 @@ Install each of these and ensure they are included in your PATH. Then install th
46
46
 
47
47
  ## Getting started with the eva-sub-cli tool
48
48
 
49
- The ["Getting Started" guide](Getting_Started_with_eva_sub_cli.md) serves as an introduction for users of the eva-sub-cli tool. It includes instructions on how to prepare your data and metadata, ensuring that users are equipped with the necessary information to successfully submit variant data. This guide is essential for new users, offering practical advice and tips for a smooth onboarding experience with the eva-sub-cli tool.
49
+ The ["Getting Started" guide](docs/Getting_Started_with_eva_sub_cli.md) serves as an introduction for users of the eva-sub-cli tool. It includes instructions on how to prepare your data and metadata, ensuring that users are equipped with the necessary information to successfully submit variant data. This guide is essential for new users, offering practical advice and tips for a smooth onboarding experience with the eva-sub-cli tool.
50
50
 
51
51
  ## Options and parameters guide
52
52
 
53
53
  The eva-sub-cli tool provides several options and parameters that you can use to tailor its functionality to your needs.
54
54
  You can view all the available parameters with the command `eva-sub-cli.py -h` and view detailed explanations for the
55
- input file requirements in the ["Getting Started" guide](Getting_Started_with_eva_sub_cli.md).
55
+ input file requirements in the ["Getting Started" guide](docs/Getting_Started_with_eva_sub_cli.md).
56
56
  Below is an overview of the key parameters.
57
57
 
58
58
  ### Submission directory
@@ -98,7 +98,7 @@ eva-sub-cli.py --metadata_xlsx metadata_spreadsheet.xlsx --submission_dir submis
98
98
 
99
99
  Make sure that Docker is running in the background, e.g. by opening Docker Desktop.
100
100
  For each of the below commands, add the command line option `--executor docker`, which will
101
- fetch and manage the docker container for you.
101
+ fetch and manage the Docker container for you.
102
102
 
103
103
  ```shell
104
104
  eva-sub-cli.py --metadata_xlsx metadata_spreadsheet.xlsx --submission_dir submission_dir --tasks VALIDATE --executor docker
@@ -132,3 +132,53 @@ This will only submit the data and not validate.
132
132
  If you are working with large VCF files and find that validation takes a very long time, you can add the
133
133
  argument `--shallow` to the command, which will validate only the first 10,000 lines in each VCF. Note that running
134
134
  shallow validation will **not** be sufficient for actual submission.
135
+
136
+
137
+ ## Leveraging Nextflow to parallelize the validation process
138
+
139
+ Nextflow is a common workflow management system that helps orchestrate tasks and interface with the execution engine (like HPC or cloud). When running natively (i.e. not using Docker), eva-sub-cli will use Nextflow to run all the validation steps. In this section we'll see how it can be parameterised to work with your compute infrastructure.
140
+
141
+ When no options are provided, Nextflow will run as many tasks as there are available CPUs on the machine executing it. To modify how many tasks can start and how Nextflow will process each one, you can provide a Nextflow configuration file in several ways.
142
+
143
+ From the command line you can use `--nextflow_config <path>` to specify the Nextflow config file you want to apply. The configuration can also be picked up from other places directly by Nextflow. Please refer to [the nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more details.
144
+
145
+ ### Basic Nextflow configuration.
146
+
147
+ There are many options to configure Nextflow so we will not provide them all. Please refer to [the documentation](https://www.nextflow.io/docs/latest/reference/config.html) for advanced features.
148
+ Below is a very basic Nextflow configuration file that will request 2 cpus for each process, essentially limiting the number of process to half the number of available CPUs
149
+ ```
150
+ process {
151
+ executor="local"
152
+ cpus=2
153
+ }
154
+ ```
155
+ In this configuration, all the process will be running on the same machine where eva-sub-cli was started as described in the schema below.
156
+ ```
157
+ (Local machine)
158
+ eva-sub-cli
159
+ |_ nextflow
160
+ |_ task1
161
+ |_ task2
162
+ ```
163
+
164
+ ### Basic Nextflow configuration for HPC use.
165
+
166
+ If you have access to High Performance Compute (HPC) environment, Nextflow supports the main resource managers such as [SLURM](https://www.nextflow.io/docs/latest/executor.html#slurm), [SGE](https://www.nextflow.io/docs/latest/executor.html#sge), [LSF](https://www.nextflow.io/docs/latest/executor.html#lsf) and others.
167
+ In the configuration below, we're assuming that you are using SLURM. It would work similarly with other resource managers.
168
+ ```
169
+ process {
170
+ executor="slurm"
171
+ queue="my_production_queue"
172
+ }
173
+ ```
174
+
175
+ In this configuration, the subtasks will be performed in other machines as specified by your SLURM resource manager as described in the schema below.
176
+ ```
177
+ (Local machine)
178
+ eva-sub-cli
179
+ |_ nextflow
180
+ (Other compute node)
181
+ task1
182
+ (Other compute node)
183
+ task2
184
+ ```
@@ -6,6 +6,7 @@ PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__))
6
6
  NEXTFLOW_DIR = os.path.join(PACKAGE_DIR, 'nextflow')
7
7
  ETC_DIR = os.path.join(PACKAGE_DIR, 'etc')
8
8
  LSRI_CLIENT_ID = "aa0fcc42-096a-4f9d-b871-aceb1a97d174"
9
+ DEFAULT_METADATA_XLSX_TEMPLATE_VERSION = '1.1.6'
9
10
 
10
11
  SUB_CLI_CONFIG_FILE = ".eva_sub_cli_config.yml"
11
12
 
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4.4'
21
- __version_tuple__ = version_tuple = (0, 4, 4)
20
+ __version__ = version = '0.4.7'
21
+ __version_tuple__ = version_tuple = (0, 4, 7)
@@ -75,11 +75,13 @@
75
75
  "properties": {
76
76
  "title": {
77
77
  "type": "string",
78
- "description": "Title of the project"
78
+ "description": "Title of the project",
79
+ "maxLength": 500
79
80
  },
80
81
  "description": {
81
82
  "type": "string",
82
- "description": "Description of the project"
83
+ "description": "Description of the project",
84
+ "maxLength": 5000
83
85
  },
84
86
  "centre": {
85
87
  "type": "string",
@@ -166,11 +168,11 @@
166
168
  "type": "string",
167
169
  "description": "Reference against which the analysis was performed. ENA or NCBI accession (starting with GCA) accepted."
168
170
  },
169
- "referenceFasta": {
171
+ "referenceFasta": {
170
172
  "type": "string",
171
173
  "description": "The path to the reference in fasta format that was used to create the VCF. (This is a local path)"
172
174
  },
173
- "assemblyReport": {
175
+ "assemblyReport": {
174
176
  "type": "string",
175
177
  "description": "The path to the assembly report associated with the assembly as found in NCBI assemblies. (This is a local path and only applicable for GCAs)"
176
178
  },
@@ -319,7 +321,7 @@
319
321
  "$ref": "eva-biosamples.json"
320
322
  },
321
323
  {
322
- "$ref": "https://www.ebi.ac.uk/biosamples/schema/store/registry/schemas/ERC000011"
324
+ "$ref": "https://www.ebi.ac.uk/biosamples/schema/store/registry/schemas/ERC000011"
323
325
  },
324
326
  {
325
327
  "$ref": "https://www.ebi.ac.uk/biosamples/schemas/certification/plant-miappe.json"
@@ -32,7 +32,7 @@ Project:
32
32
  Project Title: title
33
33
  Description: description
34
34
  Center: centre
35
- Tax ID: taxId
35
+ Taxonomy ID: taxId
36
36
  optional:
37
37
  Publication(s): publications
38
38
  Parent Project: parentProject
@@ -74,6 +74,7 @@ Analysis:
74
74
  Imputation: boolean
75
75
  Phasing: boolean
76
76
  Date: date
77
+ Software: list
77
78
 
78
79
  Sample:
79
80
  header_row: 3
@@ -89,7 +90,7 @@ Sample:
89
90
  Prefix: prefix
90
91
  Subject: subject
91
92
  Derived From: derivedFrom
92
- Tax Id: taxId
93
+ Taxonomy ID: taxId
93
94
  Scientific Name: scientificName
94
95
  Common Name: commonName
95
96
  mating_type: matingType
@@ -0,0 +1,10 @@
1
+ class MetadataTemplateVersionException(Exception):
2
+ def __init__(self, message):
3
+ self.message = message
4
+ super().__init__(self.message)
5
+
6
+
7
+ class MetadataTemplateVersionNotFoundException(Exception):
8
+ def __init__(self, message):
9
+ self.message = message
10
+ super().__init__(self.message)
@@ -1,11 +1,14 @@
1
1
  import sys
2
2
 
3
3
  import eva_sub_cli
4
+ from eva_sub_cli.exceptions.metadata_template_version_exception import MetadataTemplateVersionException, \
5
+ MetadataTemplateVersionNotFoundException
4
6
  from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
5
7
  from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
6
8
 
7
9
  if not sys.warnoptions:
8
10
  import warnings
11
+
9
12
  warnings.simplefilter("ignore")
10
13
 
11
14
  import logging
@@ -35,11 +38,16 @@ def validate_command_line_arguments(args, argparser):
35
38
  print(f"'{args.submission_dir}' does not have write permissions or is not a directory.")
36
39
  sys.exit(1)
37
40
 
41
+ if args.nextflow_config and not os.path.isfile(args.nextflow_config):
42
+ print(f"'{args.nextflow_config}' is not a file or does not exist.")
43
+ argparser.print_usage()
44
+ sys.exit(1)
45
+
38
46
 
39
47
  def parse_args(cmd_line_args):
40
48
  argparser = ArgumentParser(prog='eva-sub-cli',
41
49
  description='EVA Submission CLI - validate and submit data to EVA. '
42
- 'For full details, please see https://github.com/EBIvariation/eva-sub-cli')
50
+ 'For full details, please see https://github.com/EBIvariation/eva-sub-cli')
43
51
  argparser.add_argument('--version', action='version', version=f'%(prog)s {eva_sub_cli.__version__}')
44
52
  argparser.add_argument('--submission_dir', required=True, type=str,
45
53
  help='Path to the directory where all processing is done and submission info is stored')
@@ -71,6 +79,9 @@ def parse_args(cmd_line_args):
71
79
  argparser.add_argument('--shallow', action='store_true', default=False, dest='shallow_validation',
72
80
  help='Set the validation to be performed on the first 10000 records of the VCF. '
73
81
  'Only applies if the number of records exceed 10000')
82
+ argparser.add_argument('--nextflow_config', type=str,
83
+ help='Path to the configuration file that will be applied to the Nextflow process. '
84
+ 'This will override other nextflow configuration files you might have on your filesystem')
74
85
  argparser.add_argument('--debug', action='store_true', default=False,
75
86
  help='Set the script to output debug messages')
76
87
  args = argparser.parse_args(cmd_line_args)
@@ -111,5 +122,10 @@ def main():
111
122
  except SubmissionStatusException as sse:
112
123
  print(f'{sse}. Please try again later. If the problem persists, please contact EVA Helpdesk')
113
124
  exit_status = 68
125
+ except MetadataTemplateVersionException as mte:
126
+ print(mte)
127
+ exit_status = 69
128
+ except MetadataTemplateVersionNotFoundException as mte:
129
+ print(mte)
130
+ exit_status = 70
114
131
  return exit_status
115
-
@@ -1,6 +1,7 @@
1
1
  import argparse
2
2
  import os
3
3
 
4
+ import sys
4
5
  import yaml
5
6
  from ebi_eva_common_pyutils.logger import logging_config
6
7
  from eva_sub_cli.file_utils import open_gzip_if_required, fasta_iter
@@ -8,15 +9,16 @@ from eva_sub_cli.file_utils import open_gzip_if_required, fasta_iter
8
9
  logger = logging_config.get_logger(__name__)
9
10
 
10
11
 
11
- max_nb_lines = 10000
12
+ MAX_NB_LINES = 10000
12
13
 
13
14
 
14
- def trim_down_vcf(vcf_file, output_vcf):
15
+ def trim_down_vcf(vcf_file, output_vcf, max_nb_lines=MAX_NB_LINES):
15
16
  """
16
17
  Produce a smaller vcf files containing a maximum of 10000 records
17
18
  """
18
- with open_gzip_if_required(vcf_file) as vcf_in, open(output_vcf, 'w') as vcf_out:
19
+ with open_gzip_if_required(vcf_file) as vcf_in, open_gzip_if_required(output_vcf, 'w') as vcf_out:
19
20
  line_count = 0
21
+ trimmed_down = False
20
22
  ref_seq_names = set()
21
23
  for line in vcf_in:
22
24
  if line.startswith('#') or line_count < max_nb_lines:
@@ -25,10 +27,12 @@ def trim_down_vcf(vcf_file, output_vcf):
25
27
  line_count += 1
26
28
  ref_seq_names.add(line.split('\t')[0])
27
29
  else:
30
+ trimmed_down = True
28
31
  break
29
32
  if line_count != max_nb_lines:
30
33
  logger.warning(f'Only {line_count} found in the source VCF {vcf_file} ')
31
- return line_count, ref_seq_names
34
+
35
+ return line_count, trimmed_down, ref_seq_names
32
36
 
33
37
 
34
38
  def trim_down_fasta(fasta_file, output_fasta, ref_seq_names):
@@ -46,10 +50,9 @@ def trim_down_fasta(fasta_file, output_fasta, ref_seq_names):
46
50
  print(sequence[i:i+80], file=fasta_out)
47
51
  return found_sequences
48
52
 
49
-
50
- def main():
53
+ def parse_args(cmd_line_args):
51
54
  arg_parser = argparse.ArgumentParser(
52
- description=f'Take a VCF file and only keep {max_nb_lines} lines and remove unused fasta sequence from the '
55
+ description=f'Take a VCF file and only keep {MAX_NB_LINES} lines and remove unused fasta sequence from the '
53
56
  f'associated reference genome')
54
57
  arg_parser.add_argument('--vcf_file', dest='vcf_file', required=True,
55
58
  help='Path to the vcf file to be trimmed down')
@@ -63,16 +66,23 @@ def main():
63
66
  help='Path to the yaml file containing the trim down metrics')
64
67
 
65
68
  args = arg_parser.parse_args()
69
+ return args
70
+
71
+ def main():
72
+ args = parse_args(sys.argv[1:])
73
+
66
74
  logging_config.add_stdout_handler()
67
75
 
68
- line_count, ref_sequence = trim_down_vcf(args.vcf_file, args.output_vcf_file)
76
+ line_count, trimmed_down, ref_sequence = trim_down_vcf(args.vcf_file, args.output_vcf_file)
69
77
  sequence_found = trim_down_fasta(args.fasta_file, args.output_fasta_file, ref_sequence)
70
- trim_down_metrics = {'trim_down_vcf_record': line_count, 'number_sequence_found': sequence_found,
71
- 'trim_down_required': line_count == max_nb_lines}
78
+ trim_down_metrics = {'trim_down_vcf_record': line_count, 'number_sequence_found': len(sequence_found),
79
+ 'trim_down_required': trimmed_down}
72
80
  if len(sequence_found) != len(ref_sequence):
73
81
  logger.warning(f'Not all sequences were found in the fasta file. Cancelling trimming down of fasta file')
82
+ if os.path.exists(args.output_fasta_file):
83
+ os.remove(args.output_fasta_file)
74
84
  os.link(args.fasta_file, args.output_fasta_file)
75
85
  trim_down_metrics.pop('number_sequence_found')
76
- with open(args.output_yaml_file) as open_file:
86
+ with open(args.output_yaml_file, 'w') as open_file:
77
87
  yaml.safe_dump(trim_down_metrics, open_file)
78
88
 
@@ -46,12 +46,12 @@ def backup_file_or_directory(file_name, max_backups=None):
46
46
  os.rename(file_name, file_name + '.1')
47
47
 
48
48
 
49
- def open_gzip_if_required(input_file):
49
+ def open_gzip_if_required(input_file, mode='r'):
50
50
  """Open a file in read mode using gzip if the file extension says .gz"""
51
51
  if input_file.endswith('.gz'):
52
- return gzip.open(input_file, 'rt')
52
+ return gzip.open(input_file, mode + 't')
53
53
  else:
54
- return open(input_file, 'r')
54
+ return open(input_file, mode)
55
55
 
56
56
 
57
57
  def fasta_iter(input_fasta):
@@ -116,6 +116,7 @@ process trim_down_vcf {
116
116
  path "${vcf.getBaseName()}_trim_down.log", emit: trim_down_log
117
117
  path "${vcf.getBaseName()}_trim_down.yml", emit: trim_down_metric
118
118
 
119
+ script:
119
120
  """
120
121
  mkdir output
121
122
  $params.python_scripts.trim_down --vcf_file $vcf --output_vcf_file output/$vcf --fasta_file $fasta --output_fasta_file output/$fasta --output_yaml_file ${vcf.getBaseName()}_trim_down.yml > ${vcf.getBaseName()}_trim_down.log
@@ -2,15 +2,23 @@
2
2
  import csv
3
3
  import json
4
4
  import os
5
+ import re
5
6
  from collections import defaultdict
6
7
 
7
8
  import requests
8
9
  from ebi_eva_common_pyutils.config import WritableConfig
9
10
  from ebi_eva_common_pyutils.logger import logging_config
10
11
  from openpyxl.reader.excel import load_workbook
12
+ from packaging import version
13
+ from requests import HTTPError
14
+ from retry import retry
11
15
 
16
+ import eva_sub_cli
17
+ from eva_sub_cli import DEFAULT_METADATA_XLSX_TEMPLATE_VERSION
12
18
  from eva_sub_cli import SUB_CLI_CONFIG_FILE, __version__
13
19
  from eva_sub_cli.exceptions.invalid_file_type_exception import InvalidFileTypeError
20
+ from eva_sub_cli.exceptions.metadata_template_version_exception import MetadataTemplateVersionException, \
21
+ MetadataTemplateVersionNotFoundException
14
22
  from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
15
23
  from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
16
24
  from eva_sub_cli.submission_ws import SubmissionWSClient
@@ -120,6 +128,60 @@ def get_project_and_vcf_fasta_mapping_from_metadata_json(metadata_json, mapping_
120
128
  return project_title, vcf_fasta_report_mapping
121
129
 
122
130
 
131
+ def get_sub_cli_version():
132
+ if version.parse(eva_sub_cli.__version__).is_devrelease:
133
+ major, minor, patch = map(int, version.parse(eva_sub_cli.__version__).base_version.split('.'))
134
+ if patch > 0:
135
+ patch -= 1
136
+ elif minor > 0:
137
+ minor -= 1
138
+ patch = 0
139
+ elif major > 0:
140
+ major -= 1
141
+ minor = 0
142
+ patch = 0
143
+ return f"{major}.{minor}.{patch}"
144
+ else:
145
+ return version.parse(eva_sub_cli.__version__).base_version
146
+
147
+
148
+ @retry(exceptions=(HTTPError,), tries=3, delay=2, backoff=1.2, jitter=(1, 3))
149
+ def get_sub_cli_github_tags():
150
+ url = f"https://api.github.com/repos/EBIvariation/eva-sub-cli/tags"
151
+ response = requests.get(url)
152
+ if response.status_code == 200:
153
+ tags = [tag["name"][1:] for tag in response.json()]
154
+ return tags
155
+ else:
156
+ return []
157
+
158
+
159
+ def get_metadata_xlsx_template_link():
160
+ sub_cli_version = get_sub_cli_version()
161
+ sub_cli_tags = get_sub_cli_github_tags()
162
+ if sub_cli_version in sub_cli_tags:
163
+ return f'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/v{sub_cli_version}/eva-sub-cli/eva_sub_cli/etc/EVA_Submission_template.xlsx'
164
+ else:
165
+ return 'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/main/eva_sub_cli/etc/EVA_Submission_template.xlsx'
166
+
167
+
168
+ def verify_metadata_xlsx_version(metadata_xlsx, min_req_version):
169
+ workbook = load_workbook(metadata_xlsx)
170
+ instructions_sheet = workbook['PLEASE READ FIRST']
171
+ xlsx_sheet_version_value = instructions_sheet[3][0].value
172
+ match = re.search(r'(\d+\.\d+\.\d+)', '' if xlsx_sheet_version_value is None else xlsx_sheet_version_value)
173
+ xlsx_version = match.group(1) if match else None
174
+ if xlsx_version:
175
+ if version.parse(xlsx_version) < version.parse(min_req_version):
176
+ raise MetadataTemplateVersionException(
177
+ f"Metadata template version {xlsx_version} is lower than min required {min_req_version}. "
178
+ f"Please download the correct template from EVA github project {get_metadata_xlsx_template_link()}")
179
+ else:
180
+ raise MetadataTemplateVersionNotFoundException(
181
+ f"No version information found in metadata xlsx sheet {metadata_xlsx}. "
182
+ f"Please download the correct template from EVA github project {get_metadata_xlsx_template_link()}")
183
+
184
+
123
185
  def get_project_and_vcf_fasta_mapping_from_metadata_xlsx(metadata_xlsx, mapping_req=False):
124
186
  workbook = load_workbook(metadata_xlsx)
125
187
 
@@ -148,10 +210,15 @@ def get_project_and_vcf_fasta_mapping_from_metadata_xlsx(metadata_xlsx, mapping_
148
210
  files_headers[cell.value] = cell.column - 1
149
211
 
150
212
  for row in files_sheet.iter_rows(min_row=2, values_only=True):
151
- file_name = os.path.abspath(row[files_headers['File Name']])
213
+ file_name = row[files_headers['File Name']]
214
+ if file_name:
215
+ file_name = os.path.abspath(file_name)
152
216
  analysis_alias = row[files_headers['Analysis Alias']]
153
- reference_fasta = os.path.abspath(analysis_alias_dict[analysis_alias])
154
- vcf_fasta_report_mapping.append([os.path.abspath(file_name), os.path.abspath(reference_fasta), ''])
217
+ reference_fasta = analysis_alias_dict[analysis_alias]
218
+ if reference_fasta:
219
+ reference_fasta = os.path.abspath(reference_fasta)
220
+ if file_name and reference_fasta:
221
+ vcf_fasta_report_mapping.append([file_name, reference_fasta, ''])
155
222
 
156
223
  return project_title, vcf_fasta_report_mapping
157
224
 
@@ -190,7 +257,8 @@ def check_validation_required(tasks, sub_config, username=None, password=None):
190
257
 
191
258
 
192
259
  def orchestrate_process(submission_dir, vcf_files, reference_fasta, metadata_json, metadata_xlsx,
193
- tasks, executor, username=None, password=None, shallow_validation=False, **kwargs):
260
+ tasks, executor, username=None, password=None, shallow_validation=False, nextflow_config=None,
261
+ **kwargs):
194
262
  # load config
195
263
  config_file_path = os.path.join(submission_dir, SUB_CLI_CONFIG_FILE)
196
264
  sub_config = WritableConfig(config_file_path, version=__version__)
@@ -203,6 +271,8 @@ def orchestrate_process(submission_dir, vcf_files, reference_fasta, metadata_jso
203
271
  metadata_json = os.path.abspath(metadata_json)
204
272
  if metadata_xlsx:
205
273
  metadata_xlsx = os.path.abspath(metadata_xlsx)
274
+ # check metadata xlsx version is not lower than the required min metadata template version
275
+ verify_metadata_xlsx_version(metadata_xlsx, DEFAULT_METADATA_XLSX_TEMPLATE_VERSION)
206
276
 
207
277
  # Get the provided Project Title and VCF files mapping (VCF, Fasta and Report)
208
278
  project_title, vcf_files_mapping = get_project_title_and_create_vcf_files_mapping(
@@ -220,7 +290,8 @@ def orchestrate_process(submission_dir, vcf_files, reference_fasta, metadata_jso
220
290
  # default to native execution
221
291
  else:
222
292
  validator = NativeValidator(vcf_files_mapping, submission_dir, project_title, metadata_json, metadata_xlsx,
223
- shallow_validation=shallow_validation, submission_config=sub_config)
293
+ shallow_validation=shallow_validation, submission_config=sub_config,
294
+ nextflow_config=nextflow_config)
224
295
  with validator:
225
296
  validator.validate_and_report()
226
297
  if not metadata_json:
@@ -229,5 +300,6 @@ def orchestrate_process(submission_dir, vcf_files, reference_fasta, metadata_jso
229
300
  sub_config.set('vcf_files', value=vcf_files)
230
301
 
231
302
  if SUBMIT in tasks:
232
- with StudySubmitter(submission_dir, submission_config=sub_config, username=username, password=password) as submitter:
303
+ with StudySubmitter(submission_dir, submission_config=sub_config, username=username,
304
+ password=password) as submitter:
233
305
  submitter.submit()