An ipython notebook is a document that is read by the browser that contains both rich text and python code.
In scientific computing ipython notebooks are often used to perform an analysis some input data file that resides on the local file system.
Instead of manually pasting the full path of the file containing the data into a variable, would be convenient to be able to launch an open-file dialog in order to browse the local file system and select the file. The full path of the file should be returned in a variable (in python).
This can be achieved launching an open-file dialog from a GUI toolkit (i.e. QT). For an example see IPython Notebook: Open/select file with GUI (Qt Dialog).
However, using QT has some disadvantages. First it is an additional dependency. Second it requires enabling the QT gui integration in the notebook and this results in conflicts with the inline plots (see here).
The question here is, is it possible to obtain the full path using only Javascript?
EDIT: The answer posted below only returns the file name, not the full-path.
Using the HTML5 construct <input type="file">
is possible to instruct the browser to open a file selector dialog. Then we need to bind a javascript function to the "changed event".
The javascript can use kernel.execute(command)
to execute a command on the python kernel that assign a variable with the selected file path.
Here an example:
input_form = """
<div style="border:solid navy; padding:20px;">
<input type="file" id="file_selector" name="files[]"/>
<output id="list"></output>
</div>
"""
javascript = """
<script type="text/Javascript">
function handleFileSelect(evt) {
var kernel = IPython.notebook.kernel;
var files = evt.target.files; // FileList object
console.log('Executing orig')
console.log(files)
// files is a FileList of File objects. List some properties.
var output = [];
var f = files[0]
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</_Mli>');
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
var command = 'fname = "' + f.name + '"'
console.log(command)
kernel.execute(command);
}
document.getElementById('file_selector').addEventListener('change', handleFileSelect, false);
</script>
"""
def file_selector():
from IPython.display import HTML, display
display(HTML(input_form + javascript))
After the previous definitions putting in a cell file_selector()
will display a button "Choose file" and after a file is selected the variable fname
in the notebook will contain the file path.