This is an automated email from the ASF dual-hosted git repository.

lahirujayathilake pushed a commit to branch agent-framewok-refactoring
in repository https://gitbox.apache.org/repos/asf/airavata.git


The following commit(s) were added to refs/heads/agent-framewok-refactoring by 
this push:
     new da5a94dd38 run an agent and jl locally for development
da5a94dd38 is described below

commit da5a94dd38bb7c9be7a815dd4917cf3b129f5c33
Author: lahiruj <[email protected]>
AuthorDate: Mon Oct 7 12:02:04 2024 -0400

    run an agent and jl locally for development
---
 .../jupyter/deployments/cerebrum/README.md         |  24 +++
 .../deployments/cerebrum/v1l4/docker-agent.sh      |  10 +
 .../cerebrum/v1l4/jupyterlab/Dockerfile            |  26 +++
 .../v1l4/jupyterlab/build-jupyter-image.sh         |   1 +
 .../cerebrum/v1l4/jupyterlab/labconfig/__init__.py |   0
 .../v1l4/jupyterlab/labconfig/airavata_magics.py   | 235 +++++++++++++++++++++
 .../v1l4/jupyterlab/labconfig/bootstrap.sh         |   2 +
 .../jupyterlab/labconfig/jupyter_lab_config.py     |  25 +++
 .../v1l4/jupyterlab/run-jupyter-lab-container.sh   |   1 +
 9 files changed, 324 insertions(+)

diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/README.md 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/README.md
new file mode 100644
index 0000000000..54f9fd41f7
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/README.md
@@ -0,0 +1,24 @@
+## Setting up Dev Environment
+
+### Agent
+Build the Agent
+```shell
+cd v1l4
+./build-container.sh
+```
+
+Execute the following command to run an agent locally.
+```shell
+docker run --rm -v $(pwd):/workspace -w /workspace 
lahiruj/airavata-cerebrum-agent bash -c "./docker-agent.sh"
+```
+
+### Jupyter lab
+To run the jupyter lab
+
+```shell
+cd jupyterlab
+./build-jupyter-image.sh
+./run-jupyter-lab-container
+```
+
+
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/docker-agent.sh
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/docker-agent.sh
new file mode 100755
index 0000000000..924730aeca
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/docker-agent.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ ! -d "/tmp/v1l4" ]; then
+    mkdir -p /tmp/v1l4
+fi
+
+cp -r /opt/v1l4/* /tmp/v1l4/
+
+/opt/airavata-agent scigap02.sciencegateways.iu.edu:19900 agent2
+
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/Dockerfile
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/Dockerfile
new file mode 100644
index 0000000000..f738f8495d
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/Dockerfile
@@ -0,0 +1,26 @@
+FROM python:slim
+
+USER root
+
+RUN apt update
+RUN apt install fuse -y
+RUN pip install notebook
+RUN apt install kmod -y
+RUN apt install git -y
+RUN pip install PyJWT
+RUN pip install cybershuttle-tune==0.1.19
+RUN pip install scipy
+RUN pip install numpy
+RUN pip install matplotlib
+RUN git clone https://github.com/cyber-shuttle/jupyter-notebook-examples 
/home/jupyter-notebook-examples
+
+COPY labconfig/jupyter_lab_config.py /jupyter_lab_config.py
+COPY labconfig/airavata_magics.py /airavata_magics.py
+COPY labconfig/__init__.py /__init__.py
+COPY labconfig/bootstrap.sh /bootstrap.sh
+RUN chmod +x /bootstrap.sh
+
+EXPOSE 8888
+WORKDIR /home
+
+ENTRYPOINT ["sh", "/bootstrap.sh"]
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/build-jupyter-image.sh
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/build-jupyter-image.sh
new file mode 100755
index 0000000000..d6df5ac140
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/build-jupyter-image.sh
@@ -0,0 +1 @@
+docker build --platform linux/x86_64 -t lahiruj/cerebrum-jupyter-lab .
\ No newline at end of file
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/__init__.py
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/airavata_magics.py
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/airavata_magics.py
new file mode 100644
index 0000000000..cec1b2a10f
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/airavata_magics.py
@@ -0,0 +1,235 @@
+from IPython.core.magic import register_cell_magic
+from IPython.core.magic import register_line_magic
+
+from IPython.display import display, Image
+import base64
+import requests
+import json
+import jwt
+import time
+from pathlib import Path
+import os
+
+current_agent_info = {}
+current_agent_info["agentId"] = "agent2"
+
+EXPLICIT_TOKEN_FILE = (
+        Path(os.path.expanduser("~")) / "csagent" / "token" / "keys.json"
+)
+
+def read_explicit_token_file():
+    if not EXPLICIT_TOKEN_FILE.exists():
+        return None
+    else:
+        with open(EXPLICIT_TOKEN_FILE, "r") as f:
+            return json.load(f)
+
+def get_access_token():
+    expl_token_data = read_explicit_token_file()
+    if expl_token_data:
+        return expl_token_data["access_token"]
+
+def get_agent_status():
+    global current_agent_info
+
+    if not current_agent_info:
+        print("No agent was scheduled yet. Please run %init_remote 
cluster=<cluster> cpu=<cpu> memory=<memory mb> queue=<queue> walltime=<walltime 
minutes>")
+        return
+
+    url = 'http://scigap02.sciencegateways.iu.edu:18880/api/v1/agent/' + 
current_agent_info['agentId']
+    response = requests.get(url)
+    if response.status_code == 202:
+        return response.json()
+    else:
+        print('Invalid response reveived. Status code:', response.status_code)
+        print('Response:', response.text)
+
+def submit_agent_job(experiment_name, cluster, queue, cpus, memory, wallTime, 
access_token, gateway_id='testdrive'):
+
+    global current_agent_info
+    # URL to which the POST request will be sent
+    url = 'http://scigap02.sciencegateways.iu.edu:18880/api/v1/exp/launch'
+
+    # Data to be sent in the POST request
+    data = {
+        'experimentName': experiment_name,
+        'remoteCluster': cluster,
+        'cpuCount': cpus,
+        'nodeCount': 1,
+        'memory': memory,
+        'wallTime': wallTime,
+        'queue': queue
+    }
+
+    # Convert the data to JSON format
+    json_data = json.dumps(data)
+
+    decode = jwt.decode(access_token, options={"verify_signature": False})
+    user_id = decode['preferred_username']
+    claimsMap = {
+        "userName": user_id,
+        "gatewayID": gateway_id
+    }
+
+    # Headers
+    headers = {
+        'Content-Type': 'application/json',
+        'Authorization': 'Bearer ' + access_token,
+        'X-Claims': json.dumps(claimsMap)
+    }
+
+    # Send the POST request
+    response = requests.post(url, headers=headers, data=json_data)
+
+    # Check if the request was successful
+    if response.status_code == 200:
+        # Parse the JSON response
+        response_data = response.json()
+        print('Response:', response_data)
+        current_agent_info = response_data
+    else:
+        print('Failed to send POST request. Status code:', 
response.status_code)
+        print('Response:', response.text)
+
+def terminate_agent(access_token, gateway_id='testdrive'):
+
+    global current_agent_info
+
+    expId = current_agent_info['experimentId']
+    url = 'http://scigap02.sciencegateways.iu.edu:18880/api/v1/exp/terminate/' 
+ expId
+
+    decode = jwt.decode(access_token, options={"verify_signature": False})
+    user_id = decode['preferred_username']
+    claimsMap = {
+        "userName": user_id,
+        "gatewayID": gateway_id
+    }
+
+    # Headers
+    headers = {
+        'Content-Type': 'application/json',
+        'Authorization': 'Bearer ' + access_token,
+        'X-Claims': json.dumps(claimsMap)
+    }
+
+    # Send the POST request
+    response = requests.get(url, headers=headers)
+
+    if response.status_code == 200:
+        # Parse the JSON response
+        response_data = response.json()
+        print('Agent terminated:', response_data)
+        current_agent_info = None
+    else:
+        print('Failed to send termination request. Status code:', 
response.status_code)
+        print('Response:', response.text)
+
+
+@register_cell_magic
+def run_remote(line, cell):
+
+    global current_agent_info
+    if not current_agent_info:
+        print("No agent was scheduled yet. Please run %init_remote 
cluster=<cluster> cpu=<cpu> memory=<memory mb> queue=<queue> walltime=<walltime 
minutes>")
+
+    url = 
'http://scigap02.sciencegateways.iu.edu:18880/api/v1/agent/executejupyterrequest'
+
+    data = {
+        "sessionId": "session1",
+        "keepAlive": True,
+        "code": cell,
+        "agentId": current_agent_info["agentId"]
+    }
+
+    json_data = json.dumps(data)
+    response = requests.post(url, headers={'Content-Type': 
'application/json'}, data=json_data)
+    execution_resp = response.json()
+    execution_id = execution_resp["executionId"]
+    error = execution_resp["error"]
+    if error:
+        print("Cell execution failed. Error: " + error)
+    if execution_id:
+        while True:
+            url = 
"http://scigap02.sciencegateways.iu.edu:18880/api/v1/agent/executejupyterresponse/";
 + execution_id
+            response = requests.get(url, headers={'Accept': 
'application/json'})
+            json_response = response.json()
+            #print(json_response)
+            if json_response['available']:
+                result_str = json_response['responseString']
+                result = json.loads(result_str)
+                if 'result' in result:
+                    print(result['result'])
+                elif 'error' in result:
+                    print(result['error']['ename'])
+                    print(result['error']['evalue'])
+                    print(result['error']['traceback'])
+                elif 'display' in result:
+                    display_obj = result['display']
+                    if 'data' in display_obj:
+                        data_obj = display_obj['data']
+                        if 'image/png' in data_obj:
+                            image_data = data_obj['image/png']
+                            display(Image(data=base64.b64decode(image_data), 
format='png'))
+                break
+            time.sleep(1)
+
+@register_line_magic
+def init_remote(line):
+
+    if current_agent_info:
+        status = get_agent_status()
+        if status:
+            if status['agentUp']:
+                print("An agent is already running. Please terminate it first 
by running %terminate_remote")
+                return
+            else:
+                print("An agent was scheduled. Please terminate it first by 
running %terminate_remote")
+                return
+
+    access_token = get_access_token()
+    pairs = line.split()
+
+    # Initialize variable to store the cluster value
+    cluster_value = None
+    memory_value = None
+    cpu_value = None
+    queue_value = None
+    walltime_value = None
+
+    # Iterate through the pairs to find the cluster value
+    for pair in pairs:
+        if pair.startswith("cluster="):
+            cluster_value = pair.split("=")[1]
+        if pair.startswith("cpu="):
+            cpu_value = pair.split("=")[1]
+        if pair.startswith("memory="):
+            memory_value = pair.split("=")[1]
+        if pair.startswith("queue="):
+            queue_value = pair.split("=")[1]
+        if pair.startswith("walltime="):
+            walltime_value = pair.split("=")[1]
+
+    submit_agent_job('CS Agent', cluster_value, queue_value, cpu_value, 
memory_value, walltime_value, access_token)
+
+@register_line_magic
+def status_remote(line):
+    status = get_agent_status()
+    if status:
+        if status['agentUp']:
+            print("Agent", status['agentId'], 'is running')
+        else:
+            print("Agent", status['agentId'], 'is still prepairing. Please 
wait')
+
+@register_line_magic
+def terminate_remote(line):
+    global current_agent_info
+    access_token = get_access_token()
+    if current_agent_info:
+        terminate_agent(access_token)
+
+
+def load_ipython_extension(ipython):
+    ipython.register_magic_function(init_remote)
+    ipython.register_magic_function(status_remote)
+    ipython.register_magic_function(terminate_remote)
+    ipython.register_magic_function(run_remote)
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/bootstrap.sh
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/bootstrap.sh
new file mode 100644
index 0000000000..754a6e8f52
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/bootstrap.sh
@@ -0,0 +1,2 @@
+cd /home/jupyter-notebook-examples && git pull && cd -
+jupyter lab --config=/jupyter_lab_config.py --ip=0.0.0.0 --port=8888 
--no-browser --allow-root --NotebookApp.token=''
\ No newline at end of file
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/jupyter_lab_config.py
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/jupyter_lab_config.py
new file mode 100644
index 0000000000..a160cd77cb
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/labconfig/jupyter_lab_config.py
@@ -0,0 +1,25 @@
+import sys
+sys.path.append('/')
+
+c = get_config()
+
+c.InteractiveShellApp.exec_lines = [
+    "import sys"
+    "sys.path.append('/')"
+    "import airavata_magics",
+    "airavata_magics.load_ipython_extension(get_ipython())"
+]
+
+# Set the IP address Jupyter Lab will listen on
+c.ServerApp.ip = '0.0.0.0'
+
+# Set the port Jupyter Lab will listen on
+c.ServerApp.port = 8888
+
+# Don't open the browser by default
+c.ServerApp.open_browser = False
+
+c.FileContentsManager.use_atomic_writing = False
+
+# Allow root access
+c.ServerApp.allow_root = True
\ No newline at end of file
diff --git 
a/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/run-jupyter-lab-container.sh
 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/run-jupyter-lab-container.sh
new file mode 100755
index 0000000000..59906b0c8d
--- /dev/null
+++ 
b/modules/agent-framework/airavata-agent/jupyter/deployments/cerebrum/v1l4/jupyterlab/run-jupyter-lab-container.sh
@@ -0,0 +1 @@
+docker run -p 18888:8888 -it lahiruj/cerebrum-jupyter-lab
\ No newline at end of file

Reply via email to