Python basics#
The tutorials are written as Jupyter notebooks for interactive exploration,
but everything in them also works as plain .py scripts. This page
collects the one piece that differs between the two modes: waiting for a
workflow to finish.
Waiting for workflow completion#
Agent.RunWorkflow launches Nextflow under nohup ... & on
the agent side and returns as soon as the launch script exits. In a Jupyter
notebook that is exactly what you want — you advance the next cell once the
log output settles down. In a plain Python script the next line of code runs
immediately, so calls like GetResultSource or CheckWorkflow
will race past the still-running workflow and fail with errors such as:
FileNotFoundError: '/.../runs/<key>/_metasmith/logs.<ts>/main.log'
AssertionError: path [.../runs/<key>/results] does not exist
When the Nextflow process exits the agent writes a single sentinel line to
agent.log inside the latest log directory of the task:
runs/<key>/_metasmith/logs.<latest>/agent.log
...
run completed at [<timestamp>]
A small helper that polls for that sentinel is enough to convert any tutorial into a plain Python script:
1import time
2from pathlib import Path
3
4def wait_for_run(task_dir: Path, poll_s: float = 10.0, timeout: float | None = None) -> bool:
5 """Block until the agent writes 'run completed at' to the latest agent.log."""
6 deadline = None if timeout is None else time.monotonic() + timeout
7 while deadline is None or time.monotonic() < deadline:
8 logs = sorted((task_dir / "_metasmith").glob("logs.*"))
9 if logs:
10 agent_log = logs[-1] / "agent.log"
11 if agent_log.exists() and "run completed at" in agent_log.read_text():
12 return True
13 time.sleep(poll_s)
14 return False
Use it around RunWorkflow:
1smith.RunWorkflow(task, config_file=smith.GetNxfConfigPresets()["local"])
2
3task_dir = Path(agent_home.GetPath()) / "runs" / task.GetKey()
4if not wait_for_run(task_dir, poll_s=10):
5 raise RuntimeError("workflow did not complete in time")
6
7results_path = smith.GetResultSource(task).GetPath()
8results = DataInstanceLibrary.Load(results_path)
The helper works whether the agent home is local or remote — for remote agents
the task_dir resolves to the mounted/synced view of the run
directory exposed by the home Source.
Note
A first-class wait=True kwarg (or WaitForRun(task)
method) on Agent.RunWorkflow is planned for a future release.
Until then, use the helper above.