Downloads
Last updated
Last updated
Hyperbrowser makes it easy to download files during your browser sessions. The files you download get stored securely in our cloud infrastructure as a zip file. You can then retrieve them using a simple API call.
Create a new Hyperbrowser session and set the saveDownloads
param to true
Connect to the session using your preferred automation framework (like Puppeteer or Playwright)
Set the download location in your code
Download files
Retrieve the download zip URL from Sessions API
Please contact us at to get access to this feature.
Note the id
of the session you want to retrieve downloads for
Use the Session API to get the downloadURL for the zip, or if you are using the SDKs, you can just call the getDownloadsURL
function
The response for the getDownloadsURL
will have a status associated with it which can be not_enabled
if saveDownloads
was not enabled for the session, pending
or in_progress
if the zip file is in progress of being uploaded to our storage, and completed
or failed
once it is finished.
status: "not_enabled" | "pending" | "in_progress" | "completed" | "failed"
downloadsUrl: string | null
error?: string | null
import { connect } from "puppeteer-core";
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const hbClient = new Hyperbrowser({
apiKey: process.env.HYPERBROWSER_API_KEY,
});
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const main = async () => {
const session = await hbClient.sessions.create({
saveDownloads: true,
});
try {
const browser = await connect({
browserWSEndpoint: session.wsEndpoint,
});
const page = (await browser.pages())[0];
const cdp = await browser.target().createCDPSession();
await cdp.send("Browser.setDownloadBehavior", {
behavior: "allow",
downloadPath: "/tmp/downloads",
eventsEnabled: true,
});
await page.goto("https://browser-tests-alpha.vercel.app/api/download-test");
// Download file from the page
// Set up download listener
cdp.on("Browser.downloadWillBegin", (event) => {
console.log("Download started:", event.suggestedFilename);
});
// Create a promise that resolves when the download is complete
const downloadPromise = new Promise((resolve) => {
cdp.on("Browser.downloadProgress", (event) => {
if (event.state === "completed" || event.state === "canceled") {
resolve("Done");
}
});
});
// Start the download and wait for it to complete
await Promise.all([downloadPromise, page.locator("#download").click()]);
console.log("Download completed");
await hbClient.sessions.stop(session.id);
await sleep(3000);
// Wait for the zipped downloads to be uploaded to our storage
let downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
while (downloadsResponse.status === "in_progress") {
console.log("Waiting for downloads zip to be ready...");
await sleep(1000);
downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
}
console.log("downloadsResponse", downloadsResponse);
} catch (err) {
console.error(`Encountered error: ${err}`);
} finally {
await hbClient.sessions.stop(session.id);
}
};
main().catch((err) => console.error(`Encountered error: ${err}`));
import { chromium } from "playwright-core";
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const hbClient = new Hyperbrowser({
apiKey: process.env.HYPERBROWSER_API_KEY,
});
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const main = async () => {
const session = await hbClient.sessions.create({
saveDownloads: true,
});
try {
const browser = await chromium.connectOverCDP(session.wsEndpoint);
const context = browser.contexts()[0];
const page = context.pages()[0];
const cdp = await browser.newBrowserCDPSession();
await cdp.send("Browser.setDownloadBehavior", {
behavior: "allow",
downloadPath: "/tmp/downloads",
eventsEnabled: true,
});
await page.goto("https://browser-tests-alpha.vercel.app/api/download-test");
// Download file from the page
const downloadPromise = page.waitForEvent("download");
await page.getByRole("link", { name: "Download File" }).click();
const download = await downloadPromise;
// Wait for the download to complete
await download.path();
console.log("Downloaded file:", download.suggestedFilename());
await hbClient.sessions.stop(session.id);
await sleep(3000);
// Wait for the zipped downloads to be uploaded to our storage
let downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
while (downloadsResponse.status === "in_progress") {
console.log("Waiting for downloads zip to be ready...");
await sleep(1000);
downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
}
console.log("downloadsResponse", downloadsResponse);
} catch (err) {
console.error(`Encountered error: ${err}`);
} finally {
await hbClient.sessions.stop(session.id);
}
};
main().catch((err) => console.error(`Encountered error: ${err}`));
import os
import asyncio
from pyppeteer import connect
from hyperbrowser import AsyncHyperbrowser
from hyperbrowser.models import CreateSessionParams
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Initialize Hyperbrowser client
hb_client = AsyncHyperbrowser(api_key=os.environ.get("HYPERBROWSER_API_KEY"))
async def main():
# Create a session with downloads enabled
session = await hb_client.sessions.create(CreateSessionParams(save_downloads=True))
try:
# Connect to the browser
browser = await connect(browserWSEndpoint=session.ws_endpoint)
# Get the first page
pages = await browser.pages()
page = pages[0]
# Get the CDP client
client = page._client
# Configure download behavior
await client.send(
"Browser.setDownloadBehavior",
{
"behavior": "allow",
"downloadPath": "/tmp/downloads",
"eventsEnabled": True,
},
)
# Navigate to the test page
await page.goto("https://browser-tests-alpha.vercel.app/api/download-test")
# Set up download event handlers
download_completed = asyncio.Event()
def on_download_begin(event):
print(f"Download started: {event.get('suggestedFilename', 'unknown')}")
def on_download_progress(event):
if event.get("state") in ["completed", "canceled"]:
download_completed.set()
client.on("Browser.downloadWillBegin", on_download_begin)
client.on("Browser.downloadProgress", on_download_progress)
# Start the download by clicking the button
download_task = asyncio.create_task(download_completed.wait())
await page.click("#download")
# Add a timeout to prevent hanging indefinitely
try:
await asyncio.wait_for(download_task, timeout=30)
print("Download completed")
except asyncio.TimeoutError:
print("Download timed out after 30 seconds")
await hb_client.sessions.stop(session.id)
await asyncio.sleep(3)
# Wait for downloads to be processed and uploaded
downloads_response = await hb_client.sessions.get_downloads_url(session.id)
while downloads_response.status == "in_progress":
print("Waiting for downloads zip to be ready...")
await asyncio.sleep(1)
downloads_response = await hb_client.sessions.get_downloads_url(session.id)
print("downloadsResponse", downloads_response)
except Exception as err:
print(f"Encountered error: {err}")
finally:
await hb_client.sessions.stop(session.id)
# Run the main function
if __name__ == "__main__":
asyncio.run(main())
import asyncio
from hyperbrowser import AsyncHyperbrowser
from hyperbrowser.models import CreateSessionParams
from playwright.async_api import async_playwright
from dotenv import load_dotenv
import os
load_dotenv()
hb_client = AsyncHyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))
async def main():
session = await hb_client.sessions.create(CreateSessionParams(save_downloads=True))
try:
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(session.ws_endpoint)
context = browser.contexts[0]
page = context.pages[0]
cdp = await browser.new_browser_cdp_session()
await cdp.send(
"Browser.setDownloadBehavior",
{
"behavior": "allow",
"downloadPath": "/tmp/downloads",
"eventsEnabled": True,
},
)
# Navigate to a website
await page.goto("https://browser-tests-alpha.vercel.app/api/download-test")
# Start listening for download events before clicking
async with page.expect_download() as download_info:
await page.get_by_role("link", name="Download File").click()
download = await download_info.value
# Wait for the download to complete
await download.path()
print("Downloaded file:", download.suggested_filename)
# Stop the session and wait a few seconds to check downloads status
await hb_client.sessions.stop(session.id)
print("Session stopped, waiting a few seconds to check downloads status.")
await asyncio.sleep(3)
downloads_response = await hb_client.sessions.get_downloads_url(session.id)
while downloads_response.status == "in_progress":
print("Waiting for downloads zip to be ready...")
await asyncio.sleep(1)
downloads_response = await hb_client.sessions.get_downloads_url(session.id)
print("downloads_response\n", downloads_response.model_dump_json(indent=2))
except Exception as e:
print(f"Error: {e}")
finally:
await hb_client.sessions.stop(session.id)
if __name__ == "__main__":
asyncio.run(main())
Similarly as above, you can get the downloads zip of files that were downloaded during the session used by an AI Agent. We just need to create a session with saveDownloads
set to True and then pass in that session ID. Here is an example of doing it with OpenAI CUA.
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const hbClient = new Hyperbrowser({
apiKey: process.env.HYPERBROWSER_API_KEY,
});
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const main = async () => {
const session = await hbClient.sessions.create({
saveDownloads: true,
});
try {
const resp = await hbClient.agents.cua.startAndWait({
task: "1. Go to this site https://browser-tests-alpha.vercel.app/api/download-test. 2. Click on the Download File link once, then end the task. Do not wait or double check the download, just end the task.",
sessionId: session.id,
});
console.log("Status:", resp.status);
console.log("Final result:", resp.data?.finalResult);
await hbClient.sessions.stop(session.id);
await sleep(3000);
// Wait for the zipped downloads to be uploaded to our storage
let downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
while (downloadsResponse.status === "in_progress") {
console.log("Waiting for downloads zip to be ready...");
await sleep(1000);
downloadsResponse = await hbClient.sessions.getDownloadsURL(session.id);
}
console.log("downloadsResponse", downloadsResponse);
} catch (err) {
console.error(`Encountered error: ${err}`);
} finally {
await hbClient.sessions.stop(session.id);
}
};
main().catch((err) => console.error(`Encountered error: ${err}`));
from time import sleep
from hyperbrowser import Hyperbrowser
from hyperbrowser.models import CreateSessionParams, StartCuaTaskParams
from dotenv import load_dotenv
import os
load_dotenv()
hb_client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))
def main():
session = hb_client.sessions.create(CreateSessionParams(save_downloads=True))
try:
resp = hb_client.agents.cua.start_and_wait(
StartCuaTaskParams(
task="1. Go to this site https://browser-tests-alpha.vercel.app/api/download-test. 2. Click on the Download File link once, then end the task. Do not wait or double check the download, just end the task.",
session_id=session.id,
)
)
print("Status:", resp.status)
print("Final Result:", resp.data.final_result)
hb_client.sessions.stop(session.id)
sleep(3)
downloads_response = hb_client.sessions.get_downloads_url(session.id)
while downloads_response.status == "in_progress":
print("Waiting for downloads zip to be ready...")
sleep(1)
downloads_response = hb_client.sessions.get_downloads_url(session.id)
print("downloads_response", downloads_response.model_dump_json(indent=2))
except Exception as e:
print(f"Error: {e}")
hb_client.sessions.stop(session.id)
if __name__ == "__main__":
main()
Download zip files are stored securely in Hyperbrowser's cloud infrastructure and are retained according to your plan's data retention policy.