Skip to content

file_download

Allows downloading of a file content.

The content to be sent to the user's browser can be a file, a URL, or any data stored as a buffer of bytes.
The content can be dynamically generated when the user requests it.

Image format

Note that if the content is provided as a buffer of bytes, it can be converted to image content if and only if you have installed the python-magic Python package (as well as python-magic-bin if your platform is Windows).

The download can be triggered when clicking on a button or can be performed automatically (see the auto property).

Properties

Name Type Default Description
content(★) path|file|URL|ReadableBuffer|None
dynamic

The content to transfer.
If this is a string, a URL, or a file, then the content is read from this source.
If a readable buffer is provided (such as an array of bytes...), and to prevent the bandwidth from being consumed too much, the way the data is transferred depends on the data_url_max_size parameter of the application configuration (which is set to 50kB by default):

  • If the buffer size is smaller than this setting, then the raw content is generated as a data URL, encoded using base64 (i.e. "data:<mimetype>;base64,<data>").
  • If the buffer size exceeds this setting, then it is transferred through a temporary file.
If this property is set to None, that indicates that dynamic content is generated. Please take a look at the examples below for details on dynamic generation.

label str
dynamic

The label of the button.

on_action Callback

The name of a function that is triggered when the download is terminated (or on user action if content is None).
All the parameters of that function are optional:

  • state (State): the state instance.
  • id (optional[str]): the identifier of the button.
  • payload (dict): the details on this callback's invocation.
    This dictionary has two keys:
    • action: the name of the action that triggered this callback.
    • args: A list of two elements: args[0] reflects the name property and args[1] holds the file URL.

auto bool False

If True, the download starts as soon as the page is loaded.

render bool
dynamic
True

If True, the control is displayed.
If False, the control is not displayed.

bypass_preview bool True

If False, allows the browser to try to show the content in a different tab.
The file download is always performed.

name str

A name proposition for the file to save, that the user can change.

active bool
dynamic
True

Indicates if this component is active.
An inactive component allows no user interaction.

id str

The identifier that will be assigned to the rendered HTML component.

properties dict[str, any]

Bound to a dictionary that contains additional properties for this element.

class_name str
dynamic

The list of CSS class names that will be associated with the generated HTML Element.
These class names will be added to the default taipy-<element_type>.

hover_text str
dynamic

The information that is displayed when the user hovers over this element.

(★)content is the default property for this visual element.

Styling

All the file download controls are generated with the "taipy-file_download" CSS class. You can use this class name to select the file download controls on your page and apply style.

Usage

Default behavior

Allows downloading content when content is a file path or some content.

Definition

<|{content}|file_download|>
<taipy:file_download>{content}</taipy:file_download>
import taipy.gui.builder as tgb
...
tgb.file_download("{content}")

Standard configuration

The label property can be set to specify the label used as the button text next to the download icon.

The function name provided as on_action is called when the download is done (except if content was set to None, as show in the dynamic content examples below).

The name property is used as the default file name proposed to the user when saving the downloaded file (depending on the browser validation rules).

Definition

<|{content}|file_download|label=Download File|on_action=function_name|name=filename|>
<taipy:file_download label="Download File" on_action="function_name" name="filename">{content}</taipy:file_download>
import taipy.gui.builder as tgb
...
tgb.file_download("{content}", label="Download File", on_action=function_name, name="filename")

Preview file in the browser

The file content can be visualized in the browser (if supported and in another tab) by setting bypass_preview to False.

Definition

<|{content}|file_download|don't bypass_preview|>
<taipy:file_download bypass_preview="false">{content}</taipy:file_download>
import taipy.gui.builder as tgb
...
tgb.file_download("{content}", bypass_preview=False)

Automatic download

The file content can be downloaded automatically (when the page shows and when the content is set) when auto is set to True.

Definition

<|{content}|file_download|auto|>
<taipy:file_download auto>{content}</taipy:file_download>
import taipy.gui.builder as tgb
...
tgb.file_download("{content}", auto=True)

Dynamic content

You can download the entire source code used in this section from the GitHub repository.

