Scripting Languages
Viash supports several languages to use in your components. This guide explains how to reference scripts in your Viash config files and how to use Viash specific variables.
Requirements
If you’re using WSL2, make sure to follow the Linux instructions and execute the commands in a WSL2 terminal.
Bash doesn’t have any dependencies and is included in every modern Linux distro, including those provided for WSL2 on Microsoft’s Store app. On macOS, the default shell is Zsh since 2019, but it still comes packaged with an older Bash 3.2.
To get started with C# scripting, you need to download and install the .NET 6.0 SDK.
After installing the SDK, run this command to install the dotnet-script
tool:
dotnet tool install -g dotnet-script
To verify that dotnet-script was installed successfully, run this command to get a list of installed tools:
dotnet tool list -g
The output should look something like this:
Package Id Version Commands
---------------------------------------------
dotnet-script 1.3.1 dotnet-script
To run JavaScript on your system, you’ll need to download and install Node.js from their homepage.
To run Python scripts on your system, download and install Python. Most package managers include a python package as well. Make sure to install a version of Python that’s at least version 3.8 or newer.
To be able to run R scripts, you’ll need download and install R for your OS.
Running Scala scripts requires you to download and install Scala.
Referencing scripts in a Viash config file
When referencing a Bash script in the resources
of the functionality
section your Viash config, use bash_script
as its type:
functionality:
name: my_component
resources:
- type: bash_script
path: script.sh
When referencing a C# script in the resources
of the functionality
section your Viash config, use csharp_script
as its type:
functionality:
name: my_component
resources:
- type: csharp_script
path: script.csx
When referencing a JavaScript script in the resources
of the functionality
section your Viash config, use javascript_script
as its type:
functionality:
name: my_component
resources:
- type: javascript_script
path: script.js
When referencing a Python script in the resources
of the functionality
section your Viash config, use python_script
as its type:
functionality:
name: my_component
resources:
- type: python_script
path: script.py
When referencing a R script in the resources
of the functionality
section your Viash config, use r_script
as its type:
functionality:
name: my_component
resources:
- type: r_script
path: script.r
When referencing a Scala script in the resources
of the functionality
section your Viash config, use scala_script
as its type:
functionality:
name: my_component
resources:
- type: scala_script
path: script.scala
Executing scripts
Bash scripts end with the .sh extension. They can be run locally by using the bash
command:
bash script.sh
C# scripts end with the .csx extension. They can be run locally by using the dotnet script
command:
dotnet script script.csx
JavaScript scripts end with the .js extension. They can be run locally by using the node
command:
node script.js
Python scripts end with the .py extension. They can be run locally by using the python
command:
python script.py
R scripts end with the .r extension. They can be run locally by using the Rscript
command:
Rscript script.r
Scala scripts end with the .scala extension. They can be run locally by using the scala -nc
command:
scala -nc script.scala
Script examples
These examples will briefly show to start scripting with Viash in mind. Each example shows the source code and the output after running it.
Using variables
#!/bin/bash
hello="Hello World!"
echo $hello
!/usr/bin/env dotnet-script
#
string hello = "Hello World!";
.WriteLine(hello); Console
#!/usr/bin/env node
let hello = 'Hello World!'
console.log(hello)
#!/usr/bin/env python3
= "Hello World!"
hello print(hello)
#!/usr/bin/env Rscript
= "Hello World!"
hello cat(hello)
Rscript script.r
!/usr/bin/env scala
#
val hello = "Hello World!";
println(hello)
Output
Hello World!
Using Viash arguments as variables
Viash generates variables based on the arguments defined in the Viash config file and injects them at the top of your script.
Variables start with $par_
, followed by the name of the argument.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: bash_script
path: ViashVariables.sh
ViashVariables.sh
#!/bin/bash
echo $par_hello
Variables are grouped inside an anonymous par
class and can be referenced by name.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: csharp_script
path: ViashVariables.csx
ViashVariables.csx
!/usr/bin/env dotnet-script
#
.WriteLine(par.hello); Console
Variables are grouped inside a dictionary named par
and can be referenced by name.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: javascript_script
path: ViashVariables.js
ViashVariables.js
#!/usr/bin/env node
console.log(par['hello'])
Variables are grouped inside a dictionary named par
and can be referenced by name.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: python_script
path: ViashVariables.py
ViashVariables.py
#!/usr/bin/env python3
print(par["hello"])
Variables are grouped inside a list named par
and can be referenced by name.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: r_script
path: ViashVariables.r
ViashVariables.r
#!/usr/bin/env Rscript
cat(par$hello)
Variables are grouped inside an instance of a class named par
and can be referenced by name.
config.vsh.yaml
functionality:
name: hello_world
arguments:
- type: string
name: --hello
default: "Hello World!"
resources:
- type: scala_script
path: ViashVariables.scala
ViashVariables.scala
!/usr/bin/env scala
#
println(par.hello.get)
Using Viash placeholder variables
By adding Viash variables between a VIASH START
and a VIASH END
comment, you can write your script with Viash in mind while keeping it working for standalone execution.
#!/bin/bash
## VIASH START
par_hello="Hello World!"
## VIASH END
echo $par_hello
!/usr/bin/env dotnet-script
#
// VIASH START
var par = new {
= "Hello World!"
hello };
// VIASH END
.WriteLine(par.hello); Console
#!/usr/bin/env node
// VIASH START
let par = {
'hello': 'Hello World!'
}// VIASH END
console.log(par['hello'])
#!/usr/bin/env python3
## VIASH START
= {
par "hello": "Hello World!"
}## VIASH END
print(par["hello"])
#!/usr/bin/env Rscript
## VIASH START
<- list(
par hello = "Hello World!"
)## VIASH END
cat(par$hello)
!/usr/bin/env scala
#
// VIASH START
case class ViashPar(
: Option[String]
greeter)
val par = ViashPar(
= Some("Hello World!")
greeter )
// VIASH END
println(par.hello.get)
Output
Hello World!
Anything between VIASH START
and VIASH END
will be replaced by the injected variables Viash generates once the script is executed as part of a component. This allows you to easily troubleshoot your script while being compatible with Viash.
Language specific tips
Sourcing other scripts
With bash, you can include other bash scripts to share content and functionality by using the source
command.
By writing two scripts and adding them to the same directory, one can reference the other:
script.sh
#!/bin/bash
source include_me.sh
echo "Hello from the main script!"
include_me.sh
#!/bin/bash
echo "Hi from the included script!"
Running script.sh
results in the following output:
Hi from the included script!
Hello from the main script!
Viash supports the sourcing of scripts by adding them as a resource:
config.vsh.yaml
functionality:
name: source_example
resources:
- type: bash_script
path: script.sh
- type: bash_script
path: include_me.sh
Doing this will ensure any needed scripts will be included with the build target.
Using NuGet packages
With dotnet-script
, you can reference NuGet packages directly from within the script. In the example below, we add a reference to Newtonsoft.Json to convert a dictionary to JSON and output it to the console.
script.csx
!/usr/bin/env dotnet-script
#"nuget: Newtonsoft.Json, 13.0.1"
#r
using Newtonsoft.Json;
<string, int> downloads = new Dictionary<string, int>
Dictionary{
{ "v1.0", 501 },
{ "v1.1", 802 },
{ "v2.0", 2857 }
};
string json = JsonConvert.SerializeObject(downloads, Formatting.Indented);
.WriteLine(json); Console
Running script.csx
results in the following output:
{
"v1.0": 501,
"v1.1": 802,
"v2.0": 2857
}
We don’t have any JavaScript tips yet!
We don’t have any Python tips yet!
We don’t have any R tips yet!
We don’t have any Scala tips yet!
Meta variables
Viash offers hidden variables to use in your scripts that can be used to get meta information about your component.
Functionality name
Name of the component found in the functionality
section of the Viash config:
functionality:
name: my_component
echo $meta_functionality_name
.WriteLine(meta.functionality_name); Console
console.log(meta['functionality_name']);
print(meta["functionality_name"])
cat(meta$functionality_name)
println(meta.functionality_name)
Output
my_component
Resources directory
Path where the resources as defined in the Viash config file are stored.
echo $meta_resources_dir
.WriteLine(meta.resources_dir); Console
console.log(meta['resources_dir']);
print(meta["resources_dir"])
cat(meta$resources_dir)
println(meta.resources_dir)
When using viash run
to create a temporary build target and execute it, this will point to the temporary path where the executable was generated:
/tmp/viash_my_component9560481446119256265
After building a component using viash build
and running the generated executable, it points to the directory where the executable and the other resources reside in:
/home/user/components/my_component_target_dir
Temp directory
Path to the directory supplied by the host system where you can write temporary files to.
echo $meta_temp_dir
.WriteLine(meta.temp_dir); Console
console.log(meta['temp_dir']);
print(meta["temp_dir"])
cat(meta$temp_dir)
println(meta.temp_dir)
Output
/tmp