Skip to content

Download

py
#!/usr/bin/env -S uv run --script
#
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "trame",
#     "trame-vuetify",
# ]
# ///
import time

from trame.app import TrameApp
from trame.decorators import trigger
from trame.ui.html import DivLayout
from trame.widgets import html


class DownloadText(TrameApp):
    def __init__(self, server=None):
        super().__init__(server)
        self._build_ui()
        self.state.other_txt_content = "Some content to download..."

    @trigger("download_content")
    def generate_content(self):
        return f"Hello on the server is {time.time()}"

    def _build_ui(self):
        with DivLayout(self.server) as self.ui:
            html.Button(
                "Download from method",
                click="utils.download('method.txt', trigger('download_content'), 'text/plain')",
            )
            html.Button(
                "Download from state",
                click="utils.download('state.txt', other_txt_content, 'text/plain')",
            )


def main():
    app = DownloadText()
    app.server.start()


if __name__ == "__main__":
    main()
py
#!/usr/bin/env -S uv run --script
#
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "trame",
#     "trame-vuetify",
# ]
# ///
from pathlib import Path

from trame.app import TrameApp
from trame.decorators import trigger
from trame.ui.html import DivLayout
from trame.widgets import html

BINARY_FILE = Path(__file__).parent.parent / "data/can.ex2"


class DownloadBinary(TrameApp):
    def __init__(self, server=None):
        super().__init__(server)
        self._build_ui()

    def _build_ui(self):
        with DivLayout(self.server):
            html.Button(
                "Download ",
                click="utils.download('can.ex2', trigger('download_binary'), 'application/octet-stream')",
            )

    @trigger("download_binary")
    def download(self):
        return BINARY_FILE.read_bytes()


def main():
    app = DownloadBinary()
    app.server.start()


if __name__ == "__main__":
    main()

Upload

py
from trame.app import get_server
from trame.app.file_upload import ClientFile
from trame.ui.html import DivLayout
from trame.widgets import html

server = get_server()


def upload(files):
    for file in files:
        file_helper = ClientFile(file)
        print(file_helper.info)


with DivLayout(server) as a:
    html.Input(
        type="file",
        multiple=True,
        change=(upload, "[$event.target.files]"),
        __events=["change"],
    )


if __name__ == "__main__":
    server.start()

Local file browsing

py
from tkinter import Tk, filedialog

from trame.app import get_server
from trame.ui.html import DivLayout
from trame.widgets import html

# -----------------------------------------------------------------------------
# Trame setup
# -----------------------------------------------------------------------------

server = get_server()
state, ctrl = server.state, server.controller

# Keep track of the currently selected directory
state.selected_dir = None

root = Tk()

# Ensure the tkinter main window is hidden
root.withdraw()

# Ensure that the file browser will appear in front on Windows
root.wm_attributes("-topmost", 1)


@ctrl.set("open_directory")
def open_directory():
    kwargs = {
        "title": "Select Directory",
    }
    state.selected_dir = filedialog.askdirectory(**kwargs)


# -----------------------------------------------------------------------------
# UI setup
# -----------------------------------------------------------------------------

with DivLayout(server):
    html.Button("Select Directory", click=ctrl.open_directory)
    html.Div("{{ selected_dir }}")

# -----------------------------------------------------------------------------
# start server
# -----------------------------------------------------------------------------

if __name__ == "__main__":
    server.start()

Local CSS file

py
from pathlib import Path

from trame.app import get_server
from trame.ui.html import DivLayout
from trame.widgets import client

CSS_FILE = Path(__file__).with_name("custom.css")

server = get_server()
with DivLayout(server):
    client.Style(CSS_FILE.read_text())


if __name__ == "__main__":
    server.start()
css
body {
    background-color: red;
}

Local images as URL

py
from pathlib import Path

from trame.app import get_server
from trame.assets.local import LocalFileManager
from trame.ui.html import DivLayout
from trame.widgets import html

KEYS = []
DIRECTORY = Path(__file__).parent.parent.parent / "docs/vitepress/assets/images/apps"
ASSETS = LocalFileManager(DIRECTORY)

for image in DIRECTORY.iterdir():
    key = image.stem.replace("-", "_")
    ASSETS.url(key, image.name)
    KEYS.append(key)


server = get_server()
with DivLayout(server):
    for key in KEYS:
        html.Img(src=ASSETS[key], style="width: 200px;")


if __name__ == "__main__":
    server.start()
py
from pathlib import Path

from trame.app import get_server
from trame.ui.html import DivLayout
from trame.widgets import html

DIRECTORY = Path(__file__).parent.parent.parent / "docs/vitepress/assets/images/apps"

server = get_server()
server.enable_module({"serve": {"data": str(DIRECTORY.absolute())}})

with DivLayout(server):
    for file in DIRECTORY.iterdir():
        html.Img(src=f"/data/{file.name}", style="width: 200px;")


if __name__ == "__main__":
    server.start()