Code execution and the Files API
Two more features that work hand in hand: the Files API for uploading files once and referencing them by ID afterwards, and the code execution tool for letting Claude run Python in a sandboxed container. Individually they're useful. Combined, they turn Claude into a legitimate data analyst that can load a CSV, run Pandas, generate plots, and hand you back downloadable files.
The Files API
The Files API lets you upload a file once, receive a persistent ID, and reference that ID in subsequent messages instead of base64-encoding the file on every request.
The base64 approach you learned for images and PDFs works, but it has two real costs in production:
- Every request embeds the full file data, so a 5MB PDF referenced three times in a conversation is 15MB of data transferred over the wire.
- Base64 encoding inflates the size by about a third, which eats into your payload budget.
The Files API flow:
- Upload the file to Anthropic in a dedicated call.
- Receive a file metadata object with a unique
id. - Reference the file by ID in any future message.
The course provides an upload() helper:
file_metadata = upload("streaming.csv")
# => returns something like FileMetadata(id="file_01abc...", filename="streaming.csv", ...)
Now you can reference file_metadata.id instead of re-encoding bytes every time you want Claude to look at that file. Files live in Anthropic's storage for a while (check current docs for the exact retention), so uploads made for one request are usable in later requests too.
Use the Files API when you want to reference the same file multiple times or when the file is large enough that base64 inflation matters. Use inline base64 when you only need the file in one request and it's small.
The code execution tool
The code execution tool is a built-in Anthropic tool — like the web search tool from Module 6 — where Claude handles everything on the server side. You don't write a handler. You declare the tool and Claude can execute Python code in a sandboxed environment.
Declaration:
tools = [
{
"type": "code_execution_20250522",
"name": "code_execution",
}
]
Add it to your tools=[...] list like any other tool, and Claude can call it during its response.
The sandbox
Key properties of the code execution environment:
- Isolated Docker container. Every execution happens in a sandbox spun up on Anthropic's infrastructure.
- No network access. Claude cannot make external API calls, hit your database, or reach outside the container. This is a deliberate security boundary — the container is a computational workspace, not a gateway to the internet.
- Multiple executions per response. Claude can run code several times during a single response, iterating on its approach. Each execution is a self-contained step the model decides to take.
- Python and standard data libraries — Pandas, NumPy, Matplotlib, and similar tools are pre-installed. Expect the kind of environment a data analyst would have on their laptop.
Why no network matters
Because the container can't reach out, the Files API becomes the primary way to get data in and results out. You upload a file with the Files API, include a container_upload block in your message with the file ID, and the file becomes accessible from inside the container. Claude runs its code, produces output (including files like generated plots), and those outputs become downloadable via the Files API on the way back.
This is the "combining" story: the Files API fills the IO gap that the sandbox can't fill itself.
A real workflow: CSV analysis
Suppose you have a streaming.csv containing user information for a streaming service — subscription tier, viewing habits, whether they churned. You want Claude to analyse churn drivers and produce a plot.
Step 1: upload the file.
file_metadata = upload("streaming.csv")
Step 2: construct a message with a container upload block.
messages = []
add_user_message(
messages,
[
{
"type": "text",
"text": """
Run a detailed analysis to determine the major drivers of churn.
Your final output should include at least one detailed plot
summarising your findings.
""",
},
{
"type": "container_upload",
"file_id": file_metadata.id,
},
],
)
The container_upload block tells Claude to make this file available inside the code execution container.
Step 3: call Claude with code execution enabled.
response = chat(
messages,
tools=[
{
"type": "code_execution_20250522",
"name": "code_execution",
}
],
)
What happens next: Claude decides what code to run, executes it, looks at the output, maybe iterates with more code, generates visualisations, and composes a final response that includes both text analysis and references to any generated files.
The response shape
Responses from code execution are richer than normal text responses. You'll see several block types:
- Text blocks — Claude's analysis and commentary.
- Server tool use blocks — the actual code Claude chose to run (visible so you can see exactly what happened).
- Code execution tool result blocks — the output of running that code (stdout, stderr, return values).
code_execution_outputblocks — file outputs like generated plots, each carrying afile_idfor the generated file.
Claude may execute code multiple times in one response, iteratively building up the analysis. First a describe() call to understand the data. Then some filtering to look at the churned subset. Then a groupby().mean() to find patterns. Then a Matplotlib plot to visualise. Each execution cycle is visible in the response blocks.
Downloading generated files
When Claude generates a file (plot, transformed CSV, report), it's stored in the container and a code_execution_output block with a file_id appears in the response. To actually retrieve the file, use the Files API to download it:
download_file("file_id_from_response")
Walk the response blocks looking for code_execution_output and the file IDs inside them, then download each one. The result is a folder of generated artifacts — plots, transformed data, whatever Claude produced — alongside the textual analysis.
Beyond data analysis
Data analysis is the natural fit, but the Files API + code execution combo opens up a broader set of use cases:
- Image processing — resize, filter, watermark, or transform images programmatically.
- Document parsing and transformation — reformat, convert between formats, batch-rename.
- Mathematical computations — run numerical models, simulations, symbolic algebra.
- Report generation — produce formatted PDFs, Excel files, or HTML reports from input data.
- Code execution as a debugging aid — let Claude run small snippets to verify assumptions while answering programming questions.
The pattern is always the same: upload inputs, ask Claude to do the work, download the outputs. You delegate the computational task, maintain control of the inputs and outputs via the Files API, and let Claude iterate on its approach inside the sandbox.
Reference at a glance
| Feature | Type | Purpose |
|---|---|---|
| Files API — upload | Dedicated endpoint | Upload files once, get a persistent ID |
| Files API — download | Dedicated endpoint | Retrieve files generated during code execution |
| container_upload block | Message block | Expose a previously uploaded file to the code execution container |
| Code execution tool | Built-in tool | Run Python in a sandboxed Docker container with no network |
| code_execution_output block | Response block | Metadata for files Claude generated during execution |
Prompt caching, extended thinking, images, PDFs, citations, code execution, and the Files API — that's the "advanced features" toolkit. Pair them with the tool use and RAG modules you already built and you have an extraordinarily capable production surface. The next module covers Model Context Protocol, which lets you expose these same capabilities to other Claude-powered systems cleanly.
Key Takeaways
- 1The Files API lets you upload a file once and reference it by persistent ID in subsequent messages, avoiding base64 encoding and repeated payload transfer.
- 2The code execution tool is a built-in Anthropic tool that runs Python in an isolated Docker container with no network access — you declare it, Claude executes inside the sandbox.
- 3Because the container has no network access, the Files API is the primary channel for getting input data in and generated output files back out.
- 4Use a container_upload block with a file_id to expose an uploaded file to the code execution container, then ask Claude to analyse or transform it.
- 5Responses from code execution contain multiple block types: text, server tool use, execution results, and code_execution_output blocks carrying file IDs for generated artifacts.
- 6Claude may execute code multiple times in one response, iteratively building up an analysis — each cycle is visible in the response blocks.
- 7The pattern generalises beyond data analysis to image processing, document transformation, mathematical computation, and report generation — upload inputs, delegate the work, download outputs.