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.
- eva_sub_cli-0.4.7/.github/workflows/publish.yml +51 -0
- {eva_sub_cli-0.4.4/eva_sub_cli.egg-info → eva_sub_cli-0.4.7}/PKG-INFO +62 -11
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/README.md +53 -3
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/__init__.py +1 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/_version.py +2 -2
- eva_sub_cli-0.4.7/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
- eva_sub_cli-0.4.7/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva_schema.json +7 -5
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/spreadsheet2json_conf.yaml +3 -2
- eva_sub_cli-0.4.7/eva_sub_cli/exceptions/metadata_template_version_exception.py +10 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/cli.py +18 -2
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/trim_down.py +21 -11
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/file_utils.py +3 -3
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/nextflow/validation.nf +1 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/orchestrator.py +78 -6
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/semantic_metadata.py +42 -5
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/docker_validator.py +15 -11
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/native_validator.py +11 -9
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/validator.py +5 -2
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7/eva_sub_cli.egg-info}/PKG-INFO +62 -11
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/SOURCES.txt +9 -1
- eva_sub_cli-0.4.7/eva_sub_cli.egg-info/requires.txt +8 -0
- eva_sub_cli-0.4.7/requirements.txt +8 -0
- eva_sub_cli-0.4.7/tests/build_and_test_docker_locally.py +293 -0
- eva_sub_cli-0.4.7/tests/resources/EVA_Submission_Docker_Test.xlsx +0 -0
- eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test.xlsx +0 -0
- eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
- eva_sub_cli-0.4.7/tests/resources/EVA_Submission_test_version_missing.xlsx +0 -0
- eva_sub_cli-0.4.7/tests/resources/fasta_files/multi_seq.fa +8 -0
- {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
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_cli.py +5 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_orchestrator.py +72 -10
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_semantic_metadata.py +41 -17
- eva_sub_cli-0.4.7/tests/test_trim_down.py +108 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_validator.py +17 -8
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_xlsx2json.py +27 -0
- eva_sub_cli-0.4.4/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- eva_sub_cli-0.4.4/eva_sub_cli.egg-info/requires.txt +0 -7
- eva_sub_cli-0.4.4/requirements.txt +0 -7
- eva_sub_cli-0.4.4/tests/resources/EVA_Submission_test.xlsx +0 -0
- eva_sub_cli-0.4.4/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.github/workflows/publish_packages.yml +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.github/workflows/tests.yml +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/.gitignore +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/LICENSE +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/conda/build.sh +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/conda/meta.yaml +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/docker/Dockerfile +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7/docs}/Getting_Started_with_eva_sub_cli.md +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/auth.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/date_utils.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva-biosamples.json +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/etc/eva_logo.png +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/__init__.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/invalid_file_type_exception.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/submission_not_found_exception.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/exceptions/submission_status_exception.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/__init__.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/check_metadata_semantics.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/samples_checker.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/executables/xlsx2json.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/fasta_check.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/file_validation.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/html_report.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/metadata_validation.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/project_details.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/sample_name_check.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/jinja_templates/shallow_validation.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/metadata_utils.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/report.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/submission_ws.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/submit.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/__init__.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli/validators/validation_results_parsers.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/dependency_links.txt +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/entry_points.txt +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/eva_sub_cli.egg-info/top_level.txt +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/pyproject.toml +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/pytest.ini +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/setup.cfg +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/setup.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/ignore_test_nextflow_validation.yml +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/EVA_Submission_test.json +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/EVA_Submission_test_with_asm_report.json +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_check/invalid.vcf.assembly_check.log +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_check/invalid.vcf.text_assembly_report.txt +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/assembly_reports/input_passed.txt +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/fasta_files/input_passed.fa +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example1.vcf.gz +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example2.vcf +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/example3.vcf +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/sample_checker/metadata.json +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_report_metadata_json.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_report_metadata_xlsx.html +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.html +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/vcf_files/example2.vcf.gz +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/resources/vcf_files/input_passed.vcf +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_auth.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_docker_validator.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_file_utils.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_report.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_samples_checker.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_submit.py +0 -0
- {eva_sub_cli-0.4.4 → eva_sub_cli-0.4.7}/tests/test_utils.py +0 -0
- {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.
|
|
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.
|
|
23
|
-
Requires-Dist: jinja2
|
|
24
|
-
Requires-Dist: jsonschema
|
|
25
|
-
Requires-Dist: openpyxl
|
|
26
|
-
Requires-Dist: pyyaml
|
|
27
|
-
Requires-Dist: requests
|
|
28
|
-
Requires-Dist:
|
|
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
|
|
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
|
|
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
|
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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 {
|
|
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':
|
|
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, '
|
|
52
|
+
return gzip.open(input_file, mode + 't')
|
|
53
53
|
else:
|
|
54
|
-
return open(input_file,
|
|
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 =
|
|
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 =
|
|
154
|
-
|
|
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,
|
|
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,
|
|
303
|
+
with StudySubmitter(submission_dir, submission_config=sub_config, username=username,
|
|
304
|
+
password=password) as submitter:
|
|
233
305
|
submitter.submit()
|