-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapp.py
143 lines (121 loc) · 4.29 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import asyncio
import random
from fasthtml.common import *
from components.assets import arrow_circle_icon, github_icon
from components.chat import chat, chat_form, chat_message, chat_messages
tlink = Script(src="https://cdn.tailwindcss.com")
fasthtml_app, rt = fast_app(ws_hdr=True, hdrs=[tlink])
def title():
return Div(
Span("FastHTML + Modal", cls="font-bold text-6xl"),
Span(
Span("Get started by editing ", cls=""),
Span(
"app.py",
cls="font-mono text-green-500 bg-zinc-900 px-1 py-0.5 rounded-md text-sm",
),
Span(" or deploying to Modal with ", cls=""),
Span(
"deploy.py",
cls="font-mono text-green-500 bg-zinc-900 px-1 py-0.5 rounded-md text-sm",
),
),
cls="flex-1 flex flex-col items-center justify-center gap-2",
)
def github_link():
return A(
github_icon(),
Span("GitHub", cls="font-mono text-green-500 hover:text-green-400 text-sm"),
href="https://github.com/arihanv/fasthtml-modal",
target="_blank",
cls="font-mono text-green-500 hover:text-green-400 flex items-center gap-1",
)
def footer():
return Div(
Div(
Div("Docs", cls="text-zinc-400 text-sm"),
Div(
A(
Span(
"FastHTML",
cls="font-mono text-green-500 group-hover:text-green-400 text-xl",
),
Div(
arrow_circle_icon(),
cls="flex items-center justify-center text-green-500 group-hover:text-green-400 size-5 -rotate-45",
),
href="https://fastht.ml/",
target="_blank",
cls="justify-between items-center pl-2 pr-1 flex border border-green-500 w-40 rounded-md group",
),
Div(cls="w-px bg-zinc-700 h-6"),
A(
Span(
"Modal",
cls="font-mono text-green-500 group-hover:text-green-400 text-xl",
),
Div(
arrow_circle_icon(),
cls="flex items-center justify-center text-green-500 group-hover:text-green-400 size-5 -rotate-45",
),
href="https://modal.com/docs",
target="_blank",
cls="justify-between items-center pl-2 pr-1 flex border border-green-500 w-40 rounded-md group",
),
cls="flex items-center justify-start gap-2",
),
cls="flex flex-col items-center gap-1",
),
Div(
Div("Source", cls="text-zinc-400 flex justify-center w-full text-sm"),
Div(
github_link(),
),
cls="flex flex-col items-center gap-1",
),
cls="flex-1 flex-col flex items-center justify-center gap-5",
)
@rt("/")
async def get():
cts = Div(
title(),
chat(),
footer(),
cls="flex flex-col items-center min-h-screen bg-black",
)
return cts
@fasthtml_app.ws("/ws")
async def ws(msg: str, send):
chat_messages.append({"role": "user", "content": msg})
await send(chat_form(disabled=True))
await send(
Div(
chat_message(len(chat_messages) - 1), id="messages", hx_swap_oob="beforeend"
)
)
message = "You typed: " + msg
chunks = []
while message:
chunk_size = random.randint(4, 10)
chunk = message[:chunk_size]
chunks.append(chunk)
message = message[chunk_size:]
chat_messages.append({"role": "assistant", "content": ""})
await send(
Div(
chat_message(len(chat_messages) - 1), id="messages", hx_swap_oob="beforeend"
)
)
stream_response = ""
for chunk in chunks:
stream_response += chunk
chat_messages[-1]["content"] += chunk
await send(
Span(
chunk, id=f"msg-content-{len(chat_messages)-1}", hx_swap_oob="beforeend"
)
)
await asyncio.sleep(0.2)
await send(chat_form(disabled=False))
if __name__ == "__main__":
serve(app="fasthtml_app")