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)

Reply via email to