Skip to main content
Use write() for in-memory strings and bytes. Use upload_file() for local files, upload_dir() for directories, and upload() when you want the SDK to dispatch by source type. upload() accepts local file paths, directories, file-like objects, and stdin style streams. Directory-specific options such as conflict and ignore_patterns belong on upload_dir(); resumable options such as resumable, checksum, and spool_to_disk belong on upload_file().

Write many small files

sandbox.files.write_files([
    ("/workspace/app.py", "print('hello')\n"),
    ("/workspace/README.md", "# Demo\n"),
])

Upload one file

result = sandbox.files.upload_file("./dist/app.tar.gz", "/workspace/app.tar.gz")
print(result.transport, result.target_path, result.bytes_uploaded)
Upload destinations must be valid sandbox paths. Do not upload into /workspace/.nullspace, which is reserved for runtime metadata and resumable transfer state.

Upload a directory

result = sandbox.files.upload_dir(
    "./src",
    "/workspace/src",
    conflict="merge",
    ignore_patterns=["*.pyc", "!pkg/__init__.py"],
)
print(result.file_count, result.target_path)
Directory uploads honor .nullspaceignore from the source root and append any explicit ignore_patterns after it. Conflict policies control how existing destination files are handled; use "merge" for normal sync-style uploads and choose stricter policies when automation must fail on pre-existing paths.

Resumable upload and progress

from nullspace import FileUploadError

def on_progress(event) -> None:
    print(event.phase, event.bytes_completed, event.bytes_total, event.transport)

try:
    result = sandbox.files.upload_file(
        "./large-model.bin",
        "/data/model.bin",
        resumable=True,
        checksum="auto",
        spool_to_disk="auto",
        max_concurrency=4,
        progress=on_progress,
    )
except FileUploadError as exc:
    if exc.upload_id is None:
        raise
    result = sandbox.files.resume_upload(
        exc.upload_id,
        "./large-model.bin",
        progress=on_progress,
    )

print(result.upload_id, result.bytes_uploaded)

Signed upload URL

grant = sandbox.files.upload_url("/workspace/input.bin")
print(grant.url, grant.method, grant.headers)
Use a signed upload URL when a browser or another service should upload bytes directly. Use sandbox.upload_url(path) as a convenience wrapper around sandbox.files.upload_url(path).url. The signed upload grant includes the URL plus request metadata such as the HTTP method and required headers. Forward those fields to the client performing the direct upload.