Skip to content

Commit

Permalink
docs(examples): update and cleanup examples for v2
Browse files Browse the repository at this point in the history
  • Loading branch information
jourdain committed May 16, 2022
1 parent fe6d329 commit e8ad216
Show file tree
Hide file tree
Showing 138 changed files with 10,029 additions and 0 deletions.
42 changes: 42 additions & 0 deletions examples/00_howdoi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Getting started examples

This directory gather several examples introducing some concepts around trame.

## CLI

The cli example show how you can make use of Command Line Arguments to provide file to load and more.

## Download

The download example show how a button click can trigger a file download on the client side.

## Dynamic

The dynamic example leverage asyncio that dynamically update the state that get reflected on the client side at the discretion of the server change.

## Interactive

The interactive example show how method call can be linked to button click along with state modification directly from a widget.

## Static

The static example show how you can simply inject HTML content as string.

## Table

The table example show how you can display a table from a Pandas dataframe while enabling dynamic content filtering.

## Upload

The upload example show how the UI can select a file localy and make it available on the server side for processing.

## WWW client code to serve

When serving a trame application using apache/nginx or any other static file server you can use the following built-in utility to extract the client side needed for your trame application.

```
python \
-m trame.tools.www \
--output /path/to/output/directory \
vuetify vtk router ... # List all the trame-XXX you use within your trame application.
```
8 changes: 8 additions & 0 deletions examples/00_howdoi/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from trame.app import get_server

if __name__ == "__main__":
server = get_server()
parser = server.cli
parser.add_argument("-o", "--output", help="Working directory")
(args, _unknown) = parser.parse_known_args()
print(args.output)
21 changes: 21 additions & 0 deletions examples/00_howdoi/download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from trame.app import get_server
from trame.ui.vuetify import VAppLayout
from trame.widgets import vuetify

server = get_server()

with VAppLayout(server):
vuetify.VBtn(
"Download",
click="utils.download('my_file_name.csv', file_content, 'text/csv')",
)

server.state.file_content = """a,b,c
1,2,3
4,5,6
7,8,9
"""


if __name__ == "__main__":
server.start()
43 changes: 43 additions & 0 deletions examples/00_howdoi/dynamic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import asyncio
from trame.app import get_server, asynchronous
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import vuetify

coundown_init = 10

server = get_server()
state = server.state
state.trame__title = "Coundown"


@asynchronous.task
async def start_countdown():
try:
state.countdown = int(state.countdown)
except:
state.countdown = coundown_init

while state.countdown > 0:
with state:
await asyncio.sleep(0.5)
state.countdown -= 1


with SinglePageLayout(server) as layout:
layout.title.set_text("Countdown")

with layout.toolbar:
vuetify.VSpacer()
vuetify.VBtn(
"Start countdown",
click=start_countdown,
)

with layout.content:
vuetify.VTextField(
v_model=("countdown", coundown_init),
classes="ma-8",
)

if __name__ == "__main__":
server.start()
48 changes: 48 additions & 0 deletions examples/00_howdoi/interactive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from trame.app import get_server
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import html, vuetify

server = get_server()
state = server.state

# Initial state values
DEFAULT_VALUE = 5
state.trame_title = "Counter"

# Updates
def increment():
state.my_number += 1


def decrement():
state.my_number -= 1


@state.change("my_number")
def validate_my_number(my_number, **kwargs):
if isinstance(my_number, int):
# Prevent infinit loop
return

try:
state.my_number = int(my_number)
except:
state.my_number = DEFAULT_VALUE


with SinglePageLayout(server) as layout:
layout.title.set_text("Simple Counter Demo")

with layout.toolbar:
vuetify.VSpacer()
vuetify.VBtn("-", click=decrement)
vuetify.VBtn("+", click=increment)

with layout.content:
with html.Div(classes="ma-8"):
vuetify.VTextField(v_model=("my_number", DEFAULT_VALUE))
vuetify.VSlider(v_model=("my_number",))


if __name__ == "__main__":
server.start()
3 changes: 3 additions & 0 deletions examples/00_howdoi/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trame>=2.0.0
pandas
numpy
18 changes: 18 additions & 0 deletions examples/00_howdoi/static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from trame.app import get_server
from trame.ui.vuetify import VAppLayout

