nb-fabric 0.4.3

CLI for managing Microsoft Fabric notebooks; create, edit cells, execute interactively, schedule, and query OneLake data
// #region Imports
use anyhow::Result;
use reqwest::Client;

use crate::client;
// #endregion

// #region Functions

/// Handle `nb run <workspace/notebook>` command.
/// Triggers a notebook run and optionally waits for completion.
///
/// Inputs:
///   - reference: "workspace/notebook" format
///   - wait: if true, poll until the job finishes
///   - timeout: max seconds to wait (default 3600)
pub async fn run_run(
    http: &Client,
    reference: &str,
    wait: bool,
    timeout: u64,
) -> Result<()> {
    let (ws_name, nb_name) = client::parse_ref(reference)?;
    let ws_id = client::resolve_workspace(http, ws_name).await?;
    let nb = client::resolve_item(http, &ws_id, nb_name, "Notebook").await?;

    let poll_url = client::run_job(http, &ws_id, &nb.id).await?;

    println!("  Job submitted for '{}'", nb.display_name);

    if wait {
        println!("  Waiting for completion (timeout: {}s)...", timeout);
        let result = client::poll_job(http, &poll_url, timeout).await?;
        let status = result.status.as_deref().unwrap_or("unknown");
        println!("  Status      {}", status);
        if let Some(ref start) = result.start_time_utc {
            println!("  Started     {}", start);
        }
        if let Some(ref end) = result.end_time_utc {
            println!("  Ended       {}", end);
        }
        if let Some(ref reason) = result.failure_reason {
            if !reason.is_null() {
                println!("  Failure     {}", reason);
            }
        }
    } else {
        println!("  Poll URL    {}", poll_url);
        println!("  Use --wait to block until completion");
    }

    Ok(())
}


/// Handle `nb runs <workspace/notebook>` command.
/// Lists recent job instances for a notebook.
pub async fn run_runs(http: &Client, reference: &str) -> Result<()> {
    let (ws_name, nb_name) = client::parse_ref(reference)?;
    let ws_id = client::resolve_workspace(http, ws_name).await?;
    let nb = client::resolve_item(http, &ws_id, nb_name, "Notebook").await?;

    let jobs = client::list_job_instances(http, &ws_id, &nb.id).await?;

    if jobs.is_empty() {
        println!("  No recent runs for '{}'", nb.display_name);
        return Ok(());
    }

    println!(
        "  {:<36}  {:<12}  {:<24}  {}",
        "Job ID", "Status", "Start", "End"
    );
    println!(
        "  {:<36}  {:<12}  {:<24}  {}",
        "-".repeat(36),
        "-".repeat(12),
        "-".repeat(24),
        "-".repeat(24)
    );

    for job in &jobs {
        println!(
            "  {:<36}  {:<12}  {:<24}  {}",
            job.id.as_deref().unwrap_or("-"),
            job.status.as_deref().unwrap_or("-"),
            job.start_time_utc.as_deref().unwrap_or("-"),
            job.end_time_utc.as_deref().unwrap_or("-"),
        );
    }

    println!("\n  {} run(s)", jobs.len());
    Ok(())
}

// #endregion