diff --git a/launcher.ipynb b/launcher.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..e85c91cfb2369d202152001364c90f33051a70e7 --- /dev/null +++ b/launcher.ipynb @@ -0,0 +1,41 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "1d7eebc2-9325-42ae-8269-47b3091e052c", + "metadata": {}, + "outputs": [], + "source": [ + "from src.data import Data\n", + "from src.view import View\n", + "from src.appli import Appli\n", + "\n", + "data = Data()\n", + "layout = View(data).layout\n", + "appli = Appli(layout, data)" + ] + } + ], + "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.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/appli.py b/src/appli.py new file mode 100644 index 0000000000000000000000000000000000000000..53c0b7fb11072ecca4de96403f42b90d8216d78c --- /dev/null +++ b/src/appli.py @@ -0,0 +1,49 @@ +from jupyter_dash import JupyterDash as Dash +import dash_bootstrap_components as dbc +from src.callbacks import register_callbacks + + +class Appli: + def __init__(self, layout, data): + server_url, host, port, proxy, base_path = self._get_tl_config() + app = Dash( + server_url=server_url, + requests_pathname_prefix=base_path, + ) + app.layout = layout + app.data = data + register_callbacks(app) + app.run_server(mode="inline", host=host, port=port, proxy=proxy) + + + def _get_tl_config(self): + import socket, errno, os + # Find a free port + host = "0.0.0.0" + port = 8050 + end = 9999 + found = False + while not found: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + try: + s.bind((host, port)) + found = True + except socket.error as e: + if e.errno == errno.EADDRINUSE: + port = port + 1 + if (port > end): + raise "No available APP port" + else: + raise e + if (os.getenv("HOST", None) is not None): + proto = os.getenv("PROTO") + actualhost = os.getenv("JUPYTER_HOST", os.getenv("VOILA_HOST", "")) + localport = os.getenv("PORT", 80) + intermediatehost = os.getenv("HOST", "localhost") + base_path = f"/{actualhost}/app_proxy/{port}/" + proxified= f"{proto}://{intermediatehost}:{localport}{base_path}" + localurl = f"http://{host}:{port}" + proxy = f"{localurl}::{proxified}" + return ((proxified, host, port, proxy, base_path)) + return ((f"http://localhost:{port}", host, port, None, "/")) + diff --git a/src/callbacks.py b/src/callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..c855b16258d1a9df25cc8cf4757d3ef69cde278c --- /dev/null +++ b/src/callbacks.py @@ -0,0 +1,11 @@ +from dash import Output, Input + + +def register_callbacks(app): + @app.callback( + Output(component_id="my-output", component_property="children"), + Input(component_id="my-input", component_property="value") + ) + def update_output_div(input_value): + return f"Output: {input_value}" + \ No newline at end of file diff --git a/src/components/__init__.py b/src/components/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/components/component.py b/src/components/component.py new file mode 100644 index 0000000000000000000000000000000000000000..aad8f9a566d0096a056b8abca0ec25198209f78a --- /dev/null +++ b/src/components/component.py @@ -0,0 +1,6 @@ +class Component: + def __init__(self, data): + self.data = data + + def build(self): + raise Error("Not implemented") diff --git a/src/components/window.py b/src/components/window.py new file mode 100644 index 0000000000000000000000000000000000000000..6cf5e61de232b2071366fd81fd2783ade7642fbb --- /dev/null +++ b/src/components/window.py @@ -0,0 +1,25 @@ +from src.components.component import Component +from dash import html, dcc + +class Window(Component): + + def build(self): + return self._layout() + + def _layout(self): + return html.Div(children= + [ + html.H6("Change the value in the text box to see callbacks in action!"), + html.Div(children= + [ + "Input: ", + dcc.Input( + id="my-input", + value=self.data.initial_value, + type="text" + ) + ]), + html.Br(), + html.Div(id="my-output") + ] + ) diff --git a/src/data.py b/src/data.py new file mode 100644 index 0000000000000000000000000000000000000000..5a954a4f6052f107956f65cb431b4fdf799d3357 --- /dev/null +++ b/src/data.py @@ -0,0 +1,5 @@ +class Data: + + def __init__(self): + self.initial_value = "my initial value" + \ No newline at end of file diff --git a/src/view.py b/src/view.py new file mode 100644 index 0000000000000000000000000000000000000000..36fafbedff371a2e1a389d0dea37e563c15f3a7d --- /dev/null +++ b/src/view.py @@ -0,0 +1,7 @@ +from src.components.window import Window + + +class View: + def __init__(self, data): + self.layout = Window(data).build() + \ No newline at end of file