Skip to content

Commit

Permalink
add initial notebooks for guis
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnTurnerNIH committed Oct 31, 2024
1 parent e3f55b4 commit ff62572
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 1 deletion.
14 changes: 14 additions & 0 deletions reference_notebooks/start-bandage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#! /bin/bash
apt-get update
apt-get install ca-certificates curl -y
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
export GCSFUSE_REPO=gcsfuse-`lsb_release -c -s` && echo "deb https://packages.cloud.google.com/apt $GCSFUSE_REPO main" | tee /etc/apt/sources.list.d/gcsfuse.list > /dev/null
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fuse gcsfuse -y
mkdir "/tmp/mount-folder" && chmod 777 /tmp/mount-folder && mount -t gcsfuse -o allow_other,file_mode=777,dir_mode=777 nigms-nosi-developers-us-notebooks "/tmp/mount-folder"
docker run --rm -v /tmp/mount-folder:/config/s3 -p 8080:3000 us-east4-docker.pkg.dev/nih-cl-shared-resources/nigms-sandbox/bandage-gui
350 changes: 350 additions & 0 deletions reference_notebooks/start-gui-server.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 17,
"id": "4f80ce0b-c291-4d4a-aaa9-6a62f5cb61bd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import subprocess\n",
"subprocess.run('pip install google-cloud-compute notebook'.split(\" \"), text=True, capture_output=True)\n",
"import urllib.request\n",
"from __future__ import annotations\n",
"\n",
"import sys\n",
"from typing import Any\n",
"\n",
"from google.api_core.extended_operation import ExtendedOperation\n",
"from google.cloud import compute_v1\n",
"import time\n",
"import ipywidgets as widgets\n",
"from IPython.display import display, clear_output\n",
"from IPython.core.display import HTML\n",
"ts = time.time()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "7280cecd-7c37-414a-9f36-78b2e7eeb967",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"url = \"http://metadata.google.internal/computeMetadata/v1/project/project-id\"\n",
"req = urllib.request.Request(url)\n",
"req.add_header(\"Metadata-Flavor\", \"Google\")\n",
"project_id = urllib.request.urlopen(req).read().decode()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "cb07eb82-122b-40ad-aa51-631d4650a8ee",
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": []
},
"outputs": [],
"source": [
"def wait_for_extended_operation(\n",
" operation: ExtendedOperation, verbose_name: str = \"operation\", timeout: int = 300\n",
") -> Any:\n",
" \"\"\"\n",
" Waits for the extended (long-running) operation to complete.\n",
"\n",
" If the operation is successful, it will return its result.\n",
" If the operation ends with an error, an exception will be raised.\n",
" If there were any warnings during the execution of the operation\n",
" they will be printed to sys.stderr.\n",
"\n",
" Args:\n",
" operation: a long-running operation you want to wait on.\n",
" verbose_name: (optional) a more verbose name of the operation,\n",
" used only during error and warning reporting.\n",
" timeout: how long (in seconds) to wait for operation to finish.\n",
" If None, wait indefinitely.\n",
"\n",
" Returns:\n",
" Whatever the operation.result() returns.\n",
"\n",
" Raises:\n",
" This method will raise the exception received from `operation.exception()`\n",
" or RuntimeError if there is no exception set, but there is an `error_code`\n",
" set for the `operation`.\n",
"\n",
" In case of an operation taking longer than `timeout` seconds to complete,\n",
" a `concurrent.futures.TimeoutError` will be raised.\n",
" \"\"\"\n",
" result = operation.result(timeout=timeout)\n",
"\n",
" if operation.error_code:\n",
" print(\n",
" f\"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}\",\n",
" file=sys.stderr,\n",
" flush=True,\n",
" )\n",
" print(f\"Operation ID: {operation.name}\", file=sys.stderr, flush=True)\n",
" raise operation.exception() or RuntimeError(operation.error_message)\n",
"\n",
" if operation.warnings:\n",
" print(f\"Warnings during {verbose_name}:\\n\", file=sys.stderr, flush=True)\n",
" for warning in operation.warnings:\n",
" print(f\" - {warning.code}: {warning.message}\", file=sys.stderr, flush=True)\n",
"\n",
" return result\n",
"\n",
"\n",
"def delete_instance(zone: str, machine_name: str) -> None:\n",
" \"\"\"\n",
" Send an instance deletion request to the Compute Engine API and wait for it to complete.\n",
"\n",
" Args:\n",
" project_id: project ID or project number of the Cloud project you want to use.\n",
" zone: name of the zone you want to use. For example: “us-west3-b”\n",
" machine_name: name of the machine you want to delete.\n",
" \"\"\"\n",
" instance_client = compute_v1.InstancesClient()\n",
"\n",
" print(f\"Deleting {machine_name} from {zone}...\")\n",
" operation = instance_client.delete(project=project_id, zone=zone, instance=machine_name\n",
" )\n",
" wait_for_extended_operation(operation, \"instance deletion\")\n",
" print(f\"Instance {machine_name} deleted.\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "c7d33171-3a65-482e-a28a-31b2fdc0649d",
"metadata": {},
"source": [
"Please paste the following cell output and run it"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "5bc64703-823c-4b51-9e40-a3c2ed09998d",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"application/javascript": [
"// Send data\n",
"\n",
"fetch( 'https://api64.ipify.org/')\n",
" .then(\n",
" response => response.text()\n",
" ).then(\n",
" text => element.append(\"ip='\"+text+\"'\")\n",
" );\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"// Send data\n",
"\n",
"fetch( 'https://api64.ipify.org/')\n",
" .then(\n",
" response => response.text()\n",
" ).then(\n",
" text => element.append(\"ip='\"+text+\"'\")\n",
" );"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "2f528cb1-7c20-4daa-9dd6-726eccecf566",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"ip='128.231.234.47'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "561e3647-94cd-41c2-b950-b9404e12cb98",
"metadata": {},
"outputs": [],
"source": [
"firewall_rule_capture = subprocess.run('gcloud compute firewall-rules list'.split(\" \"), text=True, capture_output=True) \n",
"rules = firewall_rule_capture.stdout.split(\"\\n\")\n",
"rule_found = False\n",
"for x in rules:\n",
" if 'allow-gui-access-'+str(int(ts)) in x:\n",
" rule_found = True\n",
" print(\"rule already exist\")\n",
"if not rule_found:\n",
" subprocess.run(['gcloud','compute','firewall-rules','create','allow-gui-access-'+str(int(ts)),'--allow=tcp:8080','--source-ranges='+ip+'/32','--description=\"allow-gui-access\"'])"
]
},
{
"cell_type": "markdown",
"id": "6b7a9e9f-2698-462e-aefc-36755c39dbea",
"metadata": {},
"source": [
"## Now we will create a Compute instance to run our GUI program"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "7adfc414-112a-4d32-8fb2-4ff2c6fabd0d",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "61e65e7e214047e8ad514008110a96c0",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Dropdown(description='GUI:', options=('bandage', 'pymol', 'molbobity'), value='bandage')"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7d0f5644e07b4ecfaf4ce51ad6528c1f",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Button(description='Start Gui', style=ButtonStyle())"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "eae09f2d13cd41e9a04bd301d2b80435",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"w = widgets.Dropdown(\n",
" options=['bandage', 'pymol', 'molbobity'],\n",
" value='bandage',\n",
" description='GUI:',\n",
")\n",
"script_key = 'bandage'\n",
"script={\n",
" 'bandage':'start-bandage.sh',\n",
" 'pymol':'start-pymol.sh',\n",
" 'molbobity':'start-molbobity.sh',\n",
"}\n",
"def on_change(change):\n",
" if change['type'] == 'change' and change['name'] == 'value':\n",
" script_key = change['new']\n",
" print(\"changed to %s\" % change['new'])\n",
"\n",
"out = widgets.Output()\n",
"\n",
"\n",
"def on_button_clicked(b):\n",
" with out:\n",
" clear_output()\n",
" server_out = subprocess.run(['gcloud','compute','instances','create','bandage-gui-'+str(int(ts)),'--zone=us-east4-a','--boot-disk-size=200','--metadata-from-file=startup-script='+script[script_key],'--image-project=debian-cloud','--image-family=debian-12'], text=True, capture_output=True)\n",
" server_name = 'bandage-gui-'+str(int(ts))\n",
" if len(server_out.stdout) >0:\n",
" print(\"Please access the GUI at http://\"+server_out.stdout.split(\"\\n\")[1].split(\" \")[-3]+\":8080\")\n",
" print(\"Note, it may take 3-4 minutes for it to fully start\")\n",
" else:\n",
" display(HTML(server_out.stderr))\n",
" print(server_out.stderr)\n",
"\n",
"\n",
"button = widgets.Button(description=\"Start Gui\")\n",
"button.on_click(on_button_clicked)\n",
"w.observe(on_change)\n",
"display(w)\n",
"display(button)\n",
"display(out)\n"
]
},
{
"cell_type": "markdown",
"id": "55229d32-607d-4b90-8947-54f43abeb8e8",
"metadata": {},
"source": [
"Run the below to clean up the GUI once done"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "23702d79-3dee-45e4-9401-c6614c66fce8",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"delete_instance(zone='us-east4-a',machine_name=server_name)"
]
}
],
"metadata": {
"environment": {
"kernel": "conda-base-py",
"name": "workbench-notebooks.m125",
"type": "gcloud",
"uri": "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/workbench-notebooks:m125"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel) (Local)",
"language": "python",
"name": "conda-base-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
14 changes: 14 additions & 0 deletions reference_notebooks/start-pymol.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#! /bin/bash
apt-get update
apt-get install ca-certificates curl -y
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
export GCSFUSE_REPO=gcsfuse-`lsb_release -c -s` && echo "deb https://packages.cloud.google.com/apt $GCSFUSE_REPO main" | tee /etc/apt/sources.list.d/gcsfuse.list > /dev/null
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fuse gcsfuse -y
mkdir "/tmp/mount-folder" && chmod 777 /tmp/mount-folder && mount -t gcsfuse -o allow_other,file_mode=777,dir_mode=777 nigms-nosi-developers-us-notebooks "/tmp/mount-folder"
docker run --rm -v /tmp/mount-folder:/config/s3 -p 8080:3000 us-east4-docker.pkg.dev/nih-cl-shared-resources/nigms-sandbox/bandage-gui
1 change: 0 additions & 1 deletion reusable-workflow-repo
Submodule reusable-workflow-repo deleted from 323790

0 comments on commit ff62572

Please sign in to comment.