
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
web-python-kernel
Advanced tools
A Jupyter-like Python kernel for the browser with real-time streaming output, interrupt support, and seamless visualization capabilities. Run Python code with numpy, matplotlib, plotly, pandas, and more directly in your web applications.
<!DOCTYPE html>
<html>
<head>
<title>Python in Browser</title>
</head>
<body>
<div id="output"></div>
<button id="run">Run Python</button>
<script type="module">
// Import from CDN
import { KernelManager, KernelMode, KernelLanguage } from 'https://cdn.jsdelivr.net/npm/web-python-kernel@0.1.1/dist/web-python-kernel.mjs';
// Create kernel manager with worker mode (recommended)
const manager = new KernelManager({
allowedKernelTypes: [
{ mode: KernelMode.WORKER, language: KernelLanguage.PYTHON }
],
// Use SharedArrayBuffer for interrupts if available, fallback to kernel.interrupt()
interruptionMode: 'auto'
});
// Create a Python kernel
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
// Execute Python code with real-time streaming
document.getElementById('run').onclick = async () => {
const code = `
import matplotlib.pyplot as plt
import numpy as np
print("Generating plot...")
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title("Sine Wave")
plt.show()
print("Done!")
`;
// Stream output in real-time
const stream = manager.executeStream(kernelId, code);
for await (const event of stream) {
if (event.type === 'stream' && event.data.name === 'stdout') {
document.getElementById('output').innerHTML += event.data.text + '<br>';
} else if (event.type === 'display_data' && event.data.data['image/png']) {
// Display matplotlib plots
const img = document.createElement('img');
img.src = `data:image/png;base64,${event.data.data['image/png']}`;
document.getElementById('output').appendChild(img);
}
}
};
</script>
</body>
</html>
// Latest version
import { KernelManager } from 'https://cdn.jsdelivr.net/npm/web-python-kernel@latest/dist/web-python-kernel.mjs';
// Specific version
import { KernelManager } from 'https://cdn.jsdelivr.net/npm/web-python-kernel@0.1.1/dist/web-python-kernel.mjs';
// Alternative CDNs
import { KernelManager } from 'https://unpkg.com/web-python-kernel@0.1.1/dist/web-python-kernel.mjs';
import { KernelManager } from 'https://esm.sh/web-python-kernel@0.1.1/dist/web-python-kernel.mjs';
npm install web-python-kernel
import { KernelManager, KernelMode, KernelLanguage, KernelEvents } from 'web-python-kernel';
import { KernelManager, KernelMode, KernelLanguage, KernelEvents } from 'web-python-kernel';
// Create kernel manager
const manager = new KernelManager({
// Recommend worker mode for better performance and isolation
allowedKernelTypes: [
{ mode: KernelMode.WORKER, language: KernelLanguage.PYTHON }
]
});
// Create a kernel
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
// Listen for kernel events
manager.onKernelEvent(kernelId, KernelEvents.KERNEL_BUSY, () => {
console.log('Kernel is busy...');
});
manager.onKernelEvent(kernelId, KernelEvents.KERNEL_IDLE, () => {
console.log('Kernel is ready');
});
// Execute Python code with streaming output
const code = `
print("Hello from Python!")
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(f"NumPy array: {arr}")
print(f"Sum: {np.sum(arr)}")
`;
// Method 1: Real-time streaming (recommended)
const stream = manager.executeStream(kernelId, code);
for await (const event of stream) {
switch (event.type) {
case 'stream':
if (event.data.name === 'stdout') {
console.log('Output:', event.data.text);
}
break;
case 'execute_result':
console.log('Result:', event.data.data['text/plain']);
break;
case 'execute_error':
console.error('Error:', event.data.ename, event.data.evalue);
break;
}
}
// Method 2: Simple execution (no streaming)
const kernel = manager.getKernel(kernelId);
const result = await kernel.kernel.execute(code);
if (result.success) {
console.log('Execution completed');
} else {
console.error('Execution failed:', result.error);
}
Worker mode runs Python in a Web Worker for better performance and isolation:
const manager = new KernelManager({
allowedKernelTypes: [
{ mode: KernelMode.WORKER, language: KernelLanguage.PYTHON }
],
// Enable SharedArrayBuffer-based interruption (recommended)
interruptionMode: 'shared-array-buffer'
});
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
For the best interrupt experience, enable SharedArrayBuffer with proper CORS headers:
// Server headers required for SharedArrayBuffer
// Cross-Origin-Opener-Policy: same-origin
// Cross-Origin-Embedder-Policy: require-corp
const manager = new KernelManager({
// Use 'shared-array-buffer' for best interrupt performance
// Falls back to 'kernel-interrupt' automatically if SharedArrayBuffer unavailable
interruptionMode: 'auto' // or 'shared-array-buffer'
});
// Interrupt a long-running execution
const interruptSuccess = await manager.interruptKernel(kernelId);
if (interruptSuccess) {
console.log('Execution interrupted successfully');
}
Web Python Kernel automatically handles matplotlib, plotly, and other visualization libraries:
const matplotlibCode = `
import matplotlib.pyplot as plt
import numpy as np
# Create sample data
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Create plot
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.title('Trigonometric Functions')
plt.legend()
plt.grid(True)
# Display plot (automatically generates display_data event)
plt.show()
`;
const stream = manager.executeStream(kernelId, matplotlibCode);
for await (const event of stream) {
if (event.type === 'display_data' && event.data.data['image/png']) {
// Create img element to display plot
const img = document.createElement('img');
img.src = `data:image/png;base64,${event.data.data['image/png']}`;
img.style.maxWidth = '100%';
document.body.appendChild(img);
}
}
const plotlyCode = `
import micropip
await micropip.install('plotly')
import plotly.graph_objects as go
import numpy as np
# Create interactive plot
x = np.linspace(0, 10, 50)
y = np.sin(x)
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines+markers', name='sin(x)'))
fig.update_layout(title='Interactive Sine Wave')
# Display interactive plot
fig.show()
`;
// Plotly generates HTML display data
const stream = manager.executeStream(kernelId, plotlyCode);
for await (const event of stream) {
if (event.type === 'display_data' && event.data.data['text/html']) {
const plotDiv = document.createElement('div');
plotDiv.innerHTML = event.data.data['text/html'];
document.body.appendChild(plotDiv);
}
}
# Clone and setup
git clone <repository>
cd web-python-kernel
npm install
# Start playground
npm run playground
# Opens http://localhost:8080/playground.html
Enable kernel pooling for faster kernel creation:
const manager = new KernelManager({
pool: {
enabled: true,
poolSize: 2, // Keep 2 kernels ready
autoRefill: true, // Automatically create new kernels
preloadConfigs: [
{ mode: KernelMode.WORKER, language: KernelLanguage.PYTHON }
]
}
});
// Pool kernels are created in background, createKernel returns immediately
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
// Check pool status
const poolStats = manager.getPoolStats();
console.log('Pool stats:', poolStats);
// Create kernels with namespaces for organization
const dataKernelId = await manager.createKernel({
namespace: 'data-analysis',
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
const mlKernelId = await manager.createKernel({
namespace: 'machine-learning',
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON
});
// List kernels by namespace
const dataKernels = await manager.listKernels('data-analysis');
console.log('Data analysis kernels:', dataKernels);
// Destroy kernels by namespace
await manager.destroyAll('data-analysis');
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON,
env: {
'API_KEY': 'your-api-key',
'DEBUG': 'true',
'MODEL_PATH': '/models/trained.pkl'
}
});
// Python code can access these via os.environ
const code = `
import os
print(f"API Key: {os.environ.get('API_KEY')}")
print(f"Debug mode: {os.environ.get('DEBUG')}")
`;
const kernelId = await manager.createKernel({
mode: KernelMode.WORKER,
lang: KernelLanguage.PYTHON,
filesystem: {
mountPoints: {
'/data': {
type: 'memory', // or 'indexeddb'
initialData: {
'dataset.csv': csvData,
'config.json': JSON.stringify(config)
}
}
}
}
});
// Python can now access files
const code = `
import pandas as pd
df = pd.read_csv('/data/dataset.csv')
print(df.head())
`;
import { KernelEvents } from 'web-python-kernel';
// Listen for all kernel events
manager.onKernelEvent(kernelId, KernelEvents.KERNEL_BUSY, () => {
document.getElementById('status').textContent = 'Running...';
});
manager.onKernelEvent(kernelId, KernelEvents.KERNEL_IDLE, () => {
document.getElementById('status').textContent = 'Ready';
});
manager.onKernelEvent(kernelId, KernelEvents.STREAM, (data) => {
if (data.name === 'stdout') {
appendOutput(data.text);
} else if (data.name === 'stderr') {
appendError(data.text);
}
});
manager.onKernelEvent(kernelId, KernelEvents.DISPLAY_DATA, (data) => {
if (data.data['image/png']) {
displayPlot(`data:image/png;base64,${data.data['image/png']}`);
}
});
manager.onKernelEvent(kernelId, KernelEvents.EXECUTE_ERROR, (data) => {
showError(`${data.ename}: ${data.evalue}`, data.traceback);
});
// Install packages dynamically
const installCode = `
import micropip
await micropip.install(['pandas', 'scikit-learn', 'seaborn'])
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import seaborn as sns
print("All packages installed successfully!")
`;
const stream = manager.executeStream(kernelId, installCode);
for await (const event of stream) {
if (event.type === 'stream') {
console.log('Install progress:', event.data.text);
}
}
// Start a long-running computation
const longCode = `
import time
for i in range(100):
print(f"Step {i+1}/100")
time.sleep(1) # Long-running operation
print("Completed!")
`;
const stream = manager.executeStream(kernelId, longCode);
// Set up interrupt after 5 seconds
setTimeout(async () => {
const success = await manager.interruptKernel(kernelId);
if (success) {
console.log('Execution interrupted successfully');
}
}, 5000);
// Handle the stream until interruption
try {
for await (const event of stream) {
console.log('Output:', event);
}
} catch (error) {
if (error.message.includes('interrupt')) {
console.log('Execution was interrupted');
}
}
class KernelManager {
constructor(options: IKernelManagerOptions);
// Kernel lifecycle
createKernel(options: IManagerKernelOptions): Promise<string>;
getKernel(id: string): IKernelInstance | undefined;
destroyKernel(id: string): Promise<void>;
destroyAll(namespace?: string): Promise<void>;
listKernels(namespace?: string): Promise<KernelInfo[]>;
// Execution
executeStream(kernelId: string, code: string, parent?: any): AsyncGenerator;
interruptKernel(kernelId: string): Promise<boolean>;
// Events
onKernelEvent(kernelId: string, eventType: KernelEvents, listener: Function): void;
offKernelEvent(kernelId: string, eventType: KernelEvents, listener: Function): void;
// Pool management
getPoolStats(): Record<string, { available: number; total: number }>;
getPoolConfig(): PoolConfig;
}
enum KernelEvents {
KERNEL_BUSY = 'kernel_busy',
KERNEL_IDLE = 'kernel_idle',
STREAM = 'stream',
DISPLAY_DATA = 'display_data',
UPDATE_DISPLAY_DATA = 'update_display_data',
EXECUTE_RESULT = 'execute_result',
EXECUTE_ERROR = 'execute_error',
KERNEL_INFO = 'kernel_info'
}
interface IKernelManagerOptions {
pool?: IKernelPoolConfig;
allowedKernelTypes?: Array<{
mode: KernelMode;
language: KernelLanguage;
}>;
interruptionMode?: 'shared-array-buffer' | 'kernel-interrupt' | 'auto';
}
interface IManagerKernelOptions {
id?: string;
mode?: KernelMode;
lang?: KernelLanguage;
namespace?: string;
env?: Record<string, string>;
filesystem?: IFilesystemMountOptions;
lockFileURL?: string;
inactivityTimeout?: number;
maxExecutionTime?: number;
}
executeStream for real-time feedback| Command | Description |
|---|---|
npm run playground | Build and start playground |
npm run build | Build kernel bundle |
npm run serve | Start development server |
npm run test | Run all tests |
npm run test:watch | Run tests in watch mode |
npm run clean | Clean build artifacts |
web-python-kernel/
├── src/ # TypeScript source code
│ ├── manager.ts # Kernel manager implementation
│ ├── index.ts # Main kernel implementation
│ ├── types.ts # TypeScript interfaces
│ └── kernel.worker.ts # Web Worker implementation
├── tests/ # Test files
├── playground.html # Interactive demo
├── dist/ # Built bundles
│ ├── web-python-kernel.mjs # ES module
│ ├── web-python-kernel.umd.js # UMD bundle
│ └── kernel.worker.js # Worker bundle
└── package.json # Package configuration
Your web-python-kernel is ready to power Jupyter-like Python experiences in the browser!
Quick start: Use the CDN version or install via npm and start building amazing Python web applications.
Happy coding! 🐍✨
FAQs
A web-based Python kernel for browser environments with TypeScript support
The npm package web-python-kernel receives a total of 12 weekly downloads. As such, web-python-kernel popularity was classified as not popular.
We found that web-python-kernel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.