Use helper functions

How to load helper functions.

This documentation will walk you through the process of importing and using functions defined in an external file in your Viash component.

This can be useful for organizing and reusing code across multiple components or even within a single component.

We’ll cover the steps to set up the external file, import the functions, and use them within your Viash component. By the end of this guide, you’ll have a better understanding of how to leverage external files to improve your Viash development workflow.

Create helper script

When you want to reuse a function multiple times, it might make sense to store them in a separate file. For example, your helper file could contain the following helper function:

function copy_file {
  echo "Copying '$1' to '$2'."
  cp -r "$1" "$2"
}
// No example available yet.
const fs = require('fs');

function copy_file(source, dest) {
  console.log(`Copying '${source}' to '${dest}'`)
  fs.copyFile(source, dest, (err) => {
    if (err) throw err;
  });
}

module.exports = {
  copy_file
}
import shutil

def copy_file(source, dest):
  print(f"Copying '{source}' to '{dest}'.")
  shutil.copyfile(source, dest)
copy_file <- function(source, dest) {
  cat("Copying '", source, "' to '", dest, "'.\n", sep = "")
  file.copy(source, dest)
}
// No example available yet.

Add resource to component

To add a helper script as an external resource in a Viash component, you can use the resources section of the component’s config file. Not only does your resources section contain the main script, but it’s also used to specify external resources such as helper scripts and other files that the component needs to function.

Here is an example of what the config file might look after adding the helper script:

name: example_bash
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: bash_script
    path: script.sh
  - path: helper.sh
engines:
  - type: docker
    image: bash:4.0
  - type: native
runners:
  - type: executable
  - type: nextflow
name: example_csharp
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: csharp_script
    path: script.csx
  - path: helper.csx
engines:
  - type: docker
    image: ghcr.io/data-intuitive/dotnet-script:1.3.1
  - type: native
runners:
  - type: executable
  - type: nextflow
name: example_js
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: javascript_script
    path: script.js
  - path: helper.js
engines:
  - type: docker
    image: node:19-bullseye-slim
  - type: native
runners:
  - type: executable
  - type: nextflow
name: example_python
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: python_script
    path: script.py
  - path: helper.py
engines:
  - type: docker
    image: python:3.10-slim
  - type: native
runners:
  - type: executable
  - type: nextflow
name: example_r
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: r_script
    path: script.R
  - path: helper.R
engines:
  - type: docker
    image: eddelbuettel/r2u:22.04
  - type: native
runners:
  - type: executable
  - type: nextflow
name: example_scala
description: A minimal example component.
arguments:
  - type: file
    name: --input
    example: file.txt
    required: true
  - type: file
    name: --output
    direction: output
    example: output.txt
    required: true
resources:
  - type: scala_script
    path: script.scala
  - path: helper.scala
engines:
  - type: docker
    image: sbtscala/scala-sbt:eclipse-temurin-19_36_1.7.2_2.13.10
  - type: native
runners:
  - type: executable
  - type: nextflow

Import helper functions

Finally, you need to import the helper functions in your script. The procedure will differ depending on the scripting language used. Below is an example of what the main script might look like after importing the helper file.

#!/bin/bash

## VIASH START
par_input=path/to/file.txt
par_output=output.txt
## VIASH END

# view resource file
source "$meta_resources_dir/helper.sh"

# copy file
copy_file "$par_input" "$par_output"
// No example available yet.
// VIASH START
let par = {
  'input': 'path/to/file.txt',
  'output': 'output.txt'
};
// VIASH END

// import helper function
const helper = require(`${meta['resources_dir']}/helper.js`);

// copy file
helper.copy_file(par['input'], par['output'])
import sys

## VIASH START
par = {
  'input': 'file.txt',
  'output': 'output.txt'
}
## VIASH END

# import helper function
sys.path.append(meta['resources_dir'])
from helper import copy_file

# copy file
copy_file(par['input'], par['output'])
## VIASH START
par <- list(
  "input" = "file.txt",
  "output" = "output.txt"
)
## VIASH END

# import helper function
source(paste0(meta$resources_dir, "/helper.R"))

# copy file
copy_file(par$input, par$output)
// No example available yet.