latch 2.41.3.dev0__tar.gz → 2.41.3.dev2__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.41.3.dev0/latch.egg-info → latch-2.41.3.dev2}/PKG-INFO +1 -1
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/tasks.py +40 -36
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/directory.py +2 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/metadata.py +31 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2/latch.egg-info}/PKG-INFO +1 -1
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch.egg-info/SOURCES.txt +4 -11
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/centromere/ctx.py +1 -1
- latch-2.41.3.dev2/latch_cli/nextflow/dependencies.py +91 -0
- latch-2.41.3.dev2/latch_cli/nextflow/utils.py +27 -0
- latch-2.41.3.dev2/latch_cli/nextflow/workflow.py +222 -0
- latch-2.41.3.dev2/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/__pycache__/init.cpython-310.pyc +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/config/utils.py +20 -6
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/setup.py +1 -1
- latch-2.41.3.dev2/tests/__init__.py +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/__init__.cpython-311.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/__init__.cpython-38.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/__init__.cpython-39.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/init.cpython-311.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/init.cpython-38.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/__pycache__/init.cpython-39.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/example_r/__pycache__/__init__.cpython-310.pyc +0 -0
- latch-2.41.3.dev0/latch_cli/services/init/template/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/LICENSE +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/MANIFEST.in +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/README.md +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/account.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/executions.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/functions/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/functions/messages.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/functions/operators.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/functions/secrets.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/download.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/manager.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/node.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/progress.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/remote_copy.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/throttle.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/upload.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/_transfer/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/path.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/ldata/type.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/project.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/record.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/table.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/types.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/upstream_types/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/upstream_types/types.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/upstream_types/values.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/registry/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/conditional.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/dynamic.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/launch_plan.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/map_tasks.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/reference_workflow.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/resources/workflow.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/file.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/glob.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/json.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/types/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/deseq2.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/mafft.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/pathway.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/rnaseq.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch/verified/trim_galore.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch.egg-info/dependency_links.txt +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch.egg-info/entry_points.txt +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch.egg-info/requires.txt +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch.egg-info/top_level.txt +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/auth/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/auth/csrf.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/auth/oauth2.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/auth/pkce.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/auth/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/centromere/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/centromere/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/click_utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/constants.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/docker_utils/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/exceptions/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/exceptions/cache.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/exceptions/errors.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/exceptions/handler.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/exceptions/traceback.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/main.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/menus.py +0 -0
- {latch-2.41.3.dev0/latch_cli/services/cp → latch-2.41.3.dev2/latch_cli/nextflow}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/__init__.py +0 -0
- {latch-2.41.3.dev0/latch_cli/services/execute → latch-2.41.3.dev2/latch_cli/services/cp}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/cp/autocomplete.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/cp/glob.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/cp/main.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/cp/utils.py +0 -0
- {latch-2.41.3.dev0/latch_cli/services/test_data → latch-2.41.3.dev2/latch_cli/services/execute}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/execute/main.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/execute/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/get.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/get_executions.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/get_params.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/.env +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/README.md +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/common/.dockerignore +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_conda/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_conda/conda_task.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_conda/environment.yaml +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_docker/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_docker/task.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_nfcore/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_nfcore/task.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_r/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_r/environment.R +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_r/r_task.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/Snakefile +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/config.yaml +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/example_snakemake/version +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/init.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/template/LICENSE +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/template/README.md +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/template/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/template/task.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/launch.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/local_dev.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/local_dev_old.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/login.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/ls.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/mkdir.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/move.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/preview.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/register/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/register/constants.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/register/register.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/register/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/rm.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/stop_pod.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/sync.py +0 -0
- {latch-2.41.3.dev0/latch_cli/snakemake → latch-2.41.3.dev2/latch_cli/services/test_data}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/test_data/ls.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/test_data/remove.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/test_data/upload.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/test_data/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/workspace.py +0 -0
- {latch-2.41.3.dev0/latch_cli/snakemake/config → latch-2.41.3.dev2/latch_cli/snakemake}/__init__.py +0 -0
- {latch-2.41.3.dev0/latch_cli/tui → latch-2.41.3.dev2/latch_cli/snakemake/config}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/config/parser.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/serialize.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/serialize_utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/single_task_snakemake.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/utils.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/snakemake/workflow.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/tinyrequests.py +0 -0
- {latch-2.41.3.dev0/tests → latch-2.41.3.dev2/latch_cli/tui}/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/utils/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/utils/path.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/workflow_config.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/pyproject.toml +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/setup.cfg +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/tests/cp/__init__.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/tests/fixtures.py +0 -0
- {latch-2.41.3.dev0 → latch-2.41.3.dev2}/tests/test_ls.py +0 -0
|
@@ -182,40 +182,6 @@ def _get_small_pod() -> Pod:
|
|
|
182
182
|
)
|
|
183
183
|
|
|
184
184
|
|
|
185
|
-
def _get_nextflow_runtime_pod() -> Pod:
|
|
186
|
-
primary_container = V1Container(name="primary")
|
|
187
|
-
resources = V1ResourceRequirements(
|
|
188
|
-
requests={"cpu": "2", "memory": "4Gi", "ephemeral-storage": "100Gi"},
|
|
189
|
-
limits={"cpu": "2", "memory": "4Gi", "ephemeral-storage": "100Gi"},
|
|
190
|
-
)
|
|
191
|
-
primary_container.resources = resources
|
|
192
|
-
volume_mounts = [V1VolumeMount(mount_path="/nf-workdir", name="nextflow-workdir")]
|
|
193
|
-
primary_container.volume_mounts = volume_mounts
|
|
194
|
-
|
|
195
|
-
return Pod(
|
|
196
|
-
annotations={
|
|
197
|
-
"io.kubernetes.cri-o.userns-mode": (
|
|
198
|
-
"private:uidmapping=0:1048576:65536;gidmapping=0:1048576:65536"
|
|
199
|
-
)
|
|
200
|
-
},
|
|
201
|
-
pod_spec=V1PodSpec(
|
|
202
|
-
runtime_class_name="sysbox-runc",
|
|
203
|
-
service_account_name="rahul-test",
|
|
204
|
-
containers=[primary_container],
|
|
205
|
-
volumes=[
|
|
206
|
-
V1Volume(
|
|
207
|
-
name="nextflow-workdir",
|
|
208
|
-
persistent_volume_claim=V1PersistentVolumeClaimVolumeSource(
|
|
209
|
-
# this value will be injected by flytepropeller
|
|
210
|
-
claim_name="nextflow-pvc-placeholder"
|
|
211
|
-
),
|
|
212
|
-
)
|
|
213
|
-
],
|
|
214
|
-
),
|
|
215
|
-
primary_container_name="primary",
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
|
|
219
185
|
large_gpu_task = functools.partial(task, task_config=_get_large_gpu_pod())
|
|
220
186
|
"""This task will get scheduled on a large GPU-enabled node.
|
|
221
187
|
|
|
@@ -351,8 +317,6 @@ small_task = functools.partial(task, task_config=_get_small_pod())
|
|
|
351
317
|
- False
|
|
352
318
|
"""
|
|
353
319
|
|
|
354
|
-
nextflow_runtime_task = functools.partial(task, task_config=_get_nextflow_runtime_pod())
|
|
355
|
-
|
|
356
320
|
|
|
357
321
|
def custom_memory_optimized_task(cpu: int, memory: int):
|
|
358
322
|
"""Returns a custom task configuration requesting
|
|
@@ -530,3 +494,43 @@ def custom_task(
|
|
|
530
494
|
return functools.partial(
|
|
531
495
|
task, task_config=_custom_task_config(cpu, memory, storage_gib), timeout=timeout
|
|
532
496
|
)
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def nextflow_runtime_task(cpu: int, memory: int):
|
|
500
|
+
primary_container = V1Container(name="primary")
|
|
501
|
+
resources = V1ResourceRequirements(
|
|
502
|
+
requests={
|
|
503
|
+
"cpu": str(cpu),
|
|
504
|
+
"memory": f"{memory}Gi",
|
|
505
|
+
"ephemeral-storage": "20Gi",
|
|
506
|
+
},
|
|
507
|
+
limits={"cpu": str(cpu), "memory": f"{memory}Gi", "ephemeral-storage": "20Gi"},
|
|
508
|
+
)
|
|
509
|
+
primary_container.resources = resources
|
|
510
|
+
volume_mounts = [V1VolumeMount(mount_path="/nf-workdir", name="nextflow-workdir")]
|
|
511
|
+
primary_container.volume_mounts = volume_mounts
|
|
512
|
+
|
|
513
|
+
task_config = Pod(
|
|
514
|
+
annotations={
|
|
515
|
+
"io.kubernetes.cri-o.userns-mode": (
|
|
516
|
+
"private:uidmapping=0:1048576:65536;gidmapping=0:1048576:65536"
|
|
517
|
+
)
|
|
518
|
+
},
|
|
519
|
+
pod_spec=V1PodSpec(
|
|
520
|
+
runtime_class_name="sysbox-runc",
|
|
521
|
+
service_account_name="rahul-test",
|
|
522
|
+
containers=[primary_container],
|
|
523
|
+
volumes=[
|
|
524
|
+
V1Volume(
|
|
525
|
+
name="nextflow-workdir",
|
|
526
|
+
persistent_volume_claim=V1PersistentVolumeClaimVolumeSource(
|
|
527
|
+
# this value will be injected by flytepropeller
|
|
528
|
+
claim_name="nextflow-pvc-placeholder"
|
|
529
|
+
),
|
|
530
|
+
)
|
|
531
|
+
],
|
|
532
|
+
),
|
|
533
|
+
primary_container_name="primary",
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
return functools.partial(task, task_config=task_config)
|
|
@@ -114,8 +114,10 @@ class LatchDir(FlyteDirectory):
|
|
|
114
114
|
self._path_generated = False
|
|
115
115
|
|
|
116
116
|
if is_valid_url(self.path) and remote_path is None:
|
|
117
|
+
self._raw_remote_path = path
|
|
117
118
|
self._remote_directory = self.path
|
|
118
119
|
else:
|
|
120
|
+
self._raw_remote_path = remote_path
|
|
119
121
|
self._remote_directory = None if remote_path is None else str(remote_path)
|
|
120
122
|
|
|
121
123
|
if kwargs.get("downloader") is not None:
|
|
@@ -483,6 +483,21 @@ class NextflowParameter(Generic[T], LatchParameter):
|
|
|
483
483
|
self.type = Annotated[self.type, "samplesheet"]
|
|
484
484
|
|
|
485
485
|
|
|
486
|
+
@dataclass(frozen=True)
|
|
487
|
+
class NextflowRuntimeResources:
|
|
488
|
+
"""Resources for Nextflow runtime tasks"""
|
|
489
|
+
|
|
490
|
+
cpus: Optional[int] = 4
|
|
491
|
+
"""
|
|
492
|
+
Number of CPUs required for the task
|
|
493
|
+
"""
|
|
494
|
+
memory: Optional[str] = 8
|
|
495
|
+
"""
|
|
496
|
+
Memory required for the task (e.g. "1 GB")
|
|
497
|
+
"""
|
|
498
|
+
storage_gib: Optional[int] = 100
|
|
499
|
+
|
|
500
|
+
|
|
486
501
|
@dataclass
|
|
487
502
|
class LatchMetadata:
|
|
488
503
|
"""Class for organizing workflow metadata
|
|
@@ -683,7 +698,23 @@ _snakemake_metadata: Optional[SnakemakeMetadata] = None
|
|
|
683
698
|
@dataclass
|
|
684
699
|
class NextflowMetadata(LatchMetadata):
|
|
685
700
|
name: Optional[str] = None
|
|
701
|
+
"""
|
|
702
|
+
Name of the workflow
|
|
703
|
+
"""
|
|
686
704
|
parameters: Dict[str, NextflowParameter] = field(default_factory=dict)
|
|
705
|
+
"""
|
|
706
|
+
A dictionary mapping parameter names (strings) to `NextflowParameter` objects
|
|
707
|
+
"""
|
|
708
|
+
runtime_resources: NextflowRuntimeResources = field(
|
|
709
|
+
default_factory=NextflowRuntimeResources
|
|
710
|
+
)
|
|
711
|
+
"""
|
|
712
|
+
Resources (cpu/memory/storage) for Nextflow runtime task
|
|
713
|
+
"""
|
|
714
|
+
output_dir: Optional[LatchDir] = None
|
|
715
|
+
"""
|
|
716
|
+
Directory to dump Nextflow logs
|
|
717
|
+
"""
|
|
687
718
|
|
|
688
719
|
def __post_init__(self):
|
|
689
720
|
if self.name is None:
|
|
@@ -80,6 +80,10 @@ 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/nextflow/__init__.py
|
|
84
|
+
latch_cli/nextflow/dependencies.py
|
|
85
|
+
latch_cli/nextflow/utils.py
|
|
86
|
+
latch_cli/nextflow/workflow.py
|
|
83
87
|
latch_cli/services/__init__.py
|
|
84
88
|
latch_cli/services/get.py
|
|
85
89
|
latch_cli/services/get_executions.py
|
|
@@ -107,13 +111,7 @@ latch_cli/services/execute/utils.py
|
|
|
107
111
|
latch_cli/services/init/__init__.py
|
|
108
112
|
latch_cli/services/init/init.py
|
|
109
113
|
latch_cli/services/init/__pycache__/__init__.cpython-310.pyc
|
|
110
|
-
latch_cli/services/init/__pycache__/__init__.cpython-311.pyc
|
|
111
|
-
latch_cli/services/init/__pycache__/__init__.cpython-38.pyc
|
|
112
|
-
latch_cli/services/init/__pycache__/__init__.cpython-39.pyc
|
|
113
114
|
latch_cli/services/init/__pycache__/init.cpython-310.pyc
|
|
114
|
-
latch_cli/services/init/__pycache__/init.cpython-311.pyc
|
|
115
|
-
latch_cli/services/init/__pycache__/init.cpython-38.pyc
|
|
116
|
-
latch_cli/services/init/__pycache__/init.cpython-39.pyc
|
|
117
115
|
latch_cli/services/init/assemble_and_sort/.env
|
|
118
116
|
latch_cli/services/init/assemble_and_sort/LICENSE
|
|
119
117
|
latch_cli/services/init/assemble_and_sort/README.md
|
|
@@ -121,22 +119,18 @@ latch_cli/services/init/assemble_and_sort/__init__.py
|
|
|
121
119
|
latch_cli/services/init/assemble_and_sort/assemble.py
|
|
122
120
|
latch_cli/services/init/assemble_and_sort/sort.py
|
|
123
121
|
latch_cli/services/init/assemble_and_sort/system-requirements.txt
|
|
124
|
-
latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc
|
|
125
122
|
latch_cli/services/init/common/.dockerignore
|
|
126
123
|
latch_cli/services/init/example_conda/__init__.py
|
|
127
124
|
latch_cli/services/init/example_conda/conda_task.py
|
|
128
125
|
latch_cli/services/init/example_conda/environment.yaml
|
|
129
|
-
latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc
|
|
130
126
|
latch_cli/services/init/example_docker/__init__.py
|
|
131
127
|
latch_cli/services/init/example_docker/task.py
|
|
132
|
-
latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc
|
|
133
128
|
latch_cli/services/init/example_nfcore/Dockerfile
|
|
134
129
|
latch_cli/services/init/example_nfcore/__init__.py
|
|
135
130
|
latch_cli/services/init/example_nfcore/task.py
|
|
136
131
|
latch_cli/services/init/example_r/__init__.py
|
|
137
132
|
latch_cli/services/init/example_r/environment.R
|
|
138
133
|
latch_cli/services/init/example_r/r_task.py
|
|
139
|
-
latch_cli/services/init/example_r/__pycache__/__init__.cpython-310.pyc
|
|
140
134
|
latch_cli/services/init/example_snakemake/Dockerfile
|
|
141
135
|
latch_cli/services/init/example_snakemake/Snakefile
|
|
142
136
|
latch_cli/services/init/example_snakemake/config.yaml
|
|
@@ -149,7 +143,6 @@ latch_cli/services/init/template/LICENSE
|
|
|
149
143
|
latch_cli/services/init/template/README.md
|
|
150
144
|
latch_cli/services/init/template/__init__.py
|
|
151
145
|
latch_cli/services/init/template/task.py
|
|
152
|
-
latch_cli/services/init/template/__pycache__/__init__.cpython-310.pyc
|
|
153
146
|
latch_cli/services/register/__init__.py
|
|
154
147
|
latch_cli/services/register/constants.py
|
|
155
148
|
latch_cli/services/register/register.py
|
|
@@ -258,7 +258,7 @@ class _CentromereCtx:
|
|
|
258
258
|
click.secho(
|
|
259
259
|
dedent("""
|
|
260
260
|
Failed to register Nextflow workflow.
|
|
261
|
-
Make sure the project root contains a `
|
|
261
|
+
Make sure the project root contains a `latch_metadata/__init__.py`
|
|
262
262
|
with a `NextflowMetadata` object defined.
|
|
263
263
|
"""),
|
|
264
264
|
fg="red",
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
import subprocess
|
|
3
|
+
from concurrent.futures import ProcessPoolExecutor
|
|
4
|
+
from ctypes import c_int
|
|
5
|
+
from multiprocessing.managers import SyncManager
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from urllib.parse import urljoin
|
|
8
|
+
|
|
9
|
+
import boto3
|
|
10
|
+
import click
|
|
11
|
+
|
|
12
|
+
from latch_cli import tinyrequests
|
|
13
|
+
from latch_cli.utils import dedent
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _do_download(
|
|
17
|
+
url: str,
|
|
18
|
+
output_path: Path,
|
|
19
|
+
total_count: int,
|
|
20
|
+
counter,
|
|
21
|
+
lock,
|
|
22
|
+
): # todo(ayush): figure out the right type annotation for counter/lock
|
|
23
|
+
res = tinyrequests.get(url)
|
|
24
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
25
|
+
output_path.write_bytes(res.content)
|
|
26
|
+
|
|
27
|
+
with lock:
|
|
28
|
+
counter.value += 1
|
|
29
|
+
progress_str = f"{counter.value}/{total_count}"
|
|
30
|
+
|
|
31
|
+
click.echo("\x1b[0K", nl=False)
|
|
32
|
+
click.secho(progress_str, dim=True, italic=True, nl=False)
|
|
33
|
+
click.echo(f"\x1b[{len(progress_str)}D", nl=False)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def download_nf_jars(pkg_root: Path):
|
|
37
|
+
s3_resource = boto3.resource("s3")
|
|
38
|
+
bucket = s3_resource.Bucket("latch-public")
|
|
39
|
+
|
|
40
|
+
objects = list(bucket.objects.filter(Prefix=".nextflow/"))
|
|
41
|
+
|
|
42
|
+
click.secho(" Downloading Nextflow binaries: \x1b[?25l", italic=True, nl=False)
|
|
43
|
+
|
|
44
|
+
with SyncManager() as man:
|
|
45
|
+
counter = man.Value(c_int, 0)
|
|
46
|
+
lock = man.Lock()
|
|
47
|
+
with ProcessPoolExecutor() as exec:
|
|
48
|
+
for obj in objects:
|
|
49
|
+
url = urljoin(
|
|
50
|
+
"https://latch-public.s3.us-west-2.amazonaws.com/", obj.key
|
|
51
|
+
)
|
|
52
|
+
obj_path = pkg_root / ".latch" / obj.key
|
|
53
|
+
|
|
54
|
+
exec.submit(_do_download, url, obj_path, len(objects), counter, lock)
|
|
55
|
+
|
|
56
|
+
click.echo("\x1b[0K", nl=False)
|
|
57
|
+
click.secho("Done. \x1b[?25h", italic=True)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def ensure_nf_dependencies(pkg_root: Path, *, force_redownload: bool = False):
|
|
61
|
+
try:
|
|
62
|
+
subprocess.run(["java", "--version"], check=True, capture_output=True)
|
|
63
|
+
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
|
64
|
+
click.secho(
|
|
65
|
+
dedent("""\
|
|
66
|
+
Java is not installed - this is a requirement to run Nextflow.
|
|
67
|
+
Please install Java and try again.
|
|
68
|
+
"""),
|
|
69
|
+
fg="red",
|
|
70
|
+
)
|
|
71
|
+
raise click.exceptions.Exit(1) from e
|
|
72
|
+
|
|
73
|
+
nf_executable = pkg_root / ".latch" / "bin" / "nextflow"
|
|
74
|
+
nf_jars = pkg_root / ".latch" / ".nextflow"
|
|
75
|
+
|
|
76
|
+
if force_redownload:
|
|
77
|
+
nf_executable.unlink(missing_ok=True)
|
|
78
|
+
if nf_jars.exists():
|
|
79
|
+
shutil.rmtree(nf_jars)
|
|
80
|
+
|
|
81
|
+
if not nf_executable.exists():
|
|
82
|
+
res = tinyrequests.get(
|
|
83
|
+
"https://latch-public.s3.us-west-2.amazonaws.com/nextflow"
|
|
84
|
+
)
|
|
85
|
+
nf_executable.parent.mkdir(parents=True, exist_ok=True)
|
|
86
|
+
|
|
87
|
+
nf_executable.write_bytes(res.content)
|
|
88
|
+
nf_executable.chmod(0o700)
|
|
89
|
+
|
|
90
|
+
if not nf_jars.exists():
|
|
91
|
+
download_nf_jars(pkg_root)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import gql
|
|
5
|
+
from latch_sdk_gql.execute import execute
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _get_execution_name() -> Optional[str]:
|
|
9
|
+
token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", None)
|
|
10
|
+
if token is None:
|
|
11
|
+
return None
|
|
12
|
+
|
|
13
|
+
res = execute(
|
|
14
|
+
gql.gql("""
|
|
15
|
+
query executionCreatorsByToken($token: String!) {
|
|
16
|
+
executionCreatorByToken(token: $token) {
|
|
17
|
+
flytedbId
|
|
18
|
+
info {
|
|
19
|
+
displayName
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
"""),
|
|
24
|
+
{"token": token},
|
|
25
|
+
)["executionCreatorByToken"]
|
|
26
|
+
|
|
27
|
+
return res["info"]["displayName"]
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from dataclasses import fields, is_dataclass
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, List, Optional, Tuple
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
import latch.types.metadata as metadata
|
|
10
|
+
from latch.types.directory import LatchDir
|
|
11
|
+
from latch.types.file import LatchFile
|
|
12
|
+
from latch_cli.snakemake.config.utils import get_preamble, type_repr
|
|
13
|
+
from latch_cli.snakemake.utils import reindent
|
|
14
|
+
from latch_cli.utils import identifier_from_str, urljoins
|
|
15
|
+
|
|
16
|
+
template = """\
|
|
17
|
+
from dataclasses import dataclass
|
|
18
|
+
from enum import Enum
|
|
19
|
+
import os
|
|
20
|
+
import subprocess
|
|
21
|
+
import requests
|
|
22
|
+
import shutil
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
import typing
|
|
25
|
+
import typing_extensions
|
|
26
|
+
|
|
27
|
+
from latch.resources.workflow import workflow
|
|
28
|
+
from latch.resources.tasks import nextflow_runtime_task, custom_task
|
|
29
|
+
from latch.types.file import LatchFile
|
|
30
|
+
from latch.types.directory import LatchDir, LatchOutputDir
|
|
31
|
+
from latch.ldata.path import LPath
|
|
32
|
+
from latch_cli.nextflow.workflow import get_flag
|
|
33
|
+
from latch_cli.nextflow.utils import _get_execution_name
|
|
34
|
+
from latch_cli.utils import urljoins
|
|
35
|
+
from latch.types import metadata
|
|
36
|
+
from flytekit.core.annotation import FlyteAnnotation
|
|
37
|
+
|
|
38
|
+
import latch_metadata
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@custom_task(cpu=0.25, memory=0.5, storage_gib=1)
|
|
42
|
+
def initialize() -> str:
|
|
43
|
+
token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID")
|
|
44
|
+
if token is None:
|
|
45
|
+
raise RuntimeError("failed to get execution token")
|
|
46
|
+
|
|
47
|
+
print("Provisioning shared storage volume...")
|
|
48
|
+
headers = {{"Authorization": f"Latch-Execution-Token {{token}}"}}
|
|
49
|
+
resp = requests.post(
|
|
50
|
+
"http://nf-dispatcher-service.flyte.svc.cluster.local/provision-storage",
|
|
51
|
+
headers=headers,
|
|
52
|
+
json={{
|
|
53
|
+
"storage_gib": {storage_gib},
|
|
54
|
+
}}
|
|
55
|
+
)
|
|
56
|
+
resp.raise_for_status()
|
|
57
|
+
return resp.json()["name"]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
{preambles}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@nextflow_runtime_task(cpu={cpu}, memory={memory})
|
|
64
|
+
def nextflow_runtime(pvc_name: str, {param_signature}) -> None:
|
|
65
|
+
try:
|
|
66
|
+
shared_dir = Path("/nf-workdir")
|
|
67
|
+
|
|
68
|
+
shutil.copytree(
|
|
69
|
+
Path("/root"),
|
|
70
|
+
shared_dir,
|
|
71
|
+
ignore=lambda src, names: ["latch", ".latch"],
|
|
72
|
+
ignore_dangling_symlinks=True,
|
|
73
|
+
dirs_exist_ok=True,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
env = {{
|
|
77
|
+
**os.environ,
|
|
78
|
+
"NXF_HOME": "/root/.nextflow",
|
|
79
|
+
"K8_STORAGE_CLAIM_NAME": pvc_name,
|
|
80
|
+
}}
|
|
81
|
+
subprocess.run(
|
|
82
|
+
[
|
|
83
|
+
"/root/.latch/bin/nextflow",
|
|
84
|
+
"run",
|
|
85
|
+
str(shared_dir / "{nf_script}"),
|
|
86
|
+
"-work-dir",
|
|
87
|
+
str(shared_dir),
|
|
88
|
+
"-profile",
|
|
89
|
+
"{execution_profile}",
|
|
90
|
+
{params_to_flags}
|
|
91
|
+
],
|
|
92
|
+
env=env,
|
|
93
|
+
check=True,
|
|
94
|
+
)
|
|
95
|
+
except subprocess.CalledProcessError:
|
|
96
|
+
remote = LPath(urljoins("{remote_output_dir}", _get_execution_name(), "nextflow.log"))
|
|
97
|
+
print(f"Uploading .nextflow.log to {{remote.path}}")
|
|
98
|
+
remote.upload_from(Path("/root/.nextflow.log"))
|
|
99
|
+
raise
|
|
100
|
+
finally:
|
|
101
|
+
token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID")
|
|
102
|
+
if token is None:
|
|
103
|
+
raise RuntimeError("failed to get execution token")
|
|
104
|
+
|
|
105
|
+
headers = {{"Authorization": f"Latch-Execution-Token {{token}}"}}
|
|
106
|
+
resp = requests.post(
|
|
107
|
+
"http://nf-dispatcher-service.flyte.svc.cluster.local/finalize",
|
|
108
|
+
headers=headers,
|
|
109
|
+
json={{
|
|
110
|
+
"pvc_name": pvc_name,
|
|
111
|
+
}}
|
|
112
|
+
)
|
|
113
|
+
if resp.status_code != 200:
|
|
114
|
+
print("Failed to finalize workflow:", resp.status_code)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@workflow(metadata._nextflow_metadata)
|
|
119
|
+
def {workflow_func_name}({param_signature_with_defaults}) -> None:
|
|
120
|
+
pvc_name: str = initialize()
|
|
121
|
+
nextflow_runtime(pvc_name=pvc_name, {param_args})
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _get_flags_for_dataclass(name: str, val: Any) -> List[str]:
|
|
127
|
+
assert is_dataclass(val)
|
|
128
|
+
|
|
129
|
+
flags = []
|
|
130
|
+
for f in fields(val):
|
|
131
|
+
flags.extend(get_flag(f"{name}.{f.name}", getattr(val, f.name)))
|
|
132
|
+
|
|
133
|
+
return flags
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_flag(name: str, val: Any) -> List[str]:
|
|
137
|
+
flag = f"--{name}"
|
|
138
|
+
|
|
139
|
+
if isinstance(val, bool):
|
|
140
|
+
return [flag] if val else []
|
|
141
|
+
elif isinstance(val, LatchFile) or isinstance(val, LatchDir):
|
|
142
|
+
if val.remote_path is not None:
|
|
143
|
+
return [flag, val.remote_path]
|
|
144
|
+
|
|
145
|
+
return [flag, str(val.path)]
|
|
146
|
+
elif is_dataclass(val):
|
|
147
|
+
return _get_flags_for_dataclass(name, val)
|
|
148
|
+
elif isinstance(val, Enum):
|
|
149
|
+
return [flag, getattr(val, "value")]
|
|
150
|
+
else:
|
|
151
|
+
return [flag, str(val)]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def generate_nextflow_workflow(
|
|
155
|
+
pkg_root: Path,
|
|
156
|
+
workflow_name: str,
|
|
157
|
+
nf_script: Path,
|
|
158
|
+
*,
|
|
159
|
+
execution_profile: Optional[str] = None,
|
|
160
|
+
):
|
|
161
|
+
assert metadata._nextflow_metadata is not None
|
|
162
|
+
|
|
163
|
+
wf_name = metadata._nextflow_metadata.name
|
|
164
|
+
parameters = metadata._nextflow_metadata.parameters
|
|
165
|
+
resources = metadata._nextflow_metadata.runtime_resources
|
|
166
|
+
|
|
167
|
+
flags = []
|
|
168
|
+
for param_name, param in parameters.items():
|
|
169
|
+
flags.append(reindent(f"*get_flag({repr(param_name)}, {param_name})", 3))
|
|
170
|
+
|
|
171
|
+
defaults: List[Tuple[str, str]] = []
|
|
172
|
+
no_defaults: List[str] = []
|
|
173
|
+
preambles: List[str] = []
|
|
174
|
+
for param_name, param in parameters.items():
|
|
175
|
+
sig = f"{param_name}: {type_repr(param.type)}"
|
|
176
|
+
if param.default is not None:
|
|
177
|
+
if isinstance(param.default, Enum):
|
|
178
|
+
defaults.append((sig, param.default))
|
|
179
|
+
else:
|
|
180
|
+
defaults.append((sig, repr(param.default)))
|
|
181
|
+
else:
|
|
182
|
+
no_defaults.append(sig)
|
|
183
|
+
|
|
184
|
+
preamble = get_preamble(param.type)
|
|
185
|
+
if len(preamble) > 0:
|
|
186
|
+
preambles.append(preamble)
|
|
187
|
+
|
|
188
|
+
if metadata._nextflow_metadata.output_dir is None:
|
|
189
|
+
output_dir = "latch:///nextflow_outputs"
|
|
190
|
+
else:
|
|
191
|
+
output_dir = metadata._nextflow_metadata.output_dir._raw_remote_path
|
|
192
|
+
output_dir = urljoins(output_dir, wf_name)
|
|
193
|
+
|
|
194
|
+
entrypoint = template.format(
|
|
195
|
+
workflow_func_name=identifier_from_str(workflow_name),
|
|
196
|
+
nf_script=nf_script.resolve().relative_to(pkg_root.resolve()),
|
|
197
|
+
param_signature_with_defaults=", ".join(
|
|
198
|
+
no_defaults + [f"{name}={val}" for name, val in defaults]
|
|
199
|
+
),
|
|
200
|
+
param_signature=", ".join(no_defaults + [name for name, _ in defaults]),
|
|
201
|
+
param_args=", ".join(
|
|
202
|
+
f"{param_name}={param_name}" for param_name in parameters.keys()
|
|
203
|
+
),
|
|
204
|
+
params_to_flags=",\n".join(flags),
|
|
205
|
+
execution_profile=(
|
|
206
|
+
execution_profile if execution_profile is not None else "standard"
|
|
207
|
+
),
|
|
208
|
+
preambles="\n\n".join(preambles),
|
|
209
|
+
cpu=resources.cpus,
|
|
210
|
+
memory=resources.memory,
|
|
211
|
+
storage_gib=resources.storage_gib,
|
|
212
|
+
remote_output_dir=output_dir,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
entrypoint_path = pkg_root / "wf" / "entrypoint.py"
|
|
216
|
+
entrypoint_path.parent.mkdir(exist_ok=True)
|
|
217
|
+
entrypoint_path.write_text(entrypoint)
|
|
218
|
+
|
|
219
|
+
click.secho(
|
|
220
|
+
f"Nextflow workflow written to {pkg_root / 'wf' / 'entrypoint.py'}",
|
|
221
|
+
fg="green",
|
|
222
|
+
)
|
{latch-2.41.3.dev0 → latch-2.41.3.dev2}/latch_cli/services/init/__pycache__/init.cpython-310.pyc
RENAMED
|
Binary file
|
|
@@ -192,7 +192,7 @@ def parse_value(t: Type, v: JSONValue):
|
|
|
192
192
|
def is_primitive_type(
|
|
193
193
|
typ: Type,
|
|
194
194
|
) -> TypeGuard[Union[Type[None], Type[str], Type[bool], Type[int], Type[float]]]:
|
|
195
|
-
return typ in {
|
|
195
|
+
return typ in {type(None), str, bool, int, float}
|
|
196
196
|
|
|
197
197
|
|
|
198
198
|
def is_primitive_value(val: object) -> TypeGuard[Union[None, str, bool, int, float]]:
|
|
@@ -231,11 +231,12 @@ def type_repr(t: Type, *, add_namespace: bool = False) -> str:
|
|
|
231
231
|
if get_origin(t) is Annotated:
|
|
232
232
|
args = get_args(t)
|
|
233
233
|
assert len(args) > 1
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
if isinstance(args[1], FlyteAnnotation):
|
|
235
|
+
return (
|
|
236
|
+
f"typing_extensions.Annotated[{type_repr(args[0], add_namespace=add_namespace)},"
|
|
237
|
+
f" FlyteAnnotation({repr(args[1].data)})]"
|
|
238
|
+
)
|
|
239
|
+
return type_repr(args[0], add_namespace=add_namespace)
|
|
239
240
|
|
|
240
241
|
return t.__name__
|
|
241
242
|
|
|
@@ -250,6 +251,16 @@ def dataclass_repr(typ: Type) -> str:
|
|
|
250
251
|
return "\n".join(lines) + "\n\n\n"
|
|
251
252
|
|
|
252
253
|
|
|
254
|
+
def enum_repr(typ: Type) -> str:
|
|
255
|
+
assert issubclass(typ, Enum), typ
|
|
256
|
+
|
|
257
|
+
lines = [f"class {typ.__name__}(Enum):"]
|
|
258
|
+
for name, val in typ._member_map_.items():
|
|
259
|
+
lines.append(f" {name} = {repr(val.value)}")
|
|
260
|
+
|
|
261
|
+
return "\n".join(lines) + "\n\n\n"
|
|
262
|
+
|
|
263
|
+
|
|
253
264
|
def get_preamble(typ: Type) -> str:
|
|
254
265
|
if get_origin(typ) is Annotated:
|
|
255
266
|
args = get_args(typ)
|
|
@@ -262,6 +273,9 @@ def get_preamble(typ: Type) -> str:
|
|
|
262
273
|
if get_origin(typ) in {Union, list}:
|
|
263
274
|
return "".join([get_preamble(t) for t in get_args(typ)])
|
|
264
275
|
|
|
276
|
+
if issubclass(typ, Enum):
|
|
277
|
+
return enum_repr(typ)
|
|
278
|
+
|
|
265
279
|
assert is_dataclass(typ), typ
|
|
266
280
|
|
|
267
281
|
preamble = "".join([get_preamble(f.type) for f in fields(typ)])
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
latch-2.41.3.dev0/latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc
DELETED
|
Binary file
|
latch-2.41.3.dev0/latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|