Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permission denied problem with nbconvert #1430

Closed
gideonsimpson opened this issue Sep 30, 2020 · 30 comments · Fixed by #1646
Closed

Permission denied problem with nbconvert #1430

gideonsimpson opened this issue Sep 30, 2020 · 30 comments · Fixed by #1646
Labels
Milestone

Comments

@gideonsimpson
Copy link

I have a conda installation of jupyter and, after a recent update, my ability to export and otherwise convert jupyter notebooks has been curtailed. For instance, I'm having the following problem at the command line:

guardian@titan:scratch$ jupyter nbconvert --to html mynotebook.ipynb 
Traceback (most recent call last):
  File "/Users/guardian/miniconda3/bin/jupyter-nbconvert", line 7, in <module>
    from nbconvert.nbconvertapp import main
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/nbconvertapp.py", line 140, in <module>
    class NbConvertApp(JupyterApp):
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/nbconvertapp.py", line 225, in NbConvertApp
    """.format(formats=get_export_names()))
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/base.py", line 141, in get_export_names
    e = get_exporter(exporter_name)(config=config)
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/base.py", line 102, in get_exporter
    if getattr(exporter(config=config), 'enabled', True):
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/templateexporter.py", line 328, in __init__
    super().__init__(config=config, **kw)
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/exporter.py", line 114, in __init__
    self._init_preprocessors()
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/templateexporter.py", line 494, in _init_preprocessors
    conf = self._get_conf()
  File "/Users/guardian/miniconda3/lib/python3.7/site-packages/nbconvert/exporters/templateexporter.py", line 512, in _get_conf
    if conf_path.exists():
  File "/Users/guardian/miniconda3/lib/python3.7/pathlib.py", line 1361, in exists
    self.stat()
  File "/Users/guardian/miniconda3/lib/python3.7/pathlib.py", line 1183, in stat
    return self._accessor.stat(self)
PermissionError: [Errno 13] Permission denied: '/usr/local/share/jupyter/nbconvert/templates/conf.json'
@txoof
Copy link

txoof commented Sep 30, 2020

what are the permissions on the /usr/local/share/jupyter/nbconvert/templates/ directory?

try: ls -alh /usr/local/share/jupyter/nbconvert/templates/ and ls -alh /usr/local/share/jupyter/nbconvert/templates/conf.json

@gideonsimpson
Copy link
Author

I got permissions denied on both of them. What permissions should they have?

@gideonsimpson
Copy link
Author

Or, alternatively, how can I set things for the user to use a local version?

@txoof
Copy link

txoof commented Sep 30, 2020

This are the defaults created by the latest version of nbconvert

$ dir /usr/local/share/jupyter/nbconvert/templates 
total 0
drwx------  4 aaronciuffo  admin   128B Sep 29 19:56 .
drwxr-xr-x  3 aaronciuffo  admin    96B Sep 25 18:30 ..
drwx------  2 aaronciuffo  admin    64B Sep 29 19:56 html
drwx------  2 aaronciuffo  admin    64B Sep 29 19:56 latex

You should have a local copy somewhere in your path. Try jupyter --paths it should look something like this.

$ jupyter --paths                                                    (master) ✗
config:
    /Users/aaronciuffo/.jupyter
    /Users/aaronciuffo/.pyenv/versions/3.8.5/Python.framework/Versions/3.8/etc/jupyter 
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/aaronciuffo/Library/Jupyter <- local user version
    /Users/aaronciuffo/.pyenv/versions/3.8.5/Python.framework/Versions/3.8/share/jupyter <- local user version
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/aaronciuffo/Library/Jupyter/runtime

afaik the local version was created when jupyter was installed by pip.

@gideonsimpson
Copy link
Author

So the issue might be that I have two accounts on this machine, one that's admin, and the other on which I'm running the jupyter lab server. On the administrative account I have:

config:
    /Users/gideonsimpson/.jupyter
    /Users/gideonsimpson/miniconda3/etc/jupyter
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/gideonsimpson/Library/Jupyter
    /Users/gideonsimpson/miniconda3/share/jupyter
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/gideonsimpson/Library/Jupyter/runtime

while on the jupyter account, I have:

config:
    /Users/guardian/.jupyter
    /Users/guardian/miniconda3/etc/jupyter
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/guardian/Library/Jupyter
    /Users/guardian/miniconda3/share/jupyter
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/guardian/Library/Jupyter/runtime

But, the guardian account does not seem to have permissions to the /usr stuff:

gideonsimpson@machine:~$ ls -l /usr/local/share/jupyter/nbconvert/templates
total 0
drwx------  2 gideonsimpson  admin  64 Sep 16 15:31 html
drwx------  2 gideonsimpson  admin  64 Sep 16 15:31 latex

while

guardian@machine:~$ ls -l /usr/local/share/jupyter/nbconvert/template
ls: templates: Permission denied

I would not to give the guardian account root access, but am unsure of how to best handle this situation.

@txoof
Copy link

txoof commented Oct 3, 2020

I thing the solution is to change the permissions on recursively /usr/local/share/jupyter/ to 0755 and the permissions of the files within the nbconvert folder to 0644 and the executables to 0655.

This feels pretty ugly, but will probably solve your problem.

You can use the find command to do this:

# change the permissions on the directories to group, other read and execute
$ find ./ -type d -exec chmod go+rx {} \;

# change all the other files to group, other read
$ find ./ -type f -exec chmod  go+r {} \;

# change all the executables to group, other execute
$ find ./ -type f -perm -100 -exec chmod go+x {} \;

@gideonsimpson
Copy link
Author

Yup, that did it.

@JunweiSUN
Copy link

Hi @gideonsimpson , I found that if I install jupyterhub and jupyterlab using conda with root, the permission of /usr/local/share/jupyter/nbconvert/templates will be 0700, and other users without root will not be able to write conf.json into this dir. I think this is because nbconvert was not designed for multi-user initially like jupyterhub. Will there be a plan to add multi-user support for nbconvert?

@k-nayak
Copy link

k-nayak commented Jun 28, 2021

This are the defaults created by the latest version of nbconvert

$ dir /usr/local/share/jupyter/nbconvert/templates 
total 0
drwx------  4 aaronciuffo  admin   128B Sep 29 19:56 .
drwxr-xr-x  3 aaronciuffo  admin    96B Sep 25 18:30 ..
drwx------  2 aaronciuffo  admin    64B Sep 29 19:56 html
drwx------  2 aaronciuffo  admin    64B Sep 29 19:56 latex

You should have a local copy somewhere in your path. Try jupyter --paths it should look something like this.

$ jupyter --paths                                                    (master) ✗
config:
    /Users/aaronciuffo/.jupyter
    /Users/aaronciuffo/.pyenv/versions/3.8.5/Python.framework/Versions/3.8/etc/jupyter 
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/aaronciuffo/Library/Jupyter <- local user version
    /Users/aaronciuffo/.pyenv/versions/3.8.5/Python.framework/Versions/3.8/share/jupyter <- local user version
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/aaronciuffo/Library/Jupyter/runtime

afaik the local version was created when jupyter was installed by pip.

I am getting an outpu like this:
drwx------ 2 root root 4.0K Jun 23 11:08 .
drwxrwxrwx 16 root root 4.0K Jun 24 14:37 ..

also not able to create or open any .ipynb files in jupyter notebook and jupyterhub. Both installed on the same linux machine.

Any solution to this error?

@k-nayak
Copy link

k-nayak commented Jul 1, 2021

This Permission error is caused due to the version of nbconvert. nbconvert 6.1.0 was the reason for this error. I have downgraded the nbconvert to 5.6.1 and it fixed the issue for me. I no longer face the Permission error any more while trying to open .ipynb files.

@bklaas
Copy link

bklaas commented Jul 13, 2021

I administer jupyterhub/lab for two separate institutions, and this has bit us both places. As @k-nayak helpfully points out, the workaround is to downgrade to 5.6.1 (thanks!), but I would recommend this issue re-open as it's a significant break for multi-user applications of this.

@jxu
Copy link

jxu commented Sep 9, 2021

I have this problem as well and downgrading worked but is never the best solution

@jasongrout
Copy link
Member

This Permission error is caused due to the version of nbconvert. nbconvert 6.1.0 was the reason for this error.

@k-nayak - can you elaborate on this? What do you think 6.1.0 did that was wrong? @jxu, do you have any insights? @bklaas?

We're in the release process for 6.2.0, and if we have some clues as to why 6.1.0 seems to have a problem, but 5.6 does not, it would really help. Is it a permission problem when 6.1.0 is installed, but somehow 5.6 does not have the permission problem? Typically permissions are dealt with by the installer, so it's a bit puzzling.

@SylvainCorlay - did nbconvert 6.0 switch where it put templates, causing some of these permission issues?

@jasongrout
Copy link
Member

Investigating this, nbconvert 5.6 stores its templates in site-packages:

        "lib/python3.9/site-packages/nbconvert/templates/README.md",
        "lib/python3.9/site-packages/nbconvert/templates/asciidoc.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/html/basic.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/html/celltags.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/html/full.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/html/mathjax.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/html/slides_reveal.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/latex/article.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/base.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/document_contents.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/report.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/skeleton/display_priority.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/skeleton/null.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/style_bw_ipython.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/style_bw_python.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/style_ipython.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/style_jupyter.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/latex/style_python.tplx",
        "lib/python3.9/site-packages/nbconvert/templates/markdown.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/python.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/rst.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/script.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/skeleton/README.md",
        "lib/python3.9/site-packages/nbconvert/templates/skeleton/display_priority.tpl",
        "lib/python3.9/site-packages/nbconvert/templates/skeleton/null.tpl",

while nbconvert 6.1 stores its templates in the share directory:

        "share/jupyter/nbconvert/templates/asciidoc/conf.json",
        "share/jupyter/nbconvert/templates/asciidoc/index.asciidoc.j2",
        "share/jupyter/nbconvert/templates/base/celltags.j2",
        "share/jupyter/nbconvert/templates/base/display_priority.j2",
        "share/jupyter/nbconvert/templates/base/jupyter_widgets.html.j2",
        "share/jupyter/nbconvert/templates/base/mathjax.html.j2",
        "share/jupyter/nbconvert/templates/base/null.j2",
        "share/jupyter/nbconvert/templates/basic/conf.json",
        "share/jupyter/nbconvert/templates/basic/index.html.j2",
        "share/jupyter/nbconvert/templates/classic/base.html.j2",
        "share/jupyter/nbconvert/templates/classic/conf.json",
        "share/jupyter/nbconvert/templates/classic/index.html.j2",
        "share/jupyter/nbconvert/templates/classic/static/style.css",
        "share/jupyter/nbconvert/templates/compatibility/display_priority.tpl",
        "share/jupyter/nbconvert/templates/compatibility/full.tpl",
        "share/jupyter/nbconvert/templates/lab/base.html.j2",
        "share/jupyter/nbconvert/templates/lab/conf.json",
        "share/jupyter/nbconvert/templates/lab/index.html.j2",
        "share/jupyter/nbconvert/templates/lab/static/index.css",
        "share/jupyter/nbconvert/templates/lab/static/theme-dark.css",
        "share/jupyter/nbconvert/templates/lab/static/theme-light.css",
        "share/jupyter/nbconvert/templates/latex/base.tex.j2",
        "share/jupyter/nbconvert/templates/latex/conf.json",
        "share/jupyter/nbconvert/templates/latex/display_priority.j2",
        "share/jupyter/nbconvert/templates/latex/document_contents.tex.j2",
        "share/jupyter/nbconvert/templates/latex/index.tex.j2",
        "share/jupyter/nbconvert/templates/latex/null.j2",
        "share/jupyter/nbconvert/templates/latex/report.tex.j2",
        "share/jupyter/nbconvert/templates/latex/style_bw_ipython.tex.j2",
        "share/jupyter/nbconvert/templates/latex/style_bw_python.tex.j2",
        "share/jupyter/nbconvert/templates/latex/style_ipython.tex.j2",
        "share/jupyter/nbconvert/templates/latex/style_jupyter.tex.j2",
        "share/jupyter/nbconvert/templates/latex/style_python.tex.j2",
        "share/jupyter/nbconvert/templates/markdown/conf.json",
        "share/jupyter/nbconvert/templates/markdown/index.md.j2",
        "share/jupyter/nbconvert/templates/python/conf.json",
        "share/jupyter/nbconvert/templates/python/index.py.j2",
        "share/jupyter/nbconvert/templates/reveal/base.html.j2",
        "share/jupyter/nbconvert/templates/reveal/conf.json",
        "share/jupyter/nbconvert/templates/reveal/index.html.j2",
        "share/jupyter/nbconvert/templates/reveal/static/custom_reveal.css",
        "share/jupyter/nbconvert/templates/rst/conf.json",
        "share/jupyter/nbconvert/templates/rst/index.rst.j2",
        "share/jupyter/nbconvert/templates/script/conf.json",
        "share/jupyter/nbconvert/templates/script/script.j2",
        "share/jupyter/nbconvert/templates/webpdf/conf.json",
        "share/jupyter/nbconvert/templates/webpdf/index.pdf.j2"

Plenty of Jupyter packages store data in the share/jupyter directory (e.g., JupyterLab, Jupyter Notebook, IPython kernel spec, etc.). Putting files there is not out of the ordinary at all. The files in that share/jupyter directory should be readable to function.

If you install, for example, JupyterLab, Jupyter Notebook, ipywidgets, etc. in the same way, are their share/jupyter files also unreadable?

@jasongrout
Copy link
Member

jasongrout commented Sep 16, 2021

I just checked, and making those share/jupyter/nbconvert files read-only still enables nbconvert to work just fine (from the JupyterLab menu), i.e., nbconvert doesn't seem to try to write to those files. Making those share/jupyter/nbconvert files not readable predictably causes problems, leading to errors like shown above and a blank export menu in JupyterLab.

So again, are people that are seeing this issue able to install JupyterLab, ipywidgets, Jupyter Notebook in the same way and see their share/jupyter directories readable? If you are, then let's figure out what those programs are doing that is different than nbconvert to get readable directories. If those programs also end up with unreadable share directories, then I think it's a matter of documenting how to install nbconvert to have a readable share directory.

@SylvainCorlay
Copy link
Member

SylvainCorlay commented Sep 16, 2021

@jasongrout it seems that the culprit is this snippet:

additional_paths = self.template_data_paths
for path in additional_paths:
try:
ensure_dir_exists(path, mode=0o700)
except OSError:
pass

and more specifically the call to ensure_dir_exists. It causes the creation of an empty templates folder for all levels of additional_paths some of which may be system libraries.

@rvalieris
Copy link

dont know if this helps but I came across this issue on a multi-user shared jupyterhub installation, I think user1 wrote the file, then user2 tried to write the file and failed with permission denied.

I "solved" the issue by re-installing everything and removing write permissions of all users, but I'm not sure if this will break something on nbconvert.

on a multi-user install I would rather not have any user writing files on the install dir, if the file is required by nbconvert it should be installed by the package manager, otherwise write it in a user-specific directory.

@SylvainCorlay
Copy link
Member

on a multi-user install I would rather not have any user writing files on the install dir, if the file is required by nbconvert it should be installed by the package manager, otherwise write it in a user-specific directory.

yeah, if the faulty part of the code is the one I mentioned about, we should be able to not have any file or directory created by users.

@rvalieris
Copy link

yeah, if the faulty part of the code is the one I mentioned about, we should be able to not have any file or directory created by users.

nice ! I missed that post actually, looks like that could be it. although I think I remember a "conf" file inside the directory, I might be misremembering tho, sorry.

@jxu
Copy link

jxu commented Sep 16, 2021

I have a pretty messy python environment from years of sometimes using sudo for install, sometimes local user install. I guess it is something weird between running as sudo and normal user.

@jasongrout
Copy link
Member

@jasongrout it seems that the culprit is this snippet:

So (reconstructing might be happening) - this is somehow called by root once, which creates these directories with permission 700, and then those directories are not readable by other users?

@jasongrout
Copy link
Member

That code was introduced in #1028. When Maarten extended the template paths in #1056, I think the code was copied, but had some of these unintended consequences.

jasongrout added a commit to jasongrout/nbconvert that referenced this issue Sep 17, 2021
Fixes jupyter#1430

Many users are reporting that nbconvert 6.x has permission errors when queried or converting files. These seem to arise when nbconvert is installed as root, then used as a user. We hypothesize that the code removed in this commit, which attempts to create template directories throughout the jupyter path hierarchy, succeeds in creating template directories when running as root. Note that it creates the template directories with permission 700. Those permissions as root mean that regular users won’t be able to read these directories, and those are the sort of permission errors we are seeing reported.

This directory creation was originally introduced in jupyter#1028, where I think it was limited to a single user configuration directory (based on the PR discussion). In jupyter#1056, this code appears to have been copied over and applied to the entire Jupyter directory hierarchy.
@jasongrout
Copy link
Member

After reviewing the two PRs #1028 and #1056, I think we can just remove this code. I've done this in #1646, ready for review.

maartenbreddels pushed a commit that referenced this issue Sep 17, 2021
* Do not attempt to create additional template paths.

Fixes #1430

Many users are reporting that nbconvert 6.x has permission errors when queried or converting files. These seem to arise when nbconvert is installed as root, then used as a user. We hypothesize that the code removed in this commit, which attempts to create template directories throughout the jupyter path hierarchy, succeeds in creating template directories when running as root. Note that it creates the template directories with permission 700. Those permissions as root mean that regular users won’t be able to read these directories, and those are the sort of permission errors we are seeing reported.

This directory creation was originally introduced in #1028, where I think it was limited to a single user configuration directory (based on the PR discussion). In #1056, this code appears to have been copied over and applied to the entire Jupyter directory hierarchy.

* Filter additional template paths to existing paths to be consistent.
@k-nayak
Copy link

k-nayak commented Sep 17, 2021

This Permission error is caused due to the version of nbconvert. nbconvert 6.1.0 was the reason for this error.

@k-nayak - can you elaborate on this? What do you think 6.1.0 did that was wrong? @jxu, do you have any insights? @bklaas?

We're in the release process for 6.2.0, and if we have some clues as to why 6.1.0 seems to have a problem, but 5.6 does not, it would really help. Is it a permission problem when 6.1.0 is installed, but somehow 5.6 does not have the permission problem? Typically permissions are dealt with by the installer, so it's a bit puzzling.

@SylvainCorlay - did nbconvert 6.0 switch where it put templates, causing some of these permission issues?

Sorry for the late response, i don't think i have an explaination for the issue as it was something i came accross while searching multiple forums.

@jasongrout
Copy link
Member

We just released 6.2.0rc2, which fixes at least one situation that we think might cause the error (i.e., a situation where we think nbconvert will create directories with restrictive permissions that will give permission errors later when a different user accesses them).

@teh
Copy link

teh commented Dec 8, 2021

If there are other people who still hit this with the 6.2 release - in our case this happens when we're converting some notebooks in our CI which runs in a sandbox and can't access /usr. We fixed it with the patch below.

diff --git a/nbconvert/exporters/templateexporter.py b/nbconvert/exporters/templateexporter.py
index a3991b87..47cf59ed 100644
--- a/nbconvert/exporters/templateexporter.py
+++ b/nbconvert/exporters/templateexporter.py
@@ -516,9 +516,12 @@ class TemplateExporter(Exporter):
         conf = {}  # the configuration once all conf files are merged
         for path in map(Path, self.template_paths):
             conf_path = path / 'conf.json'
-            if conf_path.exists():
-                with conf_path.open() as f:
-                    conf = recursive_update(conf, json.load(f))
+            try:
+                if conf_path.exists():
+                    with conf_path.open() as f:
+                        conf = recursive_update(conf, json.load(f))
+            except PermissionError:
+                continue
         return conf
 
     @default('template_paths')

casparvl added a commit to sara-nl/easybuild-easyconfigs that referenced this issue Jan 17, 2022
….1.0, could cause permission denied errors when run in a shared environment. See jupyter/nbconvert#1430 . This was fixed in PR jupyter/nbconvert#1646 . Since many EasyBuild users work in shared environments, I think this is a relevant fix to have included.
@meeseeksmachine
Copy link

This issue has been mentioned on Jupyter Community Forum. There might be relevant details there:

https://discourse.jupyter.org/t/500-error-on-loading-notebook/12929/5

@meeseeksmachine
Copy link

This issue has been mentioned on Jupyter Community Forum. There might be relevant details there:

https://discourse.jupyter.org/t/500-error-on-loading-notebook/12929/6

@YubinXie
Copy link

In deed, this issue still exists with nbconvert 7.0.0 and 6.4.4. and it is about the permission of /usr/local/share/jupyter/nbconvert/templates/. using sudo to change permission helped.

@jjlex
Copy link

jjlex commented Mar 13, 2023

Looks like it's a problem of pathlib.

>>> from pathlib import Path
>>> p = Path('/share/apps/miniconda/2021.05/share/jupyter/nbconvert/templates/html/conf.json')
>>> p.exists()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/share/apps/miniconda/2021.05/lib/python3.8/pathlib.py", line 1400, in exists
    self.stat()
  File "/share/apps/miniconda/2021.05/lib/python3.8/pathlib.py", line 1197, in stat
    return self._accessor.stat(self)
PermissionError: [Errno 13] Permission denied: '/share/apps/miniconda/2021.05/share/jupyter/nbconvert/templates/html/conf.json'

after giving execute permission to the html folder, the problem is resolved

chmod +x /share/apps/miniconda/2021.05/share/jupyter/nbconvert/templates/html

>>> p.exists()
False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.