Rust quickstart
In this quick start guide, we will write our first script in Rust.
This tutorial covers how to create a simple script through Windmill web IDE. See the dedicated page to Develop Scripts Locally.
Scripts are the basic building blocks in Windmill. They can be run and scheduled as standalone, chained together to create Flows or displayed with a personalized User Interface as Apps.
Scripts consist of 2 parts:
- Code: for Rust scripts, it must have at least a main function.
- Settings: settings & metadata about the Script such as its path, summary, description, jsonschema of its inputs (inferred from its signature).
When stored in a code repository, these 2 parts are stored separately at <path>.rs
and <path>.script.yaml
Windmill automatically manages dependencies for you. When you import libraries in your Rust script, Windmill parses these imports upon saving the script and automatically generates a list of dependencies. It then spawns a dependency job to associate these PyPI packages with a lockfile, ensuring that the same version of the script is always executed with the same versions of its dependencies.
From the Home page, click +Script
. This will take you to the first step of script creation: Metadata.
Settings
As part of the settings menu, each script has metadata associated with it, enabling it to be defined and configured in depth.
- Path is the Script's unique identifier that consists of the script's owner, and the script's name. The owner can be either a user, or a group (folder).
- Summary (optional) is a short, human-readable summary of the Script. It
will be displayed as a title across Windmill. If omitted, the UI will use the
path
by default. - Language of the script.
- Description is where you can give instructions through the auto-generated UI to users on how to run your Script. It supports markdown.
- Script kind: Action (by default), Trigger, Approval or Error handler. This acts as a tag to filter appropriate scripts from the flow editor.
This menu also has additional settings on Runtime, Generated UI and Triggers.
Now click on the code editor on the left side.
Code
Windmill provides an online editor to work on your Scripts. The left-side is the editor itself. The right-side previews the UI that Windmill will generate from the Script's signature - this will be visible to the users of the Script. You can preview that UI, provide input values, and test your script there.
As we picked rust
for this example, Windmill provided some rust
boilerplate. Let's take a look:
//! Add dependencies in the following partial Cargo.toml manifest
//!
//! ```cargo
//! [dependencies]
//! anyhow = "1.0.86"
//! rand = "0.7.2"
//! ```
//!
//! Note that serde is used by default with the `derive` feature.
//! You can still reimport it if you need additional features.
use anyhow::anyhow;
use rand::seq::SliceRandom;
use serde::Serialize;
#[derive(Serialize, Debug)]
struct Ret {
msg: String,
number: i8,
}
fn main(who_to_greet: String, numbers: Vec<i8>) -> anyhow::Result<Ret> {
println!(
"Person to greet: {} - numbers to choose: {:?}",
who_to_greet, numbers
);
Ok(Ret {
msg: format!("Greetings {}!", who_to_greet),
number: *numbers
.choose(&mut rand::thread_rng())
.ok_or(anyhow!("There should be some numbers to choose from"))?,
})
}
In Windmill, scripts need to have a main
function that will be the script's
entrypoint. There are a few important things to note about the main
.
- The main arguments are used for generating
- the input spec of the Script
- the frontend that you see when running the Script as a standalone app.
- Type annotations are used to generate the UI form, and help pre-validate inputs. While not mandatory, they are highly recommended. You can customize the UI in later steps (but not change the input type!).
Packages can be installed using cargo. Just add the dependencies you need in the partial Cargo.toml manifest and Windmill will install them for you:
//! ```cargo
//! [dependencies]
//! anyhow = "1.0.86"
//! rand = "0.7.2"
//! ```