--- title: "Files and Batch API Workflows" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Files and Batch API Workflows} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} fixture_dir <- "files-batches" recording <- nzchar(Sys.getenv("FOUNDRY_RECORD_DOCS")) have_fixtures <- dir.exists(fixture_dir) && length(list.files(fixture_dir)) > 0 run_api <- requireNamespace("httptest2", quietly = TRUE) && (recording || have_fixtures) # Attach foundryR before start_vignette(): httptest2 only sources the package's # inst/httptest2/start-vignette.R (which sets replay placeholders) from attached # packages. library(foundryR) if (run_api) { httptest2::start_vignette(fixture_dir) } knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = run_api ) ``` ```{r libraries, eval = TRUE} library(foundryR) ``` The Batch API is useful when your research task has hundreds or thousands of independent rows: survey coding, abstract screening, entity extraction, document classification, or large-scale summarization. ## Prepare JSONL locally `foundry_batch_requests()` runs locally. It converts a data frame into the JSON Lines shape expected by the Batch API. ```{r batch-jsonl, eval = TRUE} survey <- data.frame( id = c("resp-001", "resp-002", "resp-003"), response = c( "The workshop was clear and practical.", "I liked the examples but wanted more time.", "The setup instructions were confusing." ) ) jsonl <- tempfile(fileext = ".jsonl") request_file <- foundry_batch_requests( survey, input = "response", path = jsonl, model = "gpt-5-nano", custom_id = "id", body = list( instructions = "Classify the response sentiment as positive, neutral, or negative." ) ) request_file head(readLines(jsonl), 2) ``` The example files use R's temporary directory and are removed after use. For results you want to keep, choose an explicit output path in your own workflow. ## Upload and create a batch Uploading and batch creation call the Foundry service, so these chunks are not run while building the vignette. ```{r upload-create, eval = FALSE} file <- foundry_file_upload(jsonl, purpose = "batch") unlink(jsonl) batch <- foundry_batch_create( input_file_id = file$file_id, endpoint = "/v1/responses" ) ``` The returned objects include service identifiers, status fields, file sizes, completion windows, and request counts. ## Poll and download results These service calls are not run during rendering. Poll until the batch status is `"completed"` before downloading its output. ```{r poll-download, eval = FALSE} batch <- foundry_batch_get(batch$batch_id) output_path <- tempfile(fileext = ".jsonl") foundry_file_download( file_id = batch$output_file_id, path = output_path ) ``` Output files are JSONL too. Read a few lines first before parsing a large job: ```{r output-shape, eval = FALSE} output_lines <- readLines(output_path, n = 2) head(output_lines) unlink(output_path) ``` ## Practical advice - Start with 10 to 20 rows and inspect the output before scaling up. - Use stable `custom_id` values so results join back to your data frame. - Store prompts and schema versions with your analysis code for reproducibility. - Download both output and error files when a batch finishes. ```{r cleanup, include = FALSE, eval = TRUE} unlink(jsonl) if (run_api) { httptest2::end_vignette() } ```