{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import panel as pn\n", "pn.extension()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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.\n", "\n", "Discover more on using widgets to add interactivity to your applications in the [how-to guides on interactivity](../how_to/interactivity/index.md). Alternatively, learn [how to set up callbacks and (JS-)links between parameters](../../how_to/links/index.md) or [how to use them as part of declarative UIs with Param](../../how_to/param/index.html).\n", "\n", "#### Parameters:\n", "\n", "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n", "\n", "##### Core\n", "\n", "* **`auto`** (boolean): Whether to download the file the initial click (if `True`) or when clicking a second time (or via the right-click Save file menu).\n", "* **`callback`** (callable): A callable that returns a file or file-like object (takes precedence over `file` if set). \n", "* **`embed`** (boolean): Whether to embed the data on initialization.\n", "* **`file`** (str, Path or file-like object): A path to a file or a file-like object.\n", "* **`filename`** (str): The filename to save the file as.\n", "\n", "##### Display\n", "\n", "* **`button_style`** (str): The button style, either 'solid' or 'outline'.\n", "* **`button_type`** (str): A button theme; should be one of `'default'` (white), `'primary'` (blue), `'success'` (green), `'info'` (yellow), `'light'` (light), or `'danger'` (red)\n", "* **`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](https://tabler-icons.io)/.\n", "* **`icon_size`** (str): Size of the icon as a string, e.g. 12px or 1em.\n", "* **`label`** (str): A custom label for the download button (by default uses the filename)\n", "* **`name`** (str): The title of the widget\n", "\n", "___" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "file_download = pn.widgets.FileDownload(file='FileDownload.ipynb', filename='custom_filename.ipynb')\n", "\n", "file_download" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The file data may also be embedded immediately using `embed` parameter, this allows using the widget even in a static export:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "pn.widgets.FileDownload(file='FileDownload.ipynb', embed=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "pn.widgets.FileDownload(\n", " file='FileDownload.ipynb', button_type='success', auto=False,\n", " embed=False, name=\"Right-click to download using 'Save as' dialog\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "from bokeh.sampledata.autompg import autompg\n", "\n", "from io import StringIO\n", "sio = StringIO()\n", "autompg.to_csv(sio)\n", "sio.seek(0)\n", "\n", "pn.widgets.FileDownload(sio, embed=True, filename='autompg.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "years_options = list(autompg.yr.unique())\n", "years = pn.widgets.MultiChoice(\n", " name='Years', options=years_options, value=[years_options[0]], margin=(0, 20, 0, 0)\n", ")\n", "mpg = pn.widgets.RangeSlider(\n", " name='Mile per Gallon', start=autompg.mpg.min(), end=autompg.mpg.max()\n", ")\n", "\n", "def filtered_mpg(yrs, mpg):\n", " df = autompg\n", " if years.value:\n", " df = autompg[autompg.yr.isin(yrs)]\n", " return df[(df.mpg >= mpg[0]) & (df.mpg <= mpg[1])]\n", "\n", "def filtered_file(yr, mpg):\n", " df = filtered_mpg(yr, mpg)\n", " sio = StringIO()\n", " df.to_csv(sio)\n", " sio.seek(0)\n", " return sio\n", "\n", "fd = pn.widgets.FileDownload(\n", " callback=pn.bind(filtered_file, years, mpg), filename='filtered_autompg.csv'\n", ")\n", "\n", "pn.Column(\n", " pn.Row(years, mpg),\n", " fd,\n", " pn.panel(pn.bind(filtered_mpg, years, mpg), width=600),\n", " width=600\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Styles\n", "\n", "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'`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pn.Row(\n", " *(pn.Column(*(pn.widgets.FileDownload(button_type=p, button_style=bs) for p in pn.widgets.Button.param.button_type.objects))\n", " for bs in pn.widgets.Button.param.button_style.objects)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Icons\n", "\n", "Like other buttons you can provide an explicit `icon`, either as a named icon loaded from [tabler-icons.io](https://tabler-icons.io)/:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pn.Row(\n", " pn.widgets.FileDownload(icon='alert-triangle-filled', button_type='warning', file='FileDownload.ipynb'),\n", " pn.widgets.FileDownload(icon='bug', button_type='danger', file='FileDownload.ipynb')\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or as an explicit SVG:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cash_icon = \"\"\"\n", "\n", " \n", " \n", " \n", " \n", "\n", "\"\"\"\n", "\n", "pn.widgets.FileDownload(icon=cash_icon, button_type='success', icon_size='2em', file='FileDownload.ipynb')" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }