latch 2.39.0.dev25__tar.gz → 2.39.0.dev26__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.dev25/latch.egg-info → latch-2.39.0.dev26}/PKG-INFO +1 -1
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/metadata.py +2 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26/latch.egg-info}/PKG-INFO +1 -1
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/docker_utils/__init__.py +3 -12
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/config/utils.py +21 -54
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/serialize.py +23 -9
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/utils.py +9 -2
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/build.py +5 -3
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/config.py +6 -2
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/serialize.py +1 -1
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/base.py +2 -2
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/operator.py +2 -2
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/process.py +2 -2
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/workflow.py +33 -12
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/setup.py +1 -1
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/LICENSE +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/MANIFEST.in +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/README.md +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/account.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/executions.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/functions/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/functions/messages.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/functions/operators.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/functions/secrets.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/download.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/manager.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/node.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/progress.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/remote_copy.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/throttle.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/upload.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/_transfer/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/path.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/ldata/type.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/project.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/record.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/table.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/types.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/upstream_types/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/upstream_types/types.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/upstream_types/values.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/registry/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/conditional.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/launch_plan.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/map_tasks.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/reference_workflow.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/tasks.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/resources/workflow.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/directory.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/file.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/glob.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/json.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/types/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/deseq2.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/mafft.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/pathway.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/rnaseq.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch/verified/trim_galore.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch.egg-info/SOURCES.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch.egg-info/dependency_links.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch.egg-info/entry_points.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch.egg-info/requires.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch.egg-info/top_level.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/auth/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/auth/csrf.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/auth/oauth2.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/auth/pkce.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/auth/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/centromere/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/centromere/ctx.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/centromere/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/click_utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/constants.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/exceptions/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/exceptions/cache.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/exceptions/errors.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/exceptions/handler.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/exceptions/traceback.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/config/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/common/config/parser.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/channel.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/dag.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/file_persistence.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/adapters.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/conditional.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/input.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/map.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/merge.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/nextflow/tasks/output.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/config.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/serialize.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/single_task_snakemake.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/extras/snakemake/workflow.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/main.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/menus.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/cp/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/cp/autocomplete.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/cp/glob.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/cp/main.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/cp/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/execute/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/execute/main.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/execute/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/get.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/get_executions.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/get_params.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/__init__.cpython-38.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/__init__.cpython-39.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/init.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/init.cpython-311.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/init.cpython-38.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/__pycache__/init.cpython-39.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/.env +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/README.md +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/common/.dockerignore +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_conda/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_conda/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_conda/conda_task.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_conda/environment.yaml +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_docker/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_docker/task.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nf_integration/Dockerfile +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nf_integration/latch_metadata/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nf_integration/latch_metadata/__pycache__/__init__.cpython-311.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nf_integration/main.nf +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nf_integration/workflow.nf +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nfcore/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_nfcore/task.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_r/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_r/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_r/environment.R +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_r/r_task.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/Snakefile +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/config.yaml +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/example_snakemake/version +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/init.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/template/LICENSE +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/template/README.md +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/template/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/template/__pycache__/__init__.cpython-310.pyc +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/init/template/task.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/launch.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/local_dev.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/local_dev_old.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/login.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/ls.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/mkdir.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/move.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/preview.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/register/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/register/constants.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/register/register.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/register/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/rm.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/stop_pod.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/sync.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/test_data/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/test_data/ls.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/test_data/remove.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/test_data/upload.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/test_data/utils.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/services/workspace.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/tinyrequests.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/tui/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/utils/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/utils/path.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/utils/workflow.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/latch_cli/workflow_config.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/pyproject.toml +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/setup.cfg +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/tests/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/tests/cp/__init__.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/tests/fixtures.py +0 -0
- {latch-2.39.0.dev25 → latch-2.39.0.dev26}/tests/test_ls.py +0 -0
|
@@ -696,6 +696,8 @@ class NextflowMetadata(LatchMetadata):
|
|
|
696
696
|
def __post_init__(self):
|
|
697
697
|
if self.name is None:
|
|
698
698
|
self.name = f"nf_{identifier_suffix_from_str(self.display_name.lower())}"
|
|
699
|
+
else:
|
|
700
|
+
self.name = identifier_suffix_from_str(self.name)
|
|
699
701
|
|
|
700
702
|
if self.output_directory is None:
|
|
701
703
|
self.output_directory = LatchDir("latch:///Nextflow Outputs/")
|
|
@@ -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
|
|
@@ -352,18 +353,8 @@ def generate_dockerfile(
|
|
|
352
353
|
with (pkg_root / latch_constants.pkg_config).open("r") as f:
|
|
353
354
|
config = LatchWorkflowConfig(**json.load(f))
|
|
354
355
|
|
|
355
|
-
click.echo(
|
|
356
|
-
|
|
357
|
-
click.style("Base image:", fg="bright_blue"),
|
|
358
|
-
config.base_image,
|
|
359
|
-
])
|
|
360
|
-
)
|
|
361
|
-
click.echo(
|
|
362
|
-
" ".join([
|
|
363
|
-
click.style("Latch SDK version:", fg="bright_blue"),
|
|
364
|
-
config.latch_version,
|
|
365
|
-
])
|
|
366
|
-
)
|
|
356
|
+
click.echo(" ".join([color("Base image:"), config.base_image]))
|
|
357
|
+
click.echo(" ".join([color("Latch SDK version:"), config.latch_version]))
|
|
367
358
|
click.echo()
|
|
368
359
|
|
|
369
360
|
with outfile.open("w") as f:
|
|
@@ -188,81 +188,48 @@ def parse_value(t: Type, v: JSONValue):
|
|
|
188
188
|
return t(**ret), t(**defaults)
|
|
189
189
|
|
|
190
190
|
|
|
191
|
-
def is_primitive_type(
|
|
192
|
-
typ: Type,
|
|
193
|
-
) -> TypeGuard[Union[Type[None], Type[str], Type[bool], Type[int], Type[float]]]:
|
|
194
|
-
return typ in {Type[None], str, bool, int, float}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def is_primitive_value(val: object) -> TypeGuard[Union[None, str, bool, int, float]]:
|
|
198
|
-
return is_primitive_type(type(val))
|
|
199
|
-
|
|
200
|
-
|
|
201
191
|
def is_list_type(typ: Type) -> TypeGuard[Type[List]]:
|
|
202
192
|
return get_origin(typ) is list
|
|
203
193
|
|
|
204
194
|
|
|
205
|
-
def
|
|
206
|
-
if is_primitive_type(t) or t in {LatchFile, LatchDir}:
|
|
207
|
-
return t.__name__
|
|
208
|
-
|
|
209
|
-
if get_origin(t) is None:
|
|
210
|
-
return f"{'latch_metadata.' if add_namespace else ''}{t.__name__}"
|
|
211
|
-
|
|
212
|
-
if get_origin(t) is list:
|
|
213
|
-
args = get_args(t)
|
|
214
|
-
if len(args) > 0:
|
|
215
|
-
return f"typing.List[{type_repr(args[0], add_namespace=add_namespace)}]"
|
|
216
|
-
|
|
217
|
-
return "typing.List"
|
|
218
|
-
|
|
219
|
-
if get_origin(t) is Union:
|
|
220
|
-
args = get_args(t)
|
|
221
|
-
|
|
222
|
-
if len(args) != 2 or args[1] is not type(None):
|
|
223
|
-
raise ValueError(
|
|
224
|
-
"Union types other than Optional are not yet supported in Snakemake"
|
|
225
|
-
" workflows."
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
return f"typing.Optional[{type_repr(args[0], add_namespace=add_namespace)}]"
|
|
229
|
-
|
|
230
|
-
if get_origin(t) is Annotated:
|
|
231
|
-
args = get_args(t)
|
|
232
|
-
assert len(args) > 1
|
|
233
|
-
assert isinstance(args[1], FlyteAnnotation)
|
|
234
|
-
return (
|
|
235
|
-
f"typing_extensions.Annotated[{type_repr(args[0], add_namespace=add_namespace)},"
|
|
236
|
-
f" FlyteAnnotation({repr(args[1].data)})]"
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
return t.__name__
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def dataclass_repr(typ: Type) -> str:
|
|
195
|
+
def dataclass_repr(typ: Type, *, make_optionals: bool = False) -> str:
|
|
243
196
|
assert is_dataclass(typ)
|
|
244
197
|
|
|
245
198
|
lines = ["@dataclass", f"class {typ.__name__}:"]
|
|
246
199
|
for f in fields(typ):
|
|
247
|
-
|
|
200
|
+
t = f.type
|
|
201
|
+
if make_optionals:
|
|
202
|
+
t = Optional[t]
|
|
203
|
+
|
|
204
|
+
lines.append(f" {f.name}: {type_repr(t)}")
|
|
248
205
|
|
|
249
206
|
return "\n".join(lines) + "\n\n\n"
|
|
250
207
|
|
|
251
208
|
|
|
252
|
-
def get_preamble(typ: Type) -> str:
|
|
209
|
+
def get_preamble(typ: Type, *, make_optionals: bool = False) -> str:
|
|
253
210
|
if get_origin(typ) is Annotated:
|
|
254
211
|
args = get_args(typ)
|
|
255
212
|
assert len(args) > 0
|
|
256
|
-
return get_preamble(args[0])
|
|
213
|
+
return get_preamble(args[0], make_optionals=make_optionals)
|
|
257
214
|
|
|
258
215
|
if is_primitive_type(typ) or typ in {LatchFile, LatchDir}:
|
|
259
216
|
return ""
|
|
260
217
|
|
|
261
218
|
if get_origin(typ) in {Union, list}:
|
|
262
|
-
return "".join(
|
|
219
|
+
return "".join(
|
|
220
|
+
[get_preamble(t, make_optionals=make_optionals) for t in get_args(typ)]
|
|
221
|
+
)
|
|
263
222
|
|
|
264
223
|
assert is_dataclass(typ), typ
|
|
265
224
|
|
|
266
|
-
|
|
225
|
+
preambles = []
|
|
226
|
+
for f in fields(typ):
|
|
227
|
+
t = f.type
|
|
228
|
+
if make_optionals:
|
|
229
|
+
t = Optional[f.type]
|
|
230
|
+
|
|
231
|
+
preambles.append(get_preamble(t, make_optionals=make_optionals))
|
|
232
|
+
|
|
233
|
+
preamble = "".join(preambles)
|
|
267
234
|
|
|
268
|
-
return "".join([preamble, dataclass_repr(typ)])
|
|
235
|
+
return "".join([preamble, dataclass_repr(typ, make_optionals=make_optionals)])
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from dataclasses import fields
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Any, Dict, Optional, Type, TypeVar, Union, get_args
|
|
4
|
+
from typing import Any, Dict, List, Optional, Type, TypeVar, Union, get_args
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
from flyteidl.admin.launch_plan_pb2 import LaunchPlan as _idl_admin_LaunchPlan
|
|
@@ -292,7 +292,7 @@ RegistrableEntity = Union[
|
|
|
292
292
|
]
|
|
293
293
|
|
|
294
294
|
|
|
295
|
-
def should_register_with_admin(entity:
|
|
295
|
+
def should_register_with_admin(entity: FlyteSerializableModel) -> bool:
|
|
296
296
|
return isinstance(entity, get_args(RegistrableEntity))
|
|
297
297
|
|
|
298
298
|
|
|
@@ -327,15 +327,29 @@ def serialize(
|
|
|
327
327
|
)
|
|
328
328
|
admin_lp = get_serializable_launch_plan(lp, settings, registrable_entity_cache)
|
|
329
329
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
330
|
+
click.secho(
|
|
331
|
+
"\nBuilding flyte models: \x1b[?25l",
|
|
332
|
+
nl=False,
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
registrable_entities = []
|
|
336
|
+
i = 0
|
|
337
|
+
for x in list(registrable_entity_cache.values()) + [admin_lp]:
|
|
338
|
+
progress_str = f"{i + 1}/{len(registrable_entity_cache) + 1}"
|
|
339
|
+
|
|
340
|
+
click.echo("\x1b[0K", nl=False)
|
|
341
|
+
click.secho(progress_str, dim=True, italic=True, nl=False)
|
|
342
|
+
click.echo(f"\x1b[{len(progress_str)}D", nl=False)
|
|
343
|
+
|
|
344
|
+
i += 1
|
|
345
|
+
|
|
346
|
+
if not should_register_with_admin(x):
|
|
347
|
+
continue
|
|
348
|
+
|
|
349
|
+
registrable_entities.append(x.to_flyte_idl())
|
|
337
350
|
|
|
338
351
|
click.secho("\nSerializing workflow entities", bold=True)
|
|
352
|
+
|
|
339
353
|
persist_registrable_entities(registrable_entities, output_dir)
|
|
340
354
|
|
|
341
355
|
if not write_spec:
|
|
@@ -3,7 +3,7 @@ from typing import Type, Union, get_args, get_origin
|
|
|
3
3
|
|
|
4
4
|
from typing_extensions import Annotated, TypeGuard
|
|
5
5
|
|
|
6
|
-
from latch.types.directory import LatchDir
|
|
6
|
+
from latch.types.directory import LatchDir, LatchOutputDir
|
|
7
7
|
from latch.types.file import LatchFile
|
|
8
8
|
|
|
9
9
|
|
|
@@ -17,7 +17,7 @@ def reindent(x: str, level: int) -> str:
|
|
|
17
17
|
def is_primitive_type(
|
|
18
18
|
typ: Type,
|
|
19
19
|
) -> TypeGuard[Union[Type[None], Type[str], Type[bool], Type[int], Type[float]]]:
|
|
20
|
-
return typ in {
|
|
20
|
+
return typ in {type(None), str, bool, int, float}
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def is_primitive_value(val: object) -> TypeGuard[Union[None, str, bool, int, float]]:
|
|
@@ -34,6 +34,13 @@ def is_blob_type(typ: Type) -> TypeGuard[Union[Type[LatchFile], Type[LatchDir]]]
|
|
|
34
34
|
return typ in {LatchFile, LatchDir}
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
def is_downloadable_blob_type(typ: Type):
|
|
38
|
+
if not is_blob_type(typ):
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
return typ is not LatchOutputDir
|
|
42
|
+
|
|
43
|
+
|
|
37
44
|
def type_repr(t: Type, *, add_namespace: bool = False) -> str:
|
|
38
45
|
if getattr(t, "__name__", None) == "NoneType":
|
|
39
46
|
return "None"
|
|
@@ -19,6 +19,7 @@ from flytekit.models import literals as literals_models
|
|
|
19
19
|
from latch_sdk_gql.execute import execute
|
|
20
20
|
|
|
21
21
|
from latch_cli import tinyrequests
|
|
22
|
+
from latch_cli.extras.common.config.utils import get_preamble
|
|
22
23
|
from latch_cli.extras.nextflow.tasks.base import NextflowBaseTask, NFTaskType
|
|
23
24
|
|
|
24
25
|
from ...click_utils import italic
|
|
@@ -102,7 +103,7 @@ def build_from_nextflow_dag(
|
|
|
102
103
|
|
|
103
104
|
output_name = "res"
|
|
104
105
|
if len(dep.outputNames) > 0:
|
|
105
|
-
idx = int(edge.label)
|
|
106
|
+
idx = int(edge.label or "0")
|
|
106
107
|
input_name = f"{input_name}_{idx}"
|
|
107
108
|
output_name = dep.outputNames[idx]
|
|
108
109
|
|
|
@@ -128,8 +129,6 @@ def build_from_nextflow_dag(
|
|
|
128
129
|
upstream_nodes.append(node_map[dep.id])
|
|
129
130
|
|
|
130
131
|
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()}
|
|
133
132
|
|
|
134
133
|
if vertex.type == VertexType.Process:
|
|
135
134
|
pre_adapter_task = NextflowProcessPreAdapterTask(
|
|
@@ -513,6 +512,9 @@ def generate_nf_entrypoint(
|
|
|
513
512
|
0,
|
|
514
513
|
)
|
|
515
514
|
|
|
515
|
+
for t in wf.python_interface.inputs.values():
|
|
516
|
+
preamble += get_preamble(t, make_optionals=True)
|
|
517
|
+
|
|
516
518
|
nf_script_path_in_container = nf_script.resolve().relative_to(pkg_root.resolve())
|
|
517
519
|
|
|
518
520
|
entrypoint_code = [preamble]
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
import subprocess
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import List
|
|
5
|
+
from typing import List, Optional
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
|
|
@@ -37,6 +37,7 @@ def generate_nf_metadata(
|
|
|
37
37
|
skip_confirmation: bool = False,
|
|
38
38
|
generate_defaults: bool = False,
|
|
39
39
|
infer_files: bool = False,
|
|
40
|
+
make_optionals: bool = True,
|
|
40
41
|
):
|
|
41
42
|
if not config_path.is_dir():
|
|
42
43
|
click.secho(
|
|
@@ -103,7 +104,10 @@ def generate_nf_metadata(
|
|
|
103
104
|
params: List[str] = []
|
|
104
105
|
|
|
105
106
|
for k, (typ, (val, default)) in parsed.items():
|
|
106
|
-
|
|
107
|
+
if make_optionals:
|
|
108
|
+
typ = Optional[typ]
|
|
109
|
+
|
|
110
|
+
preambles.append(get_preamble(typ, make_optionals=make_optionals))
|
|
107
111
|
|
|
108
112
|
param_str = reindent(
|
|
109
113
|
f"""\
|
|
@@ -47,8 +47,8 @@ class NextflowBaseTask(PythonAutoContainerTask[Pod]):
|
|
|
47
47
|
wf: NextflowWorkflow,
|
|
48
48
|
nf_task_type: NFTaskType,
|
|
49
49
|
# todo(ayush): expose / infer these somehow
|
|
50
|
-
cpu:
|
|
51
|
-
memory:
|
|
50
|
+
cpu: float = 0.5,
|
|
51
|
+
memory: float = 1,
|
|
52
52
|
):
|
|
53
53
|
self.id = id
|
|
54
54
|
self.wf = wf
|
|
@@ -130,7 +130,7 @@ class NextflowOperatorTask(NextflowBaseTask):
|
|
|
130
130
|
if {k} is not None:
|
|
131
131
|
{k}_p = Path({k}).resolve()
|
|
132
132
|
check_exists_and_rename({k}_p, Path("/root") / {k}_p.name)
|
|
133
|
-
wf_paths[{k}] = Path("/root") / {k}_p.name
|
|
133
|
+
wf_paths["{k}"] = Path("/root") / {k}_p.name
|
|
134
134
|
|
|
135
135
|
""",
|
|
136
136
|
2,
|
|
@@ -140,7 +140,7 @@ class NextflowOperatorTask(NextflowBaseTask):
|
|
|
140
140
|
f"""
|
|
141
141
|
if {k} is not None:
|
|
142
142
|
{k}_p = Path("/root/").resolve() # superhack
|
|
143
|
-
wf_paths[{k}] = {k}_p
|
|
143
|
+
wf_paths["{k}"] = {k}_p
|
|
144
144
|
|
|
145
145
|
""",
|
|
146
146
|
2,
|
|
@@ -136,7 +136,7 @@ class NextflowProcessTask(NextflowBaseTask):
|
|
|
136
136
|
if {k} is not None:
|
|
137
137
|
{k}_p = Path({k}).resolve()
|
|
138
138
|
check_exists_and_rename({k}_p, Path("/root") / {k}_p.name)
|
|
139
|
-
wf_paths[{k}] = Path("/root") / {k}_p.name
|
|
139
|
+
wf_paths["{k}"] = Path("/root") / {k}_p.name
|
|
140
140
|
|
|
141
141
|
""",
|
|
142
142
|
1,
|
|
@@ -146,7 +146,7 @@ class NextflowProcessTask(NextflowBaseTask):
|
|
|
146
146
|
f"""
|
|
147
147
|
if {k} is not None:
|
|
148
148
|
{k}_p = Path("/root/").resolve() # superhack
|
|
149
|
-
wf_paths[{k}] = {k}_p
|
|
149
|
+
wf_paths["{k}"] = {k}_p
|
|
150
150
|
|
|
151
151
|
""",
|
|
152
152
|
1,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from dataclasses import fields, is_dataclass
|
|
1
2
|
from pathlib import Path
|
|
2
|
-
from typing import List
|
|
3
|
+
from typing import Any, Dict, List, Tuple, Type
|
|
3
4
|
|
|
4
5
|
from flytekit.core.class_based_resolver import ClassStorageTaskResolver
|
|
5
6
|
from flytekit.core.docstring import Docstring
|
|
@@ -13,10 +14,32 @@ from flytekit.core.workflow import (
|
|
|
13
14
|
from flytekit.exceptions import scopes as exception_scopes
|
|
14
15
|
|
|
15
16
|
from latch.types import metadata
|
|
16
|
-
from
|
|
17
|
+
from latch_cli.extras.common.utils import is_blob_type, is_downloadable_blob_type
|
|
17
18
|
|
|
18
19
|
from .dag import DAG
|
|
19
20
|
|
|
21
|
+
# def _get_flattened_inputs(
|
|
22
|
+
# key: str, t: Type, val: Any, inputs: Dict[str, Tuple[Type, Any]]
|
|
23
|
+
# ):
|
|
24
|
+
# if not is_dataclass(t):
|
|
25
|
+
# inputs[key] = (t, val)
|
|
26
|
+
# return
|
|
27
|
+
|
|
28
|
+
# for f in fields(t):
|
|
29
|
+
# v = val
|
|
30
|
+
# if val is not None:
|
|
31
|
+
# v = getattr()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_flags_to_params(key: str, t: Type, flags: Dict[str, str]):
|
|
35
|
+
if is_blob_type(t):
|
|
36
|
+
flags[f"--{key}"] = f"wf_paths['wf_{key}']"
|
|
37
|
+
elif is_dataclass(t):
|
|
38
|
+
for f in fields(t):
|
|
39
|
+
_get_flags_to_params(f"{key}.{f.name}", f.type, flags)
|
|
40
|
+
else:
|
|
41
|
+
flags[f"--{key}"] = f"wf_{key}"
|
|
42
|
+
|
|
20
43
|
|
|
21
44
|
class NextflowWorkflow(WorkflowBase, ClassStorageTaskResolver):
|
|
22
45
|
def __init__(self, nf_script: Path, version: str, dag: DAG):
|
|
@@ -39,19 +62,17 @@ class NextflowWorkflow(WorkflowBase, ClassStorageTaskResolver):
|
|
|
39
62
|
docstring=docstring,
|
|
40
63
|
)
|
|
41
64
|
|
|
42
|
-
self.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
)
|
|
48
|
-
for k, v in metadata._nextflow_metadata.parameters.items()
|
|
49
|
-
}
|
|
65
|
+
self.flattened_inputs = {}
|
|
66
|
+
|
|
67
|
+
self.flags_to_params = {}
|
|
68
|
+
for k, v in metadata._nextflow_metadata.parameters.items():
|
|
69
|
+
assert v.type is not None
|
|
70
|
+
_get_flags_to_params(k, v.type, self.flags_to_params)
|
|
50
71
|
|
|
51
72
|
self.downloadable_params = {
|
|
52
|
-
k
|
|
73
|
+
k
|
|
53
74
|
for k, v in metadata._nextflow_metadata.parameters.items()
|
|
54
|
-
if
|
|
75
|
+
if is_downloadable_blob_type(v.type)
|
|
55
76
|
}
|
|
56
77
|
|
|
57
78
|
name = metadata._nextflow_metadata.name
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|