From 1a89b9d4e80f78eb3e1b5504f1bff8886d7fbd99 Mon Sep 17 00:00:00 2001 From: Paul Thurlow Date: Mon, 16 Mar 2026 11:57:04 -0700 Subject: [PATCH] Add upload id functionality to datasets create command --- src/command.rs | 12 +++++++++-- src/datasets.rs | 55 +++++++++++++++++++++++++++++++++++-------------- src/main.rs | 4 ++-- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/command.rs b/src/command.rs index 442ba93..2f2f6eb 100644 --- a/src/command.rs +++ b/src/command.rs @@ -179,7 +179,7 @@ pub enum DatasetsCommands { format: String, }, - /// Create a new dataset from a file or piped stdin + /// Create a new dataset from a file, piped stdin, or a pre-existing upload ID Create { /// Dataset label (derived from filename if omitted) #[arg(long)] @@ -190,8 +190,16 @@ pub enum DatasetsCommands { table_name: Option, /// Path to a file to upload (omit to read from stdin) - #[arg(long)] + #[arg(long, conflicts_with = "upload_id")] file: Option, + + /// Skip upload and use a pre-existing upload ID directly + #[arg(long, conflicts_with = "file")] + upload_id: Option, + + /// Source format when using --upload-id (csv, json, parquet) + #[arg(long, default_value = "csv", value_parser = ["csv", "json", "parquet"], requires = "upload_id")] + format: String, }, } diff --git a/src/datasets.rs b/src/datasets.rs index a9b44a1..15d993c 100644 --- a/src/datasets.rs +++ b/src/datasets.rs @@ -231,6 +231,8 @@ pub fn create( label: Option<&str>, table_name: Option<&str>, file: Option<&str>, + upload_id: Option<&str>, + source_format: &str, ) { let profile_config = match config::load("default") { Ok(c) => c, @@ -260,31 +262,42 @@ pub fn create( .to_string(); &label_derived } - None => match stdin_redirect_filename() { - Some(name) => { - label_derived = name; - &label_derived - } - None => { + None => { + if upload_id.is_some() { eprintln!("error: no label provided. Use --label to name the dataset."); std::process::exit(1); } - }, + match stdin_redirect_filename() { + Some(name) => { + label_derived = name; + &label_derived + } + None => { + eprintln!("error: no label provided. Use --label to name the dataset."); + std::process::exit(1); + } + } + } }, }; let client = reqwest::blocking::Client::new(); - let (upload_id, format) = match file { - Some(path) => upload_from_file(&client, &api_key, workspace_id, &profile_config.api_url, path), - None => { - use std::io::IsTerminal; - if std::io::stdin().is_terminal() { - eprintln!("error: no input data. Use --file or pipe data via stdin."); - std::process::exit(1); + let (upload_id, format, upload_id_was_uploaded): (String, &str, bool) = if let Some(id) = upload_id { + (id.to_string(), source_format, false) + } else { + let (id, fmt) = match file { + Some(path) => upload_from_file(&client, &api_key, workspace_id, &profile_config.api_url, path), + None => { + use std::io::IsTerminal; + if std::io::stdin().is_terminal() { + eprintln!("error: no input data. Use --file , --upload-id , or pipe data via stdin."); + std::process::exit(1); + } + upload_from_stdin(&client, &api_key, workspace_id, &profile_config.api_url) } - upload_from_stdin(&client, &api_key, workspace_id, &profile_config.api_url) - } + }; + (id, fmt, true) }; let source = json!({ "upload_id": upload_id, "format": format }); @@ -312,6 +325,16 @@ pub fn create( if !resp.status().is_success() { use crossterm::style::Stylize; eprintln!("{}", api_error(resp.text().unwrap_or_default()).red()); + // Only show the resume hint when the upload_id came from a fresh upload + if upload_id_was_uploaded { + eprintln!( + "{}", + format!( + "Resume dataset creation without re-uploading by passing --upload-id {upload_id}" + ) + .yellow() + ); + } std::process::exit(1); } diff --git a/src/main.rs b/src/main.rs index 715cca0..01d3aa2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,8 +70,8 @@ fn main() { Some(DatasetsCommands::List { limit, offset, format }) => { datasets::list(&workspace_id, limit, offset, &format) } - Some(DatasetsCommands::Create { label, table_name, file }) => { - datasets::create(&workspace_id, label.as_deref(), table_name.as_deref(), file.as_deref()) + Some(DatasetsCommands::Create { label, table_name, file, upload_id, format }) => { + datasets::create(&workspace_id, label.as_deref(), table_name.as_deref(), file.as_deref(), upload_id.as_deref(), &format) } None => { use clap::CommandFactory;