There are situations when the content to be downloaded cannot or should not be ready before the user presses the download button.
This happens, for example, if some data generation process needs to query live data or if this process takes a lot of time and depends on user-defined parameters. In this situation, you may not want to spend time and resources generating data that may not be used after all.

The property content of the file_download control can be set to None to handle these circumstances. In this case, the on_action callback is invoked immediately after the user has pressed the download button and is in charge of generating the data then triggering the download operation.

Here is an example of such a situation: an algorithm can generate the digits of the number Pi with a requested number of digits.
A slider control lets the user interactively pick the desired precision and a file_download control allows to download a CSV file that contains all the generated digits.
Generating all those digits every time the user moves the slider knob would waste CPU time. We really want to generate the data only when the user presses the download button.

Here is some code that achieves that:

# Initial precision
precision = 10

def pi(precision: int) -> list[int]:
    """Compute Pi to the required precision.

    Adapted from https://docs.python.org/3/library/decimal.html
    """
    saved_precision = getcontext().prec # Save precision
    getcontext().prec = precision
    three = Decimal(3)      # substitute "three=3.0" for regular floats
    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
    while s != lasts:
        lasts = s
        n, na = n+na, na+8
        d, da = d+da, da+32
        t = (t * n) / d
        s += t
    digits = []
    while s != 0:
        integral = int(s)
        digits.append(integral)
        s = (s - integral) * 10
    getcontext().prec = saved_precision
    return digits

# Generate the digits, save them in a CSV file content, and trigger a download action
# so the user can retrieve them
def download_pi(state):
    digits = pi(state.precision)
    buffer = io.StringIO()
    buffer.write("index,digit\n")
    for i, d in enumerate(digits):
        buffer.write(f"{i},{d}\n")
    download(state, content=bytes(buffer.getvalue(), "UTF-8"), name="pi.csv")

The variable precision is bound to a slider on the page: its value is updated (in the user's State), and there is no callback triggered when the slider knob moves. Only the state variable is updated for later use.

The function download_pi() is invoked as the on_action callback for the file_download control, that has its content property set to None. As a result, when the user presses the download button, download_pi() gets immediately invoked so the data can be generated. The data can be downloaded to the user's browser using an explicit call to the function download(), where we convert the string content to a byte buffer using the bytes() function.

The control definition looks like this:

Definition

<|{None}|file_download|on_action=download_pi|>
<taipy:file_download on_action="download_pi">{None}</taipy:file_download>
import taipy.gui.builder as tgb
...
tgb.file_download("{None}", on_action=download_pi)

Content in a temporary file

You can download the entire source code used in this section from the GitHub repository.

In the previous example, we could generate and store all our data in a buffer and then send it so Taipy would create a data URL to handle the transfer.
There are situations where this is not possible or inefficient. Then, a temporary file must be created.
But then, after the transfer is performed, we want to remove that file from the server filesystem since it is no longer needed.

To achieve that, we can use the on_action parameter of the function download(): it gets invoked when the transfer is done, so you can perform any task that should be executed after the file transfer.

Here is some code that demonstrates this. It is a slightly modified version of the example above, where instead of creating a io.StringIO buffer to hold the data, we create a temporary file where we write everything.
The data generation function (pi()) and the control definition remain the same.
Here are the changes to the code compared to the example above:

# Stores the path to the temporary file
temp_path = None

# Remove the temporary file
def clean_up(state):
    os.remove(state.temp_path)

# Generate the digits, save them in a CSV temporary file, then trigger a download action
# for that file.
def download_pi(state):
    digits = pi(state.precision)
    with NamedTemporaryFile("r+t", suffix=".csv", delete=False) as temp_file:
        state.temp_path = temp_file.name
        temp_file.write("index,digit\n")
        for i, d in enumerate(digits):
            temp_file.write(f"{i},{d}\n")
    download(state, content=temp_file.name, name="pi.csv", on_action=clean_up)

In the new implementation of download_pi(), we create a temporary file to write the data we want to send.
The path to this file is saved in the state object. This is made possible because the variable temp_path was declared so that state knows about it.
The call to download() now sets the content to be transferred to the temporary file path and sets the on_action parameter that indicates that, when the file transfer is performed, the function clean_up() should be called.
In clean_up(), we simply delete the temporary file, retrieving its path name from the provided state.