Skip to content

Commit db81884

Browse files
directions for setup and a script
1 parent b5ece0f commit db81884

2 files changed

Lines changed: 134 additions & 45 deletions

File tree

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,75 @@ uv run jupyter lab Ch02-statlearn-lab.ipynb
4848

4949
You can download all the labs as a `.zip` or `.tar.gz` [here](https://github.com/intro-stat-learning/ISLP_labs/releases/tag/v2.2.1)
5050

51+
# Setup script
52+
53+
We've added a setup script that ensures precisely the desired labs are checked out along with a `uv` virtual environment being created. Follow
54+
these instructions:
55+
56+
To set up a local environment to run the notebooks for a specific version of the labs, you can use the `setup_notebook_env.py` script. This script will create a directory, download the labs, and set up a Python virtual environment with all the necessary packages.
57+
58+
## Prerequisites
59+
60+
This script relies on `uv` for managing Python environments. If you don't have `uv` installed, you can install it using `pipx` or `cargo`:
61+
62+
* **Using `pipx` (recommended):**
63+
```bash
64+
pip install pipx
65+
pipx ensurepath
66+
pipx install uv
67+
```
68+
69+
* **Using `cargo` (if you have Rust installed):**
70+
```bash
71+
cargo install uv
72+
```
73+
74+
For more detailed installation instructions, please refer to the [uv documentation](https://github.com/astral-sh/uv#installation).
75+
76+
## Instructions
77+
78+
### 1. Download the setup script
79+
80+
You can find the raw Python script here: [`setup_notebook_env.py`](https://raw.githubusercontent.com/intro-stat-learning/ISLP_labs/main/setup_notebook_env.py)
81+
82+
To download and run it, first ensure `uv` is installed (see Prerequisites above), then execute the following commands in your terminal:
83+
84+
```bash
85+
curl -LO https://raw.githubusercontent.com/intro-stat-learning/ISLP_labs/main/setup_notebook_env.py
86+
uv run python setup_notebook_env.py --outdir ISLP_v2.2.1 --commit v2.2.1 --python-version 3.12
87+
```
88+
89+
### 2. Run the setup script
90+
91+
Open your terminal and run the following command to set up the environment for version `v2.2.1` of the labs with Python `3.12`. You can also specify one or more notebooks to run automatically after setup.
92+
93+
* `--outdir ISLP_v2.2.1`: This will create a directory named `ISLP_v2.2.1` for your labs.
94+
* `--commit v2.2.1`: This specifies that you want to use version `v2.2.1` of the labs.
95+
* `--python-version 3.12`: This will use Python 3.12 for the environment.
96+
* `Ch02-statlearn-lab.ipynb`: This is an optional argument to run a specific notebook after the setup is complete. It is meant for testing to be sure given notebooks run but is not required. You can list more than one notebook.
97+
98+
### 2. Activate the environment
99+
100+
Once the script is finished, you can activate the virtual environment to run other notebooks or work with the lab materials.
101+
102+
* **On macOS and Linux:**
103+
```bash
104+
source ISLP_v2.2.1/.venv/bin/activate
105+
```
106+
107+
* **On Windows:**
108+
```bash
109+
ISLP_v2.2.1\.venv\Scripts\activate
110+
```
111+
112+
### 3. Run other notebooks
113+
114+
After activating the environment, you can start Jupyter Lab to run other notebooks.
115+
116+
```bash
117+
jupyter lab
118+
```
119+
51120

52121
## Contributors ✨
53122

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ def setup_env(outdir,
2121
python_version,
2222
nbfiles,
2323
uv_executable,
24-
nbmake_timeout,
25-
nbmake_kernel,
26-
nbmake_allow_errors,
27-
nbmake_rerun):
24+
timeout,
25+
kernel,
26+
nb_allow_errors):
2827
"""
2928
Sets up a student environment for ISLP_labs.
3029
@@ -37,17 +36,15 @@ def setup_env(outdir,
3736
python_version : str
3837
Python version to use for the virtual environment.
3938
nbfiles : list
40-
List of notebook files to run with nbmake.
39+
List of notebook files to run.
4140
uv_executable : str
4241
The `uv` executable.
43-
nbmake_timeout : int
44-
Timeout for running notebooks with nbmake.
45-
nbmake_kernel : str
46-
Kernel to use for running notebooks with nbmake.
47-
nbmake_allow_errors : bool
48-
Allow errors when running notebooks with nbmake.
49-
nbmake_rerun : int
50-
Number of times to rerun notebooks with nbmake.
42+
timeout : int
43+
Timeout for running notebooks.
44+
kernel : str
45+
Kernel to use for running notebooks.
46+
nb_allow_errors : bool
47+
Allow errors when running notebooks.
5148
"""
5249
repo_url = 'https://github.com/intro-stat-learning/ISLP_labs.git'
5350

@@ -58,13 +55,14 @@ def setup_env(outdir,
5855
python_version,
5956
nbfiles,
6057
uv_executable,
61-
nbmake_timeout,
62-
nbmake_kernel,
63-
nbmake_allow_errors,
64-
nbmake_rerun)
58+
timeout,
59+
nb_allow_errors)
6560
return
6661

67-
if not outdir.exists():
62+
if outdir.exists():
63+
if any(outdir.iterdir()): # Check if directory is not empty (including hidden files)
64+
raise FileExistsError(f"Output directory '{outdir}' already exists and is not empty. Please specify an empty directory or a non-existent path.")
65+
else:
6866
outdir.mkdir(parents=True)
6967

7068
try:
@@ -91,24 +89,48 @@ def setup_env(outdir,
9189
run_command([str(uv_bin / 'pip'), 'install', '-r', 'requirements.txt', 'jupyterlab'], cwd=str(outdir))
9290

9391
if nbfiles:
94-
run_command([str(uv_bin / 'pip'), 'install', 'pytest', 'nbmake'], cwd=str(outdir))
95-
for nbfile in nbfiles:
96-
notebook_path = outdir / nbfile
97-
if not notebook_path.exists():
98-
print(f"Error: Notebook '{nbfile}' not found in the repository.", file=sys.stderr)
99-
continue
100-
101-
print(f"Running notebook {notebook_path}...")
102-
pytest_command = [str(uv_bin / 'pytest'), '--nbmake', f'--nbmake-timeout={nbmake_timeout}', '-vv', str(nbfile)]
103-
if nbmake_kernel:
104-
pytest_command.append(f'--nbmake-kernel={nbmake_kernel}')
105-
if nbmake_allow_errors:
106-
pytest_command.append('--nbmake-allow-errors')
107-
if nbmake_rerun > 0:
108-
pytest_command.append(f'--nbmake-rerun={nbmake_rerun}')
109-
110-
run_command(pytest_command, cwd=str(outdir))
111-
92+
if nb_allow_errors:
93+
for nbfile in nbfiles:
94+
notebook_path = outdir / nbfile
95+
if not notebook_path.exists():
96+
print(f"Error: Notebook '{nbfile}' not found in the repository.", file=sys.stderr)
97+
continue
98+
99+
print(f"Running notebook {notebook_path} with jupyter nbconvert...")
100+
nbconvert_command = [str(uv_bin / 'jupyter'),
101+
'nbconvert',
102+
'--to',
103+
'notebook',
104+
'--execute',
105+
'--inplace',
106+
f'--ExecutePreprocessor.timeout={timeout}',
107+
str(nbfile)]
108+
109+
if kernel:
110+
nbconvert_command.extend(['--kernel', kernel])
111+
nbconvert_command.append('--allow-errors')
112+
113+
run_command(nbconvert_command, cwd=str(outdir))
114+
else:
115+
run_command([str(uv_bin / 'pip'), 'install', 'pytest', 'nbmake'], cwd=str(outdir))
116+
for nbfile in nbfiles:
117+
notebook_path = outdir / nbfile
118+
if not notebook_path.exists():
119+
print(f"Error: Notebook '{nbfile}' not found in the repository.", file=sys.stderr)
120+
continue
121+
122+
print(f"Running notebook {notebook_path} with pytest nbmake...")
123+
pytest_command = [str(uv_bin / 'pytest'),
124+
'--nbmake',
125+
f'--nbmake-timeout={timeout}',
126+
'-vv',
127+
str(nbfile)]
128+
if kernel:
129+
pytest_command.append(f'--nbmake-kernel={kernel}')
130+
# nbmake does not have --allow-errors in the same way as nbconvert
131+
# If errors are not allowed, nbmake will fail on first error naturally
132+
133+
run_command(pytest_command, cwd=str(outdir))
112134
print("Setup completed successfully.")
113135
print(f"Environment is in: {outdir}")
114136
if sys.platform == 'win32':
@@ -127,12 +149,11 @@ def main():
127149
parser.add_argument('--commit', default='main', help='The git commit, tag, or branch to checkout (default: main)')
128150
parser.add_argument('--python-version', default='3.11', help='Python version to use (default: 3.11)')
129151
parser.add_argument('--uv-executable', default='uv', help='The `uv` executable to use (default: "uv")')
130-
parser.add_argument('--nbmake-timeout', type=int, default=3600, help='Timeout for running notebooks with nbmake (default: 3600)')
131-
parser.add_argument('--nbmake-kernel', default=None, help='Kernel to use for running notebooks with nbmake')
132-
parser.add_argument('--nbmake-allow-errors', action='store_true', help='Allow errors when running notebooks with nbmake')
133-
parser.add_argument('--nbmake-rerun', type=int, default=0, help='Number of times to rerun notebooks with nbmake')
152+
parser.add_argument('--timeout', type=int, default=3600, help='Timeout for running notebooks (default: 3600)')
153+
parser.add_argument('--kernel', default=None, help='Kernel to use for running notebooks')
154+
parser.add_argument('--allow-errors', action='store_true', help='Allow errors when running notebooks')
134155

135-
parser.add_argument('nbfiles', nargs='*', help='Optional list of notebooks to run using nbmake.')
156+
parser.add_argument('nbfiles', nargs='*', help='Optional list of notebooks to run.')
136157

137158
args = parser.parse_args()
138159

@@ -141,10 +162,9 @@ def main():
141162
args.python_version,
142163
args.nbfiles,
143164
args.uv_executable,
144-
args.nbmake_timeout,
145-
args.nbmake_kernel,
146-
args.nbmake_allow_errors,
147-
args.nbmake_rerun)
165+
args.timeout,
166+
args.kernel,
167+
args.allow_errors)
148168

149169
if __name__ == '__main__':
150170
main()

0 commit comments

Comments
 (0)