eva-sub-cli 0.5.3__tar.gz → 0.6.1__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.6.1/.github/workflows/integration-tests.yml +56 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/.github/workflows/tests.yml +1 -1
- {eva_sub_cli-0.5.3/eva_sub_cli.egg-info → eva_sub_cli-0.6.1}/PKG-INFO +1 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docker/Dockerfile +1 -3
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/input_file_overview.md +2 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/validation_overview.md +1 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/_version.py +3 -3
- eva_sub_cli-0.6.1/eva_sub_cli/call_home.py +118 -0
- eva_sub_cli-0.6.1/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
- eva_sub_cli-0.6.1/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- eva_sub_cli-0.6.1/eva_sub_cli/etc/call_home_payload_schema.json +73 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/etc/eva_schema.json +1 -2
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/check_metadata_semantics.py +8 -3
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/cli.py +36 -2
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/samples_checker.py +13 -12
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/xlsx2json.py +5 -4
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/nextflow/validation.nf +22 -4
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/orchestrator.py +3 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/report.py +4 -4
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/semantic_metadata.py +27 -2
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/submission_ws.py +11 -7
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/validators/docker_validator.py +3 -3
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/validators/validator.py +3 -3
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1/eva_sub_cli.egg-info}/PKG-INFO +1 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli.egg-info/SOURCES.txt +13 -0
- eva_sub_cli-0.6.1/tests/resources/sample_checker/evidence_type.yaml +6 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/allele_freq.vcf +9 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/fake_fasta.fa +2 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/genotype.vcf +7 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/metadata_af_no_sample_in_vcf.json +1 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/metadata_af_with_sample_in_vcf.json +1 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/metadata_genotype_no_sample_in_vcf.json +1 -0
- eva_sub_cli-0.6.1/tests/resources/sample_in_vcf_check/metadata_genotype_with_sample_in_vcf.json +1 -0
- eva_sub_cli-0.6.1/tests/test_call_home.py +207 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_cli.py +51 -3
- eva_sub_cli-0.6.1/tests/test_native_validator_sample_in_vcf.py +96 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_samples_checker.py +2 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_semantic_metadata.py +65 -15
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_submit.py +3 -3
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_utils.py +3 -1
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_validator.py +74 -0
- eva_sub_cli-0.5.3/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
- eva_sub_cli-0.5.3/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/.github/workflows/publish.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/.github/workflows/publish_docs.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/.github/workflows/trigger-eva-sub-cli-integration-tests.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/.gitignore +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/LICENSE +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/README.md +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/conda/build.sh +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/conda/meta.yaml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/README.md +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/_config.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/how_to_submit.md +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/installation.md +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/docs/using_nextflow.md +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/__init__.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/auth.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/date_utils.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/etc/eva-biosamples.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/etc/eva_logo.png +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/etc/spreadsheet2json_conf.yaml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/etc/spreadsheet2json_conf_V2.yaml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/__init__.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/invalid_file_type_exception.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/metadata_template_version_exception.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/submission_not_found_exception.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/submission_status_exception.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/exceptions/submission_upload_exception.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/__init__.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/evidence_type_checker.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/executables/trim_down.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/file_utils.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/fasta_check.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/file_validation.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/metadata_validation.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/project_details.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/report.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/sample_name_check.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/html/shallow_validation.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/fasta_check.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/file_validation.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/metadata_validation.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/project_details.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/report.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/sample_name_check.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/jinja_templates/text/shallow_validation.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/metadata.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/submit.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/utils.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/validators/__init__.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/validators/native_validator.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli/validators/validation_results_parsers.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli.egg-info/dependency_links.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli.egg-info/entry_points.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli.egg-info/requires.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/eva_sub_cli.egg-info/top_level.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/pyproject.toml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/pytest.ini +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/requirements.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/setup.cfg +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/setup.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/build_and_test_docker_locally.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/ignore_test_nextflow_validation.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_Docker_Test.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_V2.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_version_missing.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_with_asm_report.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_with_non_vcf_files.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_with_non_vcf_files.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_with_project_accession.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/EVA_Submission_test_with_project_accession.xlsx +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/assembly_check/invalid.vcf.assembly_check.log +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/assembly_check/invalid.vcf.text_assembly_report.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/assembly_reports/input_passed.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/fasta_files/input_passed.fa +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/fasta_files/multi_seq.fa +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/metadata_with_filename.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/sample_checker/example1.vcf.gz +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/sample_checker/example2.vcf +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/sample_checker/example3.vcf +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/sample_checker/metadata.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_metadata_json_report.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_metadata_json_report.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_metadata_xlsx_report.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_metadata_xlsx_report.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.html +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.assembly_check.log +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.text_assembly_report.1680102476700.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.valid_assembly_report.1680102476700.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/metadata.json +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/evidence_type_checker.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/file_info.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/input_passed.fa_check.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/input_passed_trim_down.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/metadata_conversion_errors.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/metadata_semantic_check.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/metadata_validation.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/other_validations/sample_checker.yml +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.db +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.txt +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.vcf_format.log +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/vcf_files/example2.vcf.gz +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/vcf_files/example2.vcf.gz.tbi +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/resources/vcf_files/input_passed.vcf +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_auth.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_docker_validator.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_evidence_type_checker.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_file_utils.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_metadata.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_orchestrator.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_report.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_trim_down.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_validaton_results_parsers.py +0 -0
- {eva_sub_cli-0.5.3 → eva_sub_cli-0.6.1}/tests/test_xlsx2json.py +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Integration tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
VCF_VALIDATOR_VERSION: "0.10.2"
|
|
11
|
+
NXF_VER: "23.10.0"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
integration-tests:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python 3.11
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
|
|
25
|
+
- name: Install Java and Node
|
|
26
|
+
run: sudo apt update && sudo apt install -y default-jdk nodejs npm git curl
|
|
27
|
+
|
|
28
|
+
- name: Install vcf-validator and vcf-assembly-checker
|
|
29
|
+
run: |
|
|
30
|
+
curl -LJo /usr/local/bin/vcf_validator \
|
|
31
|
+
https://github.com/EBIvariation/vcf-validator/releases/download/v${VCF_VALIDATOR_VERSION}/vcf_validator_linux
|
|
32
|
+
curl -LJo /usr/local/bin/vcf_assembly_checker \
|
|
33
|
+
https://github.com/EBIvariation/vcf-validator/releases/download/v${VCF_VALIDATOR_VERSION}/vcf_assembly_checker_linux
|
|
34
|
+
chmod 755 /usr/local/bin/vcf_validator /usr/local/bin/vcf_assembly_checker
|
|
35
|
+
|
|
36
|
+
- name: Install biovalidator
|
|
37
|
+
run: |
|
|
38
|
+
git clone https://github.com/elixir-europe/biovalidator.git
|
|
39
|
+
cd biovalidator
|
|
40
|
+
npm install
|
|
41
|
+
sudo npm link
|
|
42
|
+
|
|
43
|
+
- name: Install Nextflow
|
|
44
|
+
run: |
|
|
45
|
+
curl -L "https://github.com/nextflow-io/nextflow/releases/download/v${NXF_VER}/nextflow-${NXF_VER}-all" | bash
|
|
46
|
+
sudo mv nextflow /usr/local/bin/
|
|
47
|
+
|
|
48
|
+
- name: Install Python dependencies
|
|
49
|
+
run: |
|
|
50
|
+
python -m pip install --upgrade pip
|
|
51
|
+
pip install pytest
|
|
52
|
+
python -m pip install .
|
|
53
|
+
|
|
54
|
+
- name: Run integration tests
|
|
55
|
+
run: |
|
|
56
|
+
PYTHONPATH=. pytest tests -m integration
|
|
@@ -6,9 +6,7 @@ ENV NXF_VER=23.10.0
|
|
|
6
6
|
WORKDIR /opt
|
|
7
7
|
|
|
8
8
|
# Install JAVA and Node
|
|
9
|
-
RUN apt update && apt install -y default-jdk
|
|
10
|
-
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
11
|
-
&& apt install -y nodejs
|
|
9
|
+
RUN apt update && apt install -y default-jdk nodejs npm
|
|
12
10
|
|
|
13
11
|
# Install VCF validator
|
|
14
12
|
RUN curl -LJo /usr/local/bin/vcf_validator https://github.com/EBIvariation/vcf-validator/releases/download/v${vcf_validator_version}/vcf_validator_linux \
|
|
@@ -98,7 +98,8 @@ alias, which is a shortened identifier you must provide for each analysis.
|
|
|
98
98
|
|
|
99
99
|
This is where you describe the biological samples used for your analyses. Each row describes one sample and must include
|
|
100
100
|
the Analysis Alias to indicate which analysis it belongs to, and "Sample Name in VCF" which is the exact name of the
|
|
101
|
-
sample as it appears in the VCF file.
|
|
101
|
+
sample as it appears in the VCF file. If you are submitting a VCF without sample names (containing only allele frequencies),
|
|
102
|
+
then you can omit the "Sample Name in VCF" column.
|
|
102
103
|
|
|
103
104
|
We accept preregistered samples, which should be provided using BioSamples sample or sampleset accessions. Please
|
|
104
105
|
ensure these are publicly accessible, as otherwise EVA will not be able to validate them.
|
|
@@ -25,7 +25,7 @@ Key points to note before validating your metadata spreadsheet with the eva-sub-
|
|
|
25
25
|
- Any pre-registered projects and samples must be released and not kept in private status.
|
|
26
26
|
- Sample names in the spreadsheet must match those in the VCF file.
|
|
27
27
|
- Analysis aliases must match across the sheets (Analysis, Sample, and File sheets).
|
|
28
|
-
- Use the Hold Date field in the Project sheet for data that needs to be kept under embargo.
|
|
28
|
+
- Use the Hold Date field in the Project sheet for data that needs to be kept under embargo. The Hold Date cannot be more than 2 years in the future.
|
|
29
29
|
|
|
30
30
|
Common errors seen with metadata checks:
|
|
31
31
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.6.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 6, 1)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g13513250e'
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import traceback
|
|
3
|
+
import uuid
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
from ebi_eva_common_pyutils.config import WritableConfig
|
|
8
|
+
from ebi_eva_common_pyutils.logger import logging_config as log_cfg
|
|
9
|
+
|
|
10
|
+
from eva_sub_cli import __version__, SUB_CLI_CONFIG_FILE, ROOT_DIR
|
|
11
|
+
from eva_sub_cli.submission_ws import _submission_ws_base_url
|
|
12
|
+
|
|
13
|
+
logger = log_cfg.get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
CALL_HOME_PATH = 'call-home/events'
|
|
16
|
+
DEPLOYMENT_ID_DIR = os.path.join(os.path.expanduser('~'), '.eva-sub-cli')
|
|
17
|
+
DEPLOYMENT_ID_FILE = os.path.join(DEPLOYMENT_ID_DIR, 'deployment_id')
|
|
18
|
+
|
|
19
|
+
EVENT_START = 'START'
|
|
20
|
+
EVENT_VALIDATION_COMPLETED = 'VALIDATION_COMPLETED'
|
|
21
|
+
EVENT_END = 'END'
|
|
22
|
+
EVENT_FAILURE = 'FAILURE'
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _get_call_home_url():
|
|
26
|
+
return os.path.join(_submission_ws_base_url(), CALL_HOME_PATH)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _get_or_create_deployment_id():
|
|
30
|
+
try:
|
|
31
|
+
if os.path.isfile(DEPLOYMENT_ID_FILE):
|
|
32
|
+
with open(DEPLOYMENT_ID_FILE, 'r') as f:
|
|
33
|
+
deployment_id = f.read().strip()
|
|
34
|
+
if deployment_id:
|
|
35
|
+
return deployment_id
|
|
36
|
+
deployment_id = str(uuid.uuid4())
|
|
37
|
+
os.makedirs(DEPLOYMENT_ID_DIR, exist_ok=True)
|
|
38
|
+
with open(DEPLOYMENT_ID_FILE, 'w') as f:
|
|
39
|
+
f.write(deployment_id)
|
|
40
|
+
return deployment_id
|
|
41
|
+
except Exception:
|
|
42
|
+
logger.debug('Failed to read or create deployment ID file, using transient ID')
|
|
43
|
+
return str(uuid.uuid4())
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _get_or_create_run_id(submission_dir):
|
|
47
|
+
try:
|
|
48
|
+
config_path = os.path.join(submission_dir, SUB_CLI_CONFIG_FILE)
|
|
49
|
+
config = WritableConfig(config_path)
|
|
50
|
+
run_id = config.get('run_id')
|
|
51
|
+
if run_id:
|
|
52
|
+
return str(run_id)
|
|
53
|
+
run_id = str(uuid.uuid4())
|
|
54
|
+
config.set('run_id', value=run_id)
|
|
55
|
+
config.write()
|
|
56
|
+
return run_id
|
|
57
|
+
except Exception:
|
|
58
|
+
logger.debug('Failed to read or create run ID in config, using transient ID')
|
|
59
|
+
return str(uuid.uuid4())
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CallHomeClient:
|
|
63
|
+
|
|
64
|
+
def __init__(self, submission_dir, executor, tasks):
|
|
65
|
+
self.start_time = datetime.now(timezone.utc)
|
|
66
|
+
self.deployment_id = _get_or_create_deployment_id()
|
|
67
|
+
self.run_id = _get_or_create_run_id(submission_dir)
|
|
68
|
+
self.executor = executor
|
|
69
|
+
self.tasks = tasks
|
|
70
|
+
|
|
71
|
+
def _build_payload(self, event_type, **kwargs):
|
|
72
|
+
now = datetime.now(timezone.utc)
|
|
73
|
+
if event_type == EVENT_START:
|
|
74
|
+
runtime_seconds = 0
|
|
75
|
+
else:
|
|
76
|
+
elapsed = now - self.start_time
|
|
77
|
+
runtime_seconds = int(elapsed.total_seconds())
|
|
78
|
+
payload = {
|
|
79
|
+
'deploymentId': self.deployment_id,
|
|
80
|
+
'runId': self.run_id,
|
|
81
|
+
'eventType': event_type,
|
|
82
|
+
'cliVersion': __version__,
|
|
83
|
+
'createdAt': now.isoformat(),
|
|
84
|
+
'runtimeSeconds': runtime_seconds,
|
|
85
|
+
'executor': self.executor,
|
|
86
|
+
'tasks': self.tasks,
|
|
87
|
+
}
|
|
88
|
+
if kwargs:
|
|
89
|
+
payload.update(kwargs)
|
|
90
|
+
return payload
|
|
91
|
+
|
|
92
|
+
def _send_event(self, event_type, **kwargs):
|
|
93
|
+
try:
|
|
94
|
+
payload = self._build_payload(event_type, **kwargs)
|
|
95
|
+
requests.post(_get_call_home_url(), json=payload, timeout=5)
|
|
96
|
+
except Exception:
|
|
97
|
+
logger.debug('Failed to send %s call-home event', event_type)
|
|
98
|
+
|
|
99
|
+
def send_start(self):
|
|
100
|
+
self._send_event(EVENT_START)
|
|
101
|
+
|
|
102
|
+
def send_validation_completed(self, validation_result: dict):
|
|
103
|
+
self._send_event(EVENT_VALIDATION_COMPLETED, validation_result=validation_result)
|
|
104
|
+
|
|
105
|
+
def send_end(self):
|
|
106
|
+
self._send_event(EVENT_END)
|
|
107
|
+
|
|
108
|
+
def send_failure(self, exception=None):
|
|
109
|
+
kwargs = {}
|
|
110
|
+
if exception is not None:
|
|
111
|
+
kwargs['exceptionMessage'] = str(exception)
|
|
112
|
+
stack_trace = ''.join(
|
|
113
|
+
traceback.format_exception(type(exception), exception, exception.__traceback__)
|
|
114
|
+
)
|
|
115
|
+
# Remove the location of the file to preserve anonymity in case usernames are in the path
|
|
116
|
+
stack_trace = stack_trace.replace(ROOT_DIR, '')
|
|
117
|
+
kwargs['exceptionStacktrace'] = stack_trace
|
|
118
|
+
self._send_event(EVENT_FAILURE, **kwargs)
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Call-Home Event Payload",
|
|
4
|
+
"description": "Payload sent by the eva-sub-cli to the submission WS /call-home endpoint for usage telemetry.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"deploymentId": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"format": "uuid",
|
|
10
|
+
"description": "Persistent UUID identifying a unique CLI installation. Stored at ~/.eva-sub-cli/deployment_id."
|
|
11
|
+
},
|
|
12
|
+
"runId": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"format": "uuid",
|
|
15
|
+
"description": "Persistent UUID identifying a submission directory run. Stored in the .eva_sub_cli_config.yml file within the submission directory."
|
|
16
|
+
},
|
|
17
|
+
"eventType": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["START", "VALIDATION_COMPLETED", "END", "FAILURE"],
|
|
20
|
+
"description": "Type of lifecycle event. START is sent when main() begins, VALIDATION_COMPLETED after validation finishes, END when the program completes, FAILURE on any error."
|
|
21
|
+
},
|
|
22
|
+
"cliVersion": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Version of the eva-sub-cli package (e.g. '0.5.3')."
|
|
25
|
+
},
|
|
26
|
+
"createdAt": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"format": "date-time",
|
|
29
|
+
"description": "ISO 8601 UTC timestamp of when the event was created."
|
|
30
|
+
},
|
|
31
|
+
"runtimeSeconds": {
|
|
32
|
+
"type": "integer",
|
|
33
|
+
"minimum": 0,
|
|
34
|
+
"description": "Elapsed wall-clock seconds since the CLI started. Always 0 for START events."
|
|
35
|
+
},
|
|
36
|
+
"executor": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": ["native", "docker"],
|
|
39
|
+
"description": "Execution backend selected for validation."
|
|
40
|
+
},
|
|
41
|
+
"tasks": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"enum": ["validate", "submit"]
|
|
46
|
+
},
|
|
47
|
+
"description": "List of tasks requested by the user."
|
|
48
|
+
},
|
|
49
|
+
"validation_result": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"description": "Outcome of the validation step. Only present in VALIDATION_COMPLETED events."
|
|
52
|
+
},
|
|
53
|
+
"exceptionMessage": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "The exception message string. Only present in FAILURE events when an exception was caught."
|
|
56
|
+
},
|
|
57
|
+
"exceptionStacktrace": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Full Python stacktrace of the exception. Only present in FAILURE events when an exception was caught."
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"required": [
|
|
63
|
+
"deploymentId",
|
|
64
|
+
"runId",
|
|
65
|
+
"eventType",
|
|
66
|
+
"cliVersion",
|
|
67
|
+
"createdAt",
|
|
68
|
+
"runtimeSeconds",
|
|
69
|
+
"executor",
|
|
70
|
+
"tasks"
|
|
71
|
+
],
|
|
72
|
+
"additionalProperties": true
|
|
73
|
+
}
|
|
@@ -318,7 +318,6 @@
|
|
|
318
318
|
{
|
|
319
319
|
"required": [
|
|
320
320
|
"analysisAlias",
|
|
321
|
-
"sampleInVCF",
|
|
322
321
|
"bioSampleObject"
|
|
323
322
|
]
|
|
324
323
|
}
|
|
@@ -334,7 +333,7 @@
|
|
|
334
333
|
},
|
|
335
334
|
"sampleInVCF": {
|
|
336
335
|
"type": "string",
|
|
337
|
-
"description": "Sample Name used in the VCF file"
|
|
336
|
+
"description": "Sample Name used in the VCF file. It is a required field when genotypes are provided."
|
|
338
337
|
},
|
|
339
338
|
"bioSampleAccession": {
|
|
340
339
|
"type": "string",
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import json
|
|
3
3
|
|
|
4
|
+
import yaml
|
|
5
|
+
|
|
4
6
|
from eva_sub_cli.semantic_metadata import SemanticMetadataChecker
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
def main():
|
|
8
10
|
arg_parser = argparse.ArgumentParser(description='Perform semantic checks on the metadata')
|
|
9
11
|
arg_parser.add_argument('--metadata_json', required=True, dest='metadata_json', help='EVA metadata json file')
|
|
12
|
+
arg_parser.add_argument('--evidence_type_results', required=True, dest='evidence_type_results', help='Results of the evidence check')
|
|
10
13
|
arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
|
|
11
14
|
help='Path to the location of the results')
|
|
12
15
|
args = arg_parser.parse_args()
|
|
13
16
|
|
|
14
17
|
with open(args.metadata_json) as open_json:
|
|
15
18
|
metadata = json.load(open_json)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
with open(args.evidence_type_results) as open_yaml:
|
|
20
|
+
evidence_type_results = yaml.safe_load(open_yaml)
|
|
21
|
+
checker = SemanticMetadataChecker(metadata, evidence_type_results)
|
|
22
|
+
checker.check_all()
|
|
23
|
+
checker.write_result_yaml(args.output_yaml)
|
|
@@ -19,10 +19,12 @@ from eva_sub_cli.exceptions.metadata_template_version_exception import MetadataT
|
|
|
19
19
|
MetadataTemplateVersionNotFoundException
|
|
20
20
|
from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
|
|
21
21
|
from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
|
|
22
|
+
from eva_sub_cli.call_home import CallHomeClient
|
|
22
23
|
from eva_sub_cli.file_utils import is_submission_dir_writable, DirLockError, DirLock
|
|
23
24
|
from eva_sub_cli.orchestrator import VALIDATE, SUBMIT, DOCKER, NATIVE
|
|
24
25
|
from eva_sub_cli.validators.validator import ALL_VALIDATION_TASKS
|
|
25
26
|
|
|
27
|
+
logger = logging_config.get_logger(__name__)
|
|
26
28
|
|
|
27
29
|
def validate_command_line_arguments(args, argparser):
|
|
28
30
|
fail = False
|
|
@@ -107,42 +109,74 @@ def main():
|
|
|
107
109
|
else:
|
|
108
110
|
logging_config.add_stdout_handler(logging.INFO)
|
|
109
111
|
|
|
112
|
+
# Initialize call-home
|
|
113
|
+
call_home = None
|
|
114
|
+
try:
|
|
115
|
+
call_home = CallHomeClient(
|
|
116
|
+
submission_dir=args.submission_dir,
|
|
117
|
+
executor=args.executor,
|
|
118
|
+
tasks=args.tasks
|
|
119
|
+
)
|
|
120
|
+
call_home.send_start()
|
|
121
|
+
except Exception:
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
caught_exception = None
|
|
110
125
|
try:
|
|
111
126
|
# lock the submission directory
|
|
112
127
|
with DirLock(os.path.join(args.submission_dir)) as lock:
|
|
113
128
|
# Create the log file
|
|
114
129
|
logging_config.add_file_handler(os.path.join(args.submission_dir, 'eva_submission.log'), logging.DEBUG)
|
|
115
130
|
# Pass on all the arguments to the orchestrator
|
|
116
|
-
orchestrator.orchestrate_process(**args.__dict__)
|
|
117
|
-
except DirLockError:
|
|
131
|
+
orchestrator.orchestrate_process(call_home=call_home, **args.__dict__)
|
|
132
|
+
except DirLockError as dle:
|
|
118
133
|
print(f'Could not acquire the lock file for {args.submission_dir} because another process is using this '
|
|
119
134
|
f'directory or a previous process did not terminate correctly. '
|
|
120
135
|
f'If the problem persists, remove the lock file manually.')
|
|
136
|
+
caught_exception = dle
|
|
121
137
|
exit_status = 65
|
|
122
138
|
except FileNotFoundError as fne:
|
|
123
139
|
print(fne)
|
|
140
|
+
caught_exception = fne
|
|
124
141
|
exit_status = 66
|
|
125
142
|
except SubmissionNotFoundException as snfe:
|
|
126
143
|
print(f'{snfe}. Please contact EVA Helpdesk')
|
|
144
|
+
caught_exception = snfe
|
|
127
145
|
exit_status = 67
|
|
128
146
|
except SubmissionStatusException as sse:
|
|
129
147
|
print(f'{sse}. Please try again later. If the problem persists, please contact EVA Helpdesk')
|
|
148
|
+
caught_exception = sse
|
|
130
149
|
exit_status = 68
|
|
131
150
|
except MetadataTemplateVersionException as mte:
|
|
132
151
|
print(mte)
|
|
152
|
+
caught_exception = mte
|
|
133
153
|
exit_status = 69
|
|
134
154
|
except MetadataTemplateVersionNotFoundException as mte:
|
|
135
155
|
print(mte)
|
|
156
|
+
caught_exception = mte
|
|
136
157
|
exit_status = 70
|
|
137
158
|
except SubmissionUploadException as sue:
|
|
138
159
|
print(sue)
|
|
160
|
+
caught_exception = sue
|
|
139
161
|
exit_status = 71
|
|
140
162
|
except HTTPError as http_err:
|
|
141
163
|
print(http_err)
|
|
142
164
|
if http_err.response is not None and http_err.response.text:
|
|
143
165
|
print(http_err.response.text)
|
|
166
|
+
caught_exception = http_err
|
|
144
167
|
exit_status = 72
|
|
145
168
|
except Exception as ex:
|
|
146
169
|
print(ex)
|
|
170
|
+
caught_exception = ex
|
|
147
171
|
exit_status = 73
|
|
172
|
+
|
|
173
|
+
if caught_exception:
|
|
174
|
+
logger.exception(caught_exception)
|
|
175
|
+
|
|
176
|
+
if call_home is not None:
|
|
177
|
+
if exit_status == 0:
|
|
178
|
+
call_home.send_end()
|
|
179
|
+
else:
|
|
180
|
+
call_home.send_failure(caught_exception)
|
|
181
|
+
|
|
148
182
|
return exit_status
|
|
@@ -54,7 +54,7 @@ def compare_names_in_files_and_samples(sample_name_in_analysis, sample_name_per_
|
|
|
54
54
|
more_metadata_submitted_files)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def compare_all_analysis(metadata, files_per_analysis):
|
|
57
|
+
def compare_all_analysis(metadata, files_per_analysis, evidence_type_results):
|
|
58
58
|
overall_differences = False
|
|
59
59
|
results_per_analysis_alias = {}
|
|
60
60
|
all_analysis_alias = set(metadata.samples_per_analysis) | set(files_per_analysis)
|
|
@@ -65,7 +65,7 @@ def compare_all_analysis(metadata, files_per_analysis):
|
|
|
65
65
|
for file_path in files_per_analysis.get(analysis_alias, [])
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if need_to_check_samples(
|
|
68
|
+
if need_to_check_samples(evidence_type_results, analysis_alias):
|
|
69
69
|
(
|
|
70
70
|
has_difference, more_per_submitted_files_metadata,
|
|
71
71
|
more_submitted_files_metadata, more_metadata_submitted_files
|
|
@@ -89,13 +89,9 @@ def compare_all_analysis(metadata, files_per_analysis):
|
|
|
89
89
|
return overall_differences, results_per_analysis_alias
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
def need_to_check_samples(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
evidence_types_for_vcf_files = [detect_vcf_evidence_type(vcf_file) for vcf_file in sample_name_per_file.keys()]
|
|
96
|
-
if set(evidence_types_for_vcf_files) == {'allele_frequency'}:
|
|
97
|
-
return False
|
|
98
|
-
|
|
92
|
+
def need_to_check_samples(evidence_type_results, analysis_alias):
|
|
93
|
+
if evidence_type_results.get(analysis_alias, {}).get('evidence_type') == 'allele_frequency':
|
|
94
|
+
return False
|
|
99
95
|
return True
|
|
100
96
|
|
|
101
97
|
|
|
@@ -107,14 +103,16 @@ def write_result_yaml(output_yaml, overall_differences, results_per_analysis_ali
|
|
|
107
103
|
}, stream=open_yaml)
|
|
108
104
|
|
|
109
105
|
|
|
110
|
-
def check_sample_name_concordance(metadata_json, vcf_files, output_yaml):
|
|
106
|
+
def check_sample_name_concordance(metadata_json, vcf_files, output_yaml, evidence_type_result_file):
|
|
111
107
|
"""
|
|
112
108
|
Take the metadata following EVA standard and formatted in JSON then compare the sample names in it to the ones
|
|
113
109
|
found in the VCF files
|
|
114
110
|
"""
|
|
115
111
|
metadata = EvaMetadataJson(metadata_json)
|
|
112
|
+
with open(evidence_type_result_file) as open_yaml:
|
|
113
|
+
evidence_type_results = yaml.safe_load(open_yaml)
|
|
116
114
|
file_path_per_analysis = associate_vcf_path_with_analysis(metadata, vcf_files)
|
|
117
|
-
overall_differences, results_per_analysis_alias = compare_all_analysis(metadata, file_path_per_analysis)
|
|
115
|
+
overall_differences, results_per_analysis_alias = compare_all_analysis(metadata, file_path_per_analysis, evidence_type_results)
|
|
118
116
|
write_result_yaml(output_yaml, overall_differences, results_per_analysis_alias)
|
|
119
117
|
|
|
120
118
|
|
|
@@ -127,7 +125,10 @@ def main():
|
|
|
127
125
|
help='Path to the vcf files to compare to the metadata')
|
|
128
126
|
arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
|
|
129
127
|
help='Path to the location of the results')
|
|
128
|
+
arg_parser.add_argument('--evidence_type_results', required=True, dest='evidence_type_results',
|
|
129
|
+
help='Results of the evidence check')
|
|
130
|
+
|
|
130
131
|
|
|
131
132
|
args = arg_parser.parse_args()
|
|
132
133
|
logging_config.add_stdout_handler()
|
|
133
|
-
check_sample_name_concordance(args.metadata_json, args.vcf_files, args.output_yaml)
|
|
134
|
+
check_sample_name_concordance(args.metadata_json, args.vcf_files, args.output_yaml, args.evidence_type_results)
|
|
@@ -225,8 +225,9 @@ class XlsxParser:
|
|
|
225
225
|
return str(value)
|
|
226
226
|
|
|
227
227
|
def get_sample_data_with_split_analysis_alias(self, data, analysis_alias, sample_name_in_vcf):
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
analysis_alias_val = data.get(analysis_alias)
|
|
229
|
+
analysis_alias_list = analysis_alias_val.split(',') if analysis_alias_val else []
|
|
230
|
+
sample_in_vcf_val = data.get(sample_name_in_vcf)
|
|
230
231
|
return {analysis_alias: analysis_alias_list, sample_name_in_vcf: sample_in_vcf_val}
|
|
231
232
|
|
|
232
233
|
def get_sample_json_data(self):
|
|
@@ -245,8 +246,8 @@ class XlsxParser:
|
|
|
245
246
|
sample_data.update(bioSampleAccession=json_value[bio_sample_acc])
|
|
246
247
|
sample_json[json_key].append(sample_data)
|
|
247
248
|
else:
|
|
248
|
-
json_value.pop(analysis_alias)
|
|
249
|
-
json_value.pop(sample_name_in_vcf)
|
|
249
|
+
json_value.pop(analysis_alias, None)
|
|
250
|
+
json_value.pop(sample_name_in_vcf, None)
|
|
250
251
|
|
|
251
252
|
biosample_obj = self.get_biosample_object(json_value)
|
|
252
253
|
sample_data.update(bioSampleObject=biosample_obj)
|
|
@@ -105,20 +105,31 @@ workflow {
|
|
|
105
105
|
collect_file_size_and_md5(generate_file_size_and_md5_digests.out.file_size_and_digest_info.collect())
|
|
106
106
|
|
|
107
107
|
// Task-specific processing
|
|
108
|
+
evidence_type_results = null
|
|
109
|
+
|
|
108
110
|
if (params.tasks.contains(VCF_CHECK)) {
|
|
109
111
|
check_vcf_valid(vcf_and_ref_ch)
|
|
110
112
|
evidence_type_check(metadata_json, vcf_files.collect())
|
|
113
|
+
evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
|
|
111
114
|
}
|
|
112
115
|
if (params.tasks.contains(ASSEMBLY_CHECK)) {
|
|
113
116
|
check_vcf_reference(vcf_and_ref_ch)
|
|
114
117
|
insdc_checker(metadata_json, fasta_to_vcfs)
|
|
115
118
|
}
|
|
116
119
|
if (params.tasks.contains(METADATA_CHECK)) {
|
|
120
|
+
if (!evidence_type_results) {
|
|
121
|
+
evidence_type_check(metadata_json, vcf_files.collect())
|
|
122
|
+
evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
|
|
123
|
+
}
|
|
117
124
|
metadata_json_validation(metadata_json)
|
|
118
|
-
metadata_semantic_check(metadata_json)
|
|
125
|
+
metadata_semantic_check(metadata_json, evidence_type_results)
|
|
119
126
|
}
|
|
120
127
|
if (params.tasks.contains(SAMPLE_CHECK)) {
|
|
121
|
-
|
|
128
|
+
if (!evidence_type_results){
|
|
129
|
+
evidence_type_check(metadata_json, vcf_files.collect())
|
|
130
|
+
evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
|
|
131
|
+
}
|
|
132
|
+
sample_name_concordance(metadata_json, vcf_files.collect(), evidence_type_results)
|
|
122
133
|
}
|
|
123
134
|
}
|
|
124
135
|
|
|
@@ -294,6 +305,7 @@ process sample_name_concordance {
|
|
|
294
305
|
input:
|
|
295
306
|
path(metadata_json)
|
|
296
307
|
path(vcf_files)
|
|
308
|
+
path(evidence_type_results)
|
|
297
309
|
|
|
298
310
|
output:
|
|
299
311
|
path "sample_checker.yml", emit: sample_checker_yml
|
|
@@ -301,7 +313,9 @@ process sample_name_concordance {
|
|
|
301
313
|
|
|
302
314
|
script:
|
|
303
315
|
"""
|
|
304
|
-
$params.python_scripts.samples_checker --metadata_json $metadata_json
|
|
316
|
+
$params.python_scripts.samples_checker --metadata_json $metadata_json \
|
|
317
|
+
--vcf_files $vcf_files --output_yaml sample_checker.yml \
|
|
318
|
+
--evidence_type_results $evidence_type_results > sample_checker.log 2>&1
|
|
305
319
|
"""
|
|
306
320
|
}
|
|
307
321
|
|
|
@@ -362,6 +376,7 @@ process metadata_semantic_check {
|
|
|
362
376
|
|
|
363
377
|
input:
|
|
364
378
|
path(metadata_json)
|
|
379
|
+
path(evidence_type_results)
|
|
365
380
|
|
|
366
381
|
output:
|
|
367
382
|
path "metadata_semantic_check.yml", emit: metadata_semantic_check_yml
|
|
@@ -369,6 +384,9 @@ process metadata_semantic_check {
|
|
|
369
384
|
|
|
370
385
|
script:
|
|
371
386
|
"""
|
|
372
|
-
$params.python_scripts.semantic_checker
|
|
387
|
+
$params.python_scripts.semantic_checker \
|
|
388
|
+
--metadata_json $metadata_json \
|
|
389
|
+
--evidence_type_results $evidence_type_results \
|
|
390
|
+
--output_yaml metadata_semantic_check.yml > semantic_checker.log 2>&1
|
|
373
391
|
"""
|
|
374
392
|
}
|
|
@@ -299,7 +299,7 @@ def check_validation_required(tasks, sub_config, username=None, password=None):
|
|
|
299
299
|
|
|
300
300
|
def orchestrate_process(submission_dir, metadata_json, metadata_xlsx,
|
|
301
301
|
tasks, executor, validation_tasks=ALL_VALIDATION_TASKS, username=None, password=None,
|
|
302
|
-
shallow_validation=False, nextflow_config=None, **kwargs):
|
|
302
|
+
shallow_validation=False, nextflow_config=None, call_home=None, **kwargs):
|
|
303
303
|
# load config
|
|
304
304
|
config_file_path = os.path.join(submission_dir, SUB_CLI_CONFIG_FILE)
|
|
305
305
|
sub_config = WritableConfig(config_file_path, version=__version__)
|
|
@@ -341,6 +341,8 @@ def orchestrate_process(submission_dir, metadata_json, metadata_xlsx,
|
|
|
341
341
|
nextflow_config=nextflow_config)
|
|
342
342
|
with validator:
|
|
343
343
|
validator.validate_and_report()
|
|
344
|
+
if call_home:
|
|
345
|
+
call_home.send_validation_completed(validator.results)
|
|
344
346
|
if not metadata_json:
|
|
345
347
|
metadata_json = os.path.join(validator.output_dir, 'metadata.json')
|
|
346
348
|
sub_config.set('metadata_json', value=metadata_json)
|
|
@@ -17,16 +17,16 @@ def get_logo_data():
|
|
|
17
17
|
|
|
18
18
|
def generate_report(validation_results, validation_date, submission_dir, vcf_fasta_analysis_mapping, project_title,
|
|
19
19
|
consent_statement_required, subdir, template_file):
|
|
20
|
-
|
|
21
|
-
from eva_sub_cli.validators.validator import RUN_STATUS_KEY, PASS
|
|
20
|
+
from eva_sub_cli.validators.validator import RUN_STATUS_KEY, TRIM_DOWN, PASS
|
|
22
21
|
|
|
23
22
|
results_for_report = {k: v for k, v in validation_results.items() if k != 'ready_for_submission_to_eva'}
|
|
23
|
+
non_file_keys = {RUN_STATUS_KEY, PASS, TRIM_DOWN}
|
|
24
24
|
vcf_files = sorted(set([file_name
|
|
25
25
|
for check in results_for_report if check in ["vcf_check", "assembly_check"]
|
|
26
26
|
for file_name in results_for_report[check]
|
|
27
|
-
if file_name not in
|
|
27
|
+
if file_name not in non_file_keys
|
|
28
28
|
]))
|
|
29
|
-
fasta_files = sorted([file_name for file_name in results_for_report['fasta_check'] if file_name not in
|
|
29
|
+
fasta_files = sorted([file_name for file_name in results_for_report['fasta_check'] if file_name not in non_file_keys])
|
|
30
30
|
template = Environment(
|
|
31
31
|
loader=FileSystemLoader(os.path.join(current_dir, 'jinja_templates', subdir))
|
|
32
32
|
).get_template(template_file)
|