From 32d063b860e6898a34ceb7c7d998df38c241ed15 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Fri, 28 Jul 2023 14:37:08 +0200 Subject: [PATCH 01/11] First version in local deploy, BUT need to shut down webserver properly. --- .bumpversion.cfg | 17 ++ .gitignore | 59 ++++++ .../voila-viewer/docker-compose.overwrite.yml | 4 + .osparc/voila-viewer/metadata.yml | 178 ++++++++++++++++++ .osparc/voila-viewer/runtime.yml | 20 ++ CHANGELOG.md | 40 ++++ Dockerfile | 17 ++ docker-compose-local.yml | 16 ++ docker/boot_notebook.bash | 79 ++++++++ docker/entrypoint.bash | 75 ++++++++ requirements.in | 2 + src/templates/index.html | 11 ++ src/webserver_input_monitor.py | 24 +++ 13 files changed, 542 insertions(+) create mode 100644 .bumpversion.cfg create mode 100644 .gitignore create mode 100644 .osparc/voila-viewer/docker-compose.overwrite.yml create mode 100644 .osparc/voila-viewer/metadata.yml create mode 100644 .osparc/voila-viewer/runtime.yml create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 docker-compose-local.yml create mode 100755 docker/boot_notebook.bash create mode 100755 docker/entrypoint.bash create mode 100644 requirements.in create mode 100644 src/templates/index.html create mode 100644 src/webserver_input_monitor.py diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..8b21b73 --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,17 @@ +[bumpversion] +current_version = 2.0.9 +commit = False +message = service version: {current_version} → {new_version} +tag = False + +[bumpversion:file:.osparc/jupyter-math/metadata.yml] +search = {current_version} +replace = {new_version} + +[bumpversion:file:Makefile] +search = {current_version} +replace = {new_version} + +[bumpversion:file:docker-compose-local.yml] +search = {current_version} +replace = {new_version} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ae2859 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Build folders +build/ +deploy/ + +# test folders +test/ + +# .env files +.env + +# Python +__pycache__/ +.venv/ +.pytest_cache/ + +# java +*.class + +# vscode +.vscode/ + +# docker +.env +# temp folders +tmp/ +.tmp +# gitlab +*.toml + +.cache/ + +# not interested in storing this file +docker-compose.yml + +# ignore all files in validation +validation/ + +*.ignore.* + +# requirements go in .in file, txt generated with Makefile target +requirements.txt \ No newline at end of file diff --git a/.osparc/voila-viewer/docker-compose.overwrite.yml b/.osparc/voila-viewer/docker-compose.overwrite.yml new file mode 100644 index 0000000..7013933 --- /dev/null +++ b/.osparc/voila-viewer/docker-compose.overwrite.yml @@ -0,0 +1,4 @@ +services: + voila-viewer: + build: + dockerfile: Dockerfile diff --git a/.osparc/voila-viewer/metadata.yml b/.osparc/voila-viewer/metadata.yml new file mode 100644 index 0000000..7375ef0 --- /dev/null +++ b/.osparc/voila-viewer/metadata.yml @@ -0,0 +1,178 @@ +name: Voilà Viewer +thumbnail: https://github.com/voila-dashboards/voila/raw/main/docs/source/voila-logo.svg +description: + "Takes as input a Jupyter Notebook and it shows it using Jupyter [Voilà](https://github.com/voila-dashboards/voila)" +key: simcore/services/dynamic/voila-viewer +version: 1.0.0 +integration-version: 2.0.0 +type: dynamic +authors: + - name: Elisabetta Iavarone + email: iavarone@itis.swiss + affiliation: IT'IS Foundation +contact: iavarone@itis.swiss +inputs: + input_1: + displayOrder: 1.0 + label: input_files_1 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + fileToKeyMap: + "voila.ipynb": input_1 + input_2: + displayOrder: 2.0 + label: input_files_2 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_3: + displayOrder: 3.0 + label: input_files_3 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_4: + displayOrder: 4.0 + label: input_files_4 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_5: + displayOrder: 5.0 + label: input_files_5 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_6: + displayOrder: 6.0 + label: input_files_6 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_7: + displayOrder: 7.0 + label: input_files_7 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_8: + displayOrder: 8.0 + label: input_files_8 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_9: + displayOrder: 9.0 + label: input_files_9 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_10: + displayOrder: 10.0 + label: input_files_10 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_11: + displayOrder: 11.0 + label: input_files_11 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_12: + displayOrder: 12.0 + label: input_files_12 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_13: + displayOrder: 13.0 + label: input_files_13 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_14: + displayOrder: 14.0 + label: input_files_14 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_15: + displayOrder: 15.0 + label: input_files_15 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_16: + displayOrder: 16.0 + label: input_files_16 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_17: + displayOrder: 17.0 + label: input_files_17 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_18: + displayOrder: 18.0 + label: input_files_18 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_19: + displayOrder: 19.0 + label: input_files_19 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* + input_20: + displayOrder: 20.0 + label: input_files_20 + description: + Any input files. One or several files compressed in a zip will be + downloaded in an inputs folder. + type: data:*/* +outputs: + output_1: + displayOrder: 1.0 + label: Output files 1 + description: Output files uploaded from the outputs folder + type: data:*/* + output_2: + displayOrder: 2.0 + label: Output files 2 + description: Output files uploaded from the outputs folder + type: data:*/* + output_3: + displayOrder: 3.0 + label: Output files 3 + description: Output files uploaded from the outputs folder + type: data:*/* + output_4: + displayOrder: 4.0 + label: Output files 4 + description: Output files uploaded from the outputs folder + type: data:*/* +min-visible-inputs: 4 \ No newline at end of file diff --git a/.osparc/voila-viewer/runtime.yml b/.osparc/voila-viewer/runtime.yml new file mode 100644 index 0000000..6f83724 --- /dev/null +++ b/.osparc/voila-viewer/runtime.yml @@ -0,0 +1,20 @@ +restart-policy: no-restart +settings: + - name: ports + type: int + value: 8888 + - name: constraints + type: string + value: + - node.platform.os == linux + - name: Resources + type: Resources + value: + Limits: + NanoCPUs: 4000000000 + MemoryBytes: 17179869184 +paths-mapping: + inputs_path: /home/jovyan/work/inputs + outputs_path: /home/jovyan/work/outputs + state_paths: + - /home/jovyan/work/workspace diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6aa7ec4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +## [2.0.6] - 2022-05-08 +- shell and kernel now use the same python interpreter +- fixes issue crashing when trusting notebooks +- fixes issue crashing when copying README.ipynb +- pick between only 2 available kernels + +## [2.0.5] - 2022-03-03 +- `~/work/workspace` is now the default working directory containing `~/work/workspace/README.ipynb` +- voila preview now works as expected +- replaced readme and which is now present inside +- fixed: broken octave kernel and deactivated plugins +- fixed: broken LaTex compiler +- upgraded jupuyter-lab to v3.3.2 + +## [2.0.4] - 2022-02-02 +- added `jupyterlab-lsp` and `python-lsp-server[all]` to make the python coding experience more user friendly + +## [2.0.3] - 2022-01-28 + +- invalid notebooks will no longer cause the service to not start + +## [2.0.2] - 2022-01-27 + +- changed scratch folder to workspace +- renamed default boot mode + + +## [2.0.1] - 2022-01-26 + +- changed voila to serve on 0.0.0.0 from localhost + +## [2.0.0] - 2021-12-16 + +- updated to run via dynamic-sidecar +- output can be uploaded via the usage of symlinks +- security enhancements +- updated to python version 3.9.7 +- updated to jupuyter-lab version 3.2.4 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ba301eb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM itisfoundation/jupyter-math:2.0.9 as main +LABEL maintainer="iavarone" +USER root + +COPY --chown=$NB_UID:$NB_GID requirements.txt ${NOTEBOOK_BASE_DIR}/requirements.txt +RUN .venv/bin/pip --no-cache install pip-tools && \ + .venv/bin/pip --no-cache install -r ${NOTEBOOK_BASE_DIR}/requirements.txt + +# Copying boot scripts +COPY --chown=$NB_UID:$NB_GID docker /docker + +# Copying source code +COPY --chown=$NB_UID:$NB_GID src /src + +EXPOSE 8888 + +ENTRYPOINT [ "/bin/bash", "/docker/entrypoint.bash" ] \ No newline at end of file diff --git a/docker-compose-local.yml b/docker-compose-local.yml new file mode 100644 index 0000000..1196530 --- /dev/null +++ b/docker-compose-local.yml @@ -0,0 +1,16 @@ +version: '3.7' +services: + voila-viewer: + image: simcore/services/dynamic/voila-viewer:1.0.0 + ports: + - "8888:8888" + environment: + - DY_SIDECAR_PATH_INPUTS=/tmp/inputs + - DY_SIDECAR_PATH_OUTPUTS=/tmp/outputs + - DY_BOOT_OPTION_BOOT_MODE=0 + - DY_SIDECAR_PATH/home/jovyan/work/workspace + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix + - ${PWD}/validation/workspace:/home/jovyan/work/workspace + - ${PWD}/validation/inputs:/tmp/inputs + - ${PWD}/validation/outputs:/tmp/outputs \ No newline at end of file diff --git a/docker/boot_notebook.bash b/docker/boot_notebook.bash new file mode 100755 index 0000000..e7e7e87 --- /dev/null +++ b/docker/boot_notebook.bash @@ -0,0 +1,79 @@ +#!/bin/bash +# SEE http://redsymbol.net/articles/unofficial-bash-strict-mode/ + +set -euo pipefail +IFS=$'\n\t' +INFO="INFO: [$(basename "$0")] " + +echo "$INFO" " User :$(id "$(whoami)")" +echo "$INFO" " Workdir :$(pwd)" + +# Trust all notebooks in the notebooks folder +echo "$INFO" "trust all notebooks in path..." +find "${NOTEBOOK_BASE_DIR}" -name '*.ipynb' -type f | xargs -I % /bin/bash -c 'jupyter trust "%" || true' || true + +# Configure +# Prevents notebook to open in separate tab +mkdir --parents "$HOME/.jupyter/custom" +cat > "$HOME/.jupyter/custom/custom.js" < .jupyter_config.json < "/opt/conda/share/jupyter/lab/overrides.json" < /dev/null 2>&1 || \ + (echo "ERROR: You must mount '${DY_SIDECAR_PATH_INPUTS}' to deduce user and group ids" && exit 1) +stat "${DY_SIDECAR_PATH_OUTPUTS}" > /dev/null 2>&1 || \ + (echo "ERROR: You must mount '${DY_SIDECAR_PATH_OUTPUTS}' to deduce user and group ids" && exit 1) + +# NOTE: expects docker run ... -v /path/to/input/folder:${DY_SIDECAR_PATH_INPUTS} +# check input/output folders are owned by the same user +if [ "$(stat -c %u "${DY_SIDECAR_PATH_INPUTS}")" -ne "$(stat -c %u "${DY_SIDECAR_PATH_OUTPUTS}")" ] +then + echo "ERROR: '${DY_SIDECAR_PATH_INPUTS}' and '${DY_SIDECAR_PATH_OUTPUTS}' have different user id's. not allowed" && exit 1 +fi +# check input/outputfolders are owned by the same group +if [ "$(stat -c %g "${DY_SIDECAR_PATH_INPUTS}")" -ne "$(stat -c %g "${DY_SIDECAR_PATH_OUTPUTS}")" ] +then + echo "ERROR: '${DY_SIDECAR_PATH_INPUTS}' and '${DY_SIDECAR_PATH_OUTPUTS}' have different group id's. not allowed" && exit 1 +fi + +echo "listing inputs folder ${DY_SIDECAR_PATH_INPUTS}" +ls -lah "${DY_SIDECAR_PATH_INPUTS}" +echo "listing outputs folder ${DY_SIDECAR_PATH_OUTPUTS}" +ls -lah "${DY_SIDECAR_PATH_OUTPUTS}" + +echo "setting correct user id/group id..." +HOST_USERID=$(stat -c %u "${DY_SIDECAR_PATH_INPUTS}") +HOST_GROUPID=$(stat -c %g "${DY_SIDECAR_PATH_INPUTS}") +CONTAINER_GROUPNAME=$(getent group | grep "${HOST_GROUPID}" | cut --delimiter=: --fields=1 || echo "") +echo "CONTAINER_GROUPNAME='$CONTAINER_GROUPNAME'" + +if [ "$HOST_USERID" -eq 0 ] +then + echo "Warning: Folder mounted owned by root user... adding $NB_USER to root..." + addgroup "$NB_USER" root +else + echo "Folder mounted owned by user $HOST_USERID:$HOST_GROUPID-'$CONTAINER_GROUPNAME'..." + # take host's credentials in $NB_USER + if [ -z "$CONTAINER_GROUPNAME" ] + then + echo "Creating new group my$NB_USER" + CONTAINER_GROUPNAME=my$NB_USER + addgroup --gid "$HOST_GROUPID" "$CONTAINER_GROUPNAME" + else + echo "group already exists" + fi + + echo "adding $NB_USER to group $CONTAINER_GROUPNAME..." + usermod --append --groups "$CONTAINER_GROUPNAME" "$NB_USER" + + echo "Chainging owner ship of state directory /home/${NB_USER}/work/workspace" + chown --recursive "$NB_USER" "/home/${NB_USER}/work/workspace" + echo "Chainging owner ship of state directory ${DY_SIDECAR_PATH_INPUTS}" + chown --recursive "$NB_USER" "${DY_SIDECAR_PATH_INPUTS}" + echo "Chainging owner ship of state directory ${DY_SIDECAR_PATH_OUTPUTS}" + chown --recursive "$NB_USER" "${DY_SIDECAR_PATH_OUTPUTS}" +fi + +echo "Removing write permissions from users in placed where they are not allowed to write:" +echo "- /home/${NB_USER}/work" +chmod gu-w "/home/${NB_USER}/work" + +echo +echo "$INFO" "Starting notebook ..." +exec gosu "$NB_USER" /docker/boot_notebook.bash diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..46c78ce --- /dev/null +++ b/requirements.in @@ -0,0 +1,2 @@ +flask +dash \ No newline at end of file diff --git a/src/templates/index.html b/src/templates/index.html new file mode 100644 index 0000000..479492d --- /dev/null +++ b/src/templates/index.html @@ -0,0 +1,11 @@ + + + + + FlaskApp + + +

Hello World!

+

Welcome to FlaskApp!

+ + \ No newline at end of file diff --git a/src/webserver_input_monitor.py b/src/webserver_input_monitor.py new file mode 100644 index 0000000..824854c --- /dev/null +++ b/src/webserver_input_monitor.py @@ -0,0 +1,24 @@ +import flask, requests, multiprocessing +from flask import render_template +from time import sleep +import os +from pathlib import Path + +app = flask.Flask(__name__) + +@app.route("/") +def index(): + return render_template("index.html") + +server = multiprocessing.Process(target=app.run, args=("0.0.0.0", 8888)) + +server.start() + +input_nb = Path(os.environ["DY_SIDECAR_PATH_INPUTS"]).joinpath("input_1/voila.ipynb") +while not os.path.exists(input_nb): + sleep(0.1) + +server.terminate() +server.join() + +sleep(5) \ No newline at end of file From bfaf2a449d968152013a89626804cae43e4d99d7 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:23:38 +0200 Subject: [PATCH 02/11] It works with ANE contributions --- src/templates/index.html | 37 +++++++++++++++++++++++++++++----- src/webserver_input_monitor.py | 8 ++++++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/templates/index.html b/src/templates/index.html index 479492d..b59f4ac 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -1,11 +1,38 @@ - + + - - FlaskApp + Auto-Reload on Content Change + -

