Skip to content

Commit 69e477d

Browse files
committed
start work on notebook to supplement api
Signed-off-by: Lance-Drane <[email protected]>
1 parent c259b8f commit 69e477d

File tree

5 files changed

+81
-13
lines changed

5 files changed

+81
-13
lines changed

examples-proposed/004-time-loop/sim.conf

+4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ PORTAL_URL = https://lb.ipsportal.development.svc.spin.nersc.org
2121
# This MUST be an absolute directory
2222
# if executing portal on a web server also running JupyterHub, you can set this value to manually add your file to this location.
2323
# NOTE: "/ipsframework/runs/${RUNID}/" will automatically be prepended to the file, guaranteeing that files will NEVER be overwritten.
24+
# NOTE FOR NERSC SPECIFICALLY: if you want to share notebooks with other users, you must make sure they have the correct file permissions in the directory.
2425
JUPYTERHUB_DIR = ${PSCRATCH}
2526
# OPTIONAL
2627
# if PORTAL_URL is defined + JUPYTERHUB_DIR is defined + this value is defined, the IPSFramework can send a direct link to the JupyterHub file.
2728
# In the framework, we don't make any assumptions about how JupyterHub's base URL or root server path is configured; you'll generally want to provide the full URL up to the JupyterHub base directory.
2829
# the URL will always end with /ipsframework/runs/${RUNID}/${JUPYTER_FILE}.ipynb , but:
2930
# - /lab/tree may not necessarily be the URL path that JupyterHub users to expose the tree
3031
# - the path of the URL after /lab/tree MAY deviate from the value in JUPYTERHUB_DIR
32+
#
33+
# NOTES FOR NERSC SPECIFICALLY:
34+
# - if you think you will need to execute notebooks on a different node, replace "perlmutter-login-node-base" with the type of node you want to run on.
3135
JUPYTERHUB_URL = https://jupyter.nersc.gov/user/${USER}/perlmutter-login-node-base/lab/tree${PSCRATCH}
3236

3337
STATE_FILES = state.json

ipsframework/_jupyter/api_v1.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ def generate_tar_from_runids(runids: Union[Iterable[int], int]) -> str:
5151
tarball = THIS_DIR / f'{tarball_name}.tar.gz'
5252
with tarfile.open(tarball, 'w:gz') as archive:
5353
# add API files inside the tarball
54-
for api_file in THIS_DIR.glob('api_v*.py'):
55-
archive.add(api_file, arcname=os.path.join(tarball_name, api_file.name))
54+
for api_file in THIS_DIR.glob('api_v*'):
55+
if api_file.suffix in ('.py', '.ipynb'):
56+
arcname = os.path.join(tarball_name, api_file.name)
57+
archive.add(api_file, arcname=arcname)
5658

5759
if isinstance(runids, int):
5860
runids = [runids]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## IPS workstation\n",
8+
"\n",
9+
"You can use this notebook to quickly generate a tarfile with desired runids for download. "
10+
]
11+
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": null,
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"from pathlib import Path\n",
19+
"\n",
20+
"import api_v1\n",
21+
"from IPython.display import display\n",
22+
"from ipywidgets import HTML, Button, Layout, Textarea\n",
23+
"\n",
24+
"widget1 = Textarea(\n",
25+
" value='',\n",
26+
" placeholder='Enter runids you want to download, delimited by either spaces or newlines',\n",
27+
" description='Enter runids you want to download, delimited by either spaces or newlines',\n",
28+
" layout=Layout(width='50%', display='flex', flex_flow='column')\n",
29+
")\n",
30+
"\n",
31+
"widget2 = Button(\n",
32+
" description='Generate tar from input',\n",
33+
" layout=Layout(width='300px')\n",
34+
")\n",
35+
"\n",
36+
"def generate_tarfile(_button_widget):\n",
37+
" runids = [int(v) for v in widget1.value.split()]\n",
38+
" display(f'Generating tar file from runids: {runids}')\n",
39+
" \n",
40+
" file = Path(api_v1.generate_tar_from_runids(runids))\n",
41+
" display(f'Generated tar file {file.name} in directory {file.parent}, right click the file in the file browser to download it')\n",
42+
"\n",
43+
"widget2.on_click(generate_tarfile)\n",
44+
"\n",
45+
"display(widget1,widget2,HTML(\"\"\"<style>\n",
46+
" .widget-label { width: unset !important; }\n",
47+
"</style>\"\"\"))"
48+
]
49+
}
50+
],
51+
"metadata": {
52+
"language_info": {
53+
"name": "python"
54+
}
55+
},
56+
"nbformat": 4,
57+
"nbformat_minor": 2
58+
}

ipsframework/_jupyter/initializer.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ def _initial_data_file_code() -> str:
4949

5050

5151
def initialize_jupyter_python_api(jupyterhub_dir: str):
52-
api_filepath = Path(__file__).parent / f'api_{CURRENT_API_VERSION}.py'
53-
file_dest = Path(jupyterhub_dir) / f'api_{CURRENT_API_VERSION}.py'
54-
shutil.copyfile(api_filepath, file_dest)
52+
"""Set up the multirun API files."""
53+
source_dir = Path(__file__).parent
54+
dest_dir = Path(jupyterhub_dir)
55+
for fname in (f'api_{CURRENT_API_VERSION}.py', f'api_{CURRENT_API_VERSION}_notebook.ipynb'):
56+
shutil.copyfile(
57+
source_dir / fname,
58+
dest_dir / fname,
59+
)
5560

5661

5762
def initialize_jupyter_notebook(notebook_dest: str, notebook_src: str):

ipsframework/services.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,13 @@ def _init_jupyter(self) -> bool:
18701870
return False
18711871

18721872
self._jupyterhub_dir = root_dir
1873+
1874+
# adds module file to Jupyterhub
1875+
initialize_jupyter_import_module_file(self._jupyterhub_dir)
1876+
1877+
# add the shared python API if it doesn't exist
1878+
initialize_jupyter_python_api(str(pathlib.Path(self._jupyterhub_dir).parent))
1879+
18731880
return True
18741881

18751882
def get_staged_jupyterhub_files(self) -> List[str]:
@@ -1904,7 +1911,6 @@ def _get_jupyterhub_url(self) -> Optional[str]:
19041911
url += f'ipsframework/runs/{portal_url_host}/{runid}/'
19051912
return url
19061913

1907-
# TODO consider how we use variable_name in the API and get rid of it if it's not necessary
19081914
def initialize_jupyter_notebook(
19091915
self,
19101916
dest_notebook_name: str,
@@ -1917,18 +1923,11 @@ def initialize_jupyter_notebook(
19171923
Params:
19181924
- dest_notebook_name: name of the JupyterNotebook you want to write (do not include file paths).
19191925
- source_notebook_path: location you want to load the source notebook from
1920-
- data_module_name: name of the python file you want to generate a data file for (do not include file paths or file extensions)
19211926
"""
19221927
if not self._jupyterhub_dir:
19231928
if not self._init_jupyter():
19241929
raise Exception('Unable to initialize base JupyterHub dir')
19251930

1926-
# adds module file to Jupyterhub
1927-
initialize_jupyter_import_module_file(self._jupyterhub_dir)
1928-
1929-
# add the shared python API if it doesn't exist
1930-
initialize_jupyter_python_api(str(pathlib.Path(self._jupyterhub_dir).parent))
1931-
19321931
# adds notebook to JupyterHub
19331932
initialize_jupyter_notebook(f'{self._jupyterhub_dir}{dest_notebook_name}', source_notebook_path)
19341933

0 commit comments

Comments
 (0)