nf-meta 0.2.4__tar.gz → 0.3.0.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {nf_meta-0.2.4/src/nf_meta.egg-info → nf_meta-0.3.0.dev0}/PKG-INFO +2 -2
  2. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/README.md +1 -1
  3. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/pyproject.toml +10 -1
  4. nf_meta-0.3.0.dev0/src/nf_meta/__main__.py +135 -0
  5. nf_meta-0.3.0.dev0/src/nf_meta/core/cache.py +39 -0
  6. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/errors.py +1 -1
  7. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/events.py +1 -1
  8. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/graph.py +3 -1
  9. nf_meta-0.3.0.dev0/src/nf_meta/core/models.py +742 -0
  10. nf_meta-0.3.0.dev0/src/nf_meta/core/nf_core_utils.py +521 -0
  11. nf_meta-0.3.0.dev0/src/nf_meta/core/nf_param_validation.py +124 -0
  12. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/session.py +17 -5
  13. nf_meta-0.3.0.dev0/src/nf_meta/editor/__init__.py +41 -0
  14. nf_meta-0.3.0.dev0/src/nf_meta/editor/backend/__init__.py +1 -0
  15. nf_meta-0.3.0.dev0/src/nf_meta/editor/backend/api.py +232 -0
  16. nf_meta-0.3.0.dev0/src/nf_meta/editor/backend/serializers.py +40 -0
  17. nf_meta-0.3.0.dev0/src/nf_meta/editor/base_editor.py +46 -0
  18. nf_meta-0.3.0.dev0/src/nf_meta/editor/browser_editor.py +99 -0
  19. nf_meta-0.3.0.dev0/src/nf_meta/editor/editor.py +20 -0
  20. nf_meta-0.3.0.dev0/src/nf_meta/editor/frontend_dist/assets/index-BeQMBiE2.css +1 -0
  21. nf_meta-0.3.0.dev0/src/nf_meta/editor/frontend_dist/assets/index-C23FgNmk.js +202 -0
  22. nf_meta-0.3.0.dev0/src/nf_meta/editor/frontend_dist/assets/nfcore-BTUAiOeh.svg +76 -0
  23. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/index.html +2 -2
  24. nf_meta-0.3.0.dev0/src/nf_meta/editor/utils.py +20 -0
  25. nf_meta-0.3.0.dev0/src/nf_meta/runner/__init__.py +41 -0
  26. nf_meta-0.3.0.dev0/src/nf_meta/runner/base_runner.py +54 -0
  27. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/runner/python_runner.py +125 -111
  28. nf_meta-0.3.0.dev0/src/nf_meta/runner/runner.py +50 -0
  29. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/runner/utils.py +55 -0
  30. nf_meta-0.3.0.dev0/src/nf_meta/runner/workflow_run.py +165 -0
  31. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0/src/nf_meta.egg-info}/PKG-INFO +2 -2
  32. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta.egg-info/SOURCES.txt +12 -3
  33. nf_meta-0.2.4/src/nf_meta/__main__.py +0 -85
  34. nf_meta-0.2.4/src/nf_meta/core/models.py +0 -441
  35. nf_meta-0.2.4/src/nf_meta/core/nf_core_utils.py +0 -74
  36. nf_meta-0.2.4/src/nf_meta/editor/__init__.py +0 -66
  37. nf_meta-0.2.4/src/nf_meta/editor/backend/__init__.py +0 -1
  38. nf_meta-0.2.4/src/nf_meta/editor/backend/api.py +0 -141
  39. nf_meta-0.2.4/src/nf_meta/editor/backend/serializers.py +0 -25
  40. nf_meta-0.2.4/src/nf_meta/editor/frontend_dist/assets/index-Dn4aaNvP.js +0 -202
  41. nf_meta-0.2.4/src/nf_meta/editor/frontend_dist/assets/index-ESZ-ptZu.css +0 -1
  42. nf_meta-0.2.4/src/nf_meta/runner/__init__.py +0 -4
  43. nf_meta-0.2.4/src/nf_meta/runner/runner.py +0 -65
  44. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/LICENSE +0 -0
  45. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/MANIFEST.in +0 -0
  46. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/setup.cfg +0 -0
  47. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/__init__.py +0 -0
  48. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/__init__.py +0 -0
  49. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/core/history.py +0 -0
  50. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/assets/materialdesignicons-webfont-B7mPwVP_.ttf +0 -0
  51. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/assets/materialdesignicons-webfont-CSr8KVlo.eot +0 -0
  52. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/assets/materialdesignicons-webfont-Dp5v-WZN.woff2 +0 -0
  53. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/assets/materialdesignicons-webfont-PXm3-2wK.woff +0 -0
  54. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/editor/frontend_dist/vite.svg +0 -0
  55. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/runner/cascade_runner.py +0 -0
  56. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta/runner/errors.py +0 -0
  57. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta.egg-info/dependency_links.txt +0 -0
  58. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta.egg-info/entry_points.txt +0 -0
  59. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta.egg-info/requires.txt +0 -0
  60. {nf_meta-0.2.4 → nf_meta-0.3.0.dev0}/src/nf_meta.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nf-meta
