Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a helper function to prepare the inputs #103

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 58 additions & 9 deletions src/aiida_shell/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,17 @@
LOGGER = logging.getLogger('aiida_shell')


def launch_shell_job( # noqa: PLR0913
def prepare_shell_job_inputs(
command: str | AbstractCode,
arguments: list[str] | str | None = None,
nodes: t.Mapping[str, str | pathlib.Path | Data] | None = None,
filenames: dict[str, str] | None = None,
outputs: list[str] | None = None,
parser: ParserFunctionType | str | None = None,
metadata: dict[str, t.Any] | None = None,
submit: bool = False,
resolve_command: bool = True,
) -> tuple[dict[str, Data], ProcessNode]:
"""Launch a :class:`aiida_shell.ShellJob` job for the given command.
) -> dict[str, t.Any]:
"""Prepare inputs for the ShellJob based on the provided parameters.

:param command: The shell command to run. Should be the relative command name, e.g., ``date``. An ``AbstractCode``
instance will be automatically created for this command if it doesn't already exist. Alternatively, a pre-
Expand All @@ -48,17 +47,13 @@ def launch_shell_job( # noqa: PLR0913
a complete entry point, i.e. a string of the form ``{entry_point_group}:{entry_point_name}`` pointing to such a
callable.
:param metadata: Optional dictionary of metadata inputs to be passed to the ``ShellJob``.
:param submit: Boolean, if ``True`` will submit the job to the daemon instead of running in current interpreter.
:param resolve_command: Whether to resolve the command to the absolute path of the executable. If set to ``True``,
the ``which`` command is executed on the target computer to attempt and determine the absolute path. Otherwise,
the command is set as the ``filepath_executable`` attribute of the created ``AbstractCode`` instance.
:raises TypeError: If the value specified for ``metadata.options.computer`` is not a ``Computer``.
:raises ValueError: If ``resolve_command=True`` and the absolute path of the command on the computer could not be
determined.
:returns: The tuple of results dictionary and ``ProcessNode``, or just the ``ProcessNode`` if ``submit=True``. The
results dictionary intentionally doesn't include the ``retrieved`` and ``remote_folder`` outputs as they are
generated for each ``CalcJob`` and typically are not of interest to a user running ``launch_shell_job``. In
order to not confuse them, these nodes are omitted, but they can always be accessed through the node.
:returns: A dictionary containing prepared inputs for the ShellJob.
"""
metadata = metadata or {}
computer = metadata.get('options', {}).pop('computer', None)
Expand Down Expand Up @@ -94,6 +89,60 @@ def launch_shell_job( # noqa: PLR0913
'metadata': metadata or {},
}

return inputs


def launch_shell_job( # noqa: PLR0913
command: str | AbstractCode,
arguments: list[str] | str | None = None,
nodes: t.Mapping[str, str | pathlib.Path | Data] | None = None,
filenames: dict[str, str] | None = None,
outputs: list[str] | None = None,
parser: ParserFunctionType | str | None = None,
metadata: dict[str, t.Any] | None = None,
submit: bool = False,
resolve_command: bool = True,
) -> tuple[dict[str, Data], ProcessNode]:
"""Launch a :class:`aiida_shell.ShellJob` job for the given command.

:param command: The shell command to run. Should be the relative command name, e.g., ``date``. An ``AbstractCode``
instance will be automatically created for this command if it doesn't already exist. Alternatively, a pre-
configured ``AbstractCode`` instance can be passed directly.
:param arguments: Optional list of command line arguments optionally containing placeholders for input nodes. The
arguments can also be specified as a single string. In this case, it will be split into separate parameters
using ``shlex.split``.
:param nodes: A dictionary of ``Data`` nodes whose content is to replace placeholders in the ``arguments`` list.
:param filenames: Optional dictionary of explicit filenames to use for the ``nodes`` to be written to ``dirpath``.
:param outputs: Optional list of relative filenames that should be captured as outputs.
:param parser: Optional callable that can implement custom parsing logic of produced output files. Alternatively,
a complete entry point, i.e. a string of the form ``{entry_point_group}:{entry_point_name}`` pointing to such a
callable.
:param metadata: Optional dictionary of metadata inputs to be passed to the ``ShellJob``.
:param submit: Boolean, if ``True`` will submit the job to the daemon instead of running in current interpreter.
:param resolve_command: Whether to resolve the command to the absolute path of the executable. If set to ``True``,
the ``which`` command is executed on the target computer to attempt and determine the absolute path. Otherwise,
the command is set as the ``filepath_executable`` attribute of the created ``AbstractCode`` instance.
:raises TypeError: If the value specified for ``metadata.options.computer`` is not a ``Computer``.
:raises ValueError: If ``resolve_command=True`` and the absolute path of the command on the computer could not be
determined.
:returns: The tuple of results dictionary and ``ProcessNode``, or just the ``ProcessNode`` if ``submit=True``. The
results dictionary intentionally doesn't include the ``retrieved`` and ``remote_folder`` outputs as they are
generated for each ``CalcJob`` and typically are not of interest to a user running ``launch_shell_job``. In
order to not confuse them, these nodes are omitted, but they can always be accessed through the node.
"""

# Prepare inputs for the ShellJob
sphuber marked this conversation as resolved.
Show resolved Hide resolved
inputs = prepare_shell_job_inputs(
command=command,
arguments=arguments,
nodes=nodes,
filenames=filenames,
outputs=outputs,
parser=parser,
metadata=metadata,
resolve_command=resolve_command,
)

if submit:
current_process = Process.current()
if current_process is not None and isinstance(current_process, WorkChain):
Expand Down