FileDownload#

Download this notebook from GitHub (right-click to download).


import panel as pn
import panel_material_ui as pmui

pn.extension()

The FileDownload widget allows downloading a file on the frontend by sending the file data to the browser either on initialization (if embed=True) or when the button is clicked.

Discover more on using widgets to add interactivity to your applications in the how-to guides on interactivity. Alternatively, learn how to set up callbacks and (JS-)links between parameters or how to use them as part of declarative UIs with Param.

Parameters:#

For details on other options for customizing the component see the customization guides.

Core#

  • auto (boolean): Whether to download the file with the first click (if True) or only after clicking a second time (if False, enables right-click -> Save as).

  • callback (callable): A callable that returns a file or file-like object (takes precedence over file if set).

  • embed (boolean): Whether to embed the data on initialization.

  • file (str, Path or file-like object): A path to a file or a file-like object.

  • filename (str): The filename to save the file as.

Display#

  • color (str): A button theme; should be one of 'default' (white), 'primary' (blue), 'success' (green), 'info' (yellow), 'light' (light), or 'danger' (red).

  • description (str | Bokeh Tooltip | pn.widgets.TooltipIcon): A description which is shown when the widget is hovered.

  • icon (str): An icon to render to the left of the button label. Either an SVG or an icon name which is loaded from tabler-icons.io/.

  • icon_size (str): Size of the icon as a string, e.g. 12px or 1em.

  • label (str): A custom label for the download button (by default uses the filename)

  • variant (str): The button style, either ‘solid’, ‘outlined’, ‘text’.

Aliases#

For compatibility with Panel certain parameters are allowed as aliases:

  • button_style: Alias for variant

  • button_type: Alias for color

  • name: Alias for label


The FileDownload widget accepts a path to a file or a file-like object (with a .read method) if the latter is provided a filename must also be set. By default (auto=True and embed=False) the file is only transferred to the browser after the button is clicked (this requires a live-server or notebook kernel):

file_download = pmui.FileDownload(file='FileDownload.ipynb', filename='custom_filename.ipynb')

file_download

The file data may also be embedded immediately using embed parameter, this allows using the widget even in a static export:

pmui.FileDownload(file='FileDownload.ipynb', embed=True)
Traceback (most recent call last):
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/panel/io/mime_render.py", line 168, in exec_with_return
    out = eval(compile(_convert_expr(last_ast.body[0]), "<ast>", "eval"), global_context)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<ast>", line 1, in <module>
  File "/Users/runner/work/panel-material-ui/panel-material-ui/src/panel_material_ui/widgets/misc.py", line 37, in __init__
    super().__init__(file=file, **params)
  File "/Users/runner/work/panel-material-ui/panel-material-ui/src/panel_material_ui/widgets/base.py", line 65, in __init__
    super().__init__(**params)
  File "/Users/runner/work/panel-material-ui/panel-material-ui/src/panel_material_ui/base.py", line 241, in __init__
    super().__init__(**params)
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/panel/custom.py", line 249, in __init__
    super().__init__(**params)
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/panel/widgets/misc.py", line 161, in __init__
    self._transfer()
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/param/depends.py", line 85, in _depends
    return func(*args, **kw)
           ^^^^^^^^^^^^^^^^^
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/panel/widgets/misc.py", line 270, in _transfer
    self._sync_data(fileobj)
  File "/Users/runner/work/panel-material-ui/panel-material-ui/.pixi/envs/docs/lib/python3.11/site-packages/panel/widgets/misc.py", line 216, in _sync_data
    raise FileNotFoundError(f'File "{fileobj}" not found.')
FileNotFoundError: File "FileDownload.ipynb" not found.

If auto=False is set the file will not be downloaded on the initial click but will change the label from “Transfer ” to “Download ” once the data has been synced. This offers an opportunity to download using the Save as dialog once the data has been transferred.

pmui.FileDownload(
    file='FileDownload.ipynb', button_type='success', auto=False,
    embed=False, name="Right-click to download using 'Save as' dialog"
)

The FileDownload widget may also be given a file-like object, e.g. here we save a pandas DataFrame as a CSV to a StringIO object and pass that to the widget:

from bokeh.sampledata.autompg import autompg

from io import StringIO
sio = StringIO()
autompg.to_csv(sio)
sio.seek(0)

pmui.FileDownload(sio, embed=True, filename='autompg.csv')

If you want to generate the file dynamically, e.g. because it depends on the parameters of some widget you can also supply a callback (which may be decorated with the widgets and/or parameters it depends on):

years_options = list(autompg.yr.unique())
years = pmui.MultiChoice(
    name='Years', options=years_options, value=[years_options[0]], margin=(0, 20, 0, 0)
)
mpg = pmui.RangeSlider(
    name='Mile per Gallon', start=autompg.mpg.min(), end=autompg.mpg.max()
)

def filtered_mpg(yrs, mpg):
    df = autompg
    if years.value:
        df = autompg[autompg.yr.isin(yrs)]
    return df[(df.mpg >= mpg[0]) & (df.mpg <= mpg[1])]

def filtered_file(yr, mpg):
    df = filtered_mpg(yr, mpg)
    sio = StringIO()
    df.to_csv(sio)
    sio.seek(0)
    return sio

fd = pmui.FileDownload(
    callback=pn.bind(filtered_file, years, mpg), filename='filtered_autompg.csv'
)

pn.Column(
    pn.Row(years, mpg),
    fd,
    pn.panel(pn.bind(filtered_mpg, years, mpg), width=600),
    width=600, margin=10
)

Styles#

The color of the FileDownload button can be set by selecting one of the available button_type values and the button_style can be 'solid' or 'outline':

pn.Row(
    *(pn.Column(*(pmui.FileDownload(color=color, variant=variant, file=f'{color}.png', width=225) for color in pmui.Button.param.color.objects))
    for variant in pmui.Button.param.variant.objects)
)

Icons#

However you can also provide an explicit icon, either as a named icon loaded from Material Icons:

pn.Row(
    pmui.FileDownload(icon='warning', color='warning', file='FileDownload.ipynb'),
    pmui.FileDownload(icon='bug_report', color='error', file='FileDownload.ipynb')
)

or as an explicit SVG:

cash_icon = """
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-cash" viewBox="0 0 12 24" stroke-width="2" stroke="white" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h12v12H0z" fill="none"/>
  <path d="M7 9m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z" />
  <path d="M14 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
  <path d="M17 9v-2a2 2 0 0 0 -2 -2h-10a2 2 0 0 0 -2 2v6a2 2 0 0 0 2 2h2" />
</svg>
"""

pmui.FileDownload(icon=cash_icon, color='success', icon_size='4em', file='FileDownload.ipynb')

Controls#

The FileDownload widget exposes a number of options which can be changed from both Python and Javascript. Try out the effect of these parameters interactively:

pn.Row(file_download.controls(jslink=True), file_download)

Download this notebook from GitHub (right-click to download).