latch 2.45.2.dev2__tar.gz → 2.45.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- latch-2.45.3/PKG-INFO +13 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/type.py +1 -7
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/tasks.py +0 -43
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/directory.py +0 -2
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/file.py +0 -2
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/metadata.py +20 -176
- latch-2.45.3/latch/utils.py +179 -0
- latch-2.45.3/latch.egg-info/PKG-INFO +13 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch.egg-info/SOURCES.txt +2 -6
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/centromere/ctx.py +8 -45
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/docker_utils/__init__.py +1 -16
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/main.py +2 -46
- latch-2.45.3/latch_cli/services/init/__pycache__/__init__.cpython-311.pyc +0 -0
- latch-2.45.3/latch_cli/services/init/__pycache__/init.cpython-311.pyc +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/register/register.py +24 -66
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/config/utils.py +6 -20
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/utils/__init__.py +0 -1
- {latch-2.45.2.dev2 → latch-2.45.3}/setup.py +1 -1
- latch-2.45.2.dev2/PKG-INFO +0 -39
- latch-2.45.2.dev2/latch/utils.py +0 -122
- latch-2.45.2.dev2/latch.egg-info/PKG-INFO +0 -39
- latch-2.45.2.dev2/latch_cli/nextflow/dependencies.py +0 -81
- latch-2.45.2.dev2/latch_cli/nextflow/utils.py +0 -27
- latch-2.45.2.dev2/latch_cli/nextflow/workflow.py +0 -255
- latch-2.45.2.dev2/latch_cli/services/init/__pycache__/__init__.cpython-310.pyc +0 -0
- latch-2.45.2.dev2/latch_cli/services/init/__pycache__/init.cpython-310.pyc +0 -0
- latch-2.45.2.dev2/tests/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/LICENSE +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/MANIFEST.in +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/README.md +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/account.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/executions.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/functions/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/functions/messages.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/functions/operators.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/functions/secrets.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/download.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/manager.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/node.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/progress.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/remote_copy.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/throttle.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/upload.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/_transfer/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/ldata/path.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/project.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/record.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/table.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/types.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/upstream_types/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/upstream_types/types.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/upstream_types/values.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/registry/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/conditional.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/dynamic.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/launch_plan.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/map_tasks.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/reference_workflow.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/resources/workflow.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/glob.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/json.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/types/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/deseq2.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/mafft.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/pathway.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/rnaseq.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch/verified/trim_galore.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch.egg-info/dependency_links.txt +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch.egg-info/entry_points.txt +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch.egg-info/requires.txt +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch.egg-info/top_level.txt +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/auth/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/auth/csrf.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/auth/oauth2.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/auth/pkce.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/auth/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/centromere/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/centromere/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/click_utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/constants.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/exceptions/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/exceptions/cache.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/exceptions/errors.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/exceptions/handler.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/exceptions/traceback.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/menus.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/__init__.py +0 -0
- {latch-2.45.2.dev2/latch_cli/nextflow → latch-2.45.3/latch_cli/services/cp}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/cp/autocomplete.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/cp/glob.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/cp/main.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/cp/utils.py +0 -0
- {latch-2.45.2.dev2/latch_cli/services/cp → latch-2.45.3/latch_cli/services/execute}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/execute/main.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/execute/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/get.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/get_executions.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/get_params.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/.env +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/README.md +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/common/.dockerignore +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_conda/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_conda/conda_task.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_conda/environment.yaml +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_docker/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_docker/task.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_nfcore/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_nfcore/task.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_r/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_r/environment.R +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_r/r_task.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/Snakefile +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/config.yaml +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/example_snakemake/version +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/init.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/template/LICENSE +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/template/README.md +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/template/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/init/template/task.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/launch.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/local_dev.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/local_dev_old.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/login.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/ls.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/mkdir.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/move.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/preview.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/register/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/register/constants.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/register/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/rm.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/stop_pod.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/sync.py +0 -0
- {latch-2.45.2.dev2/latch_cli/services/execute → latch-2.45.3/latch_cli/services/test_data}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/test_data/ls.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/test_data/remove.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/test_data/upload.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/test_data/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/services/workspace.py +0 -0
- {latch-2.45.2.dev2/latch_cli/services/test_data → latch-2.45.3/latch_cli/snakemake}/__init__.py +0 -0
- {latch-2.45.2.dev2/latch_cli/snakemake → latch-2.45.3/latch_cli/snakemake/config}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/config/parser.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/serialize.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/serialize_utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/single_task_snakemake.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/utils.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/snakemake/workflow.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/tinyrequests.py +0 -0
- {latch-2.45.2.dev2/latch_cli/snakemake/config → latch-2.45.3/latch_cli/tui}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/utils/path.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/latch_cli/workflow_config.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/pyproject.toml +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/setup.cfg +0 -0
- {latch-2.45.2.dev2/latch_cli/tui → latch-2.45.3/tests}/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/tests/cp/__init__.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/tests/fixtures.py +0 -0
- {latch-2.45.2.dev2 → latch-2.45.3}/tests/test_ls.py +0 -0
latch-2.45.3/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: latch
|
|
3
|
+
Version: 2.45.3
|
|
4
|
+
Summary: The Latch SDK
|
|
5
|
+
Author-email: kenny@latch.bio
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Requires-Python: >=3.8,<3.12
|
|
11
|
+
Provides-Extra: snakemake
|
|
12
|
+
Provides-Extra: pandas
|
|
13
|
+
License-File: LICENSE
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
class LatchPathError(RuntimeError):
|
|
6
|
-
def __init__(
|
|
7
|
-
self,
|
|
8
|
-
message: str,
|
|
9
|
-
remote_path: Optional[str] = None,
|
|
10
|
-
acc_id: Optional[str] = None,
|
|
11
|
-
):
|
|
5
|
+
def __init__(self, message: str, remote_path: str = None, acc_id: str = None):
|
|
12
6
|
super().__init__(message)
|
|
13
7
|
self.message = message
|
|
14
8
|
self.remote_path = remote_path
|
|
@@ -34,12 +34,9 @@ from flytekit import task
|
|
|
34
34
|
from flytekitplugins.pod import Pod
|
|
35
35
|
from kubernetes.client.models import (
|
|
36
36
|
V1Container,
|
|
37
|
-
V1PersistentVolumeClaimVolumeSource,
|
|
38
37
|
V1PodSpec,
|
|
39
38
|
V1ResourceRequirements,
|
|
40
39
|
V1Toleration,
|
|
41
|
-
V1Volume,
|
|
42
|
-
V1VolumeMount,
|
|
43
40
|
)
|
|
44
41
|
|
|
45
42
|
from latch_cli.constants import Units
|
|
@@ -477,43 +474,3 @@ def custom_task(
|
|
|
477
474
|
return functools.partial(
|
|
478
475
|
task, task_config=_custom_task_config(cpu, memory, storage_gib), timeout=timeout
|
|
479
476
|
)
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
def nextflow_runtime_task(cpu: int, memory: int):
|
|
483
|
-
primary_container = V1Container(name="primary")
|
|
484
|
-
resources = V1ResourceRequirements(
|
|
485
|
-
requests={
|
|
486
|
-
"cpu": str(cpu),
|
|
487
|
-
"memory": f"{memory}Gi",
|
|
488
|
-
"ephemeral-storage": "20Gi",
|
|
489
|
-
},
|
|
490
|
-
limits={"cpu": str(cpu), "memory": f"{memory}Gi", "ephemeral-storage": "20Gi"},
|
|
491
|
-
)
|
|
492
|
-
primary_container.resources = resources
|
|
493
|
-
volume_mounts = [V1VolumeMount(mount_path="/nf-workdir", name="nextflow-workdir")]
|
|
494
|
-
primary_container.volume_mounts = volume_mounts
|
|
495
|
-
|
|
496
|
-
task_config = Pod(
|
|
497
|
-
annotations={
|
|
498
|
-
"io.kubernetes.cri-o.userns-mode": (
|
|
499
|
-
"private:uidmapping=0:1048576:65536;gidmapping=0:1048576:65536"
|
|
500
|
-
)
|
|
501
|
-
},
|
|
502
|
-
pod_spec=V1PodSpec(
|
|
503
|
-
runtime_class_name="sysbox-runc",
|
|
504
|
-
automount_service_account_token=True,
|
|
505
|
-
containers=[primary_container],
|
|
506
|
-
volumes=[
|
|
507
|
-
V1Volume(
|
|
508
|
-
name="nextflow-workdir",
|
|
509
|
-
persistent_volume_claim=V1PersistentVolumeClaimVolumeSource(
|
|
510
|
-
# this value will be injected by flytepropeller
|
|
511
|
-
claim_name="nextflow-pvc-placeholder"
|
|
512
|
-
),
|
|
513
|
-
)
|
|
514
|
-
],
|
|
515
|
-
),
|
|
516
|
-
primary_container_name="primary",
|
|
517
|
-
)
|
|
518
|
-
|
|
519
|
-
return functools.partial(task, task_config=task_config)
|
|
@@ -114,10 +114,8 @@ 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 = str(path)
|
|
118
117
|
self._remote_directory = self.path
|
|
119
118
|
else:
|
|
120
|
-
self._raw_remote_path = str(remote_path)
|
|
121
119
|
self._remote_directory = None if remote_path is None else str(remote_path)
|
|
122
120
|
|
|
123
121
|
if kwargs.get("downloader") is not None:
|
|
@@ -77,10 +77,8 @@ class LatchFile(FlyteFile):
|
|
|
77
77
|
self._path_generated = False
|
|
78
78
|
|
|
79
79
|
if is_valid_url(self.path) and remote_path is None:
|
|
80
|
-
self._raw_remote_path = str(path)
|
|
81
80
|
self._remote_path = str(path)
|
|
82
81
|
else:
|
|
83
|
-
self._raw_remote_path = str(remote_path)
|
|
84
82
|
self._remote_path = None if remote_path is None else str(remote_path)
|
|
85
83
|
|
|
86
84
|
if kwargs.get("downloader") is not None:
|
|
@@ -1,32 +1,13 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import functools
|
|
3
1
|
import re
|
|
4
|
-
from dataclasses import Field, asdict, dataclass, field
|
|
2
|
+
from dataclasses import Field, asdict, dataclass, field
|
|
5
3
|
from enum import Enum
|
|
6
4
|
from pathlib import Path
|
|
7
|
-
from textwrap import
|
|
8
|
-
from typing import
|
|
9
|
-
Any,
|
|
10
|
-
Callable,
|
|
11
|
-
ClassVar,
|
|
12
|
-
Collection,
|
|
13
|
-
Dict,
|
|
14
|
-
Generic,
|
|
15
|
-
List,
|
|
16
|
-
Literal,
|
|
17
|
-
Optional,
|
|
18
|
-
Protocol,
|
|
19
|
-
Tuple,
|
|
20
|
-
Type,
|
|
21
|
-
TypeVar,
|
|
22
|
-
Union,
|
|
23
|
-
get_args,
|
|
24
|
-
get_origin,
|
|
25
|
-
)
|
|
5
|
+
from textwrap import indent
|
|
6
|
+
from typing import Any, ClassVar, Dict, List, Optional, Protocol, Tuple, Type, Union
|
|
26
7
|
|
|
27
8
|
import click
|
|
28
9
|
import yaml
|
|
29
|
-
from typing_extensions import
|
|
10
|
+
from typing_extensions import TypeAlias
|
|
30
11
|
|
|
31
12
|
from latch_cli.snakemake.config.utils import validate_snakemake_type
|
|
32
13
|
from latch_cli.utils import identifier_suffix_from_str
|
|
@@ -35,6 +16,7 @@ from .directory import LatchDir
|
|
|
35
16
|
from .file import LatchFile
|
|
36
17
|
|
|
37
18
|
|
|
19
|
+
@dataclass
|
|
38
20
|
class LatchRule:
|
|
39
21
|
"""Class describing a rule that a parameter input must follow"""
|
|
40
22
|
|
|
@@ -406,33 +388,31 @@ class _IsDataclass(Protocol):
|
|
|
406
388
|
|
|
407
389
|
|
|
408
390
|
ParameterType: TypeAlias = Union[
|
|
409
|
-
None,
|
|
410
|
-
int,
|
|
411
|
-
float,
|
|
412
|
-
str,
|
|
413
|
-
bool,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
391
|
+
Type[None],
|
|
392
|
+
Type[int],
|
|
393
|
+
Type[float],
|
|
394
|
+
Type[str],
|
|
395
|
+
Type[bool],
|
|
396
|
+
Type[Enum],
|
|
397
|
+
Type[_IsDataclass],
|
|
398
|
+
Type[List["ParameterType"]],
|
|
399
|
+
Type[LatchFile],
|
|
400
|
+
Type[LatchDir],
|
|
419
401
|
]
|
|
420
402
|
|
|
421
403
|
|
|
422
|
-
T = TypeVar("T", bound=ParameterType)
|
|
423
|
-
|
|
424
|
-
|
|
425
404
|
@dataclass
|
|
426
|
-
class SnakemakeParameter(
|
|
427
|
-
type: Optional[
|
|
405
|
+
class SnakemakeParameter(LatchParameter):
|
|
406
|
+
type: Optional[ParameterType] = None
|
|
428
407
|
"""
|
|
429
408
|
The python type of the parameter.
|
|
430
409
|
"""
|
|
431
|
-
|
|
410
|
+
# todo(ayush): needs to be typed properly
|
|
411
|
+
default: Optional[Any] = None
|
|
432
412
|
|
|
433
413
|
|
|
434
414
|
@dataclass
|
|
435
|
-
class SnakemakeFileParameter(SnakemakeParameter
|
|
415
|
+
class SnakemakeFileParameter(SnakemakeParameter):
|
|
436
416
|
"""
|
|
437
417
|
Deprecated: use `file_metadata` keyword in `SnakemakeMetadata` instead
|
|
438
418
|
"""
|
|
@@ -476,108 +456,6 @@ class SnakemakeFileMetadata:
|
|
|
476
456
|
"""
|
|
477
457
|
|
|
478
458
|
|
|
479
|
-
@dataclass
|
|
480
|
-
class NextflowParameter(Generic[T], LatchParameter):
|
|
481
|
-
type: Optional[Type[T]] = None
|
|
482
|
-
"""
|
|
483
|
-
The python type of the parameter.
|
|
484
|
-
"""
|
|
485
|
-
default: Optional[T] = None
|
|
486
|
-
"""
|
|
487
|
-
Default value of the parameter
|
|
488
|
-
"""
|
|
489
|
-
|
|
490
|
-
samplesheet_type: Literal["csv", "tsv", None] = None
|
|
491
|
-
"""
|
|
492
|
-
The type of samplesheet to construct from the input parameter.
|
|
493
|
-
|
|
494
|
-
Only used if the provided parameter is a samplesheet (samplesheet=True)
|
|
495
|
-
"""
|
|
496
|
-
samplesheet_constructor: Optional[Callable[[T], Path]] = None
|
|
497
|
-
"""
|
|
498
|
-
A custom samplesheet constructor.
|
|
499
|
-
|
|
500
|
-
Should return the path of the constructed samplesheet. If samplesheet_type is also specified, this takes precedence.
|
|
501
|
-
Only used if the provided parameter is a samplesheet (samplesheet=True)
|
|
502
|
-
"""
|
|
503
|
-
|
|
504
|
-
def __post_init__(self):
|
|
505
|
-
if not self.samplesheet or self.samplesheet_constructor is not None:
|
|
506
|
-
return
|
|
507
|
-
|
|
508
|
-
t = self.type
|
|
509
|
-
if get_origin(t) is not list or not is_dataclass(get_args(t)[0]):
|
|
510
|
-
click.secho(
|
|
511
|
-
dedent("""\
|
|
512
|
-
Samplesheets must be a list of dataclasses.
|
|
513
|
-
"""),
|
|
514
|
-
fg="red",
|
|
515
|
-
)
|
|
516
|
-
raise click.exceptions.Exit(1)
|
|
517
|
-
|
|
518
|
-
if self.samplesheet_type is not None:
|
|
519
|
-
delim = "," if self.samplesheet_type == "csv" else "\t"
|
|
520
|
-
self.samplesheet_constructor = functools.partial(
|
|
521
|
-
_samplesheet_constructor, t=get_args(self.type)[0], delim=delim
|
|
522
|
-
)
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
click.secho(
|
|
526
|
-
dedent("""\
|
|
527
|
-
A Samplesheet constructor is required for a samplesheet parameter. Please either provide a value for
|
|
528
|
-
`samplesheet_type` or provide a custom callable to the `samplesheet_constructor` argument.
|
|
529
|
-
"""),
|
|
530
|
-
fg="red",
|
|
531
|
-
)
|
|
532
|
-
raise click.exceptions.Exit(1)
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
DC = TypeVar("DC", bound=_IsDataclass)
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
def _samplesheet_repr(v: Any) -> str:
|
|
539
|
-
if v is None:
|
|
540
|
-
return ""
|
|
541
|
-
if isinstance(v, LatchFile) or isinstance(v, LatchDir):
|
|
542
|
-
return v.remote_path
|
|
543
|
-
if isinstance(v, Enum):
|
|
544
|
-
return getattr(v, "value")
|
|
545
|
-
|
|
546
|
-
return str(v)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
def _samplesheet_constructor(samples: List[DC], t: DC, delim: str = ",") -> Path:
|
|
550
|
-
samplesheet = Path("samplesheet.csv")
|
|
551
|
-
|
|
552
|
-
with open(samplesheet, "w") as f:
|
|
553
|
-
writer = csv.DictWriter(f, [f.name for f in fields(t)], delimiter=delim)
|
|
554
|
-
writer.writeheader()
|
|
555
|
-
|
|
556
|
-
for sample in samples:
|
|
557
|
-
row_data = {
|
|
558
|
-
f.name: _samplesheet_repr(getattr(sample, f.name))
|
|
559
|
-
for f in fields(sample)
|
|
560
|
-
}
|
|
561
|
-
writer.writerow(row_data)
|
|
562
|
-
|
|
563
|
-
return samplesheet
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
@dataclass(frozen=True)
|
|
567
|
-
class NextflowRuntimeResources:
|
|
568
|
-
"""Resources for Nextflow runtime tasks"""
|
|
569
|
-
|
|
570
|
-
cpus: Optional[int] = 4
|
|
571
|
-
"""
|
|
572
|
-
Number of CPUs required for the task
|
|
573
|
-
"""
|
|
574
|
-
memory: Optional[str] = 8
|
|
575
|
-
"""
|
|
576
|
-
Memory required for the task (e.g. "1 GB")
|
|
577
|
-
"""
|
|
578
|
-
storage_gib: Optional[int] = 100
|
|
579
|
-
|
|
580
|
-
|
|
581
459
|
@dataclass
|
|
582
460
|
class LatchMetadata:
|
|
583
461
|
"""Class for organizing workflow metadata
|
|
@@ -773,37 +651,3 @@ class SnakemakeMetadata(LatchMetadata):
|
|
|
773
651
|
|
|
774
652
|
|
|
775
653
|
_snakemake_metadata: Optional[SnakemakeMetadata] = None
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
@dataclass
|
|
779
|
-
class NextflowMetadata(LatchMetadata):
|
|
780
|
-
name: Optional[str] = None
|
|
781
|
-
"""
|
|
782
|
-
Name of the workflow
|
|
783
|
-
"""
|
|
784
|
-
parameters: Dict[str, NextflowParameter] = field(default_factory=dict)
|
|
785
|
-
"""
|
|
786
|
-
A dictionary mapping parameter names (strings) to `NextflowParameter` objects
|
|
787
|
-
"""
|
|
788
|
-
runtime_resources: NextflowRuntimeResources = field(
|
|
789
|
-
default_factory=NextflowRuntimeResources
|
|
790
|
-
)
|
|
791
|
-
"""
|
|
792
|
-
Resources (cpu/memory/storage) for Nextflow runtime task
|
|
793
|
-
"""
|
|
794
|
-
output_dir: Optional[LatchDir] = None
|
|
795
|
-
"""
|
|
796
|
-
Directory to dump Nextflow logs
|
|
797
|
-
"""
|
|
798
|
-
|
|
799
|
-
def __post_init__(self):
|
|
800
|
-
if self.name is None:
|
|
801
|
-
self.name = f"nf_{identifier_suffix_from_str(self.display_name.lower())}"
|
|
802
|
-
else:
|
|
803
|
-
self.name = identifier_suffix_from_str(self.name)
|
|
804
|
-
|
|
805
|
-
global _nextflow_metadata
|
|
806
|
-
_nextflow_metadata = self
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
_nextflow_metadata: Optional[NextflowMetadata] = None
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import os
|
|
3
|
+
from typing import Dict, TypedDict
|
|
4
|
+
|
|
5
|
+
import gql
|
|
6
|
+
import jwt
|
|
7
|
+
from latch_sdk_config.user import user_config
|
|
8
|
+
from latch_sdk_gql.execute import execute
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def account_id_from_token(token: str) -> str:
|
|
12
|
+
"""Exchanges a valid JWT for a Latch account ID.
|
|
13
|
+
|
|
14
|
+
Latch account IDs are needed for any user-specific request, eg. register
|
|
15
|
+
workflows or copy files to Latch.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
token: JWT
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
A Latch account ID (UUID).
|
|
22
|
+
"""
|
|
23
|
+
decoded_jwt = jwt.decode(token, options={"verify_signature": False})
|
|
24
|
+
try:
|
|
25
|
+
return decoded_jwt.get("id")
|
|
26
|
+
except KeyError as e:
|
|
27
|
+
raise ValueError("Your Latch access token is malformed") from e
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def retrieve_or_login() -> str:
|
|
31
|
+
"""Returns a valid JWT to access Latch, prompting a login flow if needed.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
A JWT
|
|
35
|
+
"""
|
|
36
|
+
from latch_cli.services.login import login
|
|
37
|
+
|
|
38
|
+
token = user_config.token
|
|
39
|
+
if token == "":
|
|
40
|
+
token = login()
|
|
41
|
+
return token
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class WSInfo(TypedDict):
|
|
45
|
+
workspace_id: str
|
|
46
|
+
name: str
|
|
47
|
+
default: bool
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_workspaces() -> Dict[str, WSInfo]:
|
|
51
|
+
"""Retrieve workspaces that user can access.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
A dictionary mapping workspace IDs to workspace display names.
|
|
55
|
+
"""
|
|
56
|
+
account_id = account_id_from_token(retrieve_or_login())
|
|
57
|
+
res = execute(
|
|
58
|
+
gql.gql(
|
|
59
|
+
"""
|
|
60
|
+
query GetWorkspaces($accountId: BigInt!) {
|
|
61
|
+
userInfoByAccountId(accountId: $accountId) {
|
|
62
|
+
id
|
|
63
|
+
defaultAccount
|
|
64
|
+
}
|
|
65
|
+
teamInfoByAccountId(accountId: $accountId) {
|
|
66
|
+
accountId
|
|
67
|
+
displayName
|
|
68
|
+
}
|
|
69
|
+
teamInfos(filter: {owner: {accountId: {equalTo: $accountId}}}) {
|
|
70
|
+
nodes {
|
|
71
|
+
accountId
|
|
72
|
+
displayName
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
teamMembers(filter: {user: {accountId: {equalTo: $accountId}}}) {
|
|
76
|
+
nodes {
|
|
77
|
+
team {
|
|
78
|
+
accountId
|
|
79
|
+
displayName
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
orgInfos(filter: { ownerAccountId: { equalTo: $accountId } }) {
|
|
84
|
+
nodes {
|
|
85
|
+
teamInfosByOrgId(filter: { account: { removed: { equalTo: false } } }) {
|
|
86
|
+
nodes {
|
|
87
|
+
accountId
|
|
88
|
+
displayName
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
orgMembers(filter: { userAccountId: { equalTo: $accountId } }) {
|
|
94
|
+
nodes {
|
|
95
|
+
org {
|
|
96
|
+
teamInfosByOrgId(filter: { account: { removed: { equalTo: false } } }) {
|
|
97
|
+
nodes {
|
|
98
|
+
accountId
|
|
99
|
+
displayName
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
"""
|
|
107
|
+
),
|
|
108
|
+
{"accountId": account_id},
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
owned_teams = res["teamInfos"]["nodes"]
|
|
112
|
+
member_teams = [x["team"] for x in res["teamMembers"]["nodes"]]
|
|
113
|
+
|
|
114
|
+
owned_org_teams = [x["teamInfosByOrgId"]["nodes"] for x in res["orgInfos"]["nodes"]]
|
|
115
|
+
owned_org_teams = list(itertools.chain(*owned_org_teams))
|
|
116
|
+
|
|
117
|
+
member_org_teams = [
|
|
118
|
+
x["org"]["teamInfosByOrgId"]["nodes"] for x in res["orgMembers"]["nodes"]
|
|
119
|
+
]
|
|
120
|
+
member_org_teams = list(itertools.chain(*member_org_teams))
|
|
121
|
+
|
|
122
|
+
default_account = (
|
|
123
|
+
res["userInfoByAccountId"]["defaultAccount"]
|
|
124
|
+
if res["userInfoByAccountId"] is not None
|
|
125
|
+
else None
|
|
126
|
+
)
|
|
127
|
+
teams = {
|
|
128
|
+
x["accountId"]: WSInfo(
|
|
129
|
+
workspace_id=x["accountId"],
|
|
130
|
+
name=x["displayName"],
|
|
131
|
+
default=x["accountId"] == default_account,
|
|
132
|
+
)
|
|
133
|
+
for x in owned_teams
|
|
134
|
+
+ member_teams
|
|
135
|
+
+ (
|
|
136
|
+
[res["teamInfoByAccountId"]]
|
|
137
|
+
if res["teamInfoByAccountId"] is not None
|
|
138
|
+
else []
|
|
139
|
+
)
|
|
140
|
+
+ owned_org_teams
|
|
141
|
+
+ member_org_teams
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return teams
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def current_workspace() -> str:
|
|
148
|
+
"""Retrieves the current workspace ID based on the user's configuration.
|
|
149
|
+
|
|
150
|
+
If the workspace ID is not set, it retrieves the default workspace ID from the user's account.
|
|
151
|
+
If the default workspace ID is not set, it raises a ValueError.
|
|
152
|
+
"""
|
|
153
|
+
ws = user_config.workspace_id
|
|
154
|
+
if ws == "":
|
|
155
|
+
res = execute(
|
|
156
|
+
gql.gql(
|
|
157
|
+
"""
|
|
158
|
+
query DefaultAccountQuery {
|
|
159
|
+
accountInfoCurrent {
|
|
160
|
+
id
|
|
161
|
+
user {
|
|
162
|
+
defaultAccount
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
"""
|
|
167
|
+
),
|
|
168
|
+
)["accountInfoCurrent"]
|
|
169
|
+
|
|
170
|
+
default_ws = res["id"]
|
|
171
|
+
|
|
172
|
+
is_local = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") is None
|
|
173
|
+
if is_local and res["user"] is not None:
|
|
174
|
+
default_ws = res["user"]["defaultAccount"]
|
|
175
|
+
|
|
176
|
+
if default_ws is not None:
|
|
177
|
+
ws = default_ws
|
|
178
|
+
|
|
179
|
+
return ws
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: latch
|
|
3
|
+
Version: 2.45.3
|
|
4
|
+
Summary: The Latch SDK
|
|
5
|
+
Author-email: kenny@latch.bio
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Requires-Python: >=3.8,<3.12
|
|
11
|
+
Provides-Extra: snakemake
|
|
12
|
+
Provides-Extra: pandas
|
|
13
|
+
License-File: LICENSE
|
|
@@ -80,10 +80,6 @@ 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
|
|
87
83
|
latch_cli/services/__init__.py
|
|
88
84
|
latch_cli/services/get.py
|
|
89
85
|
latch_cli/services/get_executions.py
|
|
@@ -110,8 +106,8 @@ latch_cli/services/execute/main.py
|
|
|
110
106
|
latch_cli/services/execute/utils.py
|
|
111
107
|
latch_cli/services/init/__init__.py
|
|
112
108
|
latch_cli/services/init/init.py
|
|
113
|
-
latch_cli/services/init/__pycache__/__init__.cpython-
|
|
114
|
-
latch_cli/services/init/__pycache__/init.cpython-
|
|
109
|
+
latch_cli/services/init/__pycache__/__init__.cpython-311.pyc
|
|
110
|
+
latch_cli/services/init/__pycache__/init.cpython-311.pyc
|
|
115
111
|
latch_cli/services/init/assemble_and_sort/.env
|
|
116
112
|
latch_cli/services/init/assemble_and_sort/LICENSE
|
|
117
113
|
latch_cli/services/init/assemble_and_sort/README.md
|
|
@@ -59,7 +59,6 @@ class _CentromereCtx:
|
|
|
59
59
|
default_container: _Container
|
|
60
60
|
workflow_type: WorkflowType
|
|
61
61
|
snakefile: Optional[Path]
|
|
62
|
-
nf_script: Optional[Path]
|
|
63
62
|
|
|
64
63
|
latch_register_api_url = config.api.workflow.register
|
|
65
64
|
latch_image_api_url = config.api.workflow.upload_image
|
|
@@ -81,7 +80,6 @@ class _CentromereCtx:
|
|
|
81
80
|
disable_auto_version: bool = False,
|
|
82
81
|
remote: bool = False,
|
|
83
82
|
snakefile: Optional[Path] = None,
|
|
84
|
-
nf_script: Optional[Path] = None,
|
|
85
83
|
use_new_centromere: bool = False,
|
|
86
84
|
):
|
|
87
85
|
self.use_new_centromere = use_new_centromere
|
|
@@ -95,22 +93,13 @@ class _CentromereCtx:
|
|
|
95
93
|
self.dkr_repo = config.dkr_repo
|
|
96
94
|
self.pkg_root = pkg_root.resolve()
|
|
97
95
|
|
|
98
|
-
if snakefile
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
" register command."
|
|
102
|
-
)
|
|
103
|
-
if snakefile is not None:
|
|
96
|
+
if snakefile is None:
|
|
97
|
+
self.workflow_type = WorkflowType.latchbiosdk
|
|
98
|
+
else:
|
|
104
99
|
self.workflow_type = WorkflowType.snakemake
|
|
105
100
|
self.snakefile = snakefile
|
|
106
|
-
elif nf_script is not None:
|
|
107
|
-
self.workflow_type = WorkflowType.nextflow
|
|
108
|
-
self.nf_script = nf_script
|
|
109
|
-
else:
|
|
110
|
-
self.workflow_type = WorkflowType.latchbiosdk
|
|
111
101
|
|
|
112
102
|
self.container_map: Dict[str, _Container] = {}
|
|
113
|
-
|
|
114
103
|
if self.workflow_type == WorkflowType.latchbiosdk:
|
|
115
104
|
_import_flyte_objects([self.pkg_root])
|
|
116
105
|
for entity in FlyteEntities.entities:
|
|
@@ -137,7 +126,11 @@ class _CentromereCtx:
|
|
|
137
126
|
fg="red",
|
|
138
127
|
)
|
|
139
128
|
raise click.exceptions.Exit(1)
|
|
140
|
-
|
|
129
|
+
|
|
130
|
+
name_path = pkg_root / latch_constants.pkg_workflow_name
|
|
131
|
+
if name_path.exists():
|
|
132
|
+
self.workflow_name = name_path.read_text().strip()
|
|
133
|
+
else:
|
|
141
134
|
assert snakefile is not None
|
|
142
135
|
|
|
143
136
|
import latch.types.metadata as metadata
|
|
@@ -149,10 +142,6 @@ class _CentromereCtx:
|
|
|
149
142
|
)
|
|
150
143
|
from ..snakemake.utils import load_snakemake_metadata
|
|
151
144
|
|
|
152
|
-
name_path = pkg_root / latch_constants.pkg_workflow_name
|
|
153
|
-
if name_path.exists():
|
|
154
|
-
self.workflow_name = name_path.read_text().strip()
|
|
155
|
-
|
|
156
145
|
meta_file = load_snakemake_metadata(pkg_root)
|
|
157
146
|
if meta_file is not None:
|
|
158
147
|
click.echo(
|
|
@@ -246,32 +235,6 @@ class _CentromereCtx:
|
|
|
246
235
|
# todo(kenny): support per container task and custom workflow
|
|
247
236
|
# name for snakemake
|
|
248
237
|
self.workflow_name = f"{metadata._snakemake_metadata.name}_jit_register"
|
|
249
|
-
else:
|
|
250
|
-
assert nf_script is not None
|
|
251
|
-
|
|
252
|
-
import latch.types.metadata as metadata
|
|
253
|
-
|
|
254
|
-
from ..services.register.utils import import_module_by_path
|
|
255
|
-
|
|
256
|
-
meta = pkg_root / "latch_metadata" / "__init__.py"
|
|
257
|
-
if meta.exists():
|
|
258
|
-
click.echo(f"Using metadata file {click.style(meta, italic=True)}")
|
|
259
|
-
import_module_by_path(meta)
|
|
260
|
-
|
|
261
|
-
if metadata._nextflow_metadata is None:
|
|
262
|
-
click.secho(
|
|
263
|
-
dedent("""
|
|
264
|
-
Failed to register Nextflow workflow.
|
|
265
|
-
Make sure the project root contains a `latch_metadata/__init__.py`
|
|
266
|
-
with a `NextflowMetadata` object defined.
|
|
267
|
-
"""),
|
|
268
|
-
fg="red",
|
|
269
|
-
)
|
|
270
|
-
raise click.exceptions.Exit(1)
|
|
271
|
-
|
|
272
|
-
self.workflow_name = metadata._nextflow_metadata.name
|
|
273
|
-
|
|
274
|
-
assert self.workflow_name is not None
|
|
275
238
|
|
|
276
239
|
version_file = self.pkg_root / "version"
|
|
277
240
|
try:
|