Skip to content

Instantly share code, notes, and snippets.

@rochacbruno
Last active July 12, 2025 19:52
Show Gist options
  • Select an option

  • Save rochacbruno/3d904ec9e51d0cb23a3b7364b7919806 to your computer and use it in GitHub Desktop.

Select an option

Save rochacbruno/3d904ec9e51d0cb23a3b7364b7919806 to your computer and use it in GitHub Desktop.
Exemplos de front end com python usando diversas libs como Jinja, fasthtml, reactpy, gradio, streamlit e flet
from jinja2 import Template
from dundie.core import read
data = read(add_rates=False)
css = "<style>ul { list-style-type: none; }</style>"
js = "<script>console.log('Hello from Jinja!');</script>"
tpl = Template("""
<!DOCTYPE html>
<html>
<head>
<title>Users</title>
{{css}}
{{js}}
</head>
<body>
<h1>Users List</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
{% for u in users %}
<tr>
<td>{{ u.name }}</td>
<td>{{ u.email }}</td>
<td>{{ u.balance }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
""")
with open("/tmp/users.html", "w") as f:
page = tpl.render(users=data, css=css, js=js)
f.write(page)
# uv run --with jinja2 dundie/jinja_app.py
# firefox /tmp/users.html
from fasthtml.common import fast_app, serve, Div, P, Table, Tr, Th, Td
from dundie.core import read
app, rt = fast_app()
@rt('/')
def home():
page = Div(
P("Users"),
Table(
Tr(Th("Name"), Th("Email"), Th("Balance")),
*[
Tr(Td(user["name"]), Td(user["email"]), Td(user["balance"]))
for user in read(add_rates=False)
]
),
)
return page
serve()
# uv run --with python-fasthtml --with starlette --with uvicorn dundie/fasthtml_app.py
from reactpy import component, html, run
from dundie.core import read
@component
def Users():
page = html.div(
html.h1("Users"),
html.table(
html.thead(
html.tr(html.th("Name"), html.th("Email"), html.th("Balance"))
),
html.tbody(
html.tr(html.td(user["name"]), html.td(user["email"]), html.td(user["balance"]))
for user in read(add_rates=False)
),
),
)
return page
run(Users, "localhost", 5000)
# uv run --with reactpy --with starlette --with uvicorn --with websockets dundie/react_app.py
import gradio as gr
from dundie.core import read
with gr.Blocks() as demo:
with gr.Row():
grid = gr.Dataframe(
headers=["name", "email", "balance"],
value=[
[
user["name"],
user["email"],
f"{user['balance']:.2f}",
]
for user in read(add_rates=False)
],
interactive=False,
)
demo.launch()
# uv run --with gradio dundie/gr_app.py
import streamlit as st
from dundie.core import read
data = read(add_rates=False)
st.title("Users")
st.dataframe(data, use_container_width=True)
# uv run --with streamlit streamlit run dundie/streamlit_app.py --web
import flet as ft
from dundie.core import read
def main(page: ft.Page):
page.title = "Users"
page.add(
ft.DataTable(
columns=[
ft.DataColumn(ft.Text("Name")),
ft.DataColumn(ft.Text("Email")),
ft.DataColumn(ft.Text("Balance")),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(ft.Text(user["name"])),
ft.DataCell(ft.Text(user["email"])),
ft.DataCell(ft.Text(f"{user['balance']:.2f}")),
]
)
for user in read(add_rates=False)
],
)
)
ft.app(target=main)
# uv run --with flet dundie/flet_app.py
import sys
import flet as ft
from dundie.core import read, add, get_transactions, ResultDict
def main(page: ft.Page):
"""Entry point for Application"""
# Page and Window Settings
page.title = "Dundie Rewards"
page.scroll = ft.ScrollMode.AUTO
page.theme_mode = ft.ThemeMode.LIGHT
page.window.width = page.window.min_width = 400
page.window.height = page.window.min_height = 800
# State Variables
selected_email = ft.Ref[str]()
def router(event):
"""Called when page.go navigates to a given route"""
page.views.clear()
if event.route == "/":
page.views.append(create_users_list_view())
elif event.route == "/transactions":
page.views.append(create_user_transactions_view())
page.update()
def go_to_user_transactions(e):
"""Navigate to the transactions page for a given user"""
selected_email.current = e.control.data
page.go("/transactions")
def create_users_list_table() -> ft.DataTable:
"""Create a table of all users"""
users = read(add_rates=False)
return ft.DataTable(
columns=[
ft.DataColumn(ft.Text("Action")),
ft.DataColumn(ft.Text("Name")),
ft.DataColumn(ft.Text("Balance")),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(
ft.IconButton(
icon=ft.Icons.ADD_CIRCLE,
icon_color=ft.Colors.GREEN,
on_click=go_to_user_transactions,
data=user["email"],
)
),
ft.DataCell(ft.Text(user["name"])),
ft.DataCell(ft.Text(f"{user['balance']:.2f}")),
]
)
for user in users
],
)
def create_transactions_rows(transactions: ResultDict) -> list[ft.DataRow]:
"""Create a list of rows for a given list of transactions"""
return [
ft.DataRow(
cells=[
ft.DataCell(ft.Text(transaction["date"])),
ft.DataCell(ft.Text(transaction["actor"].split("@")[0])),
ft.DataCell(
ft.Text(
f"{transaction['value']:.2f}",
color=ft.Colors.GREEN
if transaction["value"] > 0
else ft.Colors.RED,
)
),
]
)
for transaction in transactions
]
def create_users_list_view() -> ft.View:
"""Create the main view for the users list"""
data_table = create_users_list_table()
view = ft.View(
"/",
[
ft.AppBar(
title=ft.Text("Dundie Rewards - Users"),
bgcolor=ft.Colors.BLUE_GREY_50,
),
ft.Container(
content=ft.Column(
[
ft.Text(
"All Users", size=24, weight=ft.FontWeight.BOLD
),
ft.Container(height=20),
data_table,
],
),
padding=20,
),
],
scroll=ft.ScrollMode.AUTO,
)
return view
def create_user_transactions_view() -> ft.View:
"""Create the view for the transactions of a given user"""
amount_field = ft.TextField(
label="Amount",
keyboard_type=ft.KeyboardType.NUMBER,
width=200,
icon=ft.Icons.MONEY,
)
user_info = read(add_rates=False, email=selected_email.current)
user_info = user_info[0] if user_info else None
balance_text = ft.Text(
f"Current Balance: {user_info['balance']:.2f}"
if user_info
else "User not found",
size=20,
weight=ft.FontWeight.BOLD,
)
def refresh_page():
user_info = read(add_rates=False, email=selected_email.current)
if user_info:
balance_text.value = (
f"Current Balance: {user_info[0]['balance']:.2f}"
)
transactions = get_transactions(selected_email.current)
transactions_table.rows = create_transactions_rows(transactions)
page.update()
def on_add_click(e):
try:
value = int(amount_field.value)
add(value=value, email=selected_email.current)
amount_field.value = ""
page.open(
ft.SnackBar(
content=ft.Text(
f"That's what she said! Successfully added {value} points!"
),
bgcolor=ft.Colors.GREEN,
)
)
except ValueError:
page.open(
ft.SnackBar(
content=ft.Text(
"No! No! No!Please enter a valid integer"
),
bgcolor=ft.Colors.RED,
)
)
except Exception as ex:
page.open(
ft.SnackBar(
content=ft.Text(f"Error: {str(ex)}"),
bgcolor=ft.Colors.RED,
)
)
finally:
refresh_page()
transactions = get_transactions(selected_email.current)
rows = create_transactions_rows(transactions)
transactions_table = ft.DataTable(
columns=[
ft.DataColumn(ft.Text("Date")),
ft.DataColumn(ft.Text("Actor")),
ft.DataColumn(ft.Text("Value")),
],
rows=rows,
)
return ft.View(
"/transactions",
[
ft.AppBar(
title=ft.Text(f"Transactions - {selected_email.current}"),
bgcolor=ft.Colors.BLUE_GREY_50,
leading=ft.IconButton(
icon=ft.Icons.ARROW_BACK,
on_click=lambda _: page.go("/"),
),
),
ft.Container(
content=ft.Column(
[
balance_text,
ft.Container(height=20),
ft.Row(
[
amount_field,
ft.ElevatedButton(
"Add",
icon=ft.Icons.ADD,
on_click=on_add_click,
),
],
alignment=ft.MainAxisAlignment.START,
),
ft.Container(height=30),
ft.Text(
"Transaction History",
size=20,
weight=ft.FontWeight.BOLD,
),
ft.Container(height=10),
transactions_table,
],
scroll=ft.ScrollMode.AUTO,
),
padding=20,
),
],
scroll=ft.ScrollMode.AUTO,
)
page.on_route_change = router
page.go(page.route)
def run():
"""Run the application
uv run flet dundie/app.py
uv run flet --web dundie/app.py
uv run flet --android dundie/app.py
"""
args = sys.argv[1:]
if args and args[0] == "--web":
ft.app(
target=main, view=ft.AppView.WEB_BROWSER, port=5000, host="0.0.0.0"
)
else:
ft.app(target=main)
if __name__ == "__main__":
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment