Crates.io | wmill |
lib.rs | wmill |
version | 1.548.3 |
created_at | 2025-06-18 06:21:55.045557+00 |
updated_at | 2025-09-25 10:40:53.564649+00 |
description | A client library for accessing Windmill server wrapping the Windmill client API |
homepage | https://windmill.dev |
repository | |
max_upload_size | |
id | 1716670 |
size | 590,188 |
A Rust client library for interacting with Windmill API, providing type-safe abstractions for variables, resources, scripts, jobs, and state management.
Add this to your Cargo.toml
:
[dependencies]
wmill = "0.1.0"
For async support (recommended):
[dependencies]
wmill = { version = "0.1.0", features = ["async"] }
use wmill::Windmill;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Read config from env vars
let wm = Windmill::default()?;
// Or override specific values
let wm = Windmill::new(
Some("custom_token".to_string()),
Some("my_workspace".to_string()),
Some("http://localhost:8000".to_string())
)?;
Ok(())
}
// Get variable (auto-parsed)
let db_config: serde_json::Value = wm.get_variable("u/admin/db_config").await?;
// Get raw variable
let raw_text = wm.get_variable_raw("u/user/text_note").await?;
// Set variable
wm.set_variable("new_value".to_string(), "u/user/my_var", false).await?;
// Get resource (typed)
#[derive(serde::Deserialize)]
struct DbConfig { host: String, port: u16 }
let config: DbConfig = wm.get_resource("u/admin/db").await?;
// Get raw resource
let raw_json = wm.get_resource_any("u/admin/db").await?;
// Set resource
wm.set_resource(
Some(serde_json::json!({"host": "localhost", "port": 5432})),
"u/admin/db",
"postgresql"
).await?;
// Run script async
let job_id = wm.run_script_async(
"u/user/my_script",
false,
serde_json::json!({"param": "value"}),
Some(10) // Schedule in 10 seconds
).await?;
// Run script sync
let result = wm.run_script_sync(
"u/user/my_script",
false,
serde_json::json!({"param": "value"}),
Some(10),
Some(30), // 30s timeout
true, // Verbose
true // Assert result not None
).await?;
// Wait for job completion
let result = wm.wait_job(&job_id, Some(60), true, true).await?;
// Get job status
let status = wm.get_job_status(&job_id).await?; // Running/Waiting/Completed
// Get result directly
let result = wm.get_result(&job_id).await?;
// Get typed state
#[derive(serde::Deserialize)]
struct ScriptState { counter: i32 }
let state: ScriptState = wm.get_state().await?;
// Get raw state
let raw_state = wm.get_state_any().await?;
// Update state
wm.set_state(Some(serde_json::json!({"counter": 42}))).await?;
// Set job progress
wm.set_progress(75, None).await?; // Uses current job ID from env
// Get job progress
let progress = wm.get_progress(Some(job_id.to_string())).await?;
The SDK provides direct access to underlying API endpoints through the call_api
method, which works in both async and sync contexts:
// Async usage
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let wm = Windmill::default()?;
// Make direct API call to get user
let user = wm.call_api(wmill::apis::admin_api::get_user(
&wm.client_config,
&wm.workspace,
"Alice"
)).await;
println!("User details: {:?}", user);
Ok(())
}
// Sync usage
fn main() {
let wm = Windmill::default().unwrap();
// Make direct API call to get user
let user = wm.call_api(wmill::apis::admin_api::get_user(
&wm.client_config,
&wm.workspace,
"Bob"
));
println!("User details: {:?}", user);
}
This advanced feature allows access to any Windmill API endpoint, even those not covered by the SDK's convenience methods. Use this when:
The SDK uses these environment variables:
Variable | Required | Description |
---|---|---|
WM_TOKEN |
✅ | Authentication token |
WM_WORKSPACE |
✅ | Workspace name |
BASE_INTERNAL_URL |
✅ | API base URL (without /api ) |
WM_JOB_ID |
Optional | Current job ID for progress tracking |
WM_STATE_PATH_NEW |
Optional | State path override |
Contributions are welcome! Please open an issue or submit a PR.