import fs from 'fs'import { Sandbox } from 'e2b'const sandbox = await Sandbox.create()// Read file from local filesystemconst content = fs.readFileSync('/local/path')// Upload file to sandboxawait sandbox.files.write('/path/in/sandbox', content)
from e2b import Sandboxsandbox = Sandbox.create()# Read file from local filesystemwith open("path/to/local/file", "rb") as file: # Upload file to sandbox sandbox.files.write("/path/in/sandbox", file)
Instead of reading a whole file into memory first, pass a stream (or an iterable of byte chunks) to files.write(). Chunks are uploaded as they arrive, so the size of the data doesn’t matter.
import fs from 'fs'import { Sandbox } from 'e2b'const sandbox = await Sandbox.create()// Any AsyncIterable<Uint8Array>, like a Node.js Readable...await sandbox.files.write('/path/in/sandbox', fs.createReadStream('/local/path'))// ...or a ReadableStream, like a fetch response bodyconst response = await fetch('https://example.com/large-file.zip')await sandbox.files.write('/path/in/sandbox/large-file.zip', response.body)
import requestsfrom e2b import Sandboxsandbox = Sandbox.create()# Any iterable of bytes chunks, like a streamed HTTP response...with requests.get("https://example.com/large-file.zip", stream=True) as response: sandbox.files.write("/path/in/sandbox/large-file.zip", response.iter_content(chunk_size=1024 * 1024))# ...or a generatordef chunks(): for part in range(3): yield f"part {part}\n".encode()sandbox.files.write("/path/in/sandbox/parts.txt", chunks())
import httpxfrom e2b import AsyncSandboxsandbox = await AsyncSandbox.create()# Any async iterable of bytes chunks, like a streamed HTTP response...async with httpx.AsyncClient() as client: async with client.stream("GET", "https://example.com/large-file.zip") as response: await sandbox.files.write("/path/in/sandbox/large-file.zip", response.aiter_bytes())# ...or an async generatorasync def chunks(): for part in range(3): yield f"part {part}\n".encode()await sandbox.files.write("/path/in/sandbox/parts.txt", chunks())
Streams are always uploaded as application/octet-stream and are never buffered, so useOctetStream: false (use_octet_stream=False in Python) raises an error for them. gzip: true compresses the stream on the fly.
Sandbox accepts sync iterables and AsyncSandbox accepts async iterables. In browsers that can’t stream request bodies (Firefox, Safari), convert the stream to a Blob first, for example await new Response(stream).blob().
Sometimes, you may want to let users from unauthorized environments, like a browser, upload files to the sandbox.
For this use case, you can use pre-signed URLs to let users upload files securely.Every sandbox has secured access enabled, so all you need to do is generate a URL with a signature that allows only authorized users to upload files.
You can optionally set an expiration time for the URL so that it will be valid only for a limited time.
import { Sandbox } from 'e2b'// Start a sandbox (all operations must be authorized by default)const sandbox = await Sandbox.create(template)// Create a pre-signed URL for file upload with a 10 second expirationconst publicUploadUrl = await sandbox.uploadUrl( 'demo.txt', { useSignatureExpiration: 10_000, // optional },)// Upload a file with a pre-signed URL (this can be used in any environment, such as a browser)const form = new FormData()form.append('file', 'file content')await fetch(publicUploadUrl, { method: 'POST', body: form })// File is now available in the sandbox and you can read itconst content = sandbox.files.read('/path/in/sandbox')
from e2b import Sandboximport requests# Start a sandbox (all operations must be authorized by default)sandbox = Sandbox.create(timeout=12_000)# Create a pre-signed URL for file upload with a 10 second expirationsigned_url = sandbox.upload_url(path="demo.txt", user="user", use_signature_expiration=10_000)form_data = {"file":"file content"}requests.post(signed_url, data=form_data)# File is now available in the sandbox and you can read itcontent = sandbox.files.read('/path/in/sandbox')