I am attempting to run Jupyer Lab and nbconvert from within a container being access from the host via a Google Chrome browser. The container I am using is being built with:
```dockerfile
# vim: ft=dockerfile
# A build Argument available to the FROM statement.
# Allows builders to override the Python version. However, this Containerfile
# is designed to be used with Debian based images.
ARG PYTHON_VERSION=bullseye
# Pull the Container Image from Docker Hub.
FROM docker.io/library/python:bullseye
# Install OS Packages to allow Jupyter Lab to run and export files.
RUN apt update && \
apt install --yes \
graphviz \
pandoc \
texlive-xetex \
texlive-fonts-recommended \
texlive-plain-generic
# Install Python Libraries.
RUN python3 -m pip install \
jupyterlab \
graphviz \
pyppeteer \
nbconvert \
pandas \
matplotlib
# Create a non-root user to run Jupyter Lab as.
RUN groupadd developer && \
useradd -m -s /bin/bash -d /home/developer -g developer developer
# This is because Docker LSP sees comments in a RUN block as an error.
# && \
# echo "%developer ALL=(ALL) NOPASSWD:ALL" | tee /etc/sudoers.d/developer && \
# chmod 440 /etc/sudoers.d/developer
USER developer
WORKDIR /home/developer
# This makes the container an executable. If a shell session is desired, then
# the user would need to override the entrypoint of the container.
ENTRYPOINT ["/usr/local/bin/jupyter"]
# These can be overridden when the container is ran. These can also be defined
# as part of the ENTRYPOINT, but I chose to put them in the CMD to also display
# the capability.
CMD ["lab", "--ip=0.0.0.0", "--no-browser"]
# This allows the user to run the container using predefined options.
#
# podman container runlabel --display run localhost/jupyterlab:latest
#
# podman container runlabel run localhost/jupyterlab:latest
#
# You can see the command being ran by using the --display flag before the image
# name. Doing this won't actually run the container. Other labels can be
# provided as well to provide different commands.
LABEL RUN="podman run --rm --name jupyter-lab --publish 127.0.0.1:8888:8888 localhost/jupyterlab:latest"
```
The build logs look like:
```bash
$ podman build -f JupyterLab.DevContainer.containerfile -t jupyterlab:latest .
STEP 1/10: FROM docker.io/library/python:bullseye
STEP 2/10: RUN apt update && apt install --yes graphviz pandoc texlive-xetex texlive-fonts-recommended texlive-plain-generic
--> Using cache 7a646875eda71658b26df6e6978eac83da7d848d24134a3444809c268c861223
--> 7a646875eda
STEP 3/10: RUN wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && apt install --yes ./google-chrome-stable_current_amd64.deb && rm -f ./google-chrome-stable_current_amd64.deb
--> Using cache 4f08fe5c1644f42e660e8531e1d0b5075f7e26f6751011ba0a91f11706b075d0
--> 4f08fe5c164
STEP 4/10: RUN python3 -m pip install jupyterlab graphviz pyppeteer nbconvert pandas matplotlib
--> Using cache e9f517e6692491a9c51830bcfd26c6f42ae22a2b70371e132ee36823045c8715
--> e9f517e6692
STEP 5/10: RUN groupadd developer && useradd -m -s /bin/bash -d /home/developer -g developer developer
--> Using cache 4039b595b29ac2f041d2e59cc5216518d7831746e29e887315ec28e764f21c45
--> 4039b595b29
STEP 6/10: USER developer
--> Using cache b00112a4dae7ee4859c0e14af82797301163f2ac2e335606472b9740b6ffe931
--> b00112a4dae
STEP 7/10: WORKDIR /home/developer
--> Using cache f55c5464a1bb98a96d1141da13a59d7284c7ecf91278e9e487afdc42749e10b7
--> f55c5464a1b
STEP 8/10: ENTRYPOINT ["/usr/local/bin/jupyter-lab"]
--> Using cache c5ab59a4bcdbd69ccbb0fd35d53370568ab00e5416a2696960f2e1c81c6d736a
--> c5ab59a4bcd
STEP 9/10: CMD ["--ip=0.0.0.0", "--no-browser"]
--> Using cache 8ea6710ed91b78db3b065f709bca0f52a6c68389bbeb1f7d2ded913d7d5b27c0
--> 8ea6710ed91
STEP 10/10: LABEL RUN="podman run --rm --name jupyter-lab --publish 127.0.0.1:8888:8888 localhost/jupyterlab:latest"
--> Using cache 578bab02825ec579204a5502ca7fabbff1f0ac0aa7cf1124c7c9756d7e6317b2
COMMIT jupyterlab:latest
--> 578bab02825
Successfully tagged localhost/jupyterlab:latest
578bab02825ec579204a5502ca7fabbff1f0ac0aa7cf1124c7c9756d7e6317b2
```
I am able to run the container with the following command, accessing local files and saving them.
Then I click on the URL provided by the logs which opens Google Chrome on the host.
```plaintext
[I 2022-01-13 17:01:52.178 ServerApp] jupyterlab | extension was successfully linked.
[I 2022-01-13 17:01:52.188 ServerApp] Writing Jupyter server cookie secret to /home/developer/.local/share/jupyter/runtime/jupyter_cookie_secret
[I 2022-01-13 17:01:52.464 ServerApp] nbclassic | extension was successfully linked.
[I 2022-01-13 17:01:52.486 ServerApp] nbclassic | extension was successfully loaded.
[I 2022-01-13 17:01:52.487 LabApp] JupyterLab extension loaded from /usr/local/lib/python3.10/site-packages/jupyterlab
[I 2022-01-13 17:01:52.487 LabApp] JupyterLab application directory is /usr/local/share/jupyter/lab
[I 2022-01-13 17:01:52.489 ServerApp] jupyterlab | extension was successfully loaded.
[I 2022-01-13 17:01:52.490 ServerApp] Serving notebooks from local directory: /home/developer/jupyter
[I 2022-01-13 17:01:52.490 ServerApp] Jupyter Server 1.13.2 is running at:
[I 2022-01-13 17:01:52.490 ServerApp] http://jupyer-lab:8888/lab?token=62e0bb1e0b5ff852fbbb9a08974ccc03da482eef6ab27109
[I 2022-01-13 17:01:52.490 ServerApp] or http://127.0.0.1:8888/lab?token=62e0bb1e0b5ff852fbbb9a08974ccc03da482eef6ab27109
[I 2022-01-13 17:01:52.490 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 2022-01-13 17:01:52.492 ServerApp]
To access the server, open this file in a browser:
file:///home/developer/.local/share/jupyter/runtime/jpserver-1-open.html
Or copy and paste one of these URLs:
http://jupyer-lab:8888/lab?token=62e0bb1e0b5ff852fbbb9a08974ccc03da482eef6ab27109
or http://127.0.0.1:8888/lab?token=62e0bb1e0b5ff852fbbb9a08974ccc03da482eef6ab27109
[W 2022-01-13 17:02:01.814 LabApp] Could not determine jupyterlab build status without nodejs
[I 2022-01-13 17:02:05.801 ServerApp] Writing notebook-signing key to /home/developer/.local/share/jupyter/notebook_secret
[W 2022-01-13 17:02:05.802 ServerApp] Notebook AzDO_SNOW_AzFuncApp.ipynb is not trusted
[I 2022-01-13 17:02:06.101 ServerApp] Kernel started: d86cbf9d-e4c9-4abb-88fe-7d15a83d6944
[W 2022-01-13 17:02:11.889 ServerApp] Notebook AzDO_SNOW_AzFuncApp.ipynb is not trusted
```
But then I attempt to export the Notebook as any filetype listed in the pop out menu. I get these errors in the log.
```plaintext
[W 2022-01-13 17:02:11.889 ServerApp] Notebook AzDO_SNOW_AzFuncApp.ipynb is not trusted
[E 2022-01-13 17:02:12.204 ServerApp] nbconvert failed: 'tuple' object is not callable
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/jupyter_server/nbconvert/handlers.py", line 121, in get
output, resources = await run_sync(
File "/usr/local/lib/python3.10/site-packages/anyio/to_thread.py", line 28, in run_sync
return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,
File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 818, in run_sync_in_worker_thread
return await future
File "/usr/local/lib/python3.10/asyncio/futures.py", line 284, in __await__
yield self # This tells Task to wait for completion.
File "/usr/local/lib/python3.10/asyncio/tasks.py", line 304, in __wakeup
future.result()
File "/usr/local/lib/python3.10/asyncio/futures.py", line 201, in result
raise self._exception
File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 754, in run
result = context.run(func, *args)
TypeError: 'tuple' object is not callable
[W 2022-01-13 17:02:12.209 ServerApp] 500 GET /nbconvert/html/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100): nbconvert failed: 'tuple' object is not callable
[E 2022-01-13 17:02:12.225 ServerApp] {
"Host": "127.0.0.1:8888",
"Connection": "keep-alive",
"Sec-Ch-Ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Linux\"",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1",
"Sec-Fetch-Dest": "document",
"Referer": "http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Cookie": "_xsrf=2|47c76bfc|0fd0f425962b75e5a7b3f6bf407c6a97|1642002756; username-127-0-0-1-8888=\"2|1:0|10:1642093330|23:username-127-0-0-1-8888|44:YjI2ZDIyYzMwNzQxNDk4MmE5ODExYjg1NTgwMTBmMjc=|f1b418091312997f95f4cb86c72a2655675d23764869f02c67caea7ee69efbf0\""
}
[E 2022-01-13 17:02:12.225 ServerApp] 500 GET /nbconvert/html/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100) 359.85ms referer=http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb
[W 2022-01-13 17:02:22.357 ServerApp] Notebook AzDO_SNOW_AzFuncApp.ipynb is not trusted
[E 2022-01-13 17:02:22.388 ServerApp] nbconvert failed: [Errno 2] No such file or directory: 'inkscape'
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 537, in get
value = obj._trait_values[self.name]
KeyError: 'command'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 537, in get
value = obj._trait_values[self.name]
KeyError: 'inkscape_version'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/jupyter_server/nbconvert/handlers.py", line 122, in get
exporter.from_notebook_node(nb, resources=resource_dict)
File "/usr/local/lib/python3.10/site-packages/nbconvert/exporters/pdf.py", line 168, in from_notebook_node
latex, resources = super().from_notebook_node(
File "/usr/local/lib/python3.10/site-packages/nbconvert/exporters/latex.py", line 72, in from_notebook_node
return super().from_notebook_node(nb, resources, **kw)
File "/usr/local/lib/python3.10/site-packages/nbconvert/exporters/templateexporter.py", line 376, in from_notebook_node
nb_copy, resources = super().from_notebook_node(nb, resources, **kw)
File "/usr/local/lib/python3.10/site-packages/nbconvert/exporters/exporter.py", line 147, in from_notebook_node
nb_copy, resources = self._preprocess(nb_copy, resources)
File "/usr/local/lib/python3.10/site-packages/nbconvert/exporters/exporter.py", line 334, in _preprocess
nbc, resc = preprocessor(nbc, resc)
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/base.py", line 47, in __call__
return self.preprocess(nb, resources)
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/base.py", line 69, in preprocess
nb.cells[index], resources = self.preprocess_cell(cell, resources, index)
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/convertfigures.py", line 45, in preprocess_cell
output.data[self.to_format] = self.convert_figure(
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/svg2pdf.py", line 143, in convert_figure
if isinstance(self.command, list):
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 577, in __get__
return self.get(obj, cls)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 540, in get
default = obj.trait_defaults(self.name)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 1580, in trait_defaults
return self._get_trait_default_generator(names[0])(self)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 977, in __call__
return self.func(*args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/svg2pdf.py", line 84, in _command_default
major_version = self.inkscape_version.split('.')[0]
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 577, in __get__
return self.get(obj, cls)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 540, in get
default = obj.trait_defaults(self.name)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 1580, in trait_defaults
return self._get_trait_default_generator(names[0])(self)
File "/usr/local/lib/python3.10/site-packages/traitlets/traitlets.py", line 977, in __call__
return self.func(*args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/nbconvert/preprocessors/svg2pdf.py", line 58, in _inkscape_version_default
p = subprocess.Popen([self.inkscape, '--version'],
File "/usr/local/lib/python3.10/subprocess.py", line 966, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/local/lib/python3.10/subprocess.py", line 1842, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'inkscape'
[W 2022-01-13 17:02:22.391 ServerApp] 500 GET /nbconvert/pdf/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100): nbconvert failed: [Errno 2] No such file or directory: 'inkscape'
[E 2022-01-13 17:02:22.392 ServerApp] {
"Host": "127.0.0.1:8888",
"Connection": "keep-alive",
"Sec-Ch-Ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Linux\"",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1",
"Sec-Fetch-Dest": "document",
"Referer": "http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Cookie": "_xsrf=2|47c76bfc|0fd0f425962b75e5a7b3f6bf407c6a97|1642002756; username-127-0-0-1-8888=\"2|1:0|10:1642093342|23:username-127-0-0-1-8888|44:MzE4N2M3YmM0ZGIyNGQ2M2IzZjUyODhmYmRlOTljNjE=|ad2d0d45acc712e5185ec5be9819eec0fd4d4a0bafe2b2b4f95eae1f3932881a\""
}
[E 2022-01-13 17:02:22.392 ServerApp] 500 GET /nbconvert/pdf/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100) 56.92ms referer=http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb
[W 2022-01-13 17:03:20.917 ServerApp] Notebook AzDO_SNOW_AzFuncApp.ipynb is not trusted
[E 2022-01-13 17:03:21.001 ServerApp] nbconvert failed: 'tuple' object is not callable
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/jupyter_server/nbconvert/handlers.py", line 121, in get
output, resources = await run_sync(
File "/usr/local/lib/python3.10/site-packages/anyio/to_thread.py", line 28, in run_sync
return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,
File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 818, in run_sync_in_worker_thread
return await future
File "/usr/local/lib/python3.10/asyncio/futures.py", line 284, in __await__
yield self # This tells Task to wait for completion.
File "/usr/local/lib/python3.10/asyncio/tasks.py", line 304, in __wakeup
future.result()
File "/usr/local/lib/python3.10/asyncio/futures.py", line 201, in result
raise self._exception
File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 754, in run
result = context.run(func, *args)
TypeError: 'tuple' object is not callable
[W 2022-01-13 17:03:21.002 ServerApp] 500 GET /nbconvert/markdown/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100): nbconvert failed: 'tuple' object is not callable
[E 2022-01-13 17:03:21.003 ServerApp] {
"Host": "127.0.0.1:8888",
"Connection": "keep-alive",
"Sec-Ch-Ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Linux\"",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1",
"Sec-Fetch-Dest": "document",
"Referer": "http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Cookie": "_xsrf=2|47c76bfc|0fd0f425962b75e5a7b3f6bf407c6a97|1642002756; username-127-0-0-1-8888=\"2|1:0|10:1642093399|23:username-127-0-0-1-8888|44:NzEzOTY0MmVmOWQ1NGE4NmJkODQzZGI4MzE0NzhiY2I=|6440315368eff967351c519ebe1f0bc7df40c0e94059a208443df81be628d6a9\""
}
[E 2022-01-13 17:03:21.003 ServerApp] 500 GET /nbconvert/markdown/AzDO_SNOW_AzFuncApp.ipynb?download=true (10.0.2.100) 105.06ms referer=http://127.0.0.1:8888/lab/workspaces/auto-U/tree/AzDO_SNOW_AzFuncApp.ipynb
```
The answer is to start this by running it in /notebook then once loaded, change the end to /lab and then you should be able to export the files as desired.
The Description
I am attempting to run Jupyer Lab and nbconvert from within a container being access from the host via a Google Chrome browser. The container I am using is being built with:
The build logs look like:
I am able to run the container with the following command, accessing local files and saving them.
Then I click on the URL provided by the logs which opens Google Chrome on the host.
But then I attempt to export the Notebook as any filetype listed in the pop out menu. I get these errors in the log.
Screenshot of the error in the browser: