diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb new file mode 100644 index 00000000..b20a9eca --- /dev/null +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/configure_slc_flavor.ipynb @@ -0,0 +1,298 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "70724412-6577-4e69-86a1-b0d94e32eb96", + "metadata": {}, + "source": [ + "# Configure Flavor path\n", + "\n", + "Here we will give the user the option between:\n", + " - the Exasol Script-Languages-Release Github repository which provides the Script-Languages-Container flavor used to build the builtin container of the Exasol DB or to build customized container\n", + " - to use a custom flavor path\n", + "\n", + "## Prerequisites\n", + "\n", + "Prior to using this notebook the following steps need to be completed:\n", + "1. [Configure the AI-Lab](../main_config.ipynb).\n", + "\n", + "## Setup\n", + "\n", + "### Open Secure Configuration Storage\n" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "e70ad0a9-7042-4fe8-814b-5c586b9bee6d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e6b503a366de4fbfaa27133cd764cf89", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "350dc0e4b76d4f83ba1c31818b4e4688", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Box(children=(Box(children=(Label(value='Configuration Store', layout=Layout(border_bottom='solid 1px', border…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%run ../utils/access_store_ui.ipynb\n", + "display(get_access_store_ui('../'))" + ] + }, + { + "cell_type": "markdown", + "id": "9f02bc2f-411f-4479-b2e2-1afef96e4bd8", + "metadata": {}, + "source": [ + "# Load UI functions\n", + "Let's import some other UI functions that may be used in this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 242, + "id": "224345da-f14e-4a45-bf8a-07e3ba0870dc", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "34d26190895748799ba240ff5496ae6c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%run ./utils/slc_ui.ipynb" + ] + }, + { + "cell_type": "markdown", + "id": "178b59e9-8f46-43b1-b4f8-9cd6d6bf5076", + "metadata": {}, + "source": [ + "# Configure the Flavor path\n", + "### Choose the flavor source" + ] + }, + { + "cell_type": "code", + "execution_count": 243, + "id": "0f8caa77-35a0-403d-af96-e5f8056ba489", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "13649f5f9c334d1499382b6df9af8cbb", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Box(children=(Box(children=(Label(value='Flavor choice', layout=Layout(border_bottom='solid 1px', border_left=…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(get_slc_source_selection_ui(ai_lab_config))" + ] + }, + { + "cell_type": "markdown", + "id": "fc0fe1a5-8861-4f18-8bcf-92600f86f33f", + "metadata": {}, + "source": [ + "### Use existing script-languages-repository\n", + "If the user has chosen to use an existing script-languages-repository path we simply let him choose the path." + ] + }, + { + "cell_type": "code", + "execution_count": 244, + "id": "56e16540-5f4b-4d5c-8c83-d34c1217eb00", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "dc590fa666f64d24bb267f1d77592468", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Box(children=(Box(children=(Label(value='Existing script-languages directory', layout=Layout(border_bottom='so…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(get_existing_slc_ui(ai_lab_config))" + ] + }, + { + "cell_type": "markdown", + "id": "1db0f115-9382-4e53-be08-53586b831d0b", + "metadata": {}, + "source": [ + "### Clone the Script-Languages-Release repository\n", + "If the user wants to use the Exasol script-languages-repository we need first to choose the root path where the repository should be stored." + ] + }, + { + "cell_type": "code", + "execution_count": 245, + "id": "7d84889f-7c3a-4f69-9bf1-c193481867af", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "None" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(get_slc_target_dir_ui(ai_lab_config))" + ] + }, + { + "cell_type": "markdown", + "id": "a02ee33f-1958-4f9c-a796-01c6bc2a8787", + "metadata": {}, + "source": [ + "#### Now we can clone the repository" + ] + }, + { + "cell_type": "code", + "execution_count": 246, + "id": "31132726-9827-4c9b-8fb8-0884d2f36e67", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ready\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "if use_slc_repo(ai_lab_config):\n", + " from git import Repo\n", + " \n", + " slc_dir = Path(ai_lab_config.get(\"Script-Languages-Release-Dir\"))\n", + " if not slc_dir.is_dir():\n", + " print (f\"Cloning into {slc_dir}...\")\n", + " repo = Repo.clone_from(\"https://github.com/exasol/script-languages-release\", slc_dir)\n", + " print (\"Fetching submodules...\")\n", + " repo.submodule_update(recursive=True)\n", + " else:\n", + " print(f\"Directory '{slc_dir}' already exists. Skipping cloning....\")\n", + "print(\"Ready\")" + ] + }, + { + "cell_type": "markdown", + "id": "53997bff-b4be-406f-b54f-ae9f39939ede", + "metadata": {}, + "source": [ + "#### Now we can select the flavor." + ] + }, + { + "cell_type": "code", + "execution_count": 247, + "id": "bb6b26b9-cb24-4b66-85c9-e15a0c92ff2c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a151ede22ef447c1988bb2d92f7fea09", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Box(children=(Box(children=(Label(value='Flavor choice', layout=Layout(border_bottom='solid 1px', border_left=…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(get_flavor_selection_ui(ai_lab_config))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d38d5d4-91c7-4916-9431-83a5a8e3e5c5", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "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.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/get_script_languages_release.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/get_script_languages_release.ipynb deleted file mode 100644 index 75a7877a..00000000 --- a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/get_script_languages_release.ipynb +++ /dev/null @@ -1,185 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "70724412-6577-4e69-86a1-b0d94e32eb96", - "metadata": {}, - "source": [ - "# Script-Languages-Release\n", - "\n", - "Here we will clone the Script-Languages-Release Github repository which provides the Script-Languages-Container build config used to build the builtin container of the Exasol DB or to build customized container.\n", - "\n", - "## Prerequisites\n", - "\n", - "Prior to using this notebook the following steps need to be completed:\n", - "1. [Configure the AI-Lab](../main_config.ipynb).\n", - "\n", - "## Setup\n", - "\n", - "### Open Secure Configuration Storage\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "e70ad0a9-7042-4fe8-814b-5c586b9bee6d", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "85a5beca5a144e66b4c900654a02ca03", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ec9f910e777a4a9999dcd13fdfb6a49c", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Box(children=(Box(children=(Label(value='Configuration Store', layout=Layout(border_bottom='solid 1px', border…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%run ../utils/access_store_ui.ipynb\n", - "display(get_access_store_ui('../'))" - ] - }, - { - "cell_type": "markdown", - "id": "9f02bc2f-411f-4479-b2e2-1afef96e4bd8", - "metadata": {}, - "source": [ - "# Load UI functions\n", - "Let's import some other UI functions that may be used in this notebook." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "224345da-f14e-4a45-bf8a-07e3ba0870dc", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1782f10141b54abbb308f5f13daeb7f8", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%run ../utils/main_config_ui.ipynb" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "d29dfd37-a1fa-4a3f-83a2-3d9c9038a0a8", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "40bbb9788bfc4a6aadb98dedcc0eb08a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Box(children=(Box(children=(Label(value='Script-Languages-Container Configuration', layout=Layout(border_botto…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "display(get_slc_config_ui(ai_lab_config))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "31132726-9827-4c9b-8fb8-0884d2f36e67", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/home/jupyter/script_languages_release\n" - ] - }, - { - "data": { - "text/plain": [ - "git.RootModule(name=__ROOT__, path=, url=, branch_path=refs/heads/master)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from git import Repo\n", - "\n", - "dir = ai_lab_config.get(\"slc_directory\")\n", - "print (dir)\n", - "repo = Repo.clone_from(\"https://github.com/exasol/script-languages-release\", dir)\n", - "repo.submodule_update(recursive=True)\n", - "print(\"Ready)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "43f75bb6-cf59-44d1-b8a0-74ed05be09ba", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "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.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb new file mode 100644 index 00000000..951ab611 --- /dev/null +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/using_a_script_languages_container.ipynb @@ -0,0 +1,297 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "06585243-2e50-4f9b-8d6f-b79aade6f8f5", + "metadata": {}, + "source": [ + "# Using the Script-Language Container\n", + "A [Script-Language Container](https://github.com/exasol/script-languages-release) for the Exasol database consists of a Linux container with a complete Linux distribution and all required libraries, such as a script client. The script client is responsible for the communication with the database and for executing the script code. It allows to also include user specific libraries which can then be used from within the UDF's. " + ] + }, + { + "cell_type": "markdown", + "id": "39333102-7652-4699-ba0e-d184aeec1753", + "metadata": {}, + "source": [ + "Before we start we need to configure the script-languages directory and flavor. See [Configure SLC Flavor](http://localhost:49494/lab/tree/script_languages_container/configure_slc_flavor.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "25604520-c997-4d2b-8138-02a64e7231d0", + "metadata": {}, + "source": [ + "## Setup\n", + "### Open Secure Configuration Storage" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "da57e77a-b41f-45e3-9a17-4b474bba898b", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "55496235b82f434cb9c8b66503078815", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2a16af727a574dbe89c2d702f5513ebc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Box(children=(Box(children=(Label(value='Configuration Store', layout=Layout(border_bottom='solid 1px', border…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%run ../utils/access_store_ui.ipynb\n", + "display(get_access_store_ui('../'))" + ] + }, + { + "cell_type": "markdown", + "id": "81fbc9a1-718a-4d93-8753-85b032998c1b", + "metadata": {}, + "source": [ + "### Utility functions\n", + "\n", + "#### Working directory context manager\n", + "Let's create a utility context manager function which enters a directory and jumps back to the previous directory on exit." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "27352b75-823d-40a1-b8df-d33218fd7de6", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import contextlib\n", + "from pathlib import Path\n", + "\n", + "@contextlib.contextmanager\n", + "def working_directory(path: Path):\n", + " \"\"\"Changes working directory and returns to previous on exit.\"\"\"\n", + " prev_cwd = Path.cwd()\n", + " os.chdir(path)\n", + " try:\n", + " yield\n", + " finally:\n", + " os.chdir(prev_cwd)" + ] + }, + { + "cell_type": "markdown", + "id": "c6d50944-6065-463c-be74-0e2b88c18346", + "metadata": {}, + "source": [ + "#### Show directory content" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "9543044f-0f8d-426d-a7b3-a13dac6a921d", + "metadata": {}, + "outputs": [], + "source": [ + "def show_directory_content(directory: Path):\n", + " for p in directory.iterdir():\n", + " print(p)" + ] + }, + { + "cell_type": "markdown", + "id": "9fba4c9e-4a1b-4f84-a9a6-f05810aa8922", + "metadata": {}, + "source": [ + "### Import some utility functions" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "c554d698-d5a2-4f9b-846a-f606a3f183b7", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9f901d9d3d364ae6b9a4943ddcdf5abb", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from exasol.nb_connector.utils import upward_file_search\n", + "\n", + "# This NB may be running from various locations in the NB hierarchy.\n", + "# Need to search for the styles NB from the current directory upwards.\n", + "\n", + "%run {upward_file_search('utils/ui_styles.ipynb')}\n", + "%run {upward_file_search('utils/popup_message_ui.ipynb')}" + ] + }, + { + "cell_type": "markdown", + "id": "ebddfdf9-fdac-4bb9-b8a4-58224cf50bda", + "metadata": {}, + "source": [ + "## Let's use the flavor as is\n", + "### Check selected flavor path" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "f03723b8-2229-4e10-b801-ac074c7388cb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Script-languages repository path is '/tmp/script_languages_release'\n", + "Selected flavor is 'template-Exasol-all-python-3.10'\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "slc_source_flavor_store_key = \"slc_flavor\"\n", + "slc_target_dir_store_key = \"slc_target_dir\"\n", + "\n", + "slc_dir = Path(ai_lab_config.get(slc_target_dir_store_key))\n", + "selected_flavor = ai_lab_config.get(slc_source_flavor_store_key)\n", + "print(f\"Script-languages repository path is '{slc_dir}'\")\n", + "print(f\"Selected flavor is '{selected_flavor}'\")\n", + "if not (Path(slc_dir) / \"flavors\" / selected_flavor).is_dir():\n", + " popup_message(\"Invalid script-languages directory or flavor configuration. Please re-run \")\n", + "\n", + "flavor_path = Path(\"flavors\") / selected_flavor\n" + ] + }, + { + "cell_type": "markdown", + "id": "d496fe3d-90ac-4d3e-86e0-bef8ecaf8561", + "metadata": {}, + "source": [ + "### Export the flavor\n", + "You could run the same on the command line with the `exaslct` tool:\n", + "```\n", + "cd \n", + "./exaslct export --flavor-path flavors/\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "20665390-4f31-48db-ab78-249a1ef629e9", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ready\n" + ] + } + ], + "source": [ + "from exasol_script_languages_container_tool.lib import api as exaslct_api\n", + "\n", + "export_path = \"/tmp/slc\"\n", + "output_path = \"/tmp/output\"\n", + "\n", + "with working_directory(slc_dir):\n", + " exaslct_api.export(flavor_path=(str(flavor_path),), export_path=export_path)\n", + "print(\"Ready\")" + ] + }, + { + "cell_type": "markdown", + "id": "deb31b95-f615-45c1-b47a-e8e1b0fb22c9", + "metadata": {}, + "source": [ + "#### Check the result" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "fc142500-d855-4112-bba2-ed3395889b9b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/tmp/slc/template-Exasol-all-python-3.10_release.tar.gz\n", + "/tmp/slc/template-Exasol-all-python-3.10_release.tar.gz.sha512sum\n" + ] + } + ], + "source": [ + "show_directory_content(Path(export_path))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79be765f-7849-4bee-9397-18911c0c6735", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "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.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb new file mode 100644 index 00000000..700c1d43 --- /dev/null +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook/script_languages_container/utils/slc_ui.ipynb @@ -0,0 +1,274 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2761e16d-8723-4f44-b202-d772ce751323", + "metadata": {}, + "source": [ + "# Script-Languages-Container UI\n", + "\n", + "This notebook is not supposed to be used on its own.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f044043c-8fa1-442e-8d2c-b4221accff9f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7d5b5aab56a44f02af835eeccc0ba1af", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from exasol.nb_connector.utils import upward_file_search\n", + "\n", + "# This NB may be running from various locations in the NB hierarchy.\n", + "# Need to search for the styles NB from the current directory upwards.\n", + "\n", + "%run {upward_file_search('utils/ui_styles.ipynb')}\n", + "%run {upward_file_search('utils/popup_message_ui.ipynb')}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a2e90ebe-37d6-43e6-9677-dace6c06d942", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'Secrets' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 8\u001b[0m\n\u001b[1;32m 4\u001b[0m slc_source_flavor_store_key \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mslc_flavor_path\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mipyfilechooser\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m FileChooser\n\u001b[0;32m----> 8\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21muse_slc_repo\u001b[39m(conf: \u001b[43mSecrets\u001b[49m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mbool\u001b[39m:\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m conf\u001b[38;5;241m.\u001b[39mget(slc_source_store_key) \u001b[38;5;241m==\u001b[39m slc_source_slc_repo_option_value\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_slc_source_selection_ui\u001b[39m(conf: Secrets) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m widgets\u001b[38;5;241m.\u001b[39mWidget:\n", + "\u001b[0;31mNameError\u001b[0m: name 'Secrets' is not defined" + ] + } + ], + "source": [ + "slc_source_store_key = \"slc_source\"\n", + "slc_source_slc_repo_option_value = \"Clone script languages release repository\"\n", + "slc_target_dir_store_key = \"slc_target_dir\"\n", + "slc_source_flavor_store_key = \"slc_flavor\"\n", + "\n", + "from ipyfilechooser import FileChooser\n", + "\n", + "def clone_slc_repo(conf: Secrets) -> bool:\n", + " return conf.get(slc_source_store_key) == slc_source_slc_repo_option_value\n", + "\n", + "def get_slc_source_selection_ui(conf: Secrets) -> widgets.Widget:\n", + " \"\"\"\n", + " Creates a UI form for choosing the flavor source\n", + " \"\"\"\n", + "\n", + " ui_look = get_config_styles()\n", + " ui_look.input_layout.max_width = \"500px\"\n", + " \n", + " slc_sources = [slc_source_slc_repo_option_value, \"Use existing repository\"]\n", + " default_value = conf.get(slc_source_store_key)\n", + "\n", + " flavor_source_selector = widgets.RadioButtons(options=slc_sources, value=default_value, \n", + " layout=ui_look.input_layout, style=ui_look.input_style)\n", + " select_btn = widgets.Button(description='Select', style=ui_look.button_style, layout=ui_look.button_layout)\n", + " header_lbl = widgets.Label(value='Flavor choice', style=ui_look.header_style, layout=ui_look.header_layout)\n", + "\n", + "\n", + " def select_flavor_source(btn):\n", + " conf.save(slc_source_store_key, flavor_source_selector.value)\n", + " btn.icon = 'check'\n", + "\n", + " def on_value_change(change):\n", + " select_btn.icon = 'pen'\n", + "\n", + " select_btn.on_click(select_flavor_source)\n", + " flavor_source_selector.observe(on_value_change, names=['value'])\n", + "\n", + " group_items = [header_lbl, widgets.Box([flavor_source_selector], layout=ui_look.row_layout)]\n", + " items = [widgets.Box(group_items, layout=ui_look.group_layout), select_btn]\n", + " ui = widgets.Box(items, layout=ui_look.outer_layout)\n", + " return ui\n", + "\n", + "def get_slc_target_dir_ui(conf: Secrets) -> widgets.Widget:\n", + " \"\"\"\n", + " Creates a UI form for editing the Script-Languages-Container repository configuration.\n", + " \"\"\"\n", + " default_target_dir = conf.get(slc_target_dir_store_key, '/home/jupyter')\n", + " target_dir_chooser_widget = FileChooser(path=default_target_dir, select_default=True)\n", + " target_dir_chooser_widget.show_only_dirs = True\n", + " \n", + " inputs = [\n", + " [\n", + " ('Target Base Directory', target_dir_chooser_widget, slc_target_dir_store_key),\n", + " ]\n", + " ]\n", + "\n", + " ui_look = get_config_styles()\n", + " ui_look.row_layout.max_width = \"500px\"\n", + " ui_look.group_layout.max_width = \"500px\"\n", + " save_btn = widgets.Button(description='Save', style=ui_look.button_style, layout=ui_look.button_layout)\n", + " header_lbl = widgets.Label(value='Target Directory', style=ui_look.header_style, layout=ui_look.header_layout)\n", + "\n", + " def save_configuration(btn):\n", + " target_dir = Path(target_dir_chooser_widget.selected) / \"script_languages_release\"\n", + " conf.save(slc_target_dir_store_key, str(target_dir))\n", + " btn.icon = 'check'\n", + "\n", + " def on_value_change(change):\n", + " save_btn.icon = 'pen'\n", + "\n", + " save_btn.on_click(save_configuration)\n", + "\n", + " # Apply the styles and layouts to the input fields\n", + " target_dir_chooser_widget.observe(on_value_change, names=['value'])\n", + "\n", + " group_items = [header_lbl, widgets.Box([target_dir_chooser_widget], layout=ui_look.row_layout)]\n", + " items = [widgets.Box(group_items, layout=ui_look.group_layout), save_btn]\n", + " ui = widgets.Box(items, layout=ui_look.outer_layout)\n", + " \n", + "\n", + " if clone_slc_repo(conf):\n", + " return ui\n", + "\n", + "def get_existing_slc_ui(conf: Secrets) -> widgets.Widget:\n", + " \"\"\"\n", + " Creates a UI form for choosing the existing script-languages repository.\n", + " \"\"\"\n", + " default_src_dir = conf.get(slc_target_dir_store_key, '')\n", + " select_default = True if slc_target_dir_store_key else False\n", + " src_dir_chooser_widget = FileChooser(path=default_src_dir, select_default=select_default)\n", + " src_dir_chooser_widget.show_only_dirs = True\n", + " \n", + " inputs = [\n", + " [\n", + " ('Flavor source directory', src_dir_chooser_widget, slc_target_dir_store_key),\n", + " ]\n", + " ]\n", + "\n", + " ui_look = get_config_styles()\n", + " ui_look.row_layout.max_width = \"500px\"\n", + " ui_look.group_layout.max_width = \"500px\"\n", + " save_btn = widgets.Button(description='Save', style=ui_look.button_style, layout=ui_look.button_layout)\n", + " header_lbl = widgets.Label(value='Existing script-languages directory', style=ui_look.header_style, layout=ui_look.header_layout)\n", + "\n", + "\n", + " def save_configuration(btn):\n", + " target_dir = Path(src_dir_chooser_widget.selected)\n", + " if not (target_dir / \"flavors\").is_dir():\n", + " popup_message(\"Invalid directory. You need to choose a valid script-languages repository.\")\n", + " conf.save(slc_target_dir_store_key, str(src_dir_chooser_widget.selected))\n", + " btn.icon = 'check'\n", + "\n", + " def on_value_change(change):\n", + " save_btn.icon = 'pen'\n", + "\n", + " save_btn.on_click(save_configuration)\n", + "\n", + " # Apply the styles and layouts to the input fields\n", + " src_dir_chooser_widget.observe(on_value_change, names=['value'])\n", + "\n", + " group_items = [header_lbl, widgets.Box([src_dir_chooser_widget], layout=ui_look.row_layout)]\n", + " items = [widgets.Box(group_items, layout=ui_look.group_layout), save_btn]\n", + " ui = widgets.Box(items, layout=ui_look.outer_layout)\n", + " \n", + "\n", + " if not clone_slc_repo(conf):\n", + " return ui\n", + "\n", + "\n", + "def get_flavor_selection_ui(conf: Secrets) -> widgets.Widget:\n", + " \"\"\"\n", + " Creates a UI form for choosing from a list of flavors.\n", + " \"\"\"\n", + "\n", + " from os import listdir\n", + " from os.path import isdir\n", + " from pathlib import Path\n", + "\n", + " slc_dir = conf.get(slc_target_dir_store_key)\n", + " \n", + "\n", + "\n", + " flavor_base_dir = Path(slc_dir) / \"flavors\"\n", + " flavor_dirs = [flavor_dir.name for flavor_dir in flavor_base_dir.iterdir() if flavor_dir.is_dir()]\n", + "\n", + " ui_look = get_config_styles()\n", + " ui_look.input_layout.max_width = \"500px\"\n", + "\n", + " #Setup default value\n", + " #First we check if we can match the value from the Secret store\n", + " default_src_dir = conf.get(slc_source_flavor_store_key, '')\n", + " default_src_dir_value = ''\n", + " if default_src_dir:\n", + " matching_flavor_dirs = [flavor_dir.name for flavor_dir in flavor_base_dir.iterdir() if flavor_dir.is_dir() and str(flavor_dir) == default_src_dir]\n", + " if len(matching_flavor_dirs) == 1:\n", + " default_src_dir_value = matching_flavor_dirs[0]\n", + " #If not found in the secret store, we choose the first path which matches the template-\n", + " if not default_src_dir_value:\n", + " default_src_dir_value = \"template-Exasol-all-python-3.10\"\n", + " flavor_selector = widgets.RadioButtons(options=flavor_dirs, value=default_src_dir_value, \n", + " layout=ui_look.input_layout, style=ui_look.input_style)\n", + " select_btn = widgets.Button(description='Select', style=ui_look.button_style, layout=ui_look.button_layout)\n", + " header_lbl = widgets.Label(value='Flavor choice', style=ui_look.header_style, layout=ui_look.header_layout)\n", + "\n", + "\n", + " def select_flavor(btn):\n", + " conf.save(slc_source_flavor_store_key, str(flavor_selector.value))\n", + " btn.icon = 'check'\n", + "\n", + " def on_value_change(change):\n", + " select_btn.icon = 'pen'\n", + "\n", + " select_btn.on_click(select_flavor)\n", + " flavor_selector.observe(on_value_change, names=['value'])\n", + "\n", + " group_items = [header_lbl, widgets.Box([flavor_selector], layout=ui_look.row_layout)]\n", + " items = [widgets.Box(group_items, layout=ui_look.group_layout), select_btn]\n", + " ui = widgets.Box(items, layout=ui_look.outer_layout)\n", + " return ui" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2f4a93b-6c4a-42e8-badd-7e9968ee8663", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "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.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook_requirements.txt b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook_requirements.txt index 795674a6..d74377ab 100644 --- a/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook_requirements.txt +++ b/exasol/ds/sandbox/runtime/ansible/roles/jupyter/files/notebook_requirements.txt @@ -10,4 +10,5 @@ boto3==1.26.163 exasol-notebook-connector @ git+https://github.com/exasol/notebook-connector.git@main pickleshare==0.7.5 # See https://github.com/exasol/ai-lab/issues/291 for details. exasol-script-languages-container-tool==0.19.0 -GitPython>=2.1.0 \ No newline at end of file +GitPython>=2.1.0 +ipyfilechooser==0.6.0 \ No newline at end of file