Skip to content

Commit 0703b13

Browse files
ffaismatifali
andauthored
feat(jupyterlab): added support for uv as installer (#406)
Co-authored-by: M Atif Ali <[email protected]>
1 parent 01d2c10 commit 0703b13

File tree

3 files changed

+83
-17
lines changed

3 files changed

+83
-17
lines changed

jupyterlab/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ A module that adds JupyterLab in your Coder template.
1717
module "jupyterlab" {
1818
count = data.coder_workspace.me.start_count
1919
source = "registry.coder.com/modules/jupyterlab/coder"
20-
version = "1.0.23"
20+
version = "1.0.30"
2121
agent_id = coder_agent.example.id
2222
}
2323
```

jupyterlab/main.test.ts

+48-4
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,70 @@ const executeScriptInContainerWithPip = async (
3333
};
3434
};
3535

36+
// executes the coder script after installing pip
37+
const executeScriptInContainerWithUv = async (
38+
state: TerraformState,
39+
image: string,
40+
shell = "sh",
41+
): Promise<{
42+
exitCode: number;
43+
stdout: string[];
44+
stderr: string[];
45+
}> => {
46+
const instance = findResourceInstance(state, "coder_script");
47+
const id = await runContainer(image);
48+
const respPipx = await execContainer(id, [
49+
shell,
50+
"-c",
51+
"apk --no-cache add uv gcc musl-dev linux-headers && uv venv",
52+
]);
53+
const resp = await execContainer(id, [shell, "-c", instance.script]);
54+
const stdout = resp.stdout.trim().split("\n");
55+
const stderr = resp.stderr.trim().split("\n");
56+
return {
57+
exitCode: resp.exitCode,
58+
stdout,
59+
stderr,
60+
};
61+
};
62+
3663
describe("jupyterlab", async () => {
3764
await runTerraformInit(import.meta.dir);
3865

3966
testRequiredVariables(import.meta.dir, {
4067
agent_id: "foo",
4168
});
4269

43-
it("fails without pipx", async () => {
70+
it("fails without installers", async () => {
4471
const state = await runTerraformApply(import.meta.dir, {
4572
agent_id: "foo",
4673
});
4774
const output = await executeScriptInContainer(state, "alpine");
4875
expect(output.exitCode).toBe(1);
4976
expect(output.stdout).toEqual([
50-
"\u001B[0;1mInstalling jupyterlab!",
51-
"pipx is not installed",
52-
"Please install pipx in your Dockerfile/VM image before running this script",
77+
"Checking for a supported installer",
78+
"No valid installer is not installed",
79+
"Please install pipx or uv in your Dockerfile/VM image before running this script",
5380
]);
5481
});
5582

83+
// TODO: Add faster test to run with uv.
84+
// currently times out.
85+
// it("runs with uv", async () => {
86+
// const state = await runTerraformApply(import.meta.dir, {
87+
// agent_id: "foo",
88+
// });
89+
// const output = await executeScriptInContainerWithUv(state, "python:3-alpine");
90+
// expect(output.exitCode).toBe(0);
91+
// expect(output.stdout).toEqual([
92+
// "Checking for a supported installer",
93+
// "uv is installed",
94+
// "\u001B[0;1mInstalling jupyterlab!",
95+
// "🥳 jupyterlab has been installed",
96+
// "👷 Starting jupyterlab in background...check logs at /tmp/jupyterlab.log",
97+
// ]);
98+
// });
99+
56100
// TODO: Add faster test to run with pipx.
57101
// currently times out.
58102
// it("runs with pipx", async () => {

jupyterlab/run.sh

+34-12
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,54 @@
11
#!/usr/bin/env sh
2+
INSTALLER=""
3+
check_available_installer() {
4+
# check if pipx is installed
5+
echo "Checking for a supported installer"
6+
if command -v pipx > /dev/null 2>&1; then
7+
echo "pipx is installed"
8+
INSTALLER="pipx"
9+
return
10+
fi
11+
# check if uv is installed
12+
if command -v uv > /dev/null 2>&1; then
13+
echo "uv is installed"
14+
INSTALLER="uv"
15+
return
16+
fi
17+
echo "No valid installer is not installed"
18+
echo "Please install pipx or uv in your Dockerfile/VM image before running this script"
19+
exit 1
20+
}
221

322
if [ -n "${BASE_URL}" ]; then
423
BASE_URL_FLAG="--ServerApp.base_url=${BASE_URL}"
524
fi
625

726
BOLD='\033[0;1m'
827

9-
printf "$${BOLD}Installing jupyterlab!\n"
10-
1128
# check if jupyterlab is installed
1229
if ! command -v jupyter-lab > /dev/null 2>&1; then
1330
# install jupyterlab
14-
# check if pipx is installed
15-
if ! command -v pipx > /dev/null 2>&1; then
16-
echo "pipx is not installed"
17-
echo "Please install pipx in your Dockerfile/VM image before running this script"
18-
exit 1
19-
fi
20-
# install jupyterlab
21-
pipx install -q jupyterlab
22-
printf "%s\n\n" "🥳 jupyterlab has been installed"
31+
check_available_installer
32+
printf "$${BOLD}Installing jupyterlab!\n"
33+
case $INSTALLER in
34+
uv)
35+
uv pip install -q jupyterlab \
36+
&& printf "%s\n" "🥳 jupyterlab has been installed"
37+
JUPYTERPATH="$HOME/.venv/bin/"
38+
;;
39+
pipx)
40+
pipx install jupyterlab \
41+
&& printf "%s\n" "🥳 jupyterlab has been installed"
42+
JUPYTERPATH="$HOME/.local/bin"
43+
;;
44+
esac
2345
else
2446
printf "%s\n\n" "🥳 jupyterlab is already installed"
2547
fi
2648

2749
printf "👷 Starting jupyterlab in background..."
2850
printf "check logs at ${LOG_PATH}"
29-
$HOME/.local/bin/jupyter-lab --no-browser \
51+
$JUPYTERPATH/jupyter-lab --no-browser \
3052
"$BASE_URL_FLAG" \
3153
--ServerApp.ip='*' \
3254
--ServerApp.port="${PORT}" \

0 commit comments

Comments
 (0)