latch 2.40.4__tar.gz → 2.40.4.dev0__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.40.4/latch.egg-info → latch-2.40.4.dev0}/PKG-INFO +1 -1
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/directory.py +6 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/file.py +3 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/metadata.py +83 -18
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/utils.py +10 -2
- {latch-2.40.4 → latch-2.40.4.dev0/latch.egg-info}/PKG-INFO +1 -1
- {latch-2.40.4 → latch-2.40.4.dev0}/latch.egg-info/SOURCES.txt +33 -9
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/auth/oauth2.py +7 -9
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/centromere/ctx.py +82 -32
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/click_utils.py +10 -3
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/docker_utils/__init__.py +23 -13
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/exceptions/handler.py +12 -18
- latch-2.40.4.dev0/latch_cli/extras/common/config/parser.py +82 -0
- {latch-2.40.4/latch_cli/snakemake → latch-2.40.4.dev0/latch_cli/extras/common}/config/utils.py +23 -106
- latch-2.40.4/latch_cli/snakemake/serialize_utils.py → latch-2.40.4.dev0/latch_cli/extras/common/serialize.py +188 -10
- latch-2.40.4.dev0/latch_cli/extras/common/utils.py +72 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/build.py +536 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/channel.py +89 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/config.py +162 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/dag.py +320 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/file_persistence.py +239 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/serialize.py +60 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/adapters.py +232 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/base.py +193 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/conditional.py +51 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/map.py +180 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/merge.py +111 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/operator.py +234 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks/process.py +258 -0
- latch-2.40.4.dev0/latch_cli/extras/nextflow/workflow.py +101 -0
- latch-2.40.4/latch_cli/snakemake/config/parser.py → latch-2.40.4.dev0/latch_cli/extras/snakemake/config.py +110 -132
- {latch-2.40.4/latch_cli → latch-2.40.4.dev0/latch_cli/extras}/snakemake/serialize.py +9 -40
- latch-2.40.4.dev0/latch_cli/extras/snakemake/utils.py +33 -0
- {latch-2.40.4/latch_cli → latch-2.40.4.dev0/latch_cli/extras}/snakemake/workflow.py +4 -79
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/main.py +103 -18
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/cp/autocomplete.py +1 -4
- latch-2.40.4.dev0/latch_cli/services/execute/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/get_executions.py +12 -10
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/init.cpython-311.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/__init__.py +1 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/common/.dockerignore +3 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_conda/conda_task.py +6 -8
- latch-2.40.4.dev0/latch_cli/services/init/example_nextflow/main.nf +7 -0
- latch-2.40.4.dev0/latch_cli/services/init/example_nextflow/nextflow.config +4 -0
- latch-2.40.4.dev0/latch_cli/services/init/example_nextflow/workflow.nf +50 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_nfcore/__init__.py +1 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_r/r_task.py +6 -8
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/init.py +26 -5
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/local_dev_old.py +7 -8
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/login.py +0 -1
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/move.py +1 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/preview.py +2 -1
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/register/register.py +96 -54
- latch-2.40.4.dev0/latch_cli/services/test_data/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/workspace.py +7 -9
- latch-2.40.4.dev0/latch_cli/tui/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/utils/__init__.py +10 -31
- latch-2.40.4.dev0/latch_cli/utils/workflow.py +84 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/setup.py +2 -6
- latch-2.40.4.dev0/tests/__init__.py +0 -0
- latch-2.40.4/latch_cli/snakemake/utils.py +0 -26
- {latch-2.40.4 → latch-2.40.4.dev0}/LICENSE +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/MANIFEST.in +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/README.md +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/account.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/executions.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/functions/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/functions/messages.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/functions/operators.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/functions/secrets.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/download.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/manager.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/node.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/progress.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/remote_copy.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/throttle.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/upload.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/_transfer/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/path.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/ldata/type.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/project.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/record.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/table.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/types.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/upstream_types/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/upstream_types/types.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/upstream_types/values.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/registry/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/conditional.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/dynamic.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/launch_plan.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/map_tasks.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/reference_workflow.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/tasks.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/resources/workflow.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/glob.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/json.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/types/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/deseq2.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/mafft.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/pathway.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/rnaseq.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch/verified/trim_galore.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch.egg-info/dependency_links.txt +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch.egg-info/entry_points.txt +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch.egg-info/requires.txt +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch.egg-info/top_level.txt +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/auth/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/auth/csrf.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/auth/pkce.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/auth/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/centromere/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/centromere/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/constants.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/exceptions/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/exceptions/cache.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/exceptions/errors.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/exceptions/traceback.py +0 -0
- {latch-2.40.4/latch_cli/services/cp → latch-2.40.4.dev0/latch_cli/extras}/__init__.py +0 -0
- {latch-2.40.4/latch_cli/services/execute → latch-2.40.4.dev0/latch_cli/extras/common}/__init__.py +0 -0
- {latch-2.40.4/latch_cli/services/test_data → latch-2.40.4.dev0/latch_cli/extras/common/config}/__init__.py +0 -0
- {latch-2.40.4/latch_cli/snakemake → latch-2.40.4.dev0/latch_cli/extras/nextflow}/__init__.py +0 -0
- {latch-2.40.4/latch_cli/snakemake/config → latch-2.40.4.dev0/latch_cli/extras/nextflow/tasks}/__init__.py +0 -0
- {latch-2.40.4/latch_cli/tui → latch-2.40.4.dev0/latch_cli/extras/snakemake}/__init__.py +0 -0
- {latch-2.40.4/latch_cli → latch-2.40.4.dev0/latch_cli/extras}/snakemake/single_task_snakemake.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/menus.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/__init__.py +0 -0
- {latch-2.40.4/tests → latch-2.40.4.dev0/latch_cli/services/cp}/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/cp/glob.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/cp/main.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/cp/utils.py +3 -3
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/execute/main.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/execute/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/get.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/get_params.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/__init__.cpython-38.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/__init__.cpython-39.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/init.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/init.cpython-38.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/__pycache__/init.cpython-39.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/.env +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/README.md +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_conda/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_conda/environment.yaml +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_docker/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_docker/task.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_nfcore/task.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_r/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_r/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_r/environment.R +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/Snakefile +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/config.yaml +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/example_snakemake/version +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/template/LICENSE +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/template/README.md +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/template/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/template/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/init/template/task.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/launch.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/local_dev.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/ls.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/mkdir.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/register/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/register/constants.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/register/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/rm.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/stop_pod.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/sync.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/test_data/ls.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/test_data/remove.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/test_data/upload.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/services/test_data/utils.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/tinyrequests.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/utils/path.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/latch_cli/workflow_config.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/pyproject.toml +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/setup.cfg +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/tests/cp/__init__.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/tests/fixtures.py +0 -0
- {latch-2.40.4 → latch-2.40.4.dev0}/tests/test_ls.py +0 -0
|
@@ -141,6 +141,9 @@ class LatchDir(FlyteDirectory):
|
|
|
141
141
|
|
|
142
142
|
super().__init__(self.path, downloader, self._remote_directory)
|
|
143
143
|
|
|
144
|
+
def __hash__(self) -> int:
|
|
145
|
+
return hash(self.path)
|
|
146
|
+
|
|
144
147
|
def _idempotent_set_path(self):
|
|
145
148
|
if self._path_generated:
|
|
146
149
|
return
|
|
@@ -268,6 +271,9 @@ LatchOutputDir = Annotated[
|
|
|
268
271
|
{"output": True},
|
|
269
272
|
),
|
|
270
273
|
]
|
|
274
|
+
|
|
275
|
+
LatchOutputDir.__name__ = "LatchOutputDir"
|
|
276
|
+
|
|
271
277
|
"""A LatchDir tagged as the output of some workflow.
|
|
272
278
|
|
|
273
279
|
The Latch Console uses this metadata to avoid checking for existence of the
|
|
@@ -3,16 +3,28 @@ from dataclasses import Field, asdict, dataclass, field
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from textwrap import indent
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import (
|
|
7
|
+
Any,
|
|
8
|
+
ClassVar,
|
|
9
|
+
Collection,
|
|
10
|
+
Dict,
|
|
11
|
+
Generic,
|
|
12
|
+
List,
|
|
13
|
+
Optional,
|
|
14
|
+
Protocol,
|
|
15
|
+
Tuple,
|
|
16
|
+
Type,
|
|
17
|
+
TypeVar,
|
|
18
|
+
Union,
|
|
19
|
+
)
|
|
7
20
|
|
|
8
21
|
import click
|
|
9
22
|
import yaml
|
|
10
23
|
from typing_extensions import TypeAlias
|
|
11
24
|
|
|
12
|
-
from latch_cli.snakemake.config.utils import validate_snakemake_type
|
|
13
25
|
from latch_cli.utils import identifier_suffix_from_str
|
|
14
26
|
|
|
15
|
-
from .directory import LatchDir
|
|
27
|
+
from .directory import LatchDir, LatchOutputDir
|
|
16
28
|
from .file import LatchFile
|
|
17
29
|
|
|
18
30
|
|
|
@@ -388,31 +400,33 @@ class _IsDataclass(Protocol):
|
|
|
388
400
|
|
|
389
401
|
|
|
390
402
|
ParameterType: TypeAlias = Union[
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
403
|
+
None,
|
|
404
|
+
int,
|
|
405
|
+
float,
|
|
406
|
+
str,
|
|
407
|
+
bool,
|
|
408
|
+
LatchFile,
|
|
409
|
+
LatchDir,
|
|
410
|
+
Enum,
|
|
411
|
+
_IsDataclass,
|
|
412
|
+
Collection["ParameterType"],
|
|
401
413
|
]
|
|
402
414
|
|
|
403
415
|
|
|
416
|
+
T = TypeVar("T", bound=ParameterType)
|
|
417
|
+
|
|
418
|
+
|
|
404
419
|
@dataclass
|
|
405
|
-
class SnakemakeParameter(LatchParameter):
|
|
406
|
-
type: Optional[
|
|
420
|
+
class SnakemakeParameter(Generic[T], LatchParameter):
|
|
421
|
+
type: Optional[Type[T]] = None
|
|
407
422
|
"""
|
|
408
423
|
The python type of the parameter.
|
|
409
424
|
"""
|
|
410
|
-
|
|
411
|
-
default: Optional[Any] = None
|
|
425
|
+
default: Optional[T] = None
|
|
412
426
|
|
|
413
427
|
|
|
414
428
|
@dataclass
|
|
415
|
-
class SnakemakeFileParameter(SnakemakeParameter):
|
|
429
|
+
class SnakemakeFileParameter(SnakemakeParameter[Union[LatchFile, LatchDir]]):
|
|
416
430
|
"""
|
|
417
431
|
Deprecated: use `file_metadata` keyword in `SnakemakeMetadata` instead
|
|
418
432
|
"""
|
|
@@ -456,6 +470,29 @@ class SnakemakeFileMetadata:
|
|
|
456
470
|
"""
|
|
457
471
|
|
|
458
472
|
|
|
473
|
+
@dataclass
|
|
474
|
+
class NextflowParameter(Generic[T], LatchParameter):
|
|
475
|
+
type: Optional[Type[T]] = None
|
|
476
|
+
"""
|
|
477
|
+
The python type of the parameter.
|
|
478
|
+
"""
|
|
479
|
+
default: Optional[T] = None
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@dataclass
|
|
483
|
+
class NextflowFileParameter(NextflowParameter[Union[LatchFile, LatchDir]]):
|
|
484
|
+
path: Optional[Path] = None
|
|
485
|
+
"""
|
|
486
|
+
The path where the file passed to this parameter will be copied.
|
|
487
|
+
"""
|
|
488
|
+
|
|
489
|
+
_download: bool = field(default=True, init=False)
|
|
490
|
+
|
|
491
|
+
def __post_init__(self):
|
|
492
|
+
if self.type is LatchOutputDir:
|
|
493
|
+
self._download = False
|
|
494
|
+
|
|
495
|
+
|
|
459
496
|
@dataclass
|
|
460
497
|
class LatchMetadata:
|
|
461
498
|
"""Class for organizing workflow metadata
|
|
@@ -571,6 +608,10 @@ class DockerMetadata:
|
|
|
571
608
|
"""
|
|
572
609
|
The name of the Latch Secret that contains the password for the private repository
|
|
573
610
|
"""
|
|
611
|
+
server: Optional[str] = None
|
|
612
|
+
"""
|
|
613
|
+
The name of a docker server to login to, if relevant (eg. registry.gitlab.com)
|
|
614
|
+
"""
|
|
574
615
|
|
|
575
616
|
|
|
576
617
|
@dataclass
|
|
@@ -628,6 +669,7 @@ class SnakemakeMetadata(LatchMetadata):
|
|
|
628
669
|
"""
|
|
629
670
|
|
|
630
671
|
def validate(self):
|
|
672
|
+
from latch_cli.extras.snakemake.config import validate_snakemake_type
|
|
631
673
|
|
|
632
674
|
for name, param in self.parameters.items():
|
|
633
675
|
if param.default is None:
|
|
@@ -651,3 +693,26 @@ class SnakemakeMetadata(LatchMetadata):
|
|
|
651
693
|
|
|
652
694
|
|
|
653
695
|
_snakemake_metadata: Optional[SnakemakeMetadata] = None
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
@dataclass
|
|
699
|
+
class NextflowMetadata(LatchMetadata):
|
|
700
|
+
name: Optional[str] = None
|
|
701
|
+
parameters: Dict[str, NextflowParameter] = field(default_factory=dict)
|
|
702
|
+
output_directory: Optional[LatchDir] = None
|
|
703
|
+
docker_metadata: Optional[DockerMetadata] = None
|
|
704
|
+
|
|
705
|
+
def __post_init__(self):
|
|
706
|
+
if self.name is None:
|
|
707
|
+
self.name = f"nf_{identifier_suffix_from_str(self.display_name.lower())}"
|
|
708
|
+
else:
|
|
709
|
+
self.name = identifier_suffix_from_str(self.name)
|
|
710
|
+
|
|
711
|
+
if self.output_directory is None:
|
|
712
|
+
self.output_directory = LatchDir("latch:///Nextflow Outputs/")
|
|
713
|
+
|
|
714
|
+
global _nextflow_metadata
|
|
715
|
+
_nextflow_metadata = self
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
_nextflow_metadata: Optional[NextflowMetadata] = None
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from typing import Dict
|
|
2
3
|
|
|
3
4
|
import gql
|
|
@@ -84,17 +85,24 @@ def current_workspace() -> str:
|
|
|
84
85
|
"""
|
|
85
86
|
ws = user_config.workspace_id
|
|
86
87
|
if ws == "":
|
|
87
|
-
|
|
88
|
+
res = execute(
|
|
88
89
|
gql.gql("""
|
|
89
90
|
query DefaultAccountQuery {
|
|
90
91
|
accountInfoCurrent {
|
|
92
|
+
id
|
|
91
93
|
user {
|
|
92
94
|
defaultAccount
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
"""),
|
|
97
|
-
)["accountInfoCurrent"]
|
|
99
|
+
)["accountInfoCurrent"]
|
|
100
|
+
|
|
101
|
+
default_ws = res["id"]
|
|
102
|
+
|
|
103
|
+
is_local = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") is None
|
|
104
|
+
if is_local:
|
|
105
|
+
default_ws = res["user"]["defaultAccount"]
|
|
98
106
|
|
|
99
107
|
if default_ws is not None:
|
|
100
108
|
ws = default_ws
|
|
@@ -80,6 +80,35 @@ latch_cli/exceptions/cache.py
|
|
|
80
80
|
latch_cli/exceptions/errors.py
|
|
81
81
|
latch_cli/exceptions/handler.py
|
|
82
82
|
latch_cli/exceptions/traceback.py
|
|
83
|
+
latch_cli/extras/__init__.py
|
|
84
|
+
latch_cli/extras/common/__init__.py
|
|
85
|
+
latch_cli/extras/common/serialize.py
|
|
86
|
+
latch_cli/extras/common/utils.py
|
|
87
|
+
latch_cli/extras/common/config/__init__.py
|
|
88
|
+
latch_cli/extras/common/config/parser.py
|
|
89
|
+
latch_cli/extras/common/config/utils.py
|
|
90
|
+
latch_cli/extras/nextflow/__init__.py
|
|
91
|
+
latch_cli/extras/nextflow/build.py
|
|
92
|
+
latch_cli/extras/nextflow/channel.py
|
|
93
|
+
latch_cli/extras/nextflow/config.py
|
|
94
|
+
latch_cli/extras/nextflow/dag.py
|
|
95
|
+
latch_cli/extras/nextflow/file_persistence.py
|
|
96
|
+
latch_cli/extras/nextflow/serialize.py
|
|
97
|
+
latch_cli/extras/nextflow/workflow.py
|
|
98
|
+
latch_cli/extras/nextflow/tasks/__init__.py
|
|
99
|
+
latch_cli/extras/nextflow/tasks/adapters.py
|
|
100
|
+
latch_cli/extras/nextflow/tasks/base.py
|
|
101
|
+
latch_cli/extras/nextflow/tasks/conditional.py
|
|
102
|
+
latch_cli/extras/nextflow/tasks/map.py
|
|
103
|
+
latch_cli/extras/nextflow/tasks/merge.py
|
|
104
|
+
latch_cli/extras/nextflow/tasks/operator.py
|
|
105
|
+
latch_cli/extras/nextflow/tasks/process.py
|
|
106
|
+
latch_cli/extras/snakemake/__init__.py
|
|
107
|
+
latch_cli/extras/snakemake/config.py
|
|
108
|
+
latch_cli/extras/snakemake/serialize.py
|
|
109
|
+
latch_cli/extras/snakemake/single_task_snakemake.py
|
|
110
|
+
latch_cli/extras/snakemake/utils.py
|
|
111
|
+
latch_cli/extras/snakemake/workflow.py
|
|
83
112
|
latch_cli/services/__init__.py
|
|
84
113
|
latch_cli/services/get.py
|
|
85
114
|
latch_cli/services/get_executions.py
|
|
@@ -129,6 +158,9 @@ latch_cli/services/init/example_conda/environment.yaml
|
|
|
129
158
|
latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc
|
|
130
159
|
latch_cli/services/init/example_docker/__init__.py
|
|
131
160
|
latch_cli/services/init/example_docker/task.py
|
|
161
|
+
latch_cli/services/init/example_nextflow/main.nf
|
|
162
|
+
latch_cli/services/init/example_nextflow/nextflow.config
|
|
163
|
+
latch_cli/services/init/example_nextflow/workflow.nf
|
|
132
164
|
latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc
|
|
133
165
|
latch_cli/services/init/example_nfcore/Dockerfile
|
|
134
166
|
latch_cli/services/init/example_nfcore/__init__.py
|
|
@@ -159,18 +191,10 @@ latch_cli/services/test_data/ls.py
|
|
|
159
191
|
latch_cli/services/test_data/remove.py
|
|
160
192
|
latch_cli/services/test_data/upload.py
|
|
161
193
|
latch_cli/services/test_data/utils.py
|
|
162
|
-
latch_cli/snakemake/__init__.py
|
|
163
|
-
latch_cli/snakemake/serialize.py
|
|
164
|
-
latch_cli/snakemake/serialize_utils.py
|
|
165
|
-
latch_cli/snakemake/single_task_snakemake.py
|
|
166
|
-
latch_cli/snakemake/utils.py
|
|
167
|
-
latch_cli/snakemake/workflow.py
|
|
168
|
-
latch_cli/snakemake/config/__init__.py
|
|
169
|
-
latch_cli/snakemake/config/parser.py
|
|
170
|
-
latch_cli/snakemake/config/utils.py
|
|
171
194
|
latch_cli/tui/__init__.py
|
|
172
195
|
latch_cli/utils/__init__.py
|
|
173
196
|
latch_cli/utils/path.py
|
|
197
|
+
latch_cli/utils/workflow.py
|
|
174
198
|
tests/__init__.py
|
|
175
199
|
tests/fixtures.py
|
|
176
200
|
tests/test_ls.py
|
|
@@ -164,15 +164,13 @@ class OAuth2:
|
|
|
164
164
|
"""
|
|
165
165
|
|
|
166
166
|
token_url = self.authz_server_host + "/oauth/token"
|
|
167
|
-
token_body: bytes = json.dumps(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
).encode("utf-8")
|
|
167
|
+
token_body: bytes = json.dumps({
|
|
168
|
+
"grant_type": "authorization_code",
|
|
169
|
+
"client_id": self.client_id,
|
|
170
|
+
"code_verifier": self.pkce.verifier,
|
|
171
|
+
"code": auth_code,
|
|
172
|
+
"redirect_uri": self.redirect_url,
|
|
173
|
+
}).encode("utf-8")
|
|
176
174
|
token_request = urllib.request.Request(token_url, token_body)
|
|
177
175
|
token_request.add_header("Content-Type", "application/json")
|
|
178
176
|
with urllib.request.urlopen(
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import re
|
|
2
3
|
import sys
|
|
4
|
+
import time
|
|
3
5
|
import traceback
|
|
4
6
|
from dataclasses import dataclass
|
|
5
7
|
from pathlib import Path
|
|
6
8
|
from textwrap import dedent
|
|
7
|
-
from typing import Dict, Optional, Tuple
|
|
9
|
+
from typing import Dict, Optional, Tuple, cast
|
|
8
10
|
|
|
9
11
|
import click
|
|
10
12
|
import docker
|
|
@@ -51,7 +53,7 @@ class _CentromereCtx:
|
|
|
51
53
|
dkr_repo: Optional[str] = None
|
|
52
54
|
dkr_client: Optional[docker.APIClient] = None
|
|
53
55
|
ssh_client: Optional[paramiko.SSHClient] = None
|
|
54
|
-
pkg_root:
|
|
56
|
+
pkg_root: Path # root
|
|
55
57
|
disable_auto_version: bool = False
|
|
56
58
|
image_full = None
|
|
57
59
|
version = None
|
|
@@ -59,6 +61,7 @@ class _CentromereCtx:
|
|
|
59
61
|
default_container: _Container
|
|
60
62
|
workflow_type: WorkflowType
|
|
61
63
|
snakefile: Optional[Path]
|
|
64
|
+
nf_script: Optional[Path]
|
|
62
65
|
|
|
63
66
|
latch_register_api_url = config.api.workflow.register
|
|
64
67
|
latch_image_api_url = config.api.workflow.upload_image
|
|
@@ -80,26 +83,37 @@ class _CentromereCtx:
|
|
|
80
83
|
disable_auto_version: bool = False,
|
|
81
84
|
remote: bool = False,
|
|
82
85
|
snakefile: Optional[Path] = None,
|
|
86
|
+
nf_script: Optional[Path] = None,
|
|
83
87
|
use_new_centromere: bool = False,
|
|
84
88
|
):
|
|
85
89
|
self.use_new_centromere = use_new_centromere
|
|
86
90
|
self.remote = remote
|
|
87
91
|
self.disable_auto_version = disable_auto_version
|
|
92
|
+
self.pkg_root = pkg_root.resolve()
|
|
88
93
|
|
|
89
94
|
try:
|
|
90
95
|
self.token = retrieve_or_login()
|
|
91
96
|
self.account_id = current_workspace()
|
|
92
97
|
|
|
93
98
|
self.dkr_repo = config.dkr_repo
|
|
94
|
-
self.pkg_root = pkg_root.resolve()
|
|
95
99
|
|
|
96
|
-
if snakefile
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
if snakefile and nf_script:
|
|
101
|
+
raise ValueError(
|
|
102
|
+
"Cannot provide both a snakefile and nextflow script to the"
|
|
103
|
+
" register command."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if snakefile is not None:
|
|
99
107
|
self.workflow_type = WorkflowType.snakemake
|
|
100
108
|
self.snakefile = snakefile
|
|
109
|
+
elif nf_script is not None:
|
|
110
|
+
self.workflow_type = WorkflowType.nextflow
|
|
111
|
+
self.nf_script = nf_script
|
|
112
|
+
else:
|
|
113
|
+
self.workflow_type = WorkflowType.latchbiosdk
|
|
101
114
|
|
|
102
115
|
self.container_map: Dict[str, _Container] = {}
|
|
116
|
+
|
|
103
117
|
if self.workflow_type == WorkflowType.latchbiosdk:
|
|
104
118
|
_import_flyte_objects([self.pkg_root])
|
|
105
119
|
for entity in FlyteEntities.entities:
|
|
@@ -107,36 +121,40 @@ class _CentromereCtx:
|
|
|
107
121
|
self.workflow_name = entity.name
|
|
108
122
|
|
|
109
123
|
if isinstance(entity, PythonTask):
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
124
|
+
dockerfile_path: Optional[Path] = getattr(
|
|
125
|
+
entity, "dockerfile_path", None
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
if dockerfile_path is not None:
|
|
114
129
|
self.container_map[entity.name] = _Container(
|
|
115
|
-
dockerfile=
|
|
130
|
+
dockerfile=dockerfile_path,
|
|
116
131
|
image_name=self.task_image_name(entity.name),
|
|
117
|
-
pkg_dir=
|
|
132
|
+
pkg_dir=dockerfile_path.parent,
|
|
118
133
|
)
|
|
134
|
+
|
|
119
135
|
if not hasattr(self, "workflow_name"):
|
|
120
136
|
click.secho(
|
|
121
137
|
dedent("""
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
138
|
+
Unable to locate workflow code.
|
|
139
|
+
|
|
140
|
+
If you are a registering a Snakemake/Nextflow project, make sure to pass the appropriate
|
|
141
|
+
script with either the --snakefile or --nf-script flag.
|
|
142
|
+
"""),
|
|
126
143
|
fg="red",
|
|
127
144
|
)
|
|
128
145
|
raise click.exceptions.Exit(1)
|
|
129
|
-
|
|
146
|
+
|
|
147
|
+
elif self.workflow_type == WorkflowType.snakemake:
|
|
130
148
|
assert snakefile is not None
|
|
131
149
|
|
|
132
150
|
import latch.types.metadata as metadata
|
|
133
151
|
|
|
134
|
-
from ..
|
|
135
|
-
from ..snakemake.serialize import (
|
|
152
|
+
from ..extras.snakemake.serialize import (
|
|
136
153
|
get_snakemake_metadata_example,
|
|
137
154
|
snakemake_workflow_extractor,
|
|
138
155
|
)
|
|
139
|
-
from ..snakemake.utils import load_snakemake_metadata
|
|
156
|
+
from ..extras.snakemake.utils import load_snakemake_metadata
|
|
157
|
+
from ..services.register.utils import import_module_by_path
|
|
140
158
|
|
|
141
159
|
meta_file = load_snakemake_metadata(pkg_root)
|
|
142
160
|
if meta_file is not None:
|
|
@@ -151,18 +169,17 @@ class _CentromereCtx:
|
|
|
151
169
|
except (ImportError, FileNotFoundError):
|
|
152
170
|
traceback.print_exc()
|
|
153
171
|
click.secho(
|
|
154
|
-
"\n\n\
|
|
155
|
-
|
|
156
|
-
+ "the Snakefile to extract workflow metadata.",
|
|
172
|
+
"\n\n\nThe above error occurred when reading the Snakefile"
|
|
173
|
+
" to extract workflow metadata.",
|
|
157
174
|
bold=True,
|
|
158
175
|
fg="red",
|
|
159
176
|
)
|
|
160
177
|
click.secho(
|
|
161
|
-
"\nIt is possible to avoid including the Snakefile"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
178
|
+
"\nIt is possible to avoid including the Snakefile prior to"
|
|
179
|
+
" registration by providing a `latch_metadata.py` file in"
|
|
180
|
+
" the workflow root.\nThis way it is not necessary to"
|
|
181
|
+
" install dependencies or ensure that Snakemake inputs"
|
|
182
|
+
" locally.",
|
|
166
183
|
fg="red",
|
|
167
184
|
)
|
|
168
185
|
click.secho("\nExample ", fg="red", nl=False)
|
|
@@ -207,15 +224,14 @@ class _CentromereCtx:
|
|
|
207
224
|
elif system == "Darwin":
|
|
208
225
|
res = subprocess.run(["open", new_meta]).returncode
|
|
209
226
|
elif system == "Windows":
|
|
210
|
-
import os
|
|
211
|
-
|
|
212
227
|
res = os.system(str(new_meta.resolve()))
|
|
213
228
|
else:
|
|
214
229
|
res = None
|
|
215
230
|
|
|
216
231
|
if res is not None and res != 0:
|
|
217
232
|
click.secho("Failed to open file", fg="red")
|
|
218
|
-
|
|
233
|
+
|
|
234
|
+
raise click.exceptions.Exit(1)
|
|
219
235
|
|
|
220
236
|
if metadata._snakemake_metadata is None:
|
|
221
237
|
click.secho(
|
|
@@ -232,6 +248,34 @@ class _CentromereCtx:
|
|
|
232
248
|
# name for snakemake
|
|
233
249
|
self.workflow_name = f"{metadata._snakemake_metadata.name}_jit_register"
|
|
234
250
|
|
|
251
|
+
else:
|
|
252
|
+
assert nf_script is not None
|
|
253
|
+
|
|
254
|
+
import latch.types.metadata as metadata
|
|
255
|
+
|
|
256
|
+
from ..services.register.utils import import_module_by_path
|
|
257
|
+
|
|
258
|
+
meta = pkg_root / "latch_metadata" / "__init__.py"
|
|
259
|
+
if meta.exists():
|
|
260
|
+
click.echo(f"Using metadata file {click.style(meta, italic=True)}")
|
|
261
|
+
import_module_by_path(meta)
|
|
262
|
+
|
|
263
|
+
if metadata._nextflow_metadata is None:
|
|
264
|
+
click.secho(
|
|
265
|
+
dedent(
|
|
266
|
+
"Make sure a `latch_metadata` package exists in the"
|
|
267
|
+
" nextflow project root."
|
|
268
|
+
"\nYou can generate this package with the"
|
|
269
|
+
"`latch generate-metadata --nextflow <pkg_root>` command.",
|
|
270
|
+
),
|
|
271
|
+
fg="red",
|
|
272
|
+
)
|
|
273
|
+
raise click.exceptions.Exit(1)
|
|
274
|
+
|
|
275
|
+
self.workflow_name = metadata._nextflow_metadata.name
|
|
276
|
+
|
|
277
|
+
assert self.workflow_name is not None
|
|
278
|
+
|
|
235
279
|
version_file = self.pkg_root / "version"
|
|
236
280
|
try:
|
|
237
281
|
self.version = version_file.read_text()
|
|
@@ -246,7 +290,11 @@ class _CentromereCtx:
|
|
|
246
290
|
if not self.disable_auto_version:
|
|
247
291
|
hash = hash_directory(self.pkg_root)
|
|
248
292
|
self.version = f"{self.version}-{hash[:6]}"
|
|
249
|
-
|
|
293
|
+
|
|
294
|
+
if os.environ.get("LATCH_NEW_VERSION_ALWAYS") is not None:
|
|
295
|
+
self.version = f"{self.version}-{int(time.monotonic())}"
|
|
296
|
+
|
|
297
|
+
click.echo()
|
|
250
298
|
|
|
251
299
|
if self.nucleus_check_version(self.version, self.workflow_name):
|
|
252
300
|
click.secho(
|
|
@@ -324,6 +372,8 @@ class _CentromereCtx:
|
|
|
324
372
|
|
|
325
373
|
from ..utils import identifier_suffix_from_str
|
|
326
374
|
|
|
375
|
+
assert self.workflow_name is not None
|
|
376
|
+
|
|
327
377
|
wf_name = identifier_suffix_from_str(self.workflow_name).lower()
|
|
328
378
|
wf_name = docker_image_name_illegal_pat.sub("_", wf_name)
|
|
329
379
|
|
|
@@ -110,6 +110,9 @@ class AnsiCodes:
|
|
|
110
110
|
bold = "\x1b[1m"
|
|
111
111
|
reset_bold = "\x1b[22m"
|
|
112
112
|
|
|
113
|
+
italic = "\x1b[3m"
|
|
114
|
+
reset_italic = "\x1b[23m"
|
|
115
|
+
|
|
113
116
|
underline = "\x1b[4m"
|
|
114
117
|
no_underline = "\x1b[24m"
|
|
115
118
|
|
|
@@ -119,13 +122,17 @@ class AnsiCodes:
|
|
|
119
122
|
url_end = "\x1b]8;;\x1b\\"
|
|
120
123
|
|
|
121
124
|
|
|
122
|
-
def
|
|
125
|
+
def italic(s: object) -> str:
|
|
126
|
+
return f"{AnsiCodes.italic}{s}{AnsiCodes.reset_italic}"
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def bold(s: object) -> str:
|
|
123
130
|
return f"{AnsiCodes.bold}{s}{AnsiCodes.reset_bold}"
|
|
124
131
|
|
|
125
132
|
|
|
126
|
-
def underline(s:
|
|
133
|
+
def underline(s: object) -> str:
|
|
127
134
|
return f"{AnsiCodes.underline}{s}{AnsiCodes.no_underline}"
|
|
128
135
|
|
|
129
136
|
|
|
130
|
-
def color(s:
|
|
137
|
+
def color(s: object, *, color: str = AnsiCodes.color):
|
|
131
138
|
return f"{color}{s}{AnsiCodes.reset_color}"
|
|
@@ -9,6 +9,7 @@ from typing import List
|
|
|
9
9
|
import click
|
|
10
10
|
import yaml
|
|
11
11
|
|
|
12
|
+
from latch_cli.click_utils import color
|
|
12
13
|
from latch_cli.constants import latch_constants
|
|
13
14
|
from latch_cli.utils import WorkflowType
|
|
14
15
|
from latch_cli.workflow_config import LatchWorkflowConfig, create_and_write_config
|
|
@@ -37,9 +38,12 @@ def get_prologue(
|
|
|
37
38
|
) -> List[str]:
|
|
38
39
|
if wf_type == WorkflowType.snakemake:
|
|
39
40
|
library_name = '"latch[snakemake]"'
|
|
41
|
+
elif wf_type == WorkflowType.nextflow:
|
|
42
|
+
library_name = '"latch[nextflow]"'
|
|
40
43
|
else:
|
|
41
44
|
library_name = "latch"
|
|
42
|
-
|
|
45
|
+
|
|
46
|
+
directives = [
|
|
43
47
|
"# DO NOT CHANGE",
|
|
44
48
|
f"from {config.base_image}",
|
|
45
49
|
"",
|
|
@@ -68,6 +72,11 @@ def get_prologue(
|
|
|
68
72
|
f"run pip install {library_name}=={config.latch_version}",
|
|
69
73
|
"run mkdir /opt/latch",
|
|
70
74
|
]
|
|
75
|
+
if wf_type == WorkflowType.nextflow:
|
|
76
|
+
directives.append(
|
|
77
|
+
"run apt-get update && apt-get install -y default-jre-headless"
|
|
78
|
+
)
|
|
79
|
+
return directives
|
|
71
80
|
|
|
72
81
|
|
|
73
82
|
def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]:
|
|
@@ -78,8 +87,19 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]:
|
|
|
78
87
|
"",
|
|
79
88
|
"# Latch snakemake workflow entrypoint",
|
|
80
89
|
"# DO NOT CHANGE",
|
|
90
|
+
"",
|
|
81
91
|
"copy .latch/snakemake_jit_entrypoint.py /root/snakemake_jit_entrypoint.py",
|
|
82
92
|
]
|
|
93
|
+
elif wf_type == WorkflowType.nextflow:
|
|
94
|
+
cmds += [
|
|
95
|
+
"",
|
|
96
|
+
"# Latch nextflow workflow entrypoint",
|
|
97
|
+
"# DO NOT CHANGE",
|
|
98
|
+
"",
|
|
99
|
+
"copy .latch/bin/nextflow /root/nextflow",
|
|
100
|
+
"copy .latch/.nextflow /root/.nextflow",
|
|
101
|
+
"copy .latch/nf_entrypoint.py /root/nf_entrypoint.py",
|
|
102
|
+
]
|
|
83
103
|
|
|
84
104
|
cmds += [
|
|
85
105
|
"",
|
|
@@ -339,18 +359,8 @@ def generate_dockerfile(
|
|
|
339
359
|
with (pkg_root / latch_constants.pkg_config).open("r") as f:
|
|
340
360
|
config = LatchWorkflowConfig(**json.load(f))
|
|
341
361
|
|
|
342
|
-
click.echo(
|
|
343
|
-
|
|
344
|
-
click.style("Base image:", fg="bright_blue"),
|
|
345
|
-
config.base_image,
|
|
346
|
-
])
|
|
347
|
-
)
|
|
348
|
-
click.echo(
|
|
349
|
-
" ".join([
|
|
350
|
-
click.style("Latch SDK version:", fg="bright_blue"),
|
|
351
|
-
config.latch_version,
|
|
352
|
-
])
|
|
353
|
-
)
|
|
362
|
+
click.echo(" ".join([color("Base image:"), config.base_image]))
|
|
363
|
+
click.echo(" ".join([color("Latch SDK version:"), config.latch_version]))
|
|
354
364
|
click.echo()
|
|
355
365
|
|
|
356
366
|
with outfile.open("w") as f:
|