Skip to content

W&B Sandboxes#2426

Open
ngrayluna wants to merge 5 commits intomainfrom
sandboxes
Open

W&B Sandboxes#2426
ngrayluna wants to merge 5 commits intomainfrom
sandboxes

Conversation

@ngrayluna
Copy link
Copy Markdown
Contributor

@ngrayluna ngrayluna commented Apr 7, 2026

Description

W&B Sandboxes (Private Preview). Currently documents:

  • Overview (what it is, high-level how it works)
  • Sandbox lifecycle
  • Create sandboxes
  • Run commands
  • File access (read/write/mount)
  • Secrets
  • Tutorial: Train PyTorch model in a sandbox
  • Tutorial: Invoke an agent within a sandbox

@mintlify
Copy link
Copy Markdown
Contributor

mintlify bot commented Apr 7, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
wandb 🟢 Ready View Preview Apr 7, 2026, 2:19 AM

@ngrayluna ngrayluna added the DO-NOT-MERGE For PRs that should not be merged yet label Apr 7, 2026
@ngrayluna ngrayluna changed the title Feature: W&B Sandboxes W&B Sandboxes Apr 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

📚 Mintlify Preview Links

🔗 View Full Preview

✨ Added (8 total)

📄 Pages (8)

File Preview
sandboxes.mdx Sandboxes
sandboxes/create-sandbox.mdx Create Sandbox
sandboxes/file-access.mdx File Access
sandboxes/invoke_agent_sandbox_tutorial.mdx Invoke Agent Sandbox Tutorial
sandboxes/lifecycle.mdx Lifecycle
sandboxes/mltrain_in_sandbox_tutorial.mdx Mltrain In Sandbox Tutorial
sandboxes/run-commands.mdx Run Commands
sandboxes/secrets.mdx Secrets

📝 Changed (1 total)

⚙️ Other (1)
File
docs.json

🤖 Generated automatically when Mintlify deployment succeeds
📍 Deployment: e739e37 at 2026-04-07 02:51:57 UTC

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🔗 Link Checker Results

⚠️ Some issues were detected

Checked against: https://wb-21fd5541-sandboxes.mintlify.app


Summary

Status Count
🔍 Total 30
✅ Successful 9
⏳ Timeouts 0
🔀 Redirected 0
👻 Excluded 20
❓ Unknown 0
🚫 Errors 1
⛔ Unsupported 0

Errors per input

Errors in sandboxes.mdx

Full Github Actions output

@ngrayluna ngrayluna marked this pull request as ready for review April 7, 2026 02:56
@ngrayluna ngrayluna requested a review from a team as a code owner April 7, 2026 02:56
@trane293
Copy link
Copy Markdown
Contributor

trane293 commented Apr 7, 2026

Review

Overall the docs are well-structured and cover the right topics. The API patterns are mostly accurate against the SDK. Flagging the following issues before merge.


Must Fix

1. wait_until_complete() missing .result() call
Files: sandboxes/lifecycle.mdx (line 63), sandboxes/run-commands.mdx (line 23)

Both show:

sandbox.wait_until_complete(timeout=3600.0)
print(f"Exit code: {sandbox.returncode}")

wait_until_complete() returns an OperationRef[Sandbox], not Sandbox. Without .result(), the call doesn't block and sandbox.returncode will be None. The SDK's own docstring shows the correct pattern:

sandbox.wait_until_complete(timeout=3600.0).result()
print(f"Exit code: {sandbox.returncode}")

2. Credential propagation claim is inaccurate
File: sandboxes.mdx (line 12)

"your W&B credentials work automatically, and sandbox sessions can report metrics to an active W&B run"

This is not true today. W&B credentials authenticate you to the sandbox service (creating/managing sandboxes via ATC), but they are not propagated inside the sandbox container. Code running inside the sandbox has no access to your W&B API key, so wandb.init(), wandb.log(), and Weave calls won't work without explicitly passing WANDB_API_KEY via environment_variables or the Secrets API.

Suggested rewrite: "Sandboxes authenticate using your existing W&B credentials. To use W&B or Weave inside a sandbox, pass your API key using the Secrets Manager or environment variables."


3. echo > file doesn't work without a shell
File: sandboxes/file-access.mdx (line 53)

sandbox.exec(["echo", "Hello, world.", ">", "hello.txt"]).result()

When args are passed as a list, exec() doesn't invoke a shell. The > is passed as a literal argument to echo, so no file is created and the subsequent read_file("hello.txt") would fail. Should be:

sandbox.exec(["sh", "-c", "echo 'Hello, world.' > hello.txt"]).result()

Also, Path is used on line 57 (Path("hello.txt").write_bytes(content)) but is never imported in this example.


4. LangChain agent tutorial should be replaced
File: sandboxes/invoke_agent_sandbox_tutorial.mdx

LangChain is a direct competitor. We should not be featuring their library in our docs. Beyond the competitive concern, the code has technical issues:

  • ToolRuntime[Context] (line 94): ToolRuntime is a dataclass, not a generic type
  • No version pins: create_agent was removed in LangChain v1.1.0, so pip install langchain langgraph langchain_anthropic without version constraints will break
  • @dataclass used for ResponseFormat where ToolStrategy typically expects a Pydantic BaseModel
  • Passes Anthropic API key via environment_variables instead of using the Secrets API, which contradicts the guidance on the secrets page

Recommend replacing with a framework-agnostic example, or using Weave.


5. from cwsandbox import SandboxExecutionError is a direct import from the underlying library
File: sandboxes/run-commands.mdx (line 88)