server = get_server()

html = """
<h3>Welcome to trame...</h3>
<div>
<i>Hello</i> <b>World</b>
</div>
"""

with VAppLayout(server) as layout:
layout.root.add_child(html)

if __name__ == "__main__":
server.start()
67 changes: 67 additions & 0 deletions examples/00_howdoi/table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from trame.app import get_server
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import vuetify
import json

import pandas as pd

server = get_server()

# --------------------------------------------------------------------------------
# Loading dataframe
# --------------------------------------------------------------------------------
data = json.loads(
"""
[{"name":"Frozen Yogurt","calories":200,"fat":6,"carbs":24,"protein":4,"iron":"1%"},{"name":"Ice cream sandwich","calories":200,"fat":9,"carbs":37,"protein":4.3,"iron":"1%"},{"name":"Eclair","calories":300,"fat":16,"carbs":23,"protein":6,"iron":"7%"},{"name":"Cupcake","calories":300,"fat":3.7,"carbs":67,"protein":4.3,"iron":"8%"},{"name":"Gingerbread","calories":400,"fat":16,"carbs":49,"protein":3.9,"iron":"16%"},{"name":"Jelly bean","calories":400,"fat":0,"carbs":94,"protein":0,"iron":"0%"},{"name":"Lollipop","calories":400,"fat":0.2,"carbs":98,"protein":0,"iron":"2%"},{"name":"Honeycomb","calories":400,"fat":3.2,"carbs":87,"protein":6.5,"iron":"45%"},{"name":"Donut","calories":500,"fat":25,"carbs":51,"protein":4.9,"iron":"22%"},{"name":"KitKat","calories":500,"fat":26,"carbs":65,"protein":7,"iron":"6%"}]
"""
)

frame = pd.DataFrame.from_dict(data)

# --------------------------------------------------------------------------------
# Configure table columns and options
# --------------------------------------------------------------------------------

# fmt: off
header_options = {
"name": {"text": "Dessert", "align": "start", "sortable": False},
"calories": {"text": "Calories"},
"fat": {"text": "Fat (g)"},
"carbs": {"text": "Carbs (g)"},
"protein": {"text": "Protein (g)"},
"iron": {"text": "Iron (%)"},
}

# fmt: on
headers, rows = vuetify.dataframe_to_grid(frame, header_options)
table = {
"headers": ("headers", headers),
"items": ("rows", rows),
"search": ("query", ""),
"classes": "elevation-1 ma-4",
"multi_sort": True,
"dense": True,
"items_per_page": 5,
}


# --------------------------------------------------------------------------------
# GUI
# --------------------------------------------------------------------------------

with SinglePageLayout(server) as layout:
layout.title.set_text("Vuetify table example")
with layout.toolbar:
vuetify.VSpacer()
vuetify.VTextField(
v_model=("query", ""),
placeholder="Search",
dense=True,
hide_details=True,
)

with layout.content:
vuetify.VDataTable(**table)

if __name__ == "__main__":
server.start()
29 changes: 29 additions & 0 deletions examples/00_howdoi/upload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from trame.app import get_server
from trame.ui.vuetify import VAppLayout
from trame.widgets import vuetify

server = get_server(log_network="./upload-exchange.txt")
state = server.state

with VAppLayout(server):
vuetify.VFileInput(
v_model=("file_exchange", None),
)


@state.change("file_exchange")
def file_uploaded(file_exchange, **kwargs):
if file_exchange is None:
return

file_name = file_exchange.get("name")
file_size = file_exchange.get("size")
file_time = file_exchange.get("lastModified")
file_mime_type = file_exchange.get("type")
file_binary_content = file_exchange.get("content")
print(f"Got file {file_name} of size {file_size}")
print(file_binary_content)


if __name__ == "__main__":
server.start()
1 change: 1 addition & 0 deletions examples/01_Tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tutorial examples and data are available at https://github.com/Kitware/trame-tutorial/tree/trame-v2
Loading

0 comments on commit e8ad216

Please sign in to comment.