Skip to content

Cannot download files when a custom ContentsManager is implemented #4869

@TomTJarosz

Description

@TomTJarosz

Use case:
I have a custom ContentsManager in use (extending notebook.ContentsManager as specified here https://jupyter-notebook.readthedocs.io/en/stable/extending/contents.html#writing-a-custom-contentsmanager). I would like to go download a file by clicking on 'Download' button on the Jupyter tree page.

Problem:
As a result of having a custom content manager, FilesHandler.get will be used to serve the request GET /files/<file name>?download=1 (this is the request made when clicking the 'Download' button on the Jupyter tree page). FilesHandler.get seems to be non-functional (possibly resulting from 815ed3c). Prior to this commit, FilesHandler.get returns None. Currently, calling FilesHandler.get returns a <generator object get at 0x...>. See an attached stack trace of the error below.

[E 11:16:56.049 NotebookApp] Uncaught exception GET /files/Untitled.ipynb?download=1 (::1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/files/Untitled.ipynb?download=1', version='HTTP/1.1', remote_ip='::1')
    Traceback (most recent call last):
      File "/usr/local/share/c3/conda/envs/c3notebook/lib/python3.6/site-packages/tornado/web.py", line 1597, in _execute
        result = yield result
      File "/usr/local/share/c3/conda/envs/c3notebook/lib/python3.6/site-packages/tornado/gen.py", line 1133, in run
        value = future.result()
      File "/usr/local/share/c3/conda/envs/c3notebook/lib/python3.6/site-packages/tornado/gen.py", line 1221, in handle_yield
        self.future = convert_yielded(yielded)
      File "/usr/local/share/c3/conda/envs/c3notebook/lib/python3.6/functools.py", line 807, in wrapper
        return dispatch(args[0].__class__)(*args, **kw)
      File "/usr/local/share/c3/conda/envs/c3notebook/lib/python3.6/site-packages/tornado/gen.py", line 1363, in convert_yielded
        raise BadYieldError("yielded unknown object %r" % (yielded,))
    tornado.gen.BadYieldError: yielded unknown object <generator object get at 0x113b774c0>
[D 11:16:56.049 NotebookApp] Using contents: services/contents
[D 11:16:56.050 NotebookApp] Using contents: services/contents
[E 11:16:56.050 NotebookApp] {
      "Host": "localhost:8888",
      "Connection": "keep-alive",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
      "Sec-Fetch-Mode": "navigate",
      "Sec-Fetch-User": "?1",
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
      "Sec-Fetch-Site": "same-origin",
      "Referer": "http://localhost:8888/tree",
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "en-US,en;q=0.9",
      "Cookie": "_ga=GA1.1.149903520.1553274092; Idea-b94da5fd=5e449cf1-7ab6-4227-8eff-7d7c383b912d; c3canonical=false; _xsrf=2|94454110|a91b2136ddf4a67eaf5f2c917b3d232a|1566318996; c3auth=3033ac4e5232e08eacb564838fb6c565d6a1d228ee10815c8991fb2f9fee17e4a623; c3tenant=c3; c3tag=c3; username-localhost-8889=\"2|1:0|10:1567629964|23:username-localhost-8889|44:OTBjNDA3MzMxMzhiNGZiZWFlOTBmOTMwZGY0NDNlNTQ=|cc51e887661513bf91ef6ed6c591193631ec002ea614716a40fd4e35e3ccc310\"; username-localhost-8890=\"2|1:0|10:1567630655|23:username-localhost-8890|44:MDczZGY2Zjc3ZDk0NGRkNDg4ZTY0MGUwNzY5MzIzZDE=|ee874cb6d41bb551cf0f4151528c4ea57c4892c47fa5e01c8e6abc90864359b8\"; username-localhost-8888=\"2|1:0|10:1567707380|23:username-localhost-8888|44:ZGY1YTdhMzU5ODUzNDU0ZjgxYzBkMDQxNDAyNWY0Mzg=|eaa58c0e4f2934ddd76f5ad65fbcec40d8fee075bde114e37f394ba23e636db7\""
    }
[E 11:16:56.050 NotebookApp] 500 GET /files/Untitled.ipynb?download=1 (::1) 2.03ms referer=http://localhost:8888/tree

Also provided is the of values of variables method, self.path_args, self.path_kwargs, and result in the scope https://github.com/tornadoweb/tornado/blob/v5.1.1/tornado/web.py#L1591 (just prior to an exception).

method = <bound method FilesHandler.get of <notebook.files.handlers.FilesHandler object at 0x113bb2940>>
self.path_args = ['Untitled.ipynb']
self.path_kwargs = {}
result = <generator object get at 0x113b774c0>

The result of calling FilesHandler.get('Untitled.ipynb') is returning an object which is causing an exception.

Request:
In general, I would like FilesHandler.get to work. Specifically, I would recommend to decorate FilesHandler.get with the @gen.coroutine decorator. When looking at other handlers (SessionRootHandler.get, ContentsHandler.get, MainKernelSpecHandler.get v6.0.0), it seems that a method will yield maybe_future(...) iff it is decorated with @gen.coroutine (https://stackoverflow.com/questions/37197514/python-tornado-async-fetching-of-urls also supports my assumption that the @gen.coroutine decorator should be used). Adding this decorator to FilesHandler.get locally resolved this issue locally.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions