This is an automated email from the ASF dual-hosted git repository.
dimuthuupe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata.git
The following commit(s) were added to refs/heads/master by this push:
new 5c6563131d Adding ipython kernel wrapper
5c6563131d is described below
commit 5c6563131dc47753f799114a50999344756dd6c1
Author: Dimuthu Wannipurage <[email protected]>
AuthorDate: Thu Jul 18 03:25:23 2024 -0400
Adding ipython kernel wrapper
---
modules/agent-framework/airavata-agent/agent.go | 13 ++++
.../airavata-agent/jupyter/.gitignore | 1 +
.../airavata-agent/jupyter/README.md | 18 ++++++
.../airavata-agent/jupyter/kernel.py | 73 ++++++++++++++++++++++
4 files changed, 105 insertions(+)
diff --git a/modules/agent-framework/airavata-agent/agent.go
b/modules/agent-framework/airavata-agent/agent.go
index 071418bf37..5ad7ac3ea7 100644
--- a/modules/agent-framework/airavata-agent/agent.go
+++ b/modules/agent-framework/airavata-agent/agent.go
@@ -21,6 +21,7 @@ func main() {
serverUrl := args[0]
agentId := args[1]
grpcStreamChannel := make(chan struct{})
+ kernelChannel := make(chan struct{})
conn, err := grpc.Dial(serverUrl, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
@@ -44,6 +45,17 @@ func main() {
log.Printf("Connected to the server...")
}
+ go func() {
+ log.Printf("Starting jupyter kernel")
+ cmd := exec.Command("./jupyter/venv/bin/python",
"jupyter/kernel.py")
+ _, err := cmd.Output()
+ if err != nil {
+ log.Printf(err.Error())
+ close(kernelChannel)
+ return
+ }
+ }()
+
go func() {
for {
in, err := stream.Recv()
@@ -91,6 +103,7 @@ func main() {
}()
<-grpcStreamChannel
+ <-kernelChannel
if err := stream.CloseSend(); err != nil {
log.Fatalf("failed to close the stream: %v", err)
diff --git a/modules/agent-framework/airavata-agent/jupyter/.gitignore
b/modules/agent-framework/airavata-agent/jupyter/.gitignore
new file mode 100644
index 0000000000..0ced3ff6ce
--- /dev/null
+++ b/modules/agent-framework/airavata-agent/jupyter/.gitignore
@@ -0,0 +1 @@
+venv/*
\ No newline at end of file
diff --git a/modules/agent-framework/airavata-agent/jupyter/README.md
b/modules/agent-framework/airavata-agent/jupyter/README.md
new file mode 100644
index 0000000000..3f012526e8
--- /dev/null
+++ b/modules/agent-framework/airavata-agent/jupyter/README.md
@@ -0,0 +1,18 @@
+## This initializes a jupyter kernel using a python script and controls it
using a HTTP API
+
+### Install dependencies
+```
+pip install flask jupyter jupyter-client
+```
+
+### Start the Wrapped Jupyter Kernel
+```
+python3 kernel.py
+```
+
+### Manage the jupyter kernel from the HTTP API
+```
+curl -X GET http://127.0.0.1:15000/start
+curl -X POST http://127.0.0.1:15000/execute -H "Content-Type:
application/json" -d '{"code": "print(4)"}'
+curl -X GET http://127.0.0.1:15000/stop
+```
\ No newline at end of file
diff --git a/modules/agent-framework/airavata-agent/jupyter/kernel.py
b/modules/agent-framework/airavata-agent/jupyter/kernel.py
new file mode 100644
index 0000000000..53fe3b4cea
--- /dev/null
+++ b/modules/agent-framework/airavata-agent/jupyter/kernel.py
@@ -0,0 +1,73 @@
+import time
+from jupyter_client import KernelManager
+from flask import Flask, request, jsonify
+import os
+import json
+
+
+app = Flask(__name__)
+
+km = None
+kc = None
+
[email protected]('/start', methods=['GET'])
+def start_kernel():
+
+ global km
+ global kc
+ # Create a new kernel manager
+ km = KernelManager(kernel_name='python3')
+ km.start_kernel()
+
+ # Create a client to interact with the kernel
+ kc = km.client()
+ kc.start_channels()
+
+ # Ensure the client is connected before executing code
+ kc.wait_for_ready()
+ return "Kernel started"
+
[email protected]('/execute', methods=['POST'])
+def execute():
+
+ global km
+ global kc
+
+ code = request.json.get('code', '')
+ if not code:
+ return jsonify({'error': 'No code provided'}), 400
+
+ kc.execute(code)
+
+ # Wait for the result and display it
+ while True:
+ try:
+ msg = kc.get_iopub_msg(timeout=1)
+ #print(msg)
+ content = msg["content"]
+
+ # When a message with the text stream comes and it's the result of
our execution
+ if msg["msg_type"] == "stream" and content["name"] == "stdout":
+ print(content["text"])
+ return jsonify({'result': content["text"]}), 200
+ if msg["msg_type"] == "error":
+ return jsonify({'error': content}), 200
+ except KeyboardInterrupt:
+ print("Interrupted by user.")
+ return jsonify({'error': "Intterrupted by user"}), 500
+ except:
+ pass
+
[email protected]('/stop', methods=['GET'])
+def stop():
+
+ global km
+ global kc
+
+ kc.stop_channels()
+ km.shutdown_kernel()
+ return 'Kernel shutting down...'
+
+
+if __name__ == '__main__':
+ app.run(port=15000)