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

JupyterLab fails to open files provided with FileLink does not allow to download them #5443

Closed
gregorgebhardt opened this issue Oct 5, 2018 · 10 comments · Fixed by #7311
Closed
Labels
pkg:notebook question status:resolved-locked tag:Backwards compatible
Milestone

Comments

@gregorgebhardt
Copy link

@gregorgebhardt gregorgebhardt commented Oct 5, 2018

I implemented a magic command that selects some files on the server and should output a link that allows to download them. I extended the class FileLink as follows:

from IPython.display import FileLink

class DownloadFileLink(FileLink):
    html_link_str = "<a href='{link}' download={file_name}>{link_text}</a>"

    def __init__(self, path, file_name=None, link_text=None, *args, **kwargs):
        super(DownloadFileLink, self).__init__(path, *args, **kwargs)

        self.file_name = file_name or os.path.split(path)[1]
        self.link_text = link_text or self.file_name

    def _format_path(self):
        from html import escape
        fp = ''.join([self.url_prefix, escape(self.path)])
        return ''.join([self.result_html_prefix,
                        self.html_link_str.format(link=fp, file_name=self.file_name, link_text=self.link_text),
                        self.result_html_suffix])

later, I call

from collections import namedtuple

DownloadFileLinkInfo = namedtuple('DownloadFileLinkInfo', ['path', 'file_name', 'link_text'])
dfs = DownloadFileLinkInfo('example/path/to/file.pkl', 'more_informative_name.pkl', 'click here')

display(DownloadFileLink(dfs.path, file_name=dfs.file_name, link_text=dfs.link_text))

So far, this all works, the links are displayed in the notebook, however, when I click them JupyterLab tries to open the file and fails since it is not able to open it (pickle-file). Still I also don't get the option to download the file. With the classic notebook everything works fine and also if I tab + right mouse-click on the link and open it in a new tab. In the latter case, I don't get it saved with the filename specified in the download-tag though.

@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 10, 2018

I'm trying to reproduce this. I figured out that I needed to do from IPython.display import FileLink. What is dfs? Just a path/filename/link text?

@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 10, 2018

With a stock JLab with no special url prefix, using your code above (with from IPython.display import FileLink), this generates a working link to a 'lerna.json' file in the current directory:

display(DownloadFileLink('lerna.json', file_name='filename.json', link_text='link text'))

Clicking on the link opens it up in JLab. Shift-right-clicking on the link opens the browser context menu, which allows me to open the file in a new browser tab or downloading it. Is that what you were wanting?

@jasongrout jasongrout added this to the Reference milestone Oct 10, 2018
@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 10, 2018

Perhaps the answer here is to use the browser context menu with shift-right-click?

@gregorgebhardt
Copy link
Author

@gregorgebhardt gregorgebhardt commented Oct 10, 2018

Yes, that would be a workaround. However, getting to the browser context menu via shift-right-click is quite hidden and it would be more convinient to offer the download if JLab is not able to open the file or if the file link has the download tag. Also this workaround does not allow to specify a different filename. For example in my case, I have a lot of files in a folder structure and I wrote a magic that selects some files based on some conditions. Since the selected files might have the same name in different directories or since the filename is also not very informative, I set a different filename in the download tag. With shift-right-click, the browser will store the file under its original name.

@gregorgebhardt
Copy link
Author

@gregorgebhardt gregorgebhardt commented Oct 10, 2018

I'm trying to reproduce this. I figured out that I needed to do from IPython.display import FileLink. What is dfs? Just a path/filename/link text?

Sorry, I forgot to specify this, I have updated my original post accordingly. The url_prefix is not so important and came just from the fact that my kernel runs with a different cwd than JLab.

@mgraauw
Copy link

@mgraauw mgraauw commented Oct 10, 2019

I can confirm this issue in JupyterLab 1.1.4. Following code shows it for Excel:
import pandas as pd
from IPython.display import FileLinks
df = pd.DataFrame([[1,2],[3,4]])
df.to_excel('test.xlsx')
FileLinks('.')

(Or, instead of to_excel, just put some Excel file in notebook folder)

When clicking the 'text.xslx' link displayed, JupyterLab tries to open the Excel and fails (File Load Error for test.xlsx - JupyterLab is unable to open this file type.). In Jupyter 6.0.1 it works as expected (clicking Excel file opens download dialog). Shift-right click does indeed work, but that's a workaround.

@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 10, 2019

The reason it works in the classic notebook is that the notebook punts to the browser to open a file in a new browser tab, and the browser realizes it can't show an excel file, so the browser offers the download.

It would be great if JupyterLab had a plugin for a default behavior for files it can't open, such as downloading them. It will be a bit trickier than the notebook because jlab has to make the decision rather than just punting to the browser, but hopefully not any more tricky than the current right-click download option.

@mgraauw
Copy link

@mgraauw mgraauw commented Oct 10, 2019

I see, thanks for clarifying.

jasongrout added a commit to jasongrout/jupyterlab that referenced this issue Oct 10, 2019
The presumption here is that if an A node has a download attribute explicitly set, the user really does want to download the file rather than opening the file in JLab.

Fixes jupyterlab#5443
@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 10, 2019

Ah, actually the work should be much simpler - I forgot that you had the download attribute set in this link, which we could check for. I think what we need to do is, when analyzing links and deciding whether to imbue JLab behaviors on the link, we should just skip links that have the download attribute set, leaving the handling of the link to the browser.

Indeed, I put this fix in #7311.

@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Oct 11, 2019

This should be fixed in 1.2.0a1, released today.

@jasongrout jasongrout removed this from the Reference milestone Oct 11, 2019
@jasongrout jasongrout added this to the 1.2 milestone Oct 11, 2019
@lock lock bot added the status:resolved-locked label Nov 10, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Nov 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg:notebook question status:resolved-locked tag:Backwards compatible
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants