From ead62b5e26b8e17f5087f69280e0f3f60d73e9f6 Mon Sep 17 00:00:00 2001 From: Luis Capelo <953118+luiscape@users.noreply.github.com> Date: Wed, 27 Dec 2023 13:49:25 -0500 Subject: [PATCH] Updates example to use Modal Tunnel (#530) Replaces the use of Bore with a Modal Tunnel. --- 11_notebooks/jupyter_inside_modal.py | 70 ++++++++++++++-------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/11_notebooks/jupyter_inside_modal.py b/11_notebooks/jupyter_inside_modal.py index ea6a13f3c..5a0e215ce 100644 --- a/11_notebooks/jupyter_inside_modal.py +++ b/11_notebooks/jupyter_inside_modal.py @@ -4,7 +4,8 @@ # # Quick snippet to connect to a Jupyter notebook server running inside a Modal container, # especially useful for exploring the contents of Modal network file systems. -# This uses https://github.com/ekzhang/bore to expose the server to the public internet. +# This uses [Modal Tunnels](https://modal.com/docs/guide/tunnels#tunnels-beta) +# to create a tunnel between the running Jupyter instance and the internet. import os import subprocess @@ -13,11 +14,9 @@ import modal stub = modal.Stub( - image=modal.Image.debian_slim() - .pip_install("jupyter", "bing-image-downloader~=1.1.2") - .apt_install("curl") - .run_commands("curl https://sh.rustup.rs -sSf | bash -s -- -y") - .run_commands(". $HOME/.cargo/env && cargo install bore-cli") + image=modal.Image.debian_slim().pip_install( + "jupyter", "bing-image-downloader~=1.1.2" + ) ) # This volume is not persisted, so the data will be deleted when this demo app is stopped. volume = modal.NetworkFileSystem.new() @@ -55,33 +54,33 @@ def seed_volume(): concurrency_limit=1, network_file_systems={CACHE_DIR: volume}, timeout=1_500 ) def run_jupyter(timeout: int): - jupyter_process = subprocess.Popen( - [ - "jupyter", - "notebook", - "--no-browser", - "--allow-root", - "--port=8888", - "--NotebookApp.allow_origin='*'", - "--NotebookApp.allow_remote_access=1", - ], - env={**os.environ, "JUPYTER_TOKEN": JUPYTER_TOKEN}, - ) - - bore_process = subprocess.Popen( - ["/root/.cargo/bin/bore", "local", "8888", "--to", "bore.pub"], - ) - - try: - end_time = time.time() + timeout - while time.time() < end_time: - time.sleep(5) - print(f"Reached end of {timeout} second timeout period. Exiting...") - except KeyboardInterrupt: - print("Exiting...") - finally: - bore_process.kill() - jupyter_process.kill() + jupyter_port = 8888 + with modal.forward(jupyter_port) as tunnel: + jupyter_process = subprocess.Popen( + [ + "jupyter", + "notebook", + "--no-browser", + "--allow-root", + "--ip=0.0.0.0", + f"--port={jupyter_port}", + "--NotebookApp.allow_origin='*'", + "--NotebookApp.allow_remote_access=1", + ], + env={**os.environ, "JUPYTER_TOKEN": JUPYTER_TOKEN}, + ) + + print(f"Jupyter available at => {tunnel.url}") + + try: + end_time = time.time() + timeout + while time.time() < end_time: + time.sleep(5) + print(f"Reached end of {timeout} second timeout period. Exiting...") + except KeyboardInterrupt: + print("Exiting...") + finally: + jupyter_process.kill() @stub.local_entrypoint() @@ -93,5 +92,6 @@ def main(timeout: int = 10_000): # Doing `modal run jupyter_inside_modal.py` will run a Modal app which starts -# the Juypter server at an address like http://bore.pub:$PORT/. Visit this address -# in your browser, and enter the security token you set for `JUPYTER_TOKEN`. +# the Juypter server at an address like https://u35iiiyqp5klbs.r3.modal.host. +# Visit this address in your browser, and enter the security token +# you set for `JUPYTER_TOKEN`.