setup-python-tools
cognitedata/builder-skills
Add client-side Python tool execution via Pyodide to Flows apps with automatic hook setup and chat integration.
What is setup-python-tools?
Enables Python tool execution in Flows apps using Pyodide (browser-based Python runtime). Handles Pyodide installation, runtime initialization, loading UI, and wiring into useAtlasChat. Requires integrate-atlas-chat to be completed first.
- Installs and configures Pyodide 0.29.3 for client-side Python execution
- Sets up usePyodideRuntime hook to load Pyodide, install packages, and inject Cognite SDK credentials
- Automatically fetches Python tool code from agent CDF config and executes it in the browser
- Provides loading progress UI with stage tracking and error handling
- Wires pythonRuntime into useAtlasChat to enable Python tool calls without manual tool declarations
How to install setup-python-tools
npx skills add https://github.com/cognitedata/builder-skills --skill setup-python-tools- integrate-atlas-chat skill must be completed with vendored src/atlas-agent/ code
- Python-related modules (python.ts, pyodide.ts, pyodide-react.ts, pyodide-runtime.ts) copied from integrate-atlas-chat into src/atlas-agent/
- @sinclair/typebox peer dependency already installed from integrate-atlas-chat
How to use setup-python-tools
- 1.Read package.json and the component using useAtlasChat to understand current setup
- 2.Install pyodide@0.29.3 using your package manager (pnpm/npm/yarn)
- 3.Import loadPyodide and usePyodideRuntime in your chat component
- 4.Call usePyodideRuntime hook with loadPyodide, Cognite SDK client, and optional requirements array
- 5.Add loading/error UI above chat input showing pythonProgress.stage and pythonProgress.percent
- 6.Pass pythonRuntime from the hook to useAtlasChat config
- 7.Disable ChatInput and ChatHomePage with pythonLoading flag to prevent premature message sending
Use cases
- Execute data analysis Python tools (pandas, numpy) directly in the browser without server calls
- Run Python-based transformations on time series data fetched from Cognite Data Fusion
- Build chat agents that call Python tools for calculations while maintaining full client-side execution
- Display Python tool loading progress to users during initial Pyodide download (~30-60s first load)
- Disable chat input during Python runtime initialization to prevent message sending before runtime is ready
- Frontend developers building Flows apps with Python tool support
- Teams using Atlas agents with runPythonCode tool definitions in CDF config
- Applications requiring client-side Python execution without backend Python services
setup-python-tools FAQ
No. Python tools are already defined in the agent's CDF config (type: runPythonCode). The library fetches the code automatically when the agent calls them. Only declare regular client tools via the tools array.
This version must match the CDN artifacts loaded at runtime. Installing a different version will cause runtime errors.
First load is ~30-60s (downloads ~30MB). Subsequent loads are <2s from browser cache. Show progress UI during initialization.
The usePyodideRuntime hook returns an error field. Display an error badge and keep the chat input disabled until the runtime is ready.
Yes. Pass a requirements array to usePyodideRuntime (e.g., ['pandas', 'numpy']) to install additional packages during initialization.
Full instructions (SKILL.md)
Source of truth, from cognitedata/builder-skills.
name: setup-python-tools description: "MUST be used when adding Pyodide or Python tool support to a Flows app. Do NOT manually configure usePyodideRuntime or wire pythonRuntime into useAtlasChat — this skill handles pyodide installation, hook setup, loading UI, and chat hook wiring. Prerequisite: integrate-atlas-chat (vendored src/atlas-agent + atlas chat wiring). Triggers: Pyodide, Python tools, pythonRuntime, usePyodideRuntime, runPythonCode, Python execution, client-side Python." allowed-tools: Read, Glob, Grep, Edit, Write, Bash metadata: argument-hint: "[tool-names or agent-external-id]"
Set Up Python Tool Execution
Add client-side Python tool execution via Pyodide to this Flows app.
Target: $ARGUMENTS
Prerequisite
integrate-atlas-chat must already be complete: the app should have vendored atlas-agent code under src/atlas-agent/ (including react.ts for useAtlasChat) and the peer dependency from that skill (@sinclair/typebox). Copy the Python-related modules from the integrate-atlas-chat skill code/ directory into src/atlas-agent/ when adding Pyodide (python.ts, pyodide.ts, pyodide-react.ts, pyodide-runtime.ts — see integrate-atlas-chat Step 5).
Background
Atlas agents can have Python tools defined in their CDF config (type: "runPythonCode").
When the agent calls one, it arrives as a toolConfirmation (auto-allowed) followed by a
clientTool action. The library fetches the tool's Python code from the agent config
automatically and executes it via the provided pythonRuntime.
You only need to:
- Set up
usePyodideRuntimeto get a runtime instance - Pass
pythonRuntimetouseAtlasChat
No PythonToolConfig entries — the library reads the code from the agent's CDF config.
The flow is:
usePyodideRuntimeloads Pyodide (~30MB, cached after first load), installs packages, and injects Cognite SDK credentials into the Python environment- When the agent calls a Python tool, the library fetches its code from the agent's CDF config (cached per session), wraps it, executes it in Pyodide, and returns the result
Step 1 — Understand the app
Read these files before touching anything:
package.json— detect package manager and existing deps- The component that calls
useAtlasChat— understand current tools/config
Step 2 — Install Pyodide
Install exactly pyodide@0.29.3 using the app's package manager.
This version must match the CDN artifacts loaded at runtime — installing a different version will cause errors.
- pnpm →
pnpm add pyodide@0.29.3 - npm →
npm install pyodide@0.29.3 - yarn →
yarn add pyodide@0.29.3
Note: After
integrate-atlas-chat,@sinclair/typeboxshould already be installed. If anything is missing, install the versions listed in that skill's Dependencies table.
Step 3 — Set up usePyodideRuntime
In the component that calls useAtlasChat, add the Pyodide runtime hook:
import { loadPyodide } from "pyodide";
import { usePyodideRuntime } from "./atlas-agent/pyodide-react";
import { useAtlasChat } from "./atlas-agent/react";
function MyChat() {
const { sdk, isLoading } = useDune();
// Initialize Python runtime (loads Pyodide, installs packages, sets up Cognite SDK)
const {
runtime: pythonRuntime,
loading: pythonLoading,
progress: pythonProgress,
error: pythonError,
isReady: pythonReady,
} = usePyodideRuntime({
loadPyodide,
client: isLoading ? null : sdk,
requirements: ["pandas", "numpy"], // optional — additional packages
});
// ... useAtlasChat below
}
Hook API reference
| Return field | Type | Description |
|---|---|---|
runtime | PythonRuntime | undefined | The initialized runtime, or undefined if not ready |
loading | boolean | True while Pyodide is loading / initializing |
error | string | null | Error message if initialization failed |
progress | { stage: string; percent: number } | Current init progress for UI display |
isReady | boolean | Convenience: !loading && !error && runtime !== undefined |
Loading state UI
Place the loading indicator above the chat input, not in the message list. Keep it compact — a pill/badge showing stage text and percent. Show an error badge separately. First load is ~30-60s (downloads ~30MB); subsequent loads are <2s from browser cache.
{/* Loading — shown above the input while Pyodide initializes */}
{pythonLoading && (
<div className="flex items-center gap-2 rounded-lg border bg-muted/50 px-3 py-2 text-sm text-muted-foreground">
{/* Optional: <IconBrandPython /> from @tabler/icons-react */}
<span>{pythonProgress.stage || "Initializing Python..."}</span>
{pythonProgress.percent > 0 && pythonProgress.percent < 100 && (
<span className="text-xs opacity-70">({pythonProgress.percent}%)</span>
)}
</div>
)}
{/* Error — shown if init fails (after loading finishes) */}
{pythonError && !pythonLoading && (
<div className="flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">
<span>Python runtime failed to load</span>
</div>
)}
Step 4 — Wire into useAtlasChat
Pass the runtime to useAtlasChat. That's all — no tool configs needed:
const { messages, send, isStreaming, progress, error, reset, abort } = useAtlasChat({
client: isLoading ? null : sdk,
agentExternalId: "my-agent",
tools: [renderTimeSeries], // regular client tools (declared to agent), if any
pythonRuntime, // from usePyodideRuntime — enables Python tool execution
});
Note: Python tools are NOT declared to the agent via tools. The agent already knows
about them from its CDF config. The library fetches the code automatically when needed.
Step 5 — Disable input while Python loads
The user shouldn't send messages before the runtime is ready. Disable the entire input area (not just the send button) so the state is unambiguous:
<ChatInput
onSend={handleSend}
disabled={isStreaming || pythonLoading}
// ...
/>
If you have a home page with suggestion chips, disable those too:
<ChatHomePage
onSuggestionClick={handleSuggestionClick}
disabled={pythonLoading}
/>
Done
The app can now execute Python tools client-side via Pyodide. When the agent calls a Python tool, the library automatically fetches its code from the agent config, runs it in the browser, and returns the result to the agent.
Related skills
More from cognitedata/builder-skills and the wider catalog.

skill-creator
Create, improve, and evaluate AI agent skills with iterative testing and performance benchmarking.

test-coverage
Find and fix test coverage gaps to meet the 80% line coverage hard gate for Flows apps.

use-topbar
Wire Aura Topbar into Flows/Fusion apps as the compliant single top navigation bar with breadcrumbs, theme switching, and utility strip.

code-quality
Automated code quality review for Flows apps—linting, type safety, component size, and maintainability checks.

agentic-wallet
Crypto wallet operations via the awal CLI — sign in, check balances, send USDC/ETH/POL/SOL, trade tokens, fund the wallet, and use the x402 payment protocol to discover paid services, pay for API calls, monetize an API, or query onchain data. Use whenever the user mentions signing in, login, authentication, wallet status, balance, address, sending money, paying someone, transferring tokens, ENS names, swapping/trading/converting tokens, funding/topping up/onramp, USDC, ETH, POL, SOL, the x402 bazaar, paid APIs, monetizing an endpoint, or querying onchain data on Base.

authenticate-wallet
Sign in to your wallet via email OTP before sending, trading, or funding.