3
- Version: 0.2.4
3
+ Version: 0.3.0.dev0
4
4
  Summary: nf-meta is a cli tool for building, validating and running meta-pipelines based on the Nextflow workflow language
5
5
  Author-email: Julian Flesch <julian.flesch@qbic.uni-tuebingen.de>
6
6
  License-Expression: Apache-2.0
@@ -85,7 +85,7 @@ This project features a small editor which intends to ease the creation and upda
85
85
  of these config files, by visualizing the config as a graph and
86
86
  offering user-firendly form for entering and validating values.
87
87
 
88
- ![editor](assets/nf-meta-screenshot.png)
88
+ ![editor](https://raw.githubusercontent.com/bmds-tue/nf-meta/main/assets/nf-meta-screenshot.png)
89
89
 
90
90
 
91
91
  ## Metapipeline Runners
@@ -61,7 +61,7 @@ This project features a small editor which intends to ease the creation and upda
61
61
  of these config files, by visualizing the config as a graph and
62
62
  offering user-firendly form for entering and validating values.
63
63
 
64
- ![editor](assets/nf-meta-screenshot.png)
64
+ ![editor](https://raw.githubusercontent.com/bmds-tue/nf-meta/main/assets/nf-meta-screenshot.png)
65
65
 
66
66
 
67
67
  ## Metapipeline Runners
@@ -13,7 +13,7 @@ namespaces = false
13
13
 
14
14
  [project]
15
15
  name = "nf-meta"
16
- version = "0.2.4"
16
+ version = "0.3.0-dev"
17
17
  description = "nf-meta is a cli tool for building, validating and running meta-pipelines based on the Nextflow workflow language"
18
18
  readme = "README.md"
19
19
  authors = [
@@ -47,6 +47,7 @@ dev = [
47
47
  "twine>=6.2.0",
48
48
  "pytest>=9.0.3",
49
49
  "pytest-mock>=3.15.1",
50
+ "mypy>=2.1.0",
50
51
  "types-networkx>=3.6.1.20260408",
51
52
  "types-pyyaml>=6.0.12.20260408",
52
53
  "types-requests>=2.33.0.20260503",
@@ -54,3 +55,11 @@ dev = [
54
55
 
55
56
  [tool.pytest.ini_options]
56
57
  testpaths = ["tests"]
58
+
59
+ [tool.mypy]
60
+ python_version = "3.12"
61
+ mypy_path = "src"
62
+
63
+ [[tool.mypy.overrides]]
64
+ module = ["uvicorn", "uvicorn.*"]
65
+ ignore_missing_imports = true
@@ -0,0 +1,135 @@
1
+ import click
2
+ from functools import wraps
3
+ from nf_meta.core.errors import (
4
+ GraphValidationError,
5
+ ValidationError,
6
+ format_errors_for_cli,
7
+ )
8
+ from nf_meta.runner import (
9
+ run_metapipeline,
10
+ get_registered_runners,
11
+ RunOptions,
12
+ NfMetaRunnerError,
13
+ )
14
+ from nf_meta.core.graph import MetaworkflowGraph
15
+ from nf_meta.core.session import start_session
16
+ from nf_meta.editor import get_registered_editors, EditorOptions, run_editor
17
+
18
+
19
+ @click.group()
20
+ @click.version_option()
21
+ def cli() -> None:
22
+ return
23
+
24
+
25
+ @click.command("editor")
26
+ @click.option("--verbose", "-v", is_flag=True, help="Enables verbose mode")
27
+ @click.option(
28
+ "--editor",
29
+ "-e",
30
+ type=click.Choice(get_registered_editors()),
31
+ default="browser",
32
+ help="Editor backend to use",
33
+ )
34
+ @click.option("--host", help="Host to bind the editor server to")
35
+ @click.option(
36
+ "--port",
37
+ type=int,
38
+ help="Port for the editor server (auto-assigned if omitted)",
39
+ )
40
+ @click.argument("config", required=False, type=click.Path())
41
+ def edit_browser(config, verbose, editor, host, port):
42
+ try:
43
+ start_session(config)
44
+ opts = EditorOptions(editor_name=editor)
45
+ if host is not None:
46
+ opts.host = host
47
+ if port is not None:
48
+ opts.port = port
49
+ run_editor(opts)
50
+ except (GraphValidationError, ValidationError) as e:
51
+ click.echo(format_errors_for_cli(e))
52
+ raise SystemExit(1)
53
+ except FileNotFoundError as e:
54
+ click.echo(click.style(e, fg="red"))
55
+ raise SystemExit(1)
56
+
57
+
58
+ @click.command("validate")
59
+ @click.argument("config", type=click.Path())
60
+ @click.option("--verbose", "-v", is_flag=True, help="Enables verbose mode")
61
+ def validate_config(config, verbose):
62
+ try:
63
+ g = MetaworkflowGraph.from_file(config)
64
+ click.echo(click.style("✓ Config is valid", fg="green"))
65
+ except (GraphValidationError, ValidationError) as e:
66
+ click.echo(format_errors_for_cli(e))
67
+ raise SystemExit(1)
68
+ except FileNotFoundError as e:
69
+ click.echo(click.style(e, fg="red"))
70
+ raise SystemExit(1)
71
+
72
+
73
+ @click.command("run")
74
+ @click.argument("config", type=click.Path())
75
+ @click.option("--verbose", "-v", is_flag=True, help="Enables verbose mode")
76
+ @click.option(
77
+ "--runner",
78
+ "-r",
79
+ prompt=True,
80
+ type=click.Choice(get_registered_runners()),
81
+ default="python",
82
+ )
83
+ @click.option("--resume", is_flag=True, help="Resume a previous run")
84
+ @click.option(
85
+ "--output-lines",
86
+ "-l",
87
+ default="25",
88
+ type=int,
89
+ help="Number of lines of workflow output to stream to output window (Only for Python Runner!)",
90
+ )
91
+ @click.option("--start", "-s", type=str, help="ID of workflow to start from")
92
+ @click.option("--target", "-t", type=str, help="ID of workflow to run until")
93
+ @click.option(
94
+ "--profile",
95
+ "-p",
96
+ type=str,
97
+ help="Nextflow profile to apply globally, taking precedent over config values.",
98
+ )
99
+ @click.option(
100
+ "--stub",
101
+ is_flag=True,
102
+ help="Run all workflows as stub runs (passes -stub to Nextflow)",
103
+ )
104
+ def run(config, verbose, runner, resume, output_lines, start, target, profile, stub):
105
+ try:
106
+ run_options = RunOptions(
107
+ runner_name=runner,
108
+ verbose=verbose,
109
+ output_lines=output_lines,
110
+ nf_profile=profile,
111
+ stub=stub,
112
+ resume=resume,
113
+ start=start,
114
+ target=target,
115
+ )
116
+ g = MetaworkflowGraph.from_file(config)
117
+ run_metapipeline(g, run_options)
118
+ except (GraphValidationError, ValidationError) as e:
119
+ click.echo(format_errors_for_cli(e))
120
+ raise SystemExit(1)
121
+ except NfMetaRunnerError as e:
122
+ click.echo(click.style(e.message, fg="red"))
123
+ raise SystemExit(1)
124
+ except FileNotFoundError as e:
125
+ click.echo(click.style(e, fg="red"))
126
+ raise SystemExit(1)
127
+
128
+
129
+ cli.add_command(edit_browser)
130
+ cli.add_command(validate_config)
131
+ cli.add_command(run)
132
+
133
+
134
+ if __name__ == "__main__":
135
+ cli()
@@ -0,0 +1,39 @@
1
+ import hashlib
2
+ import json
3
+ import logging
4
+ import os
5
+ from pathlib import Path
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ _ENV_VAR = "NF_META_CACHE_DIR"
10
+ GLOBAL_CACHE_DIR: Path = Path(
11
+ os.environ.get(_ENV_VAR) or Path.home() / ".cache" / "nf-meta"
12
+ )
13
+
14
+
15
+ def schema_cache_path(url: str, version: str) -> Path:
16
+ key = hashlib.sha256(f"{url}@{version}".encode()).hexdigest()[:16]
17
+ return GLOBAL_CACHE_DIR / "schemas" / f"{key}.json"
18
+
19
+
20
+ def read_schema_cache(url: str, version: str) -> dict | None:
21
+ path = schema_cache_path(url, version)
22
+ if not path.exists():
23
+ return None
24
+ try:
25
+ with open(path) as f:
26
+ return json.load(f)
27
+ except Exception as e:
28
+ logger.warning("Failed to read schema cache at %s: %s", path, e)
29
+ return None
30
+
31
+
32
+ def write_schema_cache(url: str, version: str, schema: dict) -> None:
33
+ path = schema_cache_path(url, version)
34
+ try:
35
+ path.parent.mkdir(parents=True, exist_ok=True)
36
+ with open(path, "w") as f:
37
+ json.dump(schema, f)
38
+ except Exception as e:
39
+ logger.warning("Failed to write schema cache to %s: %s", path, e)
@@ -25,7 +25,7 @@ class WorkflowReferenceErrors(GraphValidationError):
25
25
  class SessionCommandError(Exception):
26
26
  @dataclass
27
27
  class FieldError:
28
- workflow_id: str
28
+ workflow_id: Optional[str]
29
29
  field: str
30
30
  message: str
31
31
 
@@ -94,7 +94,7 @@ class Command(Protocol):
94
94
 
95
95
  @dataclass(frozen=True)
96
96
  class Transaction:
97
- commands: tuple[Command]
97
+ commands: tuple[Command, ...]
98
98
 
99
99
  def apply(self, graph: GraphEventHandler):
100
100
  # TODO: Handle errors?
@@ -7,9 +7,9 @@ import networkx as nx
7
7
 
8
8
  from .models import (
9
9
  MetaworkflowConfig,
10
- Workflow,
11
10
  GlobalOptions,
12
11
  Transition,
12
+ Workflow,
13
13
  load_config,
14
14
  dump_config,
15
15
  CONFIG_VERSION_MAX,
@@ -167,6 +167,8 @@ class MetaworkflowGraph:
167
167
  def validate_param_references(self, wf: Workflow):
168
168
  errors = []
169
169
  for ref in wf.field_refs:
170
+ if ref.namespace != "params":
171
+ continue # output references not yet validated
170
172
  referenced_wf = self.get_workflow_by_id(ref.target_wf_id)
171
173
  if not referenced_wf:
172
174
  errors.append(