This is the only place in the docs that imports from cwsandbox directly. Every other import goes through wandb.sandbox. The issue is that wandb.sandbox doesn't re-export any exception classes from cwsandbox today (there are 12 missing). Working with Pinglei to get this fixed on the SDK side. Once that lands, this import should become from wandb.sandbox import SandboxExecutionError.


Should Fix

6. Typos

  • sandboxes/run-commands.mdx (line 52): "explictly" -> "explicitly", "runnig" -> "running"
  • sandboxes/mltrain_in_sandbox_tutorial.mdx (line 34) and sandboxes/invoke_agent_sandbox_tutorial.mdx (line 46): "documenation" -> "documentation"

7. .mdx extension in links
File: sandboxes/lifecycle.mdx (line 20)

Links use /sandboxes/create-sandbox.mdx and /sandboxes/run-commands.mdx but every other page drops the .mdx extension. Should be /sandboxes/create-sandbox and /sandboxes/run-commands.

8. Line number references off by 2
File: sandboxes/mltrain_in_sandbox_tutorial.mdx (lines 223-224)

"Lines 29-31" should be "Lines 27-29" (the three print statements). "Lines 35-36" should be "Lines 33-34" (read_file and write_bytes).

9. docs.json formatting
The new entry uses "pages" : (space before colon) while the rest of the file uses "pages":.


## Wait for a sandbox to start

Use `Sandbox.wait()` when you want to confirm that the sandbox starts (sandbox reached RUNNING state) successfully before performing other operations, or when you want to separate startup errors from later command errors.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pattern that's generally not that useful.

IIRC Under the hood, we implicitly wait on any call (exec, read, write.... ??).

with Sandbox.run() as sandbox:
    sandbox.exec() # waits until sandbox is ready and then calls the exec

from wandb.sandbox import Sandbox

with Sandbox.run("sleep", "infinity") as sandbox:
sandbox.stop().result()
Copy link
Copy Markdown

@iiilisan iiilisan Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a pattern that's helpful but generally not that useful.

The python context manager will clean up on exit

with ContextManagerThing as sandbox:
    sandbox.do_stuff()

# automatically cleaned up when it hits this line (aka exits the context)

We should highlight this context manager usage since it's more ergonomic than calling stop on sandboxes

print(sandbox)
```

W&B recommends using a context manager to ensure that the sandbox is stopped automatically when it exits the block. To learn how to run commands inside a sandbox, see [Run commands](/sandboxes/run-commands). To learn about sandbox lifecycle and states, see [Lifecycle](/sandboxes/lifecycle).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd tweak this to say the context manager pattern

```python
from wandb.sandbox import Sandbox

sandbox = Sandbox.run("python", "train.py")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd need to double check but this I think is the fire and forget pattern.
They could then get the result by calling sandbox.wait_until_complete().result()

from wandb.sandbox import Sandbox

sandbox = Sandbox.run("python", "train.py")
sandbox.wait_until_complete(timeout=3600.0)
Copy link
Copy Markdown

@iiilisan iiilisan Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result = sandbox.wait_until_complete(timeout=3600.0).result() ?

should probably highlight how to get a result if they want one.

from wandb.sandbox import Sandbox

with Sandbox.run() as sandbox:
result = sandbox.exec(["pip", "install", "torch"], check=True).result()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could leave the check=True out of this example for now. the param name is a little confusing about what it does and is perhaps noisy to introduce something like this without explaining it as well.

print(result.stdout)
```

The `Sandbox.exec()` method runs a command inside a running sandbox and returns a `Process` object that you can use to wait for completion, read output, and inspect the exit code.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we link to the API for Process?

@@ -0,0 +1,93 @@
---
title: File access
Copy link
Copy Markdown

@iiilisan iiilisan Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File Operations perhaps makes the most sense.

sandbox.write_file("hello.txt", text_file.read_bytes()).result()
```

See the `Sandbox` class reference documentation for a full list of parameters and options for [`Sandbox.write_file()`](https://docs.coreweave.com/products/coreweave-sandbox/client/ref/core/sandbox#write_file).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking, would be good to link to the class as well. I find myself wanting to click Thing whenever I see it

]

print("Starting sandbox...")
with Sandbox.run(mounted_files=mounted_files) as sandbox:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow. This is a documentation gap in the CW docs. We'll need to update this. @NavarrePratt FYI

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deprioritized this because I don't want to push the mounting files thing that hard because it's extremely likely it changes once we get to implementing the CAIOS integration. I'd rather people use read and write file for now. I'm pretty sure this mount file thing is leftover from the swebaas hackathon idea.

@@ -0,0 +1,179 @@
---
title: "Tutorial: Invoke an agent in a sandbox"
description: "Learn how to invoke a LangChain agent within a sandbox environment"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be cross-selling the WB Agent here instead of Langchain?


For more in-depth examples, see:

* [W&B Sandbox tutorial](/sandboxes/invoke_agent_sandbox_tutorial)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be cross selling the WB-Agent? Seems weird to provide a tutorial for another company's product.


The previous code snippet does the following:

1. (Lines 6 - 9) Mount files to the sandbox at startup. The `mounted_files` parameter in `Sandbox.run()` allows you to specify a list of files to mount into the sandbox at startup. Each file is represented as a dictionary with two keys: `mount_path`, which specifies the path where the file will be mounted inside the sandbox, and `file_content`, which contains the content of the file as bytes. In this example, you mount `train.py` and `requirements.txt` into the sandbox.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if these are better as inline comments. 🤷

print(result.stdout)
```

## Extract a field from a structured secret
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we actually support this with W&B Secrets Manager

container_image="python:3.13",
network=NetworkOptions(egress_mode="internet"),
max_lifetime_seconds=3600,
environment_variables={"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use a secret here to promote better practices 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DO-NOT-MERGE For PRs that should not be merged yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants