Skip to content

Add support for additional language runtimes #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
8 changes: 5 additions & 3 deletions js/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ const dotenv = require('dotenv')
dotenv.config()

async function main() {
const sandbox = await CodeInterpreter.create()
const r = await sandbox.notebook.execCell('x = 1; x')
console.log(r)
const sandbox = await CodeInterpreter.create()
const jsID = await sandbox.notebook.createKernel({kernelName: "javascript"})
const execution = await sandbox.notebook.execCell("console.log('Hello World!')", { kernelID: jsID })
console.log(execution)

}

main().catch(console.error)
2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@e2b/code-interpreter",
"version": "0.0.8",
"version": "0.0.9-multikernel-code-interpreterer.1",
"description": "E2B Code Interpreter - Stateful code execution",
"homepage": "https://e2b.dev",
"license": "MIT",
Expand Down
18 changes: 9 additions & 9 deletions js/src/code-interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface Kernels {
* E2B code interpreter sandbox extension.
*/
export class CodeInterpreter extends Sandbox {
private static template = 'code-interpreter-stateful'
private static template = 'code-interpreter-multikernel'

readonly notebook = new JupyterExtension(this)

Expand Down Expand Up @@ -136,16 +136,16 @@ export class JupyterExtension {
* Once the kernel is created, this method establishes a WebSocket connection to the new kernel for
* real-time communication.
*
* @param cwd Sets the current working directory where the kernel should start. Defaults to "/home/user".
* @param kernelName The name of the kernel to create, useful if you have multiple kernel types. If not provided, the default kernel will be used.
* @returns A promise that resolves with the ID of the newly created kernel.
* @throws {Error} Throws an error if the kernel creation fails.
* @param opts The options to configure the new kernel.
* @param opts.cwd The working directory for the new kernel.
* @param opts.kernelName The name of the kernel to create.
*/
async createKernel(
cwd: string = '/home/user',
kernelName?: string
): Promise<string> {
kernelName = kernelName || 'python3'
async createKernel(opts: { cwd?: string, kernelName?: string } = {
cwd:'/home/user',
}): Promise<string> {
const kernelName = opts.kernelName || 'python3'


const data = { path: id(16), kernel: {name: kernelName}, type: "notebook", name: id(16) }
Expand Down Expand Up @@ -175,7 +175,7 @@ export class JupyterExtension {
)}/api/sessions/${sessionID}`,
{
method: 'PATCH',
body: JSON.stringify({path: cwd})
body: JSON.stringify({path: opts.cwd})
}
)

Expand Down
2 changes: 1 addition & 1 deletion python/e2b_code_interpreter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CodeInterpreter(Sandbox):
E2B code interpreter sandbox extension.
"""

template = "code-interpreter-stateful"
template = "code-interpreter-multikernel"

def __init__(
self,
Expand Down
54 changes: 36 additions & 18 deletions python/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,47 @@

load_dotenv()

python_code = """
k = 1
k
"""

code = """
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 20, 100)
y = np.sin(x)

plt.plot(x, y)
plt.show()

x = np.linspace(0, 10, 100)
java_code = """
(int) eval("1 + 1") + 3
"""

plt.plot(x, y)
plt.show()
js_code = """
console.log("Hello World");
"""

import pandas
pandas.DataFrame({"a": [1, 2, 3]})
r_code = """
x <- 13
x
"""

with CodeInterpreter() as sandbox:
print(sandbox.id)
execution = sandbox.notebook.exec_cell(code)

print(execution.results[0].formats())
print(len(execution.results))
execution = sandbox.notebook.exec_cell(python_code)
print(execution)
print(execution.logs)
print(len(execution.results))

js_id = sandbox.notebook.create_kernel(kernel_name="javascript")
execution = sandbox.notebook.exec_cell(js_code, kernel_id=js_id)
print(execution)
print(execution.logs)
print(len(execution.results))

java_id = sandbox.notebook.create_kernel(kernel_name="java")
execution = sandbox.notebook.exec_cell(java_code, kernel_id=java_id)
print(execution)
print(execution.logs)
print(len(execution.results))

r_id = sandbox.notebook.create_kernel(kernel_name="r")
execution = sandbox.notebook.exec_cell(r_code, kernel_id=r_id)
print(execution)
print(execution.logs)
print(len(execution.results))

2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "e2b-code-interpreter"
version = "0.0.9"
version = "0.0.10a1"
description = "E2B Code Interpreter - Stateful code execution"
authors = ["e2b <[email protected]>"]
license = "Apache-2.0"
Expand Down
24 changes: 23 additions & 1 deletion template/e2b.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
FROM python:3.10

ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11-jdk $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}"

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --no-install-recommends \
build-essential curl git util-linux jq
build-essential curl git util-linux jq nodejs npm

ENV PIP_DEFAULT_TIMEOUT=100 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
Expand All @@ -19,3 +23,21 @@ COPY ipython_kernel_config.py $IPYTHON_CONFIG_PATH/profile_default/

COPY ./start-up.sh $JUPYTER_CONFIG_PATH/
RUN chmod +x $JUPYTER_CONFIG_PATH/start-up.sh

# Java Kernel
RUN wget https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip && \
unzip ijava-1.3.0.zip && \
python install.py --sys-prefix

# Javascript Kernel
RUN npm install -g --unsafe-perm ijavascript
RUN ijsinstall --install=global

# R Kernel
RUN apt-get update && apt-get install -y r-base
RUN R -e "install.packages('IRkernel')"
RUN R -e "IRkernel::installspec(user = FALSE, name = 'r', displayname = 'R')"

# Bash Kernel
RUN pip install bash_kernel
RUN python -m bash_kernel.install
10 changes: 5 additions & 5 deletions template/e2b.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# This is a config for E2B sandbox template.
# You can use 'template_id' (1tsfj5yvigmgc5gmgqz2) or 'template_name (code-interpreter-stateful) from this config to spawn a sandbox:
# You can use 'template_id' (g8fvsnfpjr2truanf91h) or 'template_name (code-interpreter-multikernel) from this config to spawn a sandbox:

# Python SDK
# from e2b import Sandbox
# sandbox = Sandbox(template='code-interpreter-stateful')
# sandbox = Sandbox(template='code-interpreter-multikernel')

# JS SDK
# import { Sandbox } from 'e2b'
# const sandbox = await Sandbox.create({ template: 'code-interpreter-stateful' })
# const sandbox = await Sandbox.create({ template: 'code-interpreter-multikernel' })

memory_mb = 1_024
start_cmd = "/root/.jupyter/start-up.sh"
dockerfile = "e2b.Dockerfile"
template_name = "code-interpreter-stateful"
template_id = "1tsfj5yvigmgc5gmgqz2"
template_name = "code-interpreter-multikernel"
template_id = "g8fvsnfpjr2truanf91h"
2 changes: 2 additions & 0 deletions template/start-up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ function start_jupyter_server() {
echo "Jupyter Server started"
}

export PATH="/opt/java/openjdk/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

echo "Starting Jupyter Server..."
start_jupyter_server &
jupyter server --IdentityProvider.token=""