如何通过Jupyter Kernel Gateway的WebSocket API执行Python脚本?
Core Verdict First
The WebSocket mode of Jupyter Kernel Gateway does support executing arbitrary Python code/script content, and this is its primary use case for interactive, dynamic scenarios—unlike the HTTP mode, which ties to pre-existing notebook cells. The confusion often comes from sparse documentation, but the underlying mechanism is straightforward once you understand how it connects to Jupyter kernels.
Key Background: How WebSocket Mode Works
Instead of serving pre-defined notebook endpoints (like HTTP mode), the WebSocket mode acts as a proxy between your client and a running Jupyter Python kernel (e.g., IPython). All communication happens via WebSocket channels, following the Jupyter Kernel Protocol—this means you can send any valid Python code directly to the kernel, just like you would in a Jupyter Notebook's interactive session.
Step-by-Step Guide to Execute Python Scripts
Here’s a practical breakdown to implement this:
1. Start Kernel Gateway in WebSocket Mode
First, launch the gateway with the WebSocket API enabled. Use this command:
jupyter kernelgateway --KernelGatewayApp.api='kernel_websocket' --port=8888
You can also configure this via a jupyter_kernelgateway_config.py file if you need persistent settings.
2. Create a Kernel (via HTTP Helper Request)
Before you can send code over WebSocket, you need an active kernel instance. Use a simple HTTP POST request to create one:
curl -X POST http://localhost:8888/api/kernels
This will return a JSON response with a kernel_id—save this, you’ll need it for the WebSocket connection.
3. Establish WebSocket Connection
Connect to the kernel’s channels using the kernel_id from step 2. The WebSocket URL follows this format:
ws://<gateway-host>:<port>/api/kernels/<kernel-id>/channels
This connection is bidirectional: you’ll send code execution requests, and the kernel will send back outputs, status updates, and results.
4. Send a Python Script/Code for Execution
You need to send messages formatted to match the Jupyter Kernel Protocol. Here’s an example of an execute_request message (JSON-formatted) that runs a Python function and prints output:
{ "header": { "msg_id": "unique-message-id-123", "msg_type": "execute_request", "username": "your-username", "session": "unique-session-id-456" }, "content": { "code": """ def multiply(a, b): return a * b result = multiply(7, 6) print(f"Multiplication result: {result}") # Return the result to get it in the execute_response result """, "silent": false, "store_history": true, "user_expressions": {} }, "parent_header": {}, "metadata": {}, "buffers": [] }
Send this JSON over the WebSocket connection.
5. Process the Kernel’s Responses
The kernel will send back several message types over the WebSocket:
stream: Contains printed output (e.g., theprint()statement from your code)execute_result: Contains the return value of your code blockexecute_reply: Confirms the execution status (successokor failureerror)
You’ll need to listen for these messages on your client to retrieve outputs and status.
Critical Notes & Best Practices
- Difference from HTTP Mode: HTTP mode executes pre-written notebook cells via endpoints; WebSocket mode lets you send dynamic, arbitrary code on-demand—perfect for building interactive tools, code playgrounds, or real-time analysis systems.
- Kernel Management: Always clean up kernels when done (send an HTTP DELETE request to
http://localhost:8888/api/kernels/<kernel-id>) to avoid resource leaks. - Protocol Compliance: Stick strictly to the Jupyter Kernel Protocol message format—incorrectly formatted messages will be ignored by the kernel. Focus on the core message types (
execute_request,execute_reply,stream,execute_result) for basic execution. - Security: If deploying publicly, enable authentication (e.g., API keys, OAuth) for both the HTTP kernel management endpoints and WebSocket connections to prevent unauthorized code execution.
Example Python Client
Here’s a quick Python script using the websocket-client library to test this flow:
import websocket import json import uuid import requests # Step 1: Create kernel kernel_resp = requests.post("http://localhost:8888/api/kernels") kernel_id = kernel_resp.json()["id"] # Step 2: Connect to WebSocket ws_url = f"ws://localhost:8888/api/kernels/{kernel_id}/channels" ws = websocket.create_connection(ws_url) # Step 3: Generate unique IDs for the message msg_id = str(uuid.uuid4()) session_id = str(uuid.uuid4()) # Step 4: Build and send execution request execute_msg = { "header": { "msg_id": msg_id, "msg_type": "execute_request", "username": "test-user", "session": session_id }, "content": { "code": """ print("Running Python script via WebSocket!") total = sum(range(1, 11)) f"Sum of 1-10: {total}" """, "silent": False, "store_history": True }, "parent_header": {}, "metadata": {}, "buffers": [] } ws.send(json.dumps(execute_msg)) # Step 5: Listen for responses while True: raw_resp = ws.recv() msg = json.loads(raw_resp) msg_type = msg["header"]["msg_type"] if msg_type == "stream": print(f"[Output] {msg['content']['text'].strip()}") elif msg_type == "execute_result": print(f"[Return Value] {msg['content']['data']['text/plain'].strip()}") elif msg_type == "execute_reply": status = msg["content"]["status"] print(f"[Execution Status] {status}") if status == "ok": break # Cleanup ws.close() requests.delete(f"http://localhost:8888/api/kernels/{kernel_id}")
内容的提问来源于stack exchange,提问作者MadhaviJ

