latch 2.39.0.dev21__tar.gz → 2.39.0.dev23__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.
- {latch-2.39.0.dev21/latch.egg-info → latch-2.39.0.dev23}/PKG-INFO +1 -1
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/metadata.py +1 -1
- {latch-2.39.0.dev21 → latch-2.39.0.dev23/latch.egg-info}/PKG-INFO +1 -1
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch.egg-info/SOURCES.txt +3 -3
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/docker_utils/__init__.py +1 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/common/serialize.py +12 -4
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/build.py +22 -30
- latch-2.39.0.dev23/latch_cli/extras/nextflow/config.py +158 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/dag.py +0 -1
- latch-2.39.0.dev23/latch_cli/extras/nextflow/serialize.py +60 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/adapters.py +22 -4
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/base.py +13 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/conditional.py +5 -15
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/input.py +4 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/map.py +3 -1
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/merge.py +21 -4
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/operator.py +6 -2
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/process.py +4 -2
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/workflow.py +3 -2
- latch-2.39.0.dev21/latch_cli/extras/snakemake/config/parser.py → latch-2.39.0.dev23/latch_cli/extras/snakemake/config.py +110 -132
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/snakemake/serialize.py +3 -3
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/snakemake/utils.py +0 -4
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/snakemake/workflow.py +0 -1
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/main.py +74 -11
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/register/register.py +5 -0
- latch-2.39.0.dev23/latch_cli/utils/workflow.py +84 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/setup.py +1 -1
- latch-2.39.0.dev21/latch_cli/extras/nextflow/serialize.py +0 -11
- latch-2.39.0.dev21/latch_cli/extras/snakemake/config/utils.py +0 -320
- latch-2.39.0.dev21/tests/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/LICENSE +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/MANIFEST.in +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/README.md +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/account.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/executions.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/functions/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/functions/messages.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/functions/operators.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/functions/secrets.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/download.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/manager.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/node.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/progress.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/remote_copy.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/throttle.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/upload.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/_transfer/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/path.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/ldata/type.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/project.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/record.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/table.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/types.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/upstream_types/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/upstream_types/types.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/upstream_types/values.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/registry/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/conditional.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/launch_plan.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/map_tasks.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/reference_workflow.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/tasks.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/resources/workflow.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/directory.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/file.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/glob.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/json.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/types/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/deseq2.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/mafft.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/pathway.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/rnaseq.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch/verified/trim_galore.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch.egg-info/dependency_links.txt +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch.egg-info/entry_points.txt +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch.egg-info/requires.txt +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch.egg-info/top_level.txt +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/auth/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/auth/csrf.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/auth/oauth2.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/auth/pkce.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/auth/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/centromere/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/centromere/ctx.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/centromere/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/click_utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/constants.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/exceptions/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/exceptions/cache.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/exceptions/errors.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/exceptions/handler.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/exceptions/traceback.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/common/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/common/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/channel.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/file_persistence.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/nextflow/tasks/output.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/snakemake/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/extras/snakemake/single_task_snakemake.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/menus.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/__init__.py +0 -0
- {latch-2.39.0.dev21/latch_cli/extras/snakemake/config → latch-2.39.0.dev23/latch_cli/services/cp}/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/cp/autocomplete.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/cp/glob.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/cp/main.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/cp/utils.py +0 -0
- {latch-2.39.0.dev21/latch_cli/services/cp → latch-2.39.0.dev23/latch_cli/services/execute}/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/execute/main.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/execute/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/get.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/get_executions.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/get_params.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/__init__.cpython-38.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/__init__.cpython-39.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/init.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/init.cpython-311.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/init.cpython-38.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/__pycache__/init.cpython-39.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/.env +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/README.md +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/common/.dockerignore +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_conda/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_conda/conda_task.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_conda/environment.yaml +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_docker/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_docker/task.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nf_integration/Dockerfile +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nf_integration/latch_metadata/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nf_integration/main.nf +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nf_integration/workflow.nf +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nfcore/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_nfcore/task.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_r/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_r/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_r/environment.R +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_r/r_task.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/Snakefile +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/config.yaml +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/example_snakemake/version +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/init.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/template/LICENSE +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/template/README.md +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/template/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/template/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/init/template/task.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/launch.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/local_dev.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/local_dev_old.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/login.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/ls.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/mkdir.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/move.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/preview.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/register/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/register/constants.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/register/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/rm.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/stop_pod.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/sync.py +0 -0
- {latch-2.39.0.dev21/latch_cli/services/execute → latch-2.39.0.dev23/latch_cli/services/test_data}/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/test_data/ls.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/test_data/remove.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/test_data/upload.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/test_data/utils.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/services/workspace.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/tinyrequests.py +0 -0
- {latch-2.39.0.dev21/latch_cli/services/test_data → latch-2.39.0.dev23/latch_cli/tui}/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/utils/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/utils/path.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/latch_cli/workflow_config.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/pyproject.toml +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/setup.cfg +0 -0
- {latch-2.39.0.dev21/latch_cli/tui → latch-2.39.0.dev23/tests}/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/tests/cp/__init__.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/tests/fixtures.py +0 -0
- {latch-2.39.0.dev21 → latch-2.39.0.dev23}/tests/test_ls.py +0 -0
|
@@ -661,7 +661,7 @@ class SnakemakeMetadata(LatchMetadata):
|
|
|
661
661
|
"""
|
|
662
662
|
|
|
663
663
|
def validate(self):
|
|
664
|
-
from latch_cli.extras.snakemake.config
|
|
664
|
+
from latch_cli.extras.snakemake.config import validate_snakemake_type
|
|
665
665
|
|
|
666
666
|
for name, param in self.parameters.items():
|
|
667
667
|
if param.default is None:
|
|
@@ -85,6 +85,7 @@ latch_cli/extras/common/utils.py
|
|
|
85
85
|
latch_cli/extras/nextflow/__init__.py
|
|
86
86
|
latch_cli/extras/nextflow/build.py
|
|
87
87
|
latch_cli/extras/nextflow/channel.py
|
|
88
|
+
latch_cli/extras/nextflow/config.py
|
|
88
89
|
latch_cli/extras/nextflow/dag.py
|
|
89
90
|
latch_cli/extras/nextflow/file_persistence.py
|
|
90
91
|
latch_cli/extras/nextflow/serialize.py
|
|
@@ -100,13 +101,11 @@ latch_cli/extras/nextflow/tasks/operator.py
|
|
|
100
101
|
latch_cli/extras/nextflow/tasks/output.py
|
|
101
102
|
latch_cli/extras/nextflow/tasks/process.py
|
|
102
103
|
latch_cli/extras/snakemake/__init__.py
|
|
104
|
+
latch_cli/extras/snakemake/config.py
|
|
103
105
|
latch_cli/extras/snakemake/serialize.py
|
|
104
106
|
latch_cli/extras/snakemake/single_task_snakemake.py
|
|
105
107
|
latch_cli/extras/snakemake/utils.py
|
|
106
108
|
latch_cli/extras/snakemake/workflow.py
|
|
107
|
-
latch_cli/extras/snakemake/config/__init__.py
|
|
108
|
-
latch_cli/extras/snakemake/config/parser.py
|
|
109
|
-
latch_cli/extras/snakemake/config/utils.py
|
|
110
109
|
latch_cli/services/__init__.py
|
|
111
110
|
latch_cli/services/get.py
|
|
112
111
|
latch_cli/services/get_executions.py
|
|
@@ -193,6 +192,7 @@ latch_cli/services/test_data/utils.py
|
|
|
193
192
|
latch_cli/tui/__init__.py
|
|
194
193
|
latch_cli/utils/__init__.py
|
|
195
194
|
latch_cli/utils/path.py
|
|
195
|
+
latch_cli/utils/workflow.py
|
|
196
196
|
tests/__init__.py
|
|
197
197
|
tests/fixtures.py
|
|
198
198
|
tests/test_ls.py
|
|
@@ -90,6 +90,7 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]:
|
|
|
90
90
|
"# DO NOT CHANGE",
|
|
91
91
|
"",
|
|
92
92
|
"copy .latch/bin/nextflow /root/nextflow",
|
|
93
|
+
"copy .latch/.nextflow /root/.nextflow",
|
|
93
94
|
"copy .latch/nf_entrypoint.py /root/nf_entrypoint.py",
|
|
94
95
|
]
|
|
95
96
|
|
|
@@ -15,7 +15,7 @@ from flytekit.core.context_manager import FlyteContextManager
|
|
|
15
15
|
from flytekit.core.interface import Interface
|
|
16
16
|
from flytekit.core.node import Node
|
|
17
17
|
from flytekit.core.promise import Promise
|
|
18
|
-
from flytekit.core.type_engine import TypeEngine
|
|
18
|
+
from flytekit.core.type_engine import TypeEngine, TypeTransformerFailedError
|
|
19
19
|
from flytekit.core.utils import _dnsify
|
|
20
20
|
from flytekit.core.workflow import WorkflowBase
|
|
21
21
|
from flytekit.models import common as common_models
|
|
@@ -89,9 +89,17 @@ def interface_to_parameters(
|
|
|
89
89
|
|
|
90
90
|
ctx = FlyteContextManager.current_context()
|
|
91
91
|
if default is not None:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
try:
|
|
93
|
+
default_lv = TypeEngine.to_literal(
|
|
94
|
+
ctx, default, python_type=interface.inputs[k], expected=v.type
|
|
95
|
+
)
|
|
96
|
+
except TypeTransformerFailedError as e:
|
|
97
|
+
click.secho(
|
|
98
|
+
f"Failed to transform default value for parameter `{k}` to a"
|
|
99
|
+
f" literal: {str(e)}",
|
|
100
|
+
fg="red",
|
|
101
|
+
)
|
|
102
|
+
raise click.exceptions.Exit(1) from e
|
|
95
103
|
|
|
96
104
|
params[k] = interface_models.Parameter(
|
|
97
105
|
var=v, default=default_lv, required=required
|
|
@@ -3,24 +3,27 @@ import os
|
|
|
3
3
|
import shutil
|
|
4
4
|
import subprocess
|
|
5
5
|
import sys
|
|
6
|
-
from collections import OrderedDict
|
|
6
|
+
from collections import OrderedDict, defaultdict
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from textwrap import dedent
|
|
9
|
-
from typing import Dict, List, Optional
|
|
9
|
+
from typing import Dict, List, Optional, cast
|
|
10
10
|
|
|
11
11
|
import boto3
|
|
12
12
|
import click
|
|
13
|
+
import gql
|
|
13
14
|
from flytekit.core import constants as _common_constants
|
|
14
15
|
from flytekit.core.interface import transform_variable_map
|
|
15
16
|
from flytekit.core.node import Node
|
|
16
17
|
from flytekit.core.promise import NodeOutput, Promise
|
|
17
18
|
from flytekit.models import literals as literals_models
|
|
19
|
+
from latch_sdk_gql.execute import execute
|
|
18
20
|
|
|
19
21
|
from latch_cli import tinyrequests
|
|
22
|
+
from latch_cli.extras.nextflow.tasks.base import NextflowBaseTask, NFTaskType
|
|
20
23
|
|
|
21
24
|
from ...click_utils import italic
|
|
22
25
|
from ...menus import select_tui
|
|
23
|
-
from ...utils import identifier_from_str
|
|
26
|
+
from ...utils import current_workspace, identifier_from_str
|
|
24
27
|
from ..common.serialize import binding_from_python
|
|
25
28
|
from ..common.utils import reindent
|
|
26
29
|
from .dag import DAG, VertexType
|
|
@@ -33,7 +36,6 @@ from .tasks.input import NextflowInputTask
|
|
|
33
36
|
from .tasks.map import MapContainerTask
|
|
34
37
|
from .tasks.merge import NextflowMergeTask
|
|
35
38
|
from .tasks.operator import NextflowOperatorTask
|
|
36
|
-
from .tasks.output import NextflowOutputTask
|
|
37
39
|
from .tasks.process import NextflowProcessTask
|
|
38
40
|
from .workflow import NextflowWorkflow
|
|
39
41
|
|
|
@@ -84,6 +86,7 @@ def build_from_nextflow_dag(
|
|
|
84
86
|
|
|
85
87
|
task_bindings: List[literals_models.Binding] = [*global_wf_input_bindings]
|
|
86
88
|
branches: Dict[str, bool] = {}
|
|
89
|
+
merge_sources: Dict[str, List[str]] = defaultdict(lambda: [])
|
|
87
90
|
for dep, edge in wf.dag.ancestors()[vertex]:
|
|
88
91
|
if dep.type == VertexType.Conditional:
|
|
89
92
|
input_name = f"condition_{dep.id}"
|
|
@@ -96,11 +99,15 @@ def build_from_nextflow_dag(
|
|
|
96
99
|
node = NodeOutput(node=node_map[dep.id], var=f"condition")
|
|
97
100
|
else:
|
|
98
101
|
input_name = f"channel_{dep.id}"
|
|
99
|
-
output_name = "res"
|
|
100
102
|
|
|
103
|
+
output_name = "res"
|
|
101
104
|
if len(dep.outputNames) > 0:
|
|
102
105
|
idx = int(edge.label)
|
|
103
|
-
input_name =
|
|
106
|
+
input_name = f"{input_name}_{idx}"
|
|
107
|
+
output_name = dep.outputNames[idx]
|
|
108
|
+
|
|
109
|
+
if vertex.type == VertexType.Merge:
|
|
110
|
+
merge_sources[output_name].append(input_name)
|
|
104
111
|
|
|
105
112
|
task_inputs[input_name] = Optional[str]
|
|
106
113
|
|
|
@@ -121,6 +128,8 @@ def build_from_nextflow_dag(
|
|
|
121
128
|
upstream_nodes.append(node_map[dep.id])
|
|
122
129
|
|
|
123
130
|
node_name = get_node_name(vertex.id)
|
|
131
|
+
if vertex.type == VertexType.Merge:
|
|
132
|
+
task_outputs = {k: Optional[str] for k in merge_sources.keys()}
|
|
124
133
|
|
|
125
134
|
if vertex.type == VertexType.Process:
|
|
126
135
|
pre_adapter_task = NextflowProcessPreAdapterTask(
|
|
@@ -256,29 +265,6 @@ def build_from_nextflow_dag(
|
|
|
256
265
|
|
|
257
266
|
node_map[vertex.id] = node
|
|
258
267
|
|
|
259
|
-
elif vertex.type == VertexType.Output:
|
|
260
|
-
output_task = NextflowOutputTask(
|
|
261
|
-
inputs=task_inputs,
|
|
262
|
-
outputs=task_outputs,
|
|
263
|
-
name=vertex.label,
|
|
264
|
-
id=vertex.id,
|
|
265
|
-
statement=vertex.statement,
|
|
266
|
-
ret=vertex.ret,
|
|
267
|
-
branches=branches,
|
|
268
|
-
wf=wf,
|
|
269
|
-
)
|
|
270
|
-
wf.nextflow_tasks.append(output_task)
|
|
271
|
-
|
|
272
|
-
node = Node(
|
|
273
|
-
id=node_name,
|
|
274
|
-
metadata=output_task.construct_node_metadata(),
|
|
275
|
-
bindings=task_bindings,
|
|
276
|
-
upstream_nodes=upstream_nodes,
|
|
277
|
-
flyte_entity=output_task,
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
node_map[vertex.id] = node
|
|
281
|
-
|
|
282
268
|
elif vertex.type == VertexType.Merge:
|
|
283
269
|
merge_task = NextflowMergeTask(
|
|
284
270
|
inputs=task_inputs,
|
|
@@ -286,6 +272,7 @@ def build_from_nextflow_dag(
|
|
|
286
272
|
name=vertex.label,
|
|
287
273
|
id=vertex.id,
|
|
288
274
|
branches=branches,
|
|
275
|
+
sources=merge_sources,
|
|
289
276
|
wf=wf,
|
|
290
277
|
)
|
|
291
278
|
|
|
@@ -314,6 +301,9 @@ def build_from_nextflow_dag(
|
|
|
314
301
|
)
|
|
315
302
|
wf.nextflow_tasks.append(operator_task)
|
|
316
303
|
|
|
304
|
+
if vertex.type != "Operator":
|
|
305
|
+
operator_task.nf_task_type = NFTaskType(vertex.type)
|
|
306
|
+
|
|
317
307
|
node = Node(
|
|
318
308
|
id=node_name,
|
|
319
309
|
metadata=operator_task.construct_node_metadata(),
|
|
@@ -391,6 +381,7 @@ def ensure_nf_dependencies(pkg_root: Path, *, force_redownload: bool = False):
|
|
|
391
381
|
|
|
392
382
|
def build_nf_wf(
|
|
393
383
|
pkg_root: Path,
|
|
384
|
+
version: str,
|
|
394
385
|
nf_script: Path,
|
|
395
386
|
*,
|
|
396
387
|
redownload_dependencies: bool = False,
|
|
@@ -471,7 +462,7 @@ def build_nf_wf(
|
|
|
471
462
|
|
|
472
463
|
raise click.exceptions.Exit(0)
|
|
473
464
|
|
|
474
|
-
wf = NextflowWorkflow(nf_script, main_dag)
|
|
465
|
+
wf = NextflowWorkflow(nf_script, version, main_dag)
|
|
475
466
|
|
|
476
467
|
build_from_nextflow_dag(wf, execution_profile=execution_profile)
|
|
477
468
|
|
|
@@ -507,6 +498,7 @@ def generate_nf_entrypoint(
|
|
|
507
498
|
from latch_cli.extras.nextflow.file_persistence import download_files, stage_for_output, upload_files
|
|
508
499
|
from latch_cli.extras.nextflow.channel import get_mapper_inputs, get_boolean_value, get_mapper_outputs
|
|
509
500
|
from latch_cli.utils import check_exists_and_rename, get_parameter_json_value, urljoins
|
|
501
|
+
from latch_cli.utils.workflow import _override_task_status
|
|
510
502
|
|
|
511
503
|
from latch.resources.tasks import custom_task
|
|
512
504
|
from latch.types.directory import LatchDir, LatchOutputDir
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
from ...utils import best_effort_display_name, identifier_from_str
|
|
10
|
+
from ..common.config.parser import parse_config, write_metadata
|
|
11
|
+
from ..common.config.utils import JSONValue, get_preamble, type_repr
|
|
12
|
+
from ..common.utils import reindent
|
|
13
|
+
from .build import ensure_nf_dependencies
|
|
14
|
+
|
|
15
|
+
nextflow_metadata = """
|
|
16
|
+
from latch.types.metadata import NextflowMetadata, LatchAuthor, EnvironmentConfig
|
|
17
|
+
from latch.types.directory import LatchDir
|
|
18
|
+
|
|
19
|
+
from .parameters import generated_parameters
|
|
20
|
+
|
|
21
|
+
NextflowMetadata(
|
|
22
|
+
name="Your Workflow Name",
|
|
23
|
+
display_name="Your Workflow Name",
|
|
24
|
+
author=LatchAuthor(
|
|
25
|
+
name="Your Name",
|
|
26
|
+
),
|
|
27
|
+
parameters=generated_parameters,
|
|
28
|
+
output_directory=LatchDir("latch:///your_output_directory"),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def generate_nf_metadata(
|
|
35
|
+
config_path: Path,
|
|
36
|
+
*,
|
|
37
|
+
skip_confirmation: bool = False,
|
|
38
|
+
generate_defaults: bool = False,
|
|
39
|
+
infer_files: bool = False,
|
|
40
|
+
):
|
|
41
|
+
if not config_path.is_dir():
|
|
42
|
+
click.secho(
|
|
43
|
+
f"Nextflow config path must point to the package root directory.",
|
|
44
|
+
fg="red",
|
|
45
|
+
)
|
|
46
|
+
raise click.exceptions.Exit(1)
|
|
47
|
+
|
|
48
|
+
ensure_nf_dependencies(config_path)
|
|
49
|
+
|
|
50
|
+
env = {
|
|
51
|
+
**os.environ,
|
|
52
|
+
# read NF binaries from `.latch/.nextflow` instead of system
|
|
53
|
+
"NXF_HOME": str(config_path / ".latch" / ".nextflow"),
|
|
54
|
+
# don't display version mismatch warning
|
|
55
|
+
"NXF_DISABLE_CHECK_LATEST": "true",
|
|
56
|
+
# don't emit .nextflow.log files
|
|
57
|
+
"NXF_LOG_FILE": "/dev/null",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
config_file = ".latch/nf-config.yaml"
|
|
61
|
+
try:
|
|
62
|
+
subprocess.run(
|
|
63
|
+
[
|
|
64
|
+
".latch/bin/nextflow",
|
|
65
|
+
"config",
|
|
66
|
+
"-format",
|
|
67
|
+
"json",
|
|
68
|
+
"-output",
|
|
69
|
+
config_file,
|
|
70
|
+
],
|
|
71
|
+
check=True,
|
|
72
|
+
env=env if os.environ.get("LATCH_NEXTFLOW_DEV") is not None else None,
|
|
73
|
+
cwd=config_path,
|
|
74
|
+
)
|
|
75
|
+
except subprocess.CalledProcessError as e:
|
|
76
|
+
click.secho(
|
|
77
|
+
"Failed to read config from nextflow package.",
|
|
78
|
+
fg="red",
|
|
79
|
+
)
|
|
80
|
+
raise click.exceptions.Exit(1) from e
|
|
81
|
+
|
|
82
|
+
config_file = config_path / config_file
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
config: JSONValue = json.loads(config_file.read_text())
|
|
86
|
+
except json.JSONDecodeError as e:
|
|
87
|
+
click.secho(
|
|
88
|
+
reindent(
|
|
89
|
+
f"""
|
|
90
|
+
Error loading config from {config_file}:
|
|
91
|
+
|
|
92
|
+
{e}
|
|
93
|
+
""",
|
|
94
|
+
0,
|
|
95
|
+
),
|
|
96
|
+
fg="red",
|
|
97
|
+
)
|
|
98
|
+
raise click.exceptions.Exit(1) from e
|
|
99
|
+
|
|
100
|
+
parsed = parse_config(config.get("params", {}), infer_files=infer_files)
|
|
101
|
+
|
|
102
|
+
preambles: List[str] = []
|
|
103
|
+
params: List[str] = []
|
|
104
|
+
|
|
105
|
+
for k, (typ, (val, default)) in parsed.items():
|
|
106
|
+
preambles.append(get_preamble(typ))
|
|
107
|
+
|
|
108
|
+
param_str = reindent(
|
|
109
|
+
f"""\
|
|
110
|
+
{repr(identifier_from_str(k))}: NextflowParameter(
|
|
111
|
+
display_name={repr(best_effort_display_name(k))},
|
|
112
|
+
type={type_repr(typ)},
|
|
113
|
+
__default__),""",
|
|
114
|
+
0,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
default_str = ""
|
|
118
|
+
if generate_defaults and default is not None:
|
|
119
|
+
default_str = f" default={repr(default)},\n"
|
|
120
|
+
|
|
121
|
+
param_str = param_str.replace("__default__", default_str)
|
|
122
|
+
|
|
123
|
+
param_str = reindent(param_str, 1)
|
|
124
|
+
params.append(param_str)
|
|
125
|
+
|
|
126
|
+
params_file_str = (
|
|
127
|
+
reindent(
|
|
128
|
+
r"""
|
|
129
|
+
from dataclasses import dataclass
|
|
130
|
+
import typing
|
|
131
|
+
import typing_extensions
|
|
132
|
+
|
|
133
|
+
from flytekit.core.annotation import FlyteAnnotation
|
|
134
|
+
|
|
135
|
+
from latch.types.metadata import NextflowParameter
|
|
136
|
+
from latch.types.file import LatchFile
|
|
137
|
+
from latch.types.directory import LatchDir
|
|
138
|
+
|
|
139
|
+
__preambles__
|
|
140
|
+
|
|
141
|
+
# Import these into your `__init__.py` file:
|
|
142
|
+
#
|
|
143
|
+
# from .parameters import generated_parameters, file_metadata
|
|
144
|
+
|
|
145
|
+
generated_parameters = {
|
|
146
|
+
__params__
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
""",
|
|
150
|
+
0,
|
|
151
|
+
)
|
|
152
|
+
.replace("__preambles__", "".join(preambles))
|
|
153
|
+
.replace("__params__", "\n".join(params))
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
write_metadata(
|
|
157
|
+
nextflow_metadata, params_file_str, skip_confirmation=skip_confirmation
|
|
158
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from typing import cast
|
|
2
|
+
|
|
3
|
+
import gql
|
|
4
|
+
from latch_sdk_gql.execute import execute
|
|
5
|
+
|
|
6
|
+
from latch_cli.extras.common.serialize import serialize
|
|
7
|
+
from latch_cli.extras.nextflow.tasks.base import NextflowBaseTask
|
|
8
|
+
from latch_cli.extras.nextflow.workflow import NextflowWorkflow
|
|
9
|
+
from latch_cli.utils import current_workspace
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def serialize_nf(
|
|
13
|
+
nf_wf: NextflowWorkflow,
|
|
14
|
+
output_dir: str,
|
|
15
|
+
image_name: str,
|
|
16
|
+
dkr_repo: str,
|
|
17
|
+
):
|
|
18
|
+
serialize(nf_wf, output_dir, image_name, dkr_repo, write_spec=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def add_task_metadata(wf: NextflowWorkflow):
|
|
22
|
+
node_names = []
|
|
23
|
+
task_types = []
|
|
24
|
+
|
|
25
|
+
for node in wf.nodes:
|
|
26
|
+
task = cast(NextflowBaseTask, node.flyte_entity)
|
|
27
|
+
|
|
28
|
+
node_names.append(node.id)
|
|
29
|
+
task_types.append(task.nf_task_type)
|
|
30
|
+
|
|
31
|
+
execute(
|
|
32
|
+
gql.gql("""
|
|
33
|
+
mutation NFBulkInsertMut(
|
|
34
|
+
$nodeNames: [String]!
|
|
35
|
+
$ownerId: BigInt!
|
|
36
|
+
$types: [String]!
|
|
37
|
+
$version: String!
|
|
38
|
+
$workflowName: String!
|
|
39
|
+
) {
|
|
40
|
+
bulkInsertNextflowNodeInfo(
|
|
41
|
+
input: {
|
|
42
|
+
ownerId: $ownerId
|
|
43
|
+
workflowName: $workflowName
|
|
44
|
+
version: $version
|
|
45
|
+
nodeNames: $nodeNames
|
|
46
|
+
types: $types
|
|
47
|
+
}
|
|
48
|
+
) {
|
|
49
|
+
clientMutationId
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
"""),
|
|
53
|
+
{
|
|
54
|
+
"ownerId": current_workspace(),
|
|
55
|
+
"version": wf.version,
|
|
56
|
+
"workflowName": wf.name,
|
|
57
|
+
"nodeNames": node_names,
|
|
58
|
+
"types": task_types,
|
|
59
|
+
},
|
|
60
|
+
)
|
|
@@ -7,7 +7,7 @@ from latch.types.metadata import ParameterType, _IsDataclass
|
|
|
7
7
|
|
|
8
8
|
from ...common.utils import reindent, type_repr
|
|
9
9
|
from ..workflow import NextflowWorkflow
|
|
10
|
-
from .base import NextflowBaseTask
|
|
10
|
+
from .base import NextflowBaseTask, NFTaskType
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def dataclass_from_python_params(
|
|
@@ -65,7 +65,13 @@ class NextflowProcessPreAdapterTask(NextflowBaseTask):
|
|
|
65
65
|
self.dataclass = dataclass_from_python_params(inputs, id)
|
|
66
66
|
|
|
67
67
|
super().__init__(
|
|
68
|
-
inputs,
|
|
68
|
+
inputs,
|
|
69
|
+
{"default": List[self.dataclass]},
|
|
70
|
+
id,
|
|
71
|
+
name,
|
|
72
|
+
branches,
|
|
73
|
+
wf,
|
|
74
|
+
NFTaskType.Adapter,
|
|
69
75
|
)
|
|
70
76
|
|
|
71
77
|
def get_fn_interface(self):
|
|
@@ -110,7 +116,7 @@ class NextflowProcessPreAdapterTask(NextflowBaseTask):
|
|
|
110
116
|
def get_fn_return_stmt(self):
|
|
111
117
|
return reindent(f"return Res_{self.id}(default=result)", 1)
|
|
112
118
|
|
|
113
|
-
def get_fn_code(self,
|
|
119
|
+
def get_fn_code(self, nf_script_path_in_container: Path):
|
|
114
120
|
code_block = self.get_fn_interface()
|
|
115
121
|
code_block += self.get_fn_conditions()
|
|
116
122
|
|
|
@@ -142,6 +148,10 @@ class NextflowProcessPreAdapterTask(NextflowBaseTask):
|
|
|
142
148
|
rf"""
|
|
143
149
|
else:
|
|
144
150
|
print("TASK SKIPPED")
|
|
151
|
+
try:
|
|
152
|
+
_override_task_status(status="SKIPPED")
|
|
153
|
+
except Exception as e:
|
|
154
|
+
print(f"Failed to override task status: {{e}}")
|
|
145
155
|
result = []
|
|
146
156
|
|
|
147
157
|
""",
|
|
@@ -162,7 +172,15 @@ class NextflowProcessPostAdapterTask(NextflowBaseTask):
|
|
|
162
172
|
):
|
|
163
173
|
self.dataclass = dataclass_from_python_params(outputs, id)
|
|
164
174
|
|
|
165
|
-
super().__init__(
|
|
175
|
+
super().__init__(
|
|
176
|
+
{"default": List[self.dataclass]},
|
|
177
|
+
outputs,
|
|
178
|
+
id,
|
|
179
|
+
name,
|
|
180
|
+
{},
|
|
181
|
+
wf,
|
|
182
|
+
NFTaskType.Adapter,
|
|
183
|
+
)
|
|
166
184
|
|
|
167
185
|
def get_fn_interface(self):
|
|
168
186
|
res = ""
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import importlib
|
|
2
|
+
from enum import Enum
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Any, Dict, List, Mapping, Type, cast
|
|
4
5
|
|
|
@@ -25,6 +26,16 @@ from ...common.utils import reindent
|
|
|
25
26
|
from ..workflow import NextflowWorkflow
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
class NFTaskType(str, Enum):
|
|
30
|
+
Process = "Process"
|
|
31
|
+
Adapter = "Adapter"
|
|
32
|
+
Operator = "Operator"
|
|
33
|
+
SubWorkflow = "SubWorkflow"
|
|
34
|
+
Generator = "Generator"
|
|
35
|
+
Conditional = "Conditional"
|
|
36
|
+
Merge = "Merge"
|
|
37
|
+
|
|
38
|
+
|
|
28
39
|
class NextflowBaseTask(PythonAutoContainerTask[Pod]):
|
|
29
40
|
def __init__(
|
|
30
41
|
self,
|
|
@@ -34,12 +45,14 @@ class NextflowBaseTask(PythonAutoContainerTask[Pod]):
|
|
|
34
45
|
name: str,
|
|
35
46
|
branches: Dict[str, bool],
|
|
36
47
|
wf: NextflowWorkflow,
|
|
48
|
+
nf_task_type: NFTaskType,
|
|
37
49
|
# todo(ayush): expose / infer these somehow
|
|
38
50
|
cpu: int = 4,
|
|
39
51
|
memory: int = 8,
|
|
40
52
|
):
|
|
41
53
|
self.id = id
|
|
42
54
|
self.wf = wf
|
|
55
|
+
self.nf_task_type = nf_task_type
|
|
43
56
|
|
|
44
57
|
interface = Interface(inputs, outputs, docstring=None)
|
|
45
58
|
self._python_inputs = inputs
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Dict, List, Mapping, Optional, Type
|
|
2
2
|
|
|
3
3
|
from latch.types.metadata import ParameterType
|
|
4
|
+
from latch_cli.extras.nextflow.tasks.base import NFTaskType
|
|
4
5
|
|
|
5
6
|
from ...common.utils import reindent
|
|
6
7
|
from ..workflow import NextflowWorkflow
|
|
@@ -29,23 +30,12 @@ class NextflowConditionalTask(NextflowOperatorTask):
|
|
|
29
30
|
wf,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
results: List[str] = []
|
|
34
|
-
for out_name, out_type in self._python_outputs.items():
|
|
35
|
-
results.append(
|
|
36
|
-
reindent(
|
|
37
|
-
rf"""
|
|
38
|
-
{out_name}=json.loads(out_channels.get("{out_name}", "true"))
|
|
39
|
-
""",
|
|
40
|
-
2,
|
|
41
|
-
).rstrip()
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
return_str = ",\n".join(results)
|
|
33
|
+
self.nf_task_type = NFTaskType.Conditional
|
|
45
34
|
|
|
35
|
+
def get_fn_return_stmt(self):
|
|
46
36
|
return reindent(
|
|
47
37
|
rf"""
|
|
48
|
-
res = out_channels.get(
|
|
38
|
+
res = out_channels.get("condition")
|
|
49
39
|
|
|
50
40
|
if res is not None:
|
|
51
41
|
res = get_boolean_value(res)
|
|
@@ -53,4 +43,4 @@ class NextflowConditionalTask(NextflowOperatorTask):
|
|
|
53
43
|
return Res{self.name}(condition=res)
|
|
54
44
|
""",
|
|
55
45
|
1,
|
|
56
|
-
)
|
|
46
|
+
)
|
|
@@ -53,6 +53,10 @@ class NextflowInputTask(NextflowOperatorTask):
|
|
|
53
53
|
res = {channel_input}
|
|
54
54
|
else:
|
|
55
55
|
print("TASK SKIPPED")
|
|
56
|
+
try:
|
|
57
|
+
_override_task_status(status="SKIPPED")
|
|
58
|
+
except Exception as e:
|
|
59
|
+
print(f"Failed to override task status: {{e}}")
|
|
56
60
|
res = None
|
|
57
61
|
|
|
58
62
|
""",
|
|
@@ -18,7 +18,7 @@ from flytekit.models.interface import Variable
|
|
|
18
18
|
from flytekit.models.task import Container, K8sPod, Sql
|
|
19
19
|
from flytekitplugins.pod.task import Pod
|
|
20
20
|
|
|
21
|
-
from .base import NextflowBaseTaskResolver
|
|
21
|
+
from .base import NextflowBaseTaskResolver, NFTaskType
|
|
22
22
|
from .process import NextflowProcessTask
|
|
23
23
|
|
|
24
24
|
|
|
@@ -38,6 +38,8 @@ class MapContainerTask(PythonAutoContainerTask[Pod]):
|
|
|
38
38
|
container_task.python_interface
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
+
self.nf_task_type = NFTaskType.Process
|
|
42
|
+
|
|
41
43
|
super().__init__(
|
|
42
44
|
name=name,
|
|
43
45
|
interface=collection_interface,
|