Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ Read more about E2B on the [E2B website](https://e2b.dev) and the official [E2B
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/watsonx-ai-code-interpreter-python">Python</a></td>
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/watsonx-ai-code-interpreter-js">TypeScript</a></td>
</tr>
<tr>
<td>Google</td>
<td>Gemini 3.0 Flash</td>
<td>Data analysis and visualization</td>
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/gemini-data-analysis-python">Python</a></td>
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/gemini-data-analysis-js">TypeScript</a></td>
</tr>
</tbody>
</table>

Expand Down
5 changes: 5 additions & 0 deletions examples/gemini-data-analysis-js/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Get your E2B API key here: https://e2b.dev/docs/getting-started/api-key
E2B_API_KEY=

# Get your Google Gemini API key here: https://ai.google.dev/
GEMINI_API_KEY=
40 changes: 40 additions & 0 deletions examples/gemini-data-analysis-js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Data Analysis and Visualization with Google Gemini

This is an example that tests the capabilities of Google's Gemini models. You can choose from models like gemini-3-flash-preview. We let the LLM write the code to analyze a dataset from Kaggle and generate visualizations. We use the E2B Code Interpreter SDK for running the LLM-generated code tasks in a secure and isolated cloud environment.

## Tech Stack
- [E2B Code Interpreter SDK]((https://github.com/e2b-dev/code-interpreter)) for running the LLM-generated code
- [Gemini's 3.0 Flash](https://ai.google.dev/gemini-api/docs/models) as an LLM
- JavaScript/TypeScript


## Setup
### 1. Set up API keys
1. Copy the `.env.template` file to `.env`:
```bash
cp .env.template .env
```

2. Get your [E2B API key](https://e2b.dev/docs/getting-started/api-key) and [Google AI Studio API key](https://aistudio.google.com/).

3. Add your API keys to the `.env` file.

4. Install the dependencies:
```bash
npm install
```

5. Run the example:
```bash
npm start
```

After running the program, you should get the results of a chart visualizing the yearly temperature trends in the top 5 hottest cities.

![Example of the output](temperature_analysis.png)

If you encounter any problems, please let us know at our [Discord]((https://discord.com/invite/U7KEcGErtQ)).
If you want to let the world know about what you're building with E2B, tag [@e2b_dev](https://twitter.com/e2b_dev) on X (Twitter).

### 4. Visit our docs
Check the documentation to learn more about how to use E2B. [Visit our docs](https://e2b.dev/docs).
164 changes: 164 additions & 0 deletions examples/gemini-data-analysis-js/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import fs from 'node:fs'
import { GoogleGenAI, Type } from '@google/genai'
import { Sandbox, Result } from '@e2b/code-interpreter'
import { OutputMessage } from '@e2b/code-interpreter'
import * as dotenv from 'dotenv'

dotenv.config()

// 1. Initialize Gemini Client
const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const MODEL_NAME = 'gemini-3-flash-preview'

const SYSTEM_PROMPT = `
You are an expert Data Analyst and Python programmer.
You have access to a remote Python environment (E2B sandbox).
Your task is to analyze data, write Python code to perform the analysis and generate visualizations.

When asked to analyze data:
1. Verify what files are available.
2. Write Python code to load the data (usually pandas).
3. Perform the request analysis.
4. Generate charts using matplotlib or seaborn.
5. ALWAYS save the chart as a file (e.g., 'output.png', 'chart.png').
6. Print relevant insights to stdout.

IMPORTANT CODE OUTPUT FORMAT:
You must strictly output your Python code in the following format:
\`\`\`python
# ... your code here ...
\`\`\`
Do not include any other markdown code blocks or shell commands unless explicitly asked.
`

// 2. Define the tool
const executePythonTool = {
name: 'execute_python',
description: 'Execute python code in a Jupyter notebook cell and returns any result, stdout, stderr, display_data, and error.',
parameters: {
type: Type.OBJECT,
properties: {
code: {
type: Type.STRING,
description: 'The python code to execute in a single cell.',
}
},
required: ['code']
}
}

// 3. E2B Code Interpreter Helper
async function codeInterpret(codeInterpreter: Sandbox, code: string) {
console.log('Running code interpreter...')

const exec = await codeInterpreter.runCode(code, {
onStderr: (msg: OutputMessage) => console.log(`[Stderr] ${msg.line}`),
onStdout: (stdout: OutputMessage) => console.log(`[Stdout] ${stdout.line}`),
})

if (exec.error) {
console.log('[Code Interpreter ERROR]', exec.error)
throw new Error(exec.error.value)
}
return exec
}

async function uploadDataset(codeInterpreter: Sandbox): Promise<string> {
console.log('Uploading dataset to Code Interpreter sandbox...')
const datasetPath = './city_temperature.csv'

if (!fs.existsSync(datasetPath)) {
throw new Error('Dataset file not found')
}

const fileBuffer = fs.readFileSync(datasetPath)

try {
const remotePath = await codeInterpreter.files.write('city_temperature.csv', fileBuffer)
if (!remotePath) {
throw new Error('Failed to upload dataset')
}
console.log('Uploaded at', remotePath)
return remotePath.path
} catch (error) {
console.error('Error during file upload:', error)
throw error
}
}

// 4. Main Chat Logic
async function run() {
console.log('Starting E2B Code Interpreter...');
const codeInterpreter = await Sandbox.create({ apiKey: process.env.E2B_API_KEY });

try {
await uploadDataset(codeInterpreter);

// Initialize Chat Session
const chat = client.chats.create({
model: MODEL_NAME,
config: {
systemInstruction: SYSTEM_PROMPT,
tools: [{ functionDeclarations: [executePythonTool] }],
},
});

// First Message
let response = await chat.sendMessage({ message: "Analyze the temperature data for the top 5 hottest cities globally. Create a visualization showing their average temperatures over the years." });

while (true) {
const parts = response.candidates[0].content.parts;
const functionCalls = parts.filter(p => p.functionCall);

if (functionCalls.length > 0) {
const toolResponseParts = [];

for (const call of functionCalls) {
const fc = call.functionCall;
console.log(`\nTool Call: ${fc.name}`);

const exec = await codeInterpret(codeInterpreter, fc.args.code);

let outputStr = "";

// Handle Results (Images, etc)
for (const res of exec.results) {
if (res.png) {
// Decode base64 PNG from E2B and save
fs.writeFileSync('temperature_analysis.png', Buffer.from(res.png, 'base64'));
console.log("Chart saved to temperature_analysis.png");
}
}

// Collect logs from the Execution object
if (exec.logs.stdout.length) outputStr += exec.logs.stdout.join("\n") + "\n";
if (exec.logs.stderr.length) outputStr += exec.logs.stderr.join("\n") + "\n";

if (!outputStr) outputStr = "Code executed successfully.";

toolResponseParts.push({
functionResponse: {
name: fc.name,
response: { result: outputStr }
}
});
}

console.log("Sending tool outputs back to Gemini...");
response = await chat.sendMessage({ message: toolResponseParts });

} else {
console.log(`\nFinal Response: ${response.text}`);
break;
}
}

} catch (e) {
console.error("Error in execution loop:", e);
} finally {
await codeInterpreter.kill();
console.log("Sandbox closed.");
}
}

run();
Loading