Repository: bokeh/bokeh

Issue:
[FEATURE] Extend FileInput to return filename and make output clearer
I have been playing with the new FileInput widget in the 1.3.0rc2 release and have 2 suggestions/needs I found I had:

- Return the filename of the file being uploaded, since I need to display the names of imported files back to the users.
- Return the actual base64 encoded string of the file content separately from the mime type, rather than combined as they are at the moment. (something like this `data:application/json;base64,ewogICAgInBlcnNvbiI6IHsKICAgICAgICAiYWdlIjogMjIKICAgIH0KfQo=`)

I have a working version that does both of these so if its wanted I can create a pull request to maybe get into the 1.3.0 main release.


#### Background:
Following #9083 / #6096 I saw that the new widget is based on the Panels one, but it seems they have some sort of logic to split up the file string in the python part of the code after the ts bit. The new bokehjs code just does this logic in the ts instead.


Discussion:
> I have a working version that does both of these so if its wanted I can create a pull request to maybe get into the 1.3.0 main release.

Yes, if you can submit it today-ish. These seem like good improvements my only request is in the docs for filename make it very clear that it is just the filename and not a path and that in fact browsers do not allow the full path to be returned (heading off future bug reports or questions about it)

Resolving patch:
diff --git a/bokeh/models/widgets/inputs.py b/bokeh/models/widgets/inputs.py
--- a/bokeh/models/widgets/inputs.py
+++ b/bokeh/models/widgets/inputs.py
@@ -87,10 +87,19 @@ class FileInput(Widget):
 
     '''
 
-    file = String(default="", readonly=True, help="""
+    value = String(default="", readonly=True, help="""
     A base64-encoded string of the contents of the selected file.
     """)
 
+    mime_type = String(default="", readonly=True, help="""
+    The mime type of the selected file.
+    """)
+
+    filename = String(default="", readonly=True, help="""
+    The filename of the selected file.
+    The file path is not included as browsers do not allow access to it.
+    """)
+
     accept = String(default="", help="""
     Comma-separated list of standard HTML file input filters that restrict what
     files the user can pick from. Values can be:
diff --git a/examples/plotting/file/file_input.py b/examples/plotting/file/file_input.py
new file mode 100644
--- /dev/null
+++ b/examples/plotting/file/file_input.py
@@ -0,0 +1,21 @@
+from bokeh.plotting import show, output_file
+from bokeh.models import FileInput, Div, CustomJS
+from bokeh.layouts import column
+
+
+# Set up widgets
+file_input = FileInput(accept=".csv,.json")
+para = Div(text="<h1>FileInput Values:</h1><p>filename:<p>b64 value:")
+
+# Create CustomJS callback to display file_input attributes on change
+callback = CustomJS(args=dict(para=para, file_input=file_input), code="""
+    para.text = "<h1>FileInput Values:</h1><p>filename: " + file_input.filename  + "<p>b64 value: " + file_input.value
+""")
+
+# Attach callback to FileInput widget
+file_input.js_on_change('change', callback)
+
+
+output_file("file_input.html")
+
+show(column(file_input, para))


Test patch:
diff --git a/tests/baselines/examples/plotting/file/file_input b/tests/baselines/examples/plotting/file/file_input
new file mode 100644
--- /dev/null
+++ b/tests/baselines/examples/plotting/file/file_input
@@ -0,0 +1,3 @@
+Column bbox=[0, 0, 310, 180]
+  FileInput bbox=[5, 5, 300, 21]
+  Div bbox=[5, 36, 212, 139]