Is there a way to circumvent (isn’t reactive until file upload is done):
Like using javascript?
Is there a way to circumvent (isn’t reactive until file upload is done):
Like using javascript?
Any ideas why I am getting a bunch of errors? It works alone as a bokeh component, but the moment I call pn.extension(), it returns all the errors.
import panel as pn
from bokeh.core.properties import List, String, Dict, Int, Complex, Float
from bokeh.models import Button, LayoutDOM
import param
from panel.widgets.base import Widget
IMPL = """
import * as p from "core/properties"
import {LayoutDOM, LayoutDOMView} from "models/layouts/layout_dom"
export class FileInputView extends LayoutDOMView
initialize: (options) ->
super(options)
input = document.createElement("input")
input.type = "file"
input.onchange = () => @model.value = input.value
@el.appendChild(input)
export class FileInput extends LayoutDOM
default_view: FileInputView
type: "FileInput"
@define {
value: [ p.String ]
mime_type: [ p.String ]
filename = [ p.String ]
}
"""
class _BkFileInput(LayoutDOM):
__implementation__ = IMPL
value = String()
mime_type = String()
filename = String()
class FileInput(Widget):
value = param.Parameter(default=None)
_widget_type = _BkFileInput
_rename = {'name': None, 'filename': None}
def _process_param_change(self, msg):
msg = super()._process_param_change(msg)
if 'value' in msg:
msg.pop('value')
if 'mime_type' in msg:
msg.pop('mime_type')
return msg
def _filter_properties(self, properties):
properties = super()._filter_properties(properties)
return properties + ['value', 'mime_type', 'filename']
def _process_property_change(self, msg):
msg = super()._process_property_change(msg)
if 'value' in msg:
if isinstance(msg['value'], string_types):
msg['value'] = b64decode(msg['value'])
else:
msg['value'] = [b64decode(content) for content in msg['value']]
return msg
pn.extension()
fi = FileInput()
button = pn.widgets.Button()
Compilation failed:
_BkFileInput.ts:6:1 - error TS1005: ',' expected.
6 initialize: (options) ->
~~~~~~~~~~
_BkFileInput.ts:6:11 - error TS1005: ',' expected.
6 initialize: (options) ->
~
_BkFileInput.ts:6:23 - error TS1005: ',' expected.
6 initialize: (options) ->
~
_BkFileInput.ts:6:24 - error TS1109: Expression expected.
6 initialize: (options) ->
~
_BkFileInput.ts:10:24 - error TS1005: '{' expected.
10 input.onchange = () => @model.value = input.value
~
_BkFileInput.ts:10:36 - error TS1146: Declaration expected.
10 input.onchange = () => @model.value = input.value
_BkFileInput.ts:10:37 - error TS1128: Declaration or statement expected.
10 input.onchange = () => @model.value = input.value
~
_BkFileInput.ts:14:1 - error TS1005: ',' expected.
14 default_view: FileInputView
~~~~~~~~~~~~
_BkFileInput.ts:14:13 - error TS1005: ',' expected.
14 default_view: FileInputView
~
_BkFileInput.ts:15:1 - error TS1005: ',' expected.
15 type: "FileInput"
~~~~
_BkFileInput.ts:15:5 - error TS1005: ',' expected.
15 type: "FileInput"
~
_BkFileInput.ts:16:1 - error TS1005: ',' expected.
16 @define {
~
_BkFileInput.ts:16:8 - error TS1146: Declaration expected.
16 @define {
_BkFileInput.ts:21:1 - error TS1005: '}' expected.
This kind of works, although very clunky.
import base64
from io import BytesIO
import param
import panel as pn
from panel.widgets.base import Widget
from bokeh.core.properties import List, String, Dict, Int, Complex, Float
from bokeh.models import Button, LayoutDOM
pn.extension()
IMPL = """
import * as p from "core/properties"
import {LayoutDOM, LayoutDOMView} from "models/layouts/layout_dom"
export class FileInputView extends LayoutDOMView
initialize: (options) ->
super(options)
input = document.createElement("input")
input.type = "file"
input.onchange = () => @model.value = input.value
@el.appendChild(input)
export class FileInput extends LayoutDOM
default_view: FileInputView
type: "FileInput"
@define {
value: [ p.String ]
mime_type: [ p.String ]
filename = [ p.String ]
}
"""
class FileInput(LayoutDOM):
__implementation__ = IMPL
value = String()
mime_type = String()
filename = String()
fi = FileInput()
button = pn.widgets.Button(name="Status", disabled=True)
input_value = base64.b64decode(fi.value)
def test(attr, old, new):
button.loading = True
fi.on_change("value", test)
pn.Column(fi, button)
pn.pane.JPG(BytesIO(base64.b64decode(fi.value)))
Okay, better solution is to use jscallback:
An alternative is to build you own file upload widget using ReactiveHTML
. I’m experimenting with one here paithon/image_input.py
The progress is there. I’m just not uploading big files. So its quick.