Hello World!

-

Welcome to FlaskApp!

+

Waiting for voila.ipynb in input 1...

+

If voilà doesn't load after connecting input 1, reload the Service UI

+ + + \ No newline at end of file diff --git a/src/webserver_input_monitor.py b/src/webserver_input_monitor.py index 824854c..2c40034 100644 --- a/src/webserver_input_monitor.py +++ b/src/webserver_input_monitor.py @@ -1,14 +1,18 @@ import flask, requests, multiprocessing from flask import render_template from time import sleep +from uuid import uuid4 import os from pathlib import Path app = flask.Flask(__name__) +UNIQUE_TOKEN = "_".join([f"{uuid4()}" for x in range(10)]) + @app.route("/") def index(): - return render_template("index.html") + unique_tracking_token = UNIQUE_TOKEN + return render_template("index.html", unique_tracking_token=unique_tracking_token) server = multiprocessing.Process(target=app.run, args=("0.0.0.0", 8888)) @@ -21,4 +25,4 @@ def index(): server.terminate() server.join() -sleep(5) \ No newline at end of file +#sleep(5) \ No newline at end of file From 28ccdc1fb965abd9c6e01694822a8e8d0381928c Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:29:44 +0200 Subject: [PATCH 03/11] Added CI files --- .github/CODEOWNERS | 9 +++ .github/ISSUE_TEMPLATE/ask_question.md | 17 +++++ .github/ISSUE_TEMPLATE/bug_report.md | 44 +++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 28 +++++++++ .github/workflows/check-image.yml | 22 +++++++ CHANGELOG.md | 38 +----------- Makefile | 75 +++++++++++++++++++++++ 7 files changed, 197 insertions(+), 36 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/ask_question.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/check-image.yml create mode 100644 Makefile diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..0bd0700 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,9 @@ + +# Maps code in repository with maintainers +# Order is important. The last matching pattern has the most precedence. +# SEE https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-code-owners#example-of-a-codeowners-file + +* @elisabettai + +# NOTE: '/' denotes the root of the repository +/src/templates/index.html @GitHK diff --git a/.github/ISSUE_TEMPLATE/ask_question.md b/.github/ISSUE_TEMPLATE/ask_question.md new file mode 100644 index 0000000..11cb029 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ask_question.md @@ -0,0 +1,17 @@ +--- +name: 💬 Question +about: Ask a question +labels: question +assignees: elisabettai, newton1985, app-team +--- + +## What version of this service are you using? + + + +## How can we help you? diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..03030d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,44 @@ +--- +name: 🐛 Bug +about: File a bug/issue +labels: bug +assignees: GitHK +--- + +## What version of this service are you using? + + + +## Long story short + + + +## Expected behaviour + + + +## Actual behaviour + + + +## Steps to reproduce + + + +## Your environment + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..888fe5f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,28 @@ +--- +name: ✨ Feature request +about: Suggest an idea to implement +labels: enhancement +assignees: elisabettai +--- + +## User Story + + + +## Example + + + + +## Definition of Done + diff --git a/.github/workflows/check-image.yml b/.github/workflows/check-image.yml new file mode 100644 index 0000000..b6bc5b3 --- /dev/null +++ b/.github/workflows/check-image.yml @@ -0,0 +1,22 @@ +name: Build and check image + +on: push + +jobs: + verify-image-build: + runs-on: ubuntu-latest + steps: + - name: Checkout repo content + uses: actions/checkout@v2 + - name: ooil version + uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 + with: + args: ooil --version + - name: Assemble docker-compose spec + uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 + with: + args: ooil compose + - name: Build all images if multiple + uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 + with: + args: docker-compose build diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aa7ec4..79a709b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,40 +1,6 @@ # Changelog -## [2.0.6] - 2022-05-08 -- shell and kernel now use the same python interpreter -- fixes issue crashing when trusting notebooks -- fixes issue crashing when copying README.ipynb -- pick between only 2 available kernels +## [1.0.0] - 2022-02-08 +- First version -## [2.0.5] - 2022-03-03 -- `~/work/workspace` is now the default working directory containing `~/work/workspace/README.ipynb` -- voila preview now works as expected -- replaced readme and which is now present inside -- fixed: broken octave kernel and deactivated plugins -- fixed: broken LaTex compiler -- upgraded jupuyter-lab to v3.3.2 -## [2.0.4] - 2022-02-02 -- added `jupyterlab-lsp` and `python-lsp-server[all]` to make the python coding experience more user friendly - -## [2.0.3] - 2022-01-28 - -- invalid notebooks will no longer cause the service to not start - -## [2.0.2] - 2022-01-27 - -- changed scratch folder to workspace -- renamed default boot mode - - -## [2.0.1] - 2022-01-26 - -- changed voila to serve on 0.0.0.0 from localhost - -## [2.0.0] - 2021-12-16 - -- updated to run via dynamic-sidecar -- output can be uploaded via the usage of symlinks -- security enhancements -- updated to python version 3.9.7 -- updated to jupuyter-lab version 3.2.4 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..05d4c6a --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +# minimalistic utility to test and develop locally + +SHELL = /bin/sh +.DEFAULT_GOAL := help + +export DOCKER_IMAGE_NAME ?= voila-viewer +export DOCKER_IMAGE_TAG ?= 1.0.0 + + + +# PYTHON ENVIRON --------------------------------------------------------------------------------------- +.PHONY: devenv +.venv: + @python3 --version + python3 -m venv $@ + # upgrading package managers + $@/bin/pip install --upgrade \ + pip \ + wheel \ + setuptools + +devenv: .venv ## create a python virtual environment with tools to dev, run and tests cookie-cutter + # installing extra tools + @$ Date: Wed, 2 Aug 2023 15:29:55 +0200 Subject: [PATCH 04/11] Added CI files --- .github/ISSUE_TEMPLATE/ask_question.md | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/ask_question.md b/.github/ISSUE_TEMPLATE/ask_question.md index 11cb029..b2265bf 100644 --- a/.github/ISSUE_TEMPLATE/ask_question.md +++ b/.github/ISSUE_TEMPLATE/ask_question.md @@ -2,7 +2,7 @@ name: 💬 Question about: Ask a question labels: question -assignees: elisabettai, newton1985, app-team +assignees: elisabettai --- ## What version of this service are you using? diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 03030d6..abdd495 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: 🐛 Bug about: File a bug/issue labels: bug -assignees: GitHK +assignees: elisabettai --- ## What version of this service are you using? From 9d51572d778440ec3f94a867171f37eb6e8317d5 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:38:53 +0200 Subject: [PATCH 05/11] Add requirements build in CI --- .github/workflows/check-image.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/check-image.yml b/.github/workflows/check-image.yml index b6bc5b3..0669627 100644 --- a/.github/workflows/check-image.yml +++ b/.github/workflows/check-image.yml @@ -16,6 +16,10 @@ jobs: uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 with: args: ooil compose + - name: Create requirements.txt + uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 + with: + args: make requirements - name: Build all images if multiple uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 with: From 311b421eb66655a419b7bc2a38c09b6710b4269e Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:43:06 +0200 Subject: [PATCH 06/11] Track also requirements.txt --- .gitignore | 5 +---- requirements.txt | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 7ae2859..be71fd5 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,4 @@ docker-compose.yml # ignore all files in validation validation/ -*.ignore.* - -# requirements go in .in file, txt generated with Makefile target -requirements.txt \ No newline at end of file +*.ignore.* \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..208fe84 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,38 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --output-file=requirements.txt requirements.in +# +blinker==1.6.2 + # via flask +click==8.1.6 + # via flask +dash==2.9.3 + # via -r requirements.in +dash-core-components==2.0.0 + # via dash +dash-html-components==2.0.0 + # via dash +dash-table==5.0.0 + # via dash +flask==2.3.2 + # via + # -r requirements.in + # dash +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +packaging==23.1 + # via plotly +plotly==5.15.0 + # via dash +tenacity==8.2.2 + # via plotly +werkzeug==2.3.6 + # via flask From 25408d619b8b3b96dfe4b22751615334a4ada48c Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:46:09 +0200 Subject: [PATCH 07/11] Fix CI file --- .github/workflows/check-image.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/check-image.yml b/.github/workflows/check-image.yml index 0669627..b6bc5b3 100644 --- a/.github/workflows/check-image.yml +++ b/.github/workflows/check-image.yml @@ -16,10 +16,6 @@ jobs: uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 with: args: ooil compose - - name: Create requirements.txt - uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 - with: - args: make requirements - name: Build all images if multiple uses: docker://itisfoundation/ci-service-integration-library:v1.0.1-dev-43 with: From 9ca7c3161ead9b73106171f40a0eb0c15722ebd1 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:09:31 +0200 Subject: [PATCH 08/11] A bit of styling --- .osparc/voila-viewer/runtime.yml | 2 +- docker/boot_notebook.bash | 2 +- src/templates/index.html | 26 ++++++++++++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.osparc/voila-viewer/runtime.yml b/.osparc/voila-viewer/runtime.yml index 6f83724..adb2043 100644 --- a/.osparc/voila-viewer/runtime.yml +++ b/.osparc/voila-viewer/runtime.yml @@ -1,4 +1,4 @@ -restart-policy: no-restart +restart-policy: on-inputs-downloaded settings: - name: ports type: int diff --git a/docker/boot_notebook.bash b/docker/boot_notebook.bash index e7e7e87..a0a7920 100755 --- a/docker/boot_notebook.bash +++ b/docker/boot_notebook.bash @@ -76,4 +76,4 @@ python /src/webserver_input_monitor.py echo "Starting voila" cp $DY_SIDECAR_PATH_INPUTS/input_1/voila.ipynb "${NOTEBOOK_BASE_DIR}"/workspace/voila.ipynb -voila "${NOTEBOOK_BASE_DIR}"/workspace/voila.ipynb --enable_nbextensions=True --port 8888 --Voila.ip="0.0.0.0" --no-browser \ No newline at end of file +voila "${NOTEBOOK_BASE_DIR}"/workspace/voila.ipynb --enable_nbextensions=True --port 8888 --Voila.ip="0.0.0.0" --no-browser #--VoilaConfiguration.file_whitelist="['.*']" \ No newline at end of file diff --git a/src/templates/index.html b/src/templates/index.html index b59f4ac..1420cc1 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -5,19 +5,28 @@ Auto-Reload on Content Change - -

Waiting for voila.ipynb in input 1...

-

If voilà doesn't load after connecting input 1, reload the Service UI

+ +

Waiting for Jupyter notebook...

+

Add a voila.ipynb file in input 1.

If voila.ipynb is not rendered after connecting input 1, reload the Service UI

+ + + \ No newline at end of file From c93eedf2e26a3dfb9d1acc44954cbed2e5c09de9 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:17:50 +0200 Subject: [PATCH 09/11] Addressed PR comments --- .osparc/voila-viewer/metadata.yml | 22 +--------------------- src/templates/index.html | 2 +- src/webserver_input_monitor.py | 2 -- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/.osparc/voila-viewer/metadata.yml b/.osparc/voila-viewer/metadata.yml index 7375ef0..8943177 100644 --- a/.osparc/voila-viewer/metadata.yml +++ b/.osparc/voila-viewer/metadata.yml @@ -154,25 +154,5 @@ inputs: Any input files. One or several files compressed in a zip will be downloaded in an inputs folder. type: data:*/* -outputs: - output_1: - displayOrder: 1.0 - label: Output files 1 - description: Output files uploaded from the outputs folder - type: data:*/* - output_2: - displayOrder: 2.0 - label: Output files 2 - description: Output files uploaded from the outputs folder - type: data:*/* - output_3: - displayOrder: 3.0 - label: Output files 3 - description: Output files uploaded from the outputs folder - type: data:*/* - output_4: - displayOrder: 4.0 - label: Output files 4 - description: Output files uploaded from the outputs folder - type: data:*/* +outputs: {} min-visible-inputs: 4 \ No newline at end of file diff --git a/src/templates/index.html b/src/templates/index.html index 1420cc1..8b55b77 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -37,7 +37,7 @@

Waiting for Jupyter notebook...

.catch(error => console.error('Error fetching content:', error)); } - // going lowre will cause multipel kernesl to be started + // going lower will cause multiple kernels to be started const checkInteervalMS = 2000; setInterval(getContent, checkInteervalMS); diff --git a/src/webserver_input_monitor.py b/src/webserver_input_monitor.py index 2c40034..ec7d2c9 100644 --- a/src/webserver_input_monitor.py +++ b/src/webserver_input_monitor.py @@ -24,5 +24,3 @@ def index(): server.terminate() server.join() - -#sleep(5) \ No newline at end of file From 3352fe84d0cef2157614e64d09b114f8f7e60755 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Thu, 3 Aug 2023 16:41:55 +0200 Subject: [PATCH 10/11] OM review and removed restart-policy --- .osparc/voila-viewer/metadata.yml | 9 +++++++-- .osparc/voila-viewer/runtime.yml | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.osparc/voila-viewer/metadata.yml b/.osparc/voila-viewer/metadata.yml index 8943177..76c82fc 100644 --- a/.osparc/voila-viewer/metadata.yml +++ b/.osparc/voila-viewer/metadata.yml @@ -154,5 +154,10 @@ inputs: Any input files. One or several files compressed in a zip will be downloaded in an inputs folder. type: data:*/* -outputs: {} -min-visible-inputs: 4 \ No newline at end of file +outputs: + output_1: + displayOrder: 1.0 + label: Output files 1 + description: Output files uploaded from the outputs folder + type: data:*/* +min-visible-inputs: 2 \ No newline at end of file diff --git a/.osparc/voila-viewer/runtime.yml b/.osparc/voila-viewer/runtime.yml index adb2043..6f83724 100644 --- a/.osparc/voila-viewer/runtime.yml +++ b/.osparc/voila-viewer/runtime.yml @@ -1,4 +1,4 @@ -restart-policy: on-inputs-downloaded +restart-policy: no-restart settings: - name: ports type: int From daec0adbba00882ab51d72d0ce4644fde299b581 Mon Sep 17 00:00:00 2001 From: Elisabetta Iavarone <18575092+elisabettai@users.noreply.github.com> Date: Fri, 4 Aug 2023 11:46:27 +0200 Subject: [PATCH 11/11] README and CHANGELOG --- CHANGELOG.md | 4 ++-- README.md | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79a709b..70d5e82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [1.0.0] - 2022-02-08 -- First version +## [1.0.0] - 2023-08-04 +- First version for testing in master diff --git a/README.md b/README.md index 4e2138c..d70a6d4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ ## Voilà Viewer Source code of the correspondng o²S²PARC Service that takes as input a Jupyter Notebook and it shows it using Jupyter [Voilà](https://github.com/voila-dashboards/voila) + +## How it works +The Service waits for a `voila.ipynb` file in input_1, when it is found, in renders it with voila: + + +![Voila_Viewer_v1](https://github.com/ITISFoundation/voila-viewer/assets/18575092/73d43e27-71d8-4733-bf20-32262a2e9824) + +## How to test + +### Locally + +``` +make build run-local # Then visit 127.0.0.1:8888 in your browser +``` +A `voila.ipynb` has to be `added to validation/inputs/input_1` +### In a local o²S²PARC deployment + +``` +make build publish-local +``` + +### In o²S²PARC +Use the "Voila-viewer Example" template in master.