forked from modal-labs/modal-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjupyter_inside_modal.py
99 lines (81 loc) · 3.09 KB
/
jupyter_inside_modal.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# ---
# args: ["--timeout", 10]
# ---
# ## Overview
#
# Quick snippet showing how to connect to a Jupyter notebook server running inside a Modal container,
# especially useful for exploring the contents of Modal Volumes.
# This uses [Modal Tunnels](https://modal.com/docs/guide/tunnels#tunnels-beta)
# to create a tunnel between the running Jupyter instance and the internet.
#
# If you want to your Jupyter notebook to run _locally_ and execute remote Modal Functions in certain cells, see the `basic.ipynb` example :)
import os
import subprocess
import time
import modal
app = modal.App(
image=modal.Image.debian_slim().pip_install(
"jupyter", "bing-image-downloader~=1.1.2"
)
)
volume = modal.Volume.from_name(
"modal-examples-jupyter-inside-modal-data", create_if_missing=True
)
CACHE_DIR = "/root/cache"
JUPYTER_TOKEN = "1234" # Change me to something non-guessable!
@app.function(volumes={CACHE_DIR: volume})
def seed_volume():
# Bing it!
from bing_image_downloader import downloader
# This will save into the Modal volume and allow you view the images
# from within Jupyter at a path like `/root/cache/modal labs/Image_1.png`.
downloader.download(
query="modal labs",
limit=10,
output_dir=CACHE_DIR,
force_replace=False,
timeout=60,
verbose=True,
)
volume.commit()
# This is all that's needed to create a long-lived Jupyter server process in Modal
# that you can access in your Browser through a secure network tunnel.
# This can be useful when you want to interactively engage with Volume contents
# without having to download it to your host computer.
@app.function(concurrency_limit=1, volumes={CACHE_DIR: volume}, timeout=1_500)
def run_jupyter(timeout: int):
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()
@app.local_entrypoint()
def main(timeout: int = 10_000):
# Write some images to a volume, for demonstration purposes.
seed_volume.remote()
# Run the Jupyter Notebook server
run_jupyter.remote(timeout=timeout)
# Doing `modal run jupyter_inside_modal.py` will run a Modal app which starts
# 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`.