eva-sub-cli 0.6.1__tar.gz → 0.6.3__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 → eva_sub_cli-0.6.3}/.github/workflows/integration-tests.yml +3 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/.github/workflows/publish.yml +5 -2
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/.github/workflows/tests.yml +5 -2
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/.github/workflows/trigger-eva-sub-cli-integration-tests.yml +3 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/PKG-INFO +2 -2
- eva_sub_cli-0.6.3/eva_sub_cli/_version.py +24 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/spreadsheet2json_conf.yaml +1 -0
- eva_sub_cli-0.6.3/eva_sub_cli/exceptions.py +40 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/cli.py +25 -27
- eva_sub_cli-0.6.3/eva_sub_cli/executables/format_metadata.py +42 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/xlsx2json.py +1 -11
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/file_utils.py +0 -23
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/nextflow/validation.nf +30 -3
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/orchestrator.py +6 -49
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/semantic_metadata.py +7 -3
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/submission_ws.py +1 -1
- eva_sub_cli-0.6.3/eva_sub_cli/utils.py +72 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/validators/docker_validator.py +1 -1
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/validators/validator.py +20 -10
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/PKG-INFO +2 -2
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/SOURCES.txt +4 -6
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/entry_points.txt +1 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/requires.txt +1 -1
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/pyproject.toml +2 -1
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/requirements.txt +1 -1
- eva_sub_cli-0.6.3/tests/resources/EVA_Submission_test_with_links.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_cli.py +10 -16
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_file_utils.py +1 -32
- eva_sub_cli-0.6.3/tests/test_format_metadata.py +64 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_orchestrator.py +26 -9
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_semantic_metadata.py +10 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_validator.py +39 -4
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_xlsx2json.py +32 -7
- eva_sub_cli-0.6.1/eva_sub_cli/_version.py +0 -34
- eva_sub_cli-0.6.1/eva_sub_cli/exceptions/invalid_file_type_exception.py +0 -4
- eva_sub_cli-0.6.1/eva_sub_cli/exceptions/metadata_template_version_exception.py +0 -10
- eva_sub_cli-0.6.1/eva_sub_cli/exceptions/submission_not_found_exception.py +0 -4
- eva_sub_cli-0.6.1/eva_sub_cli/exceptions/submission_status_exception.py +0 -5
- eva_sub_cli-0.6.1/eva_sub_cli/exceptions/submission_upload_exception.py +0 -5
- eva_sub_cli-0.6.1/eva_sub_cli/utils.py +0 -20
- eva_sub_cli-0.6.1/eva_sub_cli/validators/__init__.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/.github/workflows/publish_docs.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/.gitignore +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/LICENSE +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/README.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/conda/build.sh +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/conda/meta.yaml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docker/Dockerfile +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/README.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/_config.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/how_to_submit.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/input_file_overview.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/installation.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/using_nextflow.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/docs/validation_overview.md +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/__init__.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/auth.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/call_home.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/date_utils.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/call_home_payload_schema.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/eva-biosamples.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/eva_logo.png +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/eva_schema.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/etc/spreadsheet2json_conf_V2.yaml +0 -0
- {eva_sub_cli-0.6.1/eva_sub_cli/exceptions → eva_sub_cli-0.6.3/eva_sub_cli/executables}/__init__.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/check_metadata_semantics.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/evidence_type_checker.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/samples_checker.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/executables/trim_down.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/fasta_check.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/file_validation.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/metadata_validation.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/project_details.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/report.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/sample_name_check.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/html/shallow_validation.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/fasta_check.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/file_validation.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/metadata_validation.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/project_details.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/report.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/sample_name_check.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/jinja_templates/text/shallow_validation.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/metadata.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/report.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/submit.py +0 -0
- {eva_sub_cli-0.6.1/eva_sub_cli/executables → eva_sub_cli-0.6.3/eva_sub_cli/validators}/__init__.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/validators/native_validator.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli/validators/validation_results_parsers.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/dependency_links.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/eva_sub_cli.egg-info/top_level.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/pytest.ini +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/setup.cfg +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/setup.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/build_and_test_docker_locally.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/ignore_test_nextflow_validation.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_Docker_Test.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_V2.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_version_missing.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_with_asm_report.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_with_non_vcf_files.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_with_non_vcf_files.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_with_project_accession.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/EVA_Submission_test_with_project_accession.xlsx +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/assembly_check/invalid.vcf.assembly_check.log +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/assembly_check/invalid.vcf.text_assembly_report.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/assembly_reports/input_passed.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/fasta_files/input_passed.fa +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/fasta_files/multi_seq.fa +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/metadata_with_filename.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_checker/evidence_type.yaml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_checker/example1.vcf.gz +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_checker/example2.vcf +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_checker/example3.vcf +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_checker/metadata.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/allele_freq.vcf +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/fake_fasta.fa +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/genotype.vcf +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/metadata_af_no_sample_in_vcf.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/metadata_af_with_sample_in_vcf.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/metadata_genotype_no_sample_in_vcf.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/sample_in_vcf_check/metadata_genotype_with_sample_in_vcf.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_metadata_json_report.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_metadata_json_report.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_metadata_xlsx_report.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_metadata_xlsx_report.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.html +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.assembly_check.log +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.text_assembly_report.1680102476700.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.valid_assembly_report.1680102476700.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/metadata.json +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/evidence_type_checker.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/file_info.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/input_passed.fa_check.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/input_passed_trim_down.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/metadata_conversion_errors.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/metadata_semantic_check.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/metadata_validation.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/other_validations/sample_checker.yml +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.db +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.txt +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.vcf_format.log +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/vcf_files/example2.vcf.gz +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/vcf_files/example2.vcf.gz.tbi +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/resources/vcf_files/input_passed.vcf +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_auth.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_call_home.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_check_fasta_insdc.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_docker_validator.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_evidence_type_checker.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_metadata.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_native_validator_sample_in_vcf.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_report.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_samples_checker.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_submit.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_trim_down.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_utils.py +0 -0
- {eva_sub_cli-0.6.1 → eva_sub_cli-0.6.3}/tests/test_validaton_results_parsers.py +0 -0
|
@@ -5,12 +5,15 @@ on:
|
|
|
5
5
|
tags:
|
|
6
6
|
- '**'
|
|
7
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
8
11
|
jobs:
|
|
9
12
|
test:
|
|
10
13
|
runs-on: ubuntu-latest
|
|
11
14
|
strategy:
|
|
12
15
|
matrix:
|
|
13
|
-
python-version: ["3.
|
|
16
|
+
python-version: ["3.11"]
|
|
14
17
|
steps:
|
|
15
18
|
- uses: actions/checkout@v4
|
|
16
19
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -38,7 +41,7 @@ jobs:
|
|
|
38
41
|
- name: Set up Python
|
|
39
42
|
uses: actions/setup-python@v5
|
|
40
43
|
with:
|
|
41
|
-
python-version: '3.
|
|
44
|
+
python-version: '3.11'
|
|
42
45
|
cache: pip
|
|
43
46
|
cache-dependency-path: '**/pyproject.toml'
|
|
44
47
|
- name: Install dependencies
|
|
@@ -4,14 +4,17 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
branches: [ main ]
|
|
6
6
|
pull_request:
|
|
7
|
-
branches: [ main
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
8
11
|
|
|
9
12
|
jobs:
|
|
10
13
|
build:
|
|
11
14
|
runs-on: ubuntu-latest
|
|
12
15
|
strategy:
|
|
13
16
|
matrix:
|
|
14
|
-
python-version: ["3.
|
|
17
|
+
python-version: ["3.11", "3.12"]
|
|
15
18
|
|
|
16
19
|
steps:
|
|
17
20
|
- uses: actions/checkout@v2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eva_sub_cli
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
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,7 +19,7 @@ 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
|
|
22
|
+
Requires-Dist: ebi_eva_common_pyutils>=0.7.4
|
|
23
23
|
Requires-Dist: jinja2==3.*,>=3.0.0
|
|
24
24
|
Requires-Dist: jsonschema==4.*
|
|
25
25
|
Requires-Dist: openpyxl==3.*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.6.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 6, 3)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'g1c826d931'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class NoVcfsFoundException(Exception):
|
|
2
|
+
def __init__(self, message):
|
|
3
|
+
self.message = message
|
|
4
|
+
super().__init__(self.message)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class InvalidFileTypeError(Exception):
|
|
8
|
+
def __init__(self, message):
|
|
9
|
+
self.message = message
|
|
10
|
+
super().__init__(self.message)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MetadataTemplateVersionException(Exception):
|
|
14
|
+
def __init__(self, message):
|
|
15
|
+
self.message = message
|
|
16
|
+
super().__init__(self.message)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class MetadataTemplateVersionNotFoundException(Exception):
|
|
20
|
+
def __init__(self, message):
|
|
21
|
+
self.message = message
|
|
22
|
+
super().__init__(self.message)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SubmissionNotFoundException(Exception):
|
|
26
|
+
def __init__(self, message):
|
|
27
|
+
self.message = message
|
|
28
|
+
super().__init__(self.message)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SubmissionStatusException(Exception):
|
|
32
|
+
def __init__(self, message):
|
|
33
|
+
self.message = message
|
|
34
|
+
super().__init__(self.message)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class SubmissionUploadException(Exception):
|
|
38
|
+
def __init__(self, message):
|
|
39
|
+
self.message = message
|
|
40
|
+
super().__init__(self.message)
|
|
@@ -2,8 +2,6 @@ import sys
|
|
|
2
2
|
|
|
3
3
|
from requests import HTTPError
|
|
4
4
|
|
|
5
|
-
from eva_sub_cli.exceptions.submission_upload_exception import SubmissionUploadException
|
|
6
|
-
|
|
7
5
|
if not sys.warnoptions:
|
|
8
6
|
import warnings
|
|
9
7
|
warnings.simplefilter("ignore")
|
|
@@ -15,10 +13,8 @@ from ebi_eva_common_pyutils.logger import logging_config
|
|
|
15
13
|
|
|
16
14
|
import eva_sub_cli
|
|
17
15
|
from eva_sub_cli import orchestrator
|
|
18
|
-
from eva_sub_cli.exceptions
|
|
19
|
-
|
|
20
|
-
from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
|
|
21
|
-
from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
|
|
16
|
+
from eva_sub_cli.exceptions import MetadataTemplateVersionException, MetadataTemplateVersionNotFoundException, \
|
|
17
|
+
SubmissionStatusException, SubmissionNotFoundException, SubmissionUploadException, NoVcfsFoundException
|
|
22
18
|
from eva_sub_cli.call_home import CallHomeClient
|
|
23
19
|
from eva_sub_cli.file_utils import is_submission_dir_writable, DirLockError, DirLock
|
|
24
20
|
from eva_sub_cli.orchestrator import VALIDATE, SUBMIT, DOCKER, NATIVE
|
|
@@ -130,48 +126,50 @@ def main():
|
|
|
130
126
|
# Pass on all the arguments to the orchestrator
|
|
131
127
|
orchestrator.orchestrate_process(call_home=call_home, **args.__dict__)
|
|
132
128
|
except DirLockError as dle:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
logger.exception(f'Could not acquire the lock file for {args.submission_dir} because another process is using '
|
|
130
|
+
f'this directory or a previous process did not terminate correctly. '
|
|
131
|
+
f'If the problem persists, remove the lock file manually.')
|
|
136
132
|
caught_exception = dle
|
|
137
133
|
exit_status = 65
|
|
138
134
|
except FileNotFoundError as fne:
|
|
139
|
-
|
|
135
|
+
logger.exception(fne)
|
|
140
136
|
caught_exception = fne
|
|
141
137
|
exit_status = 66
|
|
138
|
+
except NoVcfsFoundException as nvfe:
|
|
139
|
+
logger.exception(f'{nvfe}. Please ensure that you have listed VCF files in the metadata (.vcf or .vcf.gz file '
|
|
140
|
+
f'extension), and that you have not modified the metadata template in any way.')
|
|
141
|
+
caught_exception = nvfe
|
|
142
|
+
exit_status = 67
|
|
142
143
|
except SubmissionNotFoundException as snfe:
|
|
143
|
-
|
|
144
|
+
logger.exception(f'{snfe}. Please contact EVA Helpdesk')
|
|
144
145
|
caught_exception = snfe
|
|
145
|
-
exit_status =
|
|
146
|
+
exit_status = 68
|
|
146
147
|
except SubmissionStatusException as sse:
|
|
147
|
-
|
|
148
|
+
logger.exception(f'{sse}. Please try again later. If the problem persists, please contact EVA Helpdesk')
|
|
148
149
|
caught_exception = sse
|
|
149
|
-
exit_status =
|
|
150
|
+
exit_status = 69
|
|
150
151
|
except MetadataTemplateVersionException as mte:
|
|
151
|
-
|
|
152
|
+
logger.exception(mte)
|
|
152
153
|
caught_exception = mte
|
|
153
|
-
exit_status =
|
|
154
|
+
exit_status = 70
|
|
154
155
|
except MetadataTemplateVersionNotFoundException as mte:
|
|
155
|
-
|
|
156
|
+
logger.exception(mte)
|
|
156
157
|
caught_exception = mte
|
|
157
|
-
exit_status =
|
|
158
|
+
exit_status = 71
|
|
158
159
|
except SubmissionUploadException as sue:
|
|
159
|
-
|
|
160
|
+
logger.exception(sue)
|
|
160
161
|
caught_exception = sue
|
|
161
|
-
exit_status =
|
|
162
|
+
exit_status = 72
|
|
162
163
|
except HTTPError as http_err:
|
|
163
|
-
|
|
164
|
+
logger.exception(http_err)
|
|
164
165
|
if http_err.response is not None and http_err.response.text:
|
|
165
166
|
print(http_err.response.text)
|
|
166
167
|
caught_exception = http_err
|
|
167
|
-
exit_status =
|
|
168
|
+
exit_status = 73
|
|
168
169
|
except Exception as ex:
|
|
169
|
-
|
|
170
|
+
logger.exception(ex)
|
|
170
171
|
caught_exception = ex
|
|
171
|
-
exit_status =
|
|
172
|
-
|
|
173
|
-
if caught_exception:
|
|
174
|
-
logger.exception(caught_exception)
|
|
172
|
+
exit_status = 74
|
|
175
173
|
|
|
176
174
|
if call_home is not None:
|
|
177
175
|
if exit_status == 0:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import shutil
|
|
5
|
+
|
|
6
|
+
from ebi_eva_common_pyutils.logger import logging_config
|
|
7
|
+
logger = logging_config.get_logger(__name__)
|
|
8
|
+
|
|
9
|
+
def format_experiment_type(json_file_input, json_file_output):
|
|
10
|
+
try:
|
|
11
|
+
with open(json_file_input, 'r') as input:
|
|
12
|
+
json_data = json.load(input)
|
|
13
|
+
|
|
14
|
+
for analysis_item in json_data.get("analysis", []):
|
|
15
|
+
original_experiment_type = analysis_item.get("experimentType", "")
|
|
16
|
+
logger.info(f"Formatting metadata - experiment type to capitalized - {original_experiment_type}")
|
|
17
|
+
experiment_type_capital = original_experiment_type.capitalize()
|
|
18
|
+
analysis_item["experimentType"] = experiment_type_capital or ""
|
|
19
|
+
|
|
20
|
+
with open(json_file_output, 'w') as output:
|
|
21
|
+
json.dump(json_data, output, indent=4)
|
|
22
|
+
return json_file_output
|
|
23
|
+
|
|
24
|
+
except (FileNotFoundError, json.JSONDecodeError, KeyError) as e:
|
|
25
|
+
# if the try block fails, copy the input file (because nextflow is expecting the output file).
|
|
26
|
+
logger.error(f"Failed to process JSON: {e}")
|
|
27
|
+
shutil.copy(json_file_input, json_file_output)
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def main():
|
|
32
|
+
arg_parser = argparse.ArgumentParser(
|
|
33
|
+
description='Formats experiment type for the metadata.')
|
|
34
|
+
arg_parser.add_argument('--metadata_json_input', required=True, dest='metadata_json_input',
|
|
35
|
+
help='EVA metadata json file INPUT')
|
|
36
|
+
arg_parser.add_argument('--metadata_json_output', required=True, dest='metadata_json_output',
|
|
37
|
+
help='EVA metadata json file OUTPUT')
|
|
38
|
+
args = arg_parser.parse_args()
|
|
39
|
+
format_experiment_type(args.metadata_json_input, args.metadata_json_output)
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
main()
|
|
@@ -9,8 +9,6 @@ from ebi_eva_common_pyutils.logger import logging_config
|
|
|
9
9
|
from openpyxl.reader.excel import load_workbook
|
|
10
10
|
from openpyxl.workbook import Workbook
|
|
11
11
|
|
|
12
|
-
from eva_sub_cli.orchestrator import get_sub_cli_version, get_sub_cli_github_tags
|
|
13
|
-
|
|
14
12
|
WORKSHEETS_KEY_NAME = 'worksheets'
|
|
15
13
|
REQUIRED_HEADERS_KEY_NAME = 'required'
|
|
16
14
|
OPTIONAL_HEADERS_KEY_NAME = 'optional'
|
|
@@ -259,8 +257,7 @@ class XlsxParser:
|
|
|
259
257
|
# If the file could not be loaded at all, return without generating JSON.
|
|
260
258
|
if not self.file_loaded:
|
|
261
259
|
return
|
|
262
|
-
|
|
263
|
-
json_data = {'$schema': self.get_json_schema_link()}
|
|
260
|
+
json_data = {}
|
|
264
261
|
for title in self.xlsx_conf[WORKSHEETS_KEY_NAME]:
|
|
265
262
|
self.active_worksheet = title
|
|
266
263
|
if title == PROJECT:
|
|
@@ -281,13 +278,6 @@ class XlsxParser:
|
|
|
281
278
|
with open(output_json_file, 'w') as open_file:
|
|
282
279
|
json.dump(json_data, open_file, cls=DateTimeEncoder)
|
|
283
280
|
|
|
284
|
-
def get_json_schema_link(self):
|
|
285
|
-
sub_cli_version = get_sub_cli_version()
|
|
286
|
-
sub_cli_tags = get_sub_cli_github_tags()
|
|
287
|
-
if sub_cli_version in sub_cli_tags:
|
|
288
|
-
return f'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/refs/tags/v{sub_cli_version}/eva_sub_cli/etc/eva_schema.json'
|
|
289
|
-
else:
|
|
290
|
-
return 'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/main/eva_sub_cli/etc/eva_schema.json'
|
|
291
281
|
|
|
292
282
|
def translate_header(self, title, header):
|
|
293
283
|
if header in self.xlsx_conf[title].get(REQUIRED_HEADERS_KEY_NAME, {}):
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import glob
|
|
2
2
|
import gzip
|
|
3
3
|
import os
|
|
4
|
-
import shutil
|
|
5
4
|
import time
|
|
6
5
|
from itertools import groupby
|
|
7
6
|
|
|
@@ -132,28 +131,6 @@ def _assess_vcf_evidence_type_manual(vcf_file):
|
|
|
132
131
|
open_file.close()
|
|
133
132
|
|
|
134
133
|
|
|
135
|
-
def backup_file_or_directory(file_name, max_backups=None):
|
|
136
|
-
"""
|
|
137
|
-
Rename a file or directory by adding a '.1' at the end. If the '.1' file exists it move it to a '.2' and so on.
|
|
138
|
-
Keep at most the specified number of backups, if None will keep all.
|
|
139
|
-
"""
|
|
140
|
-
suffix = 1
|
|
141
|
-
backup_name = f'{file_name}.{suffix}'
|
|
142
|
-
while os.path.exists(backup_name):
|
|
143
|
-
suffix += 1
|
|
144
|
-
backup_name = f'{file_name}.{suffix}'
|
|
145
|
-
|
|
146
|
-
for i in range(suffix, 1, -1):
|
|
147
|
-
if max_backups and i > max_backups:
|
|
148
|
-
if os.path.isfile(file_name):
|
|
149
|
-
os.remove(f'{file_name}.{i - 1}')
|
|
150
|
-
else:
|
|
151
|
-
shutil.rmtree(f'{file_name}.{i - 1}')
|
|
152
|
-
else:
|
|
153
|
-
os.rename(f'{file_name}.{i - 1}', f'{file_name}.{i}')
|
|
154
|
-
os.rename(file_name, file_name + '.1')
|
|
155
|
-
|
|
156
|
-
|
|
157
134
|
def open_gzip_if_required(input_file, mode='r'):
|
|
158
135
|
"""Open a file in read mode using gzip if the file extension says .gz"""
|
|
159
136
|
if input_file.endswith('.gz'):
|
|
@@ -42,7 +42,8 @@ params.python_scripts = [
|
|
|
42
42
|
"fasta_checker": "check_fasta_insdc.py",
|
|
43
43
|
"xlsx2json": "xlsx2json.py",
|
|
44
44
|
"semantic_checker": "check_metadata_semantics.py",
|
|
45
|
-
"trim_down": "trim_down.py"
|
|
45
|
+
"trim_down": "trim_down.py",
|
|
46
|
+
"format_metadata": "format_metadata.py"
|
|
46
47
|
]
|
|
47
48
|
// prefix to prepend to all provided path
|
|
48
49
|
params.base_dir = ""
|
|
@@ -66,7 +67,6 @@ schema_dir = file(projectDir).parent + '/etc'
|
|
|
66
67
|
conversion_configuration = "${schema_dir}/$params.conversion_configuration_name"
|
|
67
68
|
|
|
68
69
|
|
|
69
|
-
|
|
70
70
|
def joinBasePath(path) {
|
|
71
71
|
if (path) {
|
|
72
72
|
return params.base_dir + '/' + path
|
|
@@ -98,8 +98,11 @@ workflow {
|
|
|
98
98
|
convert_xlsx_2_json(joinBasePath(params.metadata_xlsx))
|
|
99
99
|
metadata_json = convert_xlsx_2_json.out.metadata_json
|
|
100
100
|
} else {
|
|
101
|
-
metadata_json = joinBasePath(params.metadata_json)
|
|
101
|
+
metadata_json = file(joinBasePath(params.metadata_json), checkIfExists:true)
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
metadata_json_format(metadata_json)
|
|
105
|
+
metadata_json = metadata_json_format.out.metadata_formatted_json
|
|
103
106
|
// File size and MD5
|
|
104
107
|
generate_file_size_and_md5_digests(vcf_files)
|
|
105
108
|
collect_file_size_and_md5(generate_file_size_and_md5_digests.out.file_size_and_digest_info.collect())
|
|
@@ -177,6 +180,7 @@ process check_vcf_valid {
|
|
|
177
180
|
"""
|
|
178
181
|
trap 'if [[ \$? == 1 ]]; then exit 0; fi' EXIT
|
|
179
182
|
|
|
183
|
+
rm -rf ${output_dir}/vcf_format
|
|
180
184
|
mkdir -p vcf_format
|
|
181
185
|
$params.executable.vcf_validator -i $vcf -r text -o vcf_format --require-evidence > vcf_format/${vcf}.vcf_format.log 2>&1
|
|
182
186
|
"""
|
|
@@ -206,6 +210,7 @@ process check_vcf_reference {
|
|
|
206
210
|
"""
|
|
207
211
|
trap 'if [[ \$? == 1 || \$? == 139 ]]; then exit 0; fi' EXIT
|
|
208
212
|
|
|
213
|
+
rm -rf ${output_dir}/assembly_check
|
|
209
214
|
mkdir -p assembly_check
|
|
210
215
|
$params.executable.vcf_assembly_checker -i $vcf -f $fasta $report_opt -r summary,text -o assembly_check --require-genbank > assembly_check/${vcf}.assembly_check.log 2>&1
|
|
211
216
|
"""
|
|
@@ -274,6 +279,28 @@ process convert_xlsx_2_json {
|
|
|
274
279
|
"""
|
|
275
280
|
}
|
|
276
281
|
|
|
282
|
+
process metadata_json_format {
|
|
283
|
+
|
|
284
|
+
label 'short_time', 'small_mem'
|
|
285
|
+
|
|
286
|
+
publishDir output_dir,
|
|
287
|
+
overwrite: true,
|
|
288
|
+
mode: "copy"
|
|
289
|
+
|
|
290
|
+
input:
|
|
291
|
+
path(metadata_json)
|
|
292
|
+
|
|
293
|
+
output:
|
|
294
|
+
path "metadata_formatted.log", emit: metadata_formatted
|
|
295
|
+
path "metadata_formatted_case_insensitive.json", emit: metadata_formatted_json
|
|
296
|
+
|
|
297
|
+
script:
|
|
298
|
+
def output_json = "metadata_formatted_case_insensitive.json"
|
|
299
|
+
"""
|
|
300
|
+
$params.python_scripts.format_metadata --metadata_json_input $metadata_json --metadata_json_output $output_json > metadata_formatted.log 2>&1
|
|
301
|
+
"""
|
|
302
|
+
}
|
|
303
|
+
|
|
277
304
|
process metadata_json_validation {
|
|
278
305
|
|
|
279
306
|
label 'short_time', 'small_mem'
|
|
@@ -9,23 +9,18 @@ from ebi_eva_common_pyutils.config import WritableConfig
|
|
|
9
9
|
from ebi_eva_common_pyutils.logger import logging_config
|
|
10
10
|
from openpyxl.reader.excel import load_workbook
|
|
11
11
|
from packaging import version
|
|
12
|
-
from requests import HTTPError
|
|
13
|
-
from retry import retry
|
|
14
12
|
|
|
15
|
-
import eva_sub_cli
|
|
16
13
|
from eva_sub_cli import MINIMUM_METADATA_XLSX_TEMPLATE_VERSION
|
|
17
14
|
from eva_sub_cli import SUB_CLI_CONFIG_FILE, __version__
|
|
18
|
-
from eva_sub_cli.exceptions
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
|
|
22
|
-
from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
|
|
15
|
+
from eva_sub_cli.exceptions import InvalidFileTypeError, MetadataTemplateVersionException, \
|
|
16
|
+
MetadataTemplateVersionNotFoundException, SubmissionNotFoundException, SubmissionStatusException, \
|
|
17
|
+
NoVcfsFoundException
|
|
23
18
|
from eva_sub_cli.file_utils import is_vcf_file
|
|
24
19
|
from eva_sub_cli.metadata import EvaMetadataJson
|
|
25
20
|
from eva_sub_cli.submission_ws import SubmissionWSClient
|
|
26
21
|
from eva_sub_cli.submit import StudySubmitter, SUB_CLI_CONFIG_KEY_SUBMISSION_ID, \
|
|
27
22
|
SUB_CLI_CONFIG_KEY_SUBMISSION_UPLOAD_URL
|
|
28
|
-
from eva_sub_cli.utils import get_project_title_from_ena
|
|
23
|
+
from eva_sub_cli.utils import get_project_title_from_ena, get_metadata_xlsx_template_link
|
|
29
24
|
from eva_sub_cli.validators.docker_validator import DockerValidator
|
|
30
25
|
from eva_sub_cli.validators.native_validator import NativeValidator
|
|
31
26
|
from eva_sub_cli.validators.validator import READY_FOR_SUBMISSION_TO_EVA, ALL_VALIDATION_TASKS
|
|
@@ -115,6 +110,8 @@ def validate_vcf_mapping(vcf_mapping):
|
|
|
115
110
|
:param vcf_mapping: iterable of triples (VCF file path, reference FASTA path, optional assembly report path)
|
|
116
111
|
:return:
|
|
117
112
|
"""
|
|
113
|
+
if len(vcf_mapping) == 0:
|
|
114
|
+
raise NoVcfsFoundException('No VCF files detected in metadata')
|
|
118
115
|
for vcf_file, fasta_file, report_file in vcf_mapping:
|
|
119
116
|
if not (vcf_file and os.path.isfile(vcf_file)):
|
|
120
117
|
raise FileNotFoundError(f'The variant file {vcf_file} does not exist, please check the file path.')
|
|
@@ -154,46 +151,6 @@ def get_project_and_vcf_fasta_mapping_from_metadata_json(metadata_json):
|
|
|
154
151
|
return project_title, vcf_fasta_report_mapping
|
|
155
152
|
|
|
156
153
|
|
|
157
|
-
def get_sub_cli_version():
|
|
158
|
-
if version.parse(eva_sub_cli.__version__).is_devrelease:
|
|
159
|
-
version_values = [int(v) for v in version.parse(eva_sub_cli.__version__).base_version.split('.')]
|
|
160
|
-
major = version_values[0]
|
|
161
|
-
minor = version_values[1] if len(version_values) > 1 else 0
|
|
162
|
-
patch = version_values[2] if len(version_values) > 2 else 0
|
|
163
|
-
if patch > 0:
|
|
164
|
-
patch -= 1
|
|
165
|
-
elif minor > 0:
|
|
166
|
-
minor -= 1
|
|
167
|
-
patch = 0
|
|
168
|
-
elif major > 0:
|
|
169
|
-
major -= 1
|
|
170
|
-
minor = 0
|
|
171
|
-
patch = 0
|
|
172
|
-
return f"{major}.{minor}.{patch}"
|
|
173
|
-
else:
|
|
174
|
-
return version.parse(eva_sub_cli.__version__).base_version
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
@retry(exceptions=(HTTPError,), tries=3, delay=2, backoff=1.2, jitter=(1, 3))
|
|
178
|
-
def get_sub_cli_github_tags():
|
|
179
|
-
url = f"https://api.github.com/repos/EBIvariation/eva-sub-cli/tags"
|
|
180
|
-
response = requests.get(url)
|
|
181
|
-
if response.status_code == 200:
|
|
182
|
-
tags = [tag["name"][1:] for tag in response.json()]
|
|
183
|
-
return tags
|
|
184
|
-
else:
|
|
185
|
-
return []
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def get_metadata_xlsx_template_link():
|
|
189
|
-
sub_cli_version = get_sub_cli_version()
|
|
190
|
-
sub_cli_tags = get_sub_cli_github_tags()
|
|
191
|
-
if sub_cli_version in sub_cli_tags:
|
|
192
|
-
return f'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/refs/tags/v{sub_cli_version}/eva_sub_cli/etc/EVA_Submission_template.xlsx'
|
|
193
|
-
else:
|
|
194
|
-
return 'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/main/eva_sub_cli/etc/EVA_Submission_template.xlsx'
|
|
195
|
-
|
|
196
|
-
|
|
197
154
|
def verify_and_get_metadata_xlsx_version(metadata_xlsx, min_req_version):
|
|
198
155
|
workbook = load_workbook(metadata_xlsx)
|
|
199
156
|
instructions_sheet = workbook['PLEASE READ FIRST']
|
|
@@ -93,9 +93,13 @@ class SemanticMetadataChecker(AppLogger):
|
|
|
93
93
|
self.check_taxonomy_code(project[TAX_ID_KEY], f'/{PROJECT_KEY}/{TAX_ID_KEY}')
|
|
94
94
|
# Check sample taxonomies for novel samples
|
|
95
95
|
for idx, sample in enumerate(self.metadata[SAMPLE_KEY]):
|
|
96
|
-
if BIOSAMPLE_OBJECT_KEY in sample
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
if BIOSAMPLE_OBJECT_KEY in sample:
|
|
97
|
+
if TAX_ID_KEY in sample[BIOSAMPLE_OBJECT_KEY][CHARACTERISTICS_KEY]:
|
|
98
|
+
self.check_taxonomy_code(sample[BIOSAMPLE_OBJECT_KEY][CHARACTERISTICS_KEY][TAX_ID_KEY][0]['text'],
|
|
99
|
+
f'/{SAMPLE_KEY}/{idx}/{BIOSAMPLE_OBJECT_KEY}/{CHARACTERISTICS_KEY}/{TAX_ID_KEY}')
|
|
100
|
+
else:
|
|
101
|
+
self.add_error(f'/{SAMPLE_KEY}/{idx}/{BIOSAMPLE_OBJECT_KEY}/{CHARACTERISTICS_KEY}/{TAX_ID_KEY}',
|
|
102
|
+
f"must have required property '{TAX_ID_KEY}'")
|
|
99
103
|
|
|
100
104
|
def check_uniqueness_analysis_alias(self):
|
|
101
105
|
analyses = self.metadata[ANALYSIS_KEY]
|
|
@@ -7,7 +7,7 @@ from retry import retry
|
|
|
7
7
|
|
|
8
8
|
from eva_sub_cli import SUBMISSION_WS_VAR
|
|
9
9
|
from eva_sub_cli.auth import get_auth
|
|
10
|
-
from eva_sub_cli.exceptions
|
|
10
|
+
from eva_sub_cli.exceptions import SubmissionUploadException
|
|
11
11
|
|
|
12
12
|
DEFAULT_SUBMISSION_WS_URL = 'https://www.ebi.ac.uk/eva/webservices/submission-ws/v1/'
|
|
13
13
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from packaging import version
|
|
3
|
+
from requests import HTTPError
|
|
4
|
+
from retry import retry
|
|
5
|
+
|
|
6
|
+
import eva_sub_cli
|
|
7
|
+
from ebi_eva_common_pyutils.ena_utils import download_xml_from_ena
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_project_title_from_ena(project_accession):
|
|
11
|
+
try:
|
|
12
|
+
xml_root = download_xml_from_ena(f'https://www.ebi.ac.uk/ena/browser/api/xml/{project_accession}')
|
|
13
|
+
project_title = next(iter(xml_root.xpath('/PROJECT_SET/PROJECT/TITLE/text()')), None)
|
|
14
|
+
except HTTPError as e:
|
|
15
|
+
# We cannot currently differentiate between the service returning an error and the accession not existing
|
|
16
|
+
raise Exception(f"{project_accession} does not exist in ENA or is private")
|
|
17
|
+
except Exception as e:
|
|
18
|
+
raise Exception(f'Unexpected error occurred while getting project details from ENA for {project_accession}')
|
|
19
|
+
|
|
20
|
+
if not project_title:
|
|
21
|
+
raise Exception(f"{project_accession} does not exist in ENA or is private")
|
|
22
|
+
|
|
23
|
+
return project_title
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_sub_cli_version():
|
|
27
|
+
if version.parse(eva_sub_cli.__version__).is_devrelease:
|
|
28
|
+
version_values = [int(v) for v in version.parse(eva_sub_cli.__version__).base_version.split('.')]
|
|
29
|
+
major = version_values[0]
|
|
30
|
+
minor = version_values[1] if len(version_values) > 1 else 0
|
|
31
|
+
patch = version_values[2] if len(version_values) > 2 else 0
|
|
32
|
+
if patch > 0:
|
|
33
|
+
patch -= 1
|
|
34
|
+
elif minor > 0:
|
|
35
|
+
minor -= 1
|
|
36
|
+
patch = 0
|
|
37
|
+
elif major > 0:
|
|
38
|
+
major -= 1
|
|
39
|
+
minor = 0
|
|
40
|
+
patch = 0
|
|
41
|
+
return f"{major}.{minor}.{patch}"
|
|
42
|
+
else:
|
|
43
|
+
return version.parse(eva_sub_cli.__version__).base_version
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@retry(exceptions=(HTTPError,), tries=3, delay=2, backoff=1.2, jitter=(1, 3))
|
|
47
|
+
def get_sub_cli_github_tags():
|
|
48
|
+
url = f"https://api.github.com/repos/EBIvariation/eva-sub-cli/tags"
|
|
49
|
+
response = requests.get(url)
|
|
50
|
+
if response.status_code == 200:
|
|
51
|
+
tags = [tag["name"][1:] for tag in response.json()]
|
|
52
|
+
return tags
|
|
53
|
+
else:
|
|
54
|
+
return []
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_metadata_xlsx_template_link():
|
|
58
|
+
sub_cli_version = get_sub_cli_version()
|
|
59
|
+
sub_cli_tags = get_sub_cli_github_tags()
|
|
60
|
+
if sub_cli_version in sub_cli_tags:
|
|
61
|
+
return f'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/refs/tags/v{sub_cli_version}/eva_sub_cli/etc/EVA_Submission_template.xlsx'
|
|
62
|
+
else:
|
|
63
|
+
return 'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/main/eva_sub_cli/etc/EVA_Submission_template.xlsx'
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_json_schema_link():
|
|
67
|
+
sub_cli_version = get_sub_cli_version()
|
|
68
|
+
sub_cli_tags = get_sub_cli_github_tags()
|
|
69
|
+
if sub_cli_version in sub_cli_tags:
|
|
70
|
+
return f'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/refs/tags/v{sub_cli_version}/eva_sub_cli/etc/eva_schema.json'
|
|
71
|
+
else:
|
|
72
|
+
return 'https://raw.githubusercontent.com/EBIvariation/eva-sub-cli/main/eva_sub_cli/etc/eva_schema.json'
|
|
@@ -9,7 +9,7 @@ from retry import retry
|
|
|
9
9
|
from eva_sub_cli.validators.validator import Validator, ALL_VALIDATION_TASKS
|
|
10
10
|
|
|
11
11
|
default_container_image = 'ebivariation/eva-sub-cli'
|
|
12
|
-
default_container_tag = 'v0.0.
|
|
12
|
+
default_container_tag = 'v0.0.13'
|
|
13
13
|
container_validation_dir = '/opt/vcf_validation'
|
|
14
14
|
container_validation_output_dir = 'vcf_validation_output'
|
|
15
15
|
|