Pydantic AI Workspace sandboxes: fetch Sume artifacts

Pydantic AI's Workspace abstraction runs tools locally or in sandboxes. Inside a sandbox, fetch Sume artifact URLs, and give Sume inputs as public HTTPS URLs.

4 min readSume
All posts

Pydantic AI's releases for September and October 2026 describe a new Workspace abstraction so tools work locally or in sandboxes such as E2B, Modal and Sprites. The Sume side is simple: media you send to Sume must be a public HTTPS URL, so a file that exists only inside a sandbox cannot be an input. Results come back as Sume media URLs you can download.

What the release says

From the Pydantic AI releases page, read on 2026-10-03: a Workspace abstraction lets the same tools run locally or in a sandbox, with E2B, Modal and Sprites named. See the release notes for the API; this post uses no Pydantic AI code.

Inputs: public HTTPS only

Sume generation requests accept media as public HTTPS URLs. Localhost, private-network, non-HTTPS, signed or private URLs and mismatched content types are rejected before submission. A path such as /workspace/clip.mp4, or a URL that only resolves inside the sandbox, will be refused.

Where an input can live (per Sume docs, read 2026-10-03)
Input locationAccepted?
Public HTTPS URLYes
Sume-hosted media.sume.com artifactYes
localhost or private networkNo, rejected
Signed or private URLNo, rejected

To get a sandbox file to Sume, host it at a public HTTPS location first, or use the asset flow: sume assets upload-url on the CLI, or assets_upload_url then assets_complete on MCP. Hosted MCP cannot read files from your laptop, and the same is true of a remote sandbox.

Outputs: download from the result

Completed jobs return artifact objects whose url is a Sume-owned media URL. Sume mirrors generated outputs there before exposing them, and the docs tell integrations to store the Sume URL, not raw provider URLs. Treat the URL as opaque.

import requests

def fetch_artifact(job_id: str, api_key: str, dest: str) -> str:
    headers = {"Authorization": f"Bearer {api_key}"}
    r = requests.get(f"https://api.sume.com/v1/jobs/{job_id}/result",
                     headers=headers, timeout=30)
    r.raise_for_status()
    url = r.json()["result"]["artifacts"][0]["url"]
    data = requests.get(url, timeout=120)
    data.raise_for_status()
    with open(dest, "wb") as f:
        f.write(data.content)
    return dest

Keep the key out of the sandbox

Prefer to call Sume from the host process and pass only the artifact URL or file into the sandbox. If the sandbox must call the API, give it a key scoped to what it needs, and never log the key or signed URLs.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume