TabSailTabSail

Upload and download files

Stream file content, distinguish local and remote paths, and finish transfers before closing the browser.

These fragments assume an initialized TypeScript client and a ready session owned by your application. Start with the Quickstart for lifecycle setup.

Upload a document

const uploaded = await client.sessions.files.upload(session.id, {
  file: new TextEncoder().encode("name,value\nexample,1\n"),
  filename: "input.csv",
  contentType: "text/csv",
});

The returned browserPath is inside the remote browser, not your application's filesystem. For a file input, the remote CDP pattern is:

const cdp = await page.context().newCDPSession(page);
const document = await cdp.send("DOM.getDocument");
const input = await cdp.send("DOM.querySelector", {
  nodeId: document.root.nodeId,
  selector: 'input[type="file"]',
});
if (!input.nodeId) throw new Error("File input not found");
await cdp.send("DOM.setFileInputFiles", {
  nodeId: input.nodeId,
  files: [uploaded.browserPath],
});

This fragment additionally requires a connected Playwright page containing the target file input. Adapt the selector to your website.

Retrieve file bytes

To copy a known ready file to your application's local storage:

import { open } from "node:fs/promises";

const output = await open("saved-input.csv", "w");
try {
  const download = await client.sessions.files.download(session.id, uploaded.id);
  try {
    for await (const chunk of download) await output.writeFile(chunk);
  } finally {
    await download.close();
  }
} finally {
  await output.close();
}

For a website download, first list sessions.files.list(session.id, { origin: "download" }), follow pagination, and inspect the chosen file's status. Complete and verify the stream before releasing the session.

Python accepts bytes, pathlib.Path, or a binary file object for upload. Consume downloads with async with client.sessions.files.download(session_id, file_id) as download and download.aiter_bytes().

Handle interruption

Uploads are not automatically replayed after an unknown result. Inspect the file list before deciding whether another upload is required. HTTP transfer deadlines are separate from the browser lifetime. An early download exit closes the local response; it does not close the remote browser or preserve the temporary file indefinitely.

On this page