Skip to content

Commit be9bc07

Browse files
committed
rewrite chatbot slightly
- use super() + constructor for initializing subclasses - keep number of attributes low - use list.insert() when adding new messages in History - each step shows its actual number
1 parent 87a6da7 commit be9bc07

File tree

9 files changed

+142
-158
lines changed

9 files changed

+142
-158
lines changed

notebooks/tps/chatbot/README-chatbot-nb.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,19 @@ vous aurez envie de *bookmark* ces entrées dans la doc, pour plus d'info:
123123
* <https://flet.dev> le point d'entrée principal
124124
* <https://flet.dev/docs/controls> pour les détails des objets disponibles
125125

126-
````{admonition} python ou flet run
126+
`````{admonition} python ou flet run
127127
:class: dropdown
128128
129-
on peut **aussi* lancer le programme de manière plus traditionnelle avec juste `python chatbot.py`
130-
mais dans ce cas on n'a pas le *hot reload* et l'usage c'est une grosse différence de confort !
129+
````{div}
130+
on peut **aussi** lancer le programme de manière plus traditionnelle avec juste `python chatbot.py`
131+
mais dans ce cas on n'a pas le *hot reload* et à l'usage, c'est une grosse différence de confort !
131132
en outre il est conseillé de regarder les possibilités offertes par la CLI (i.e. le programme `flet`)
132133
qui permet de faire **aussi** d'autres choses très utiles:
133134
```{image} media/flet-help.png
134135
:width: 400px
135136
```
136137
````
138+
`````
137139

138140
+++
139141

notebooks/tps/chatbot/chatbot-03.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@
3333
]
3434

3535

36-
TITLE = "My first Chatbot"
36+
TITLE = "My first Chatbot - 03"
3737

3838

39+
# being a Column, ChatbotApp can be directly included in a Page
40+
# also it is a container for other controls
3941
# see https://flet.dev/docs/tutorials/python-todo/#reusable-ui-components
4042
class ChatbotApp(ft.Column):
4143

4244
def __init__(self):
43-
super().__init__()
44-
self.header = ft.Text(value=TITLE, size=40)
45+
header = ft.Text(value=TITLE, size=40)
4546

4647
self.streaming = ft.Checkbox(label="streaming", value=False)
4748
self.model = ft.Dropdown(
@@ -57,14 +58,13 @@ def __init__(self):
5758

5859
self.submit = ft.ElevatedButton("Send", on_click=self.show_current_settings)
5960

60-
self.controls = [
61-
self.header,
62-
ft.Row(
63-
[self.streaming, self.model, self.server, self.submit],
64-
alignment=ft.MainAxisAlignment.CENTER,
65-
),
66-
]
67-
self.horizontal_alignment=ft.CrossAxisAlignment.CENTER
61+
row = ft.Row(
62+
[self.streaming, self.model, self.server, self.submit],
63+
alignment=ft.MainAxisAlignment.CENTER,
64+
)
65+
super().__init__(
66+
[header, row],
67+
horizontal_alignment=ft.CrossAxisAlignment.CENTER)
6868

6969
# in this version we access the application status through
7070
# attributes in the 'ChatbotApp' instance

notebooks/tps/chatbot/chatbot-04.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
]
3131

3232

33-
TITLE = "My first Chatbot"
33+
TITLE = "My first Chatbot 04"
3434

3535

3636
class History(ft.Column):
@@ -40,23 +40,20 @@ class History(ft.Column):
4040
"""
4141

4242
def __init__(self):
43-
super().__init__()
44-
self.controls = [
45-
ft.TextField(label="Type a message..."),
46-
]
43+
super().__init__([ft.TextField(label="Type a message...")])
4744

45+
# leave the prompt as the last entry
46+
# so insert at the penultimate position;
4847
def add_message(self, message):
49-
self.controls[-1:-1] = [ft.Text(value=message)]
48+
self.controls.insert(-1, ft.Text(value=message))
5049
def current_prompt(self):
5150
return self.controls[-1].value
5251

5352

54-
# see https://flet.dev/docs/tutorials/python-todo/#reusable-ui-components
5553
class ChatbotApp(ft.Column):
5654

5755
def __init__(self):
58-
super().__init__()
59-
self.header = ft.Text(value=TITLE, size=40)
56+
header = ft.Text(value=TITLE, size=40)
6057

6158
self.streaming = ft.Checkbox(label="streaming", value=False)
6259
self.model = ft.Dropdown(
@@ -74,15 +71,14 @@ def __init__(self):
7471

7572
self.history = History()
7673

77-
self.controls = [
78-
self.header,
79-
ft.Row(
80-
[self.streaming, self.model, self.server, self.submit],
81-
alignment=ft.MainAxisAlignment.CENTER,
82-
),
83-
self.history,
84-
]
85-
self.horizontal_alignment=ft.CrossAxisAlignment.CENTER
74+
row = ft.Row(
75+
[self.streaming, self.model, self.server, self.submit],
76+
alignment=ft.MainAxisAlignment.CENTER,
77+
)
78+
super().__init__(
79+
[header, row, self.history],
80+
horizontal_alignment=ft.CrossAxisAlignment.CENTER)
81+
8682

8783
# in this version we access the application status through
8884
# attributes in the 'ChatbotApp' instance

notebooks/tps/chatbot/chatbot-05.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@
3333
]
3434

3535

36-
TITLE = "My first Chatbot"
36+
TITLE = "My first Chatbot 05"
3737

3838

39-
def spot_server(value):
40-
return next(server for server in SERVERS if value in server["name"])
39+
# find the server details from the UI label
40+
def spot_server(servername):
41+
return next(server for server in SERVERS if servername in server["name"])
4142

4243

4344
def send_request(servername, model, streaming, prompt):
@@ -58,23 +59,20 @@ class History(ft.Column):
5859
"""
5960

6061
def __init__(self):
61-
super().__init__()
62-
self.controls = [
63-
ft.TextField(label="Type a message..."),
64-
]
62+
super().__init__([ft.TextField(label="Type a message...")])
6563

64+
# leave the prompt as the last entry
65+
# so insert at the penultimate position;
6666
def add_message(self, message):
67-
self.controls[-1:-1] = [ft.Text(value=message)]
67+
self.controls.insert(-1, ft.Text(value=message))
6868
def current_prompt(self):
6969
return self.controls[-1].value
7070

7171

72-
# see https://flet.dev/docs/tutorials/python-todo/#reusable-ui-components
7372
class ChatbotApp(ft.Column):
7473

7574
def __init__(self):
76-
super().__init__()
77-
self.header = ft.Text(value=TITLE, size=40)
75+
header = ft.Text(value=TITLE, size=40)
7876

7977
self.streaming = ft.Checkbox(label="streaming", value=False)
8078
self.model = ft.Dropdown(
@@ -92,15 +90,14 @@ def __init__(self):
9290

9391
self.history = History()
9492

95-
self.controls = [
96-
self.header,
97-
ft.Row(
98-
[self.streaming, self.model, self.server, self.submit],
99-
alignment=ft.MainAxisAlignment.CENTER,
100-
),
101-
self.history,
102-
]
103-
self.horizontal_alignment=ft.CrossAxisAlignment.CENTER
93+
row = ft.Row(
94+
[self.streaming, self.model, self.server, self.submit],
95+
alignment=ft.MainAxisAlignment.CENTER,
96+
)
97+
super().__init__(
98+
[header, row, self.history],
99+
horizontal_alignment=ft.CrossAxisAlignment.CENTER)
100+
104101

105102
# in this version we access the application status through
106103
# attributes in the 'ChatbotApp' instance

notebooks/tps/chatbot/chatbot-06.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
]
3838

3939

40-
TITLE = "My first Chatbot"
40+
TITLE = "My first Chatbot 06"
4141

4242

4343
# find the server details from the UI label
@@ -52,10 +52,7 @@ class History(ft.Column):
5252
"""
5353

5454
def __init__(self):
55-
super().__init__()
56-
self.controls = [
57-
ft.TextField(label="Type a message..."),
58-
]
55+
super().__init__([ft.TextField(label="Type a message...")])
5956

6057
# insert material - prompt or answer - to allow for different styles
6158
def add_prompt(self, message):
@@ -67,7 +64,7 @@ def _add_entry(self, message, kind):
6764
display.color = "blue" if kind == "prompt" else "green"
6865
display.size = 20 if kind == "prompt" else 16
6966
display.italic = kind == "prompt"
70-
self.controls[-1:-1] = [display]
67+
self.controls.insert(-1, display)
7168

7269
# we always insert in the penultimate position
7370
# given that the last item in controls is the prompt TextField
@@ -77,14 +74,11 @@ def current_prompt(self):
7774
return self.controls[-1].value
7875

7976

80-
# being a Column, ChatbotApp can be directly included in a Page
81-
# also it is a container for other controls
8277
class ChatbotApp(ft.Column):
8378

8479
def __init__(self, page):
85-
super().__init__()
8680
self.page = page
87-
self.header = ft.Text(value=TITLE, size=40)
81+
header = ft.Text(value=TITLE, size=40)
8882

8983
self.streaming = ft.Checkbox(label="streaming", value=False)
9084
self.model = ft.Dropdown(
@@ -102,15 +96,14 @@ def __init__(self, page):
10296

10397
self.history = History()
10498

105-
self.controls = [
106-
self.header,
107-
ft.Row(
108-
[self.streaming, self.model, self.server, self.submit],
109-
alignment=ft.MainAxisAlignment.CENTER,
110-
),
111-
self.history,
112-
]
113-
self.horizontal_alignment=ft.CrossAxisAlignment.CENTER
99+
row = ft.Row(
100+
[self.streaming, self.model, self.server, self.submit],
101+
alignment=ft.MainAxisAlignment.CENTER,
102+
)
103+
super().__init__(
104+
[header, row, self.history],
105+
horizontal_alignment=ft.CrossAxisAlignment.CENTER)
106+
114107

115108
def submit(self, event):
116109
# disable the button to prevent double submission

notebooks/tps/chatbot/chatbot-07.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
]
3737

3838

39-
TITLE = "My first Chatbot"
39+
TITLE = "My first Chatbot 07"
4040

4141

4242
# find the server details from the UI label
@@ -50,15 +50,15 @@ class History(ft.Column):
5050
where prompts and answers alternate
5151
"""
5252

53+
# need to pass the app object so we can invoke its submit method
5354
def __init__(self, app):
54-
super().__init__()
5555
self.app = app
56-
self.controls = [
56+
super().__init__([
5757
ft.TextField(
5858
label="Type a message...",
5959
on_submit=lambda event: self.app.submit(event),
60-
),
61-
]
60+
)
61+
])
6262

6363
# insert material - prompt or answer - to allow for different styles
6464
def add_prompt(self, message):
@@ -70,7 +70,7 @@ def _add_entry(self, message, kind):
7070
display.color = "blue" if kind == "prompt" else "green"
7171
display.size = 20 if kind == "prompt" else 16
7272
display.italic = kind == "prompt"
73-
self.controls[-1:-1] = [display]
73+
self.controls.insert(-1, display)
7474

7575
# we always insert in the penultimate position
7676
# given that the last item in controls is the prompt TextField
@@ -80,15 +80,11 @@ def current_prompt(self):
8080
return self.controls[-1].value
8181

8282

83-
# being a Column, ChatbotApp can be directly included in a Page
84-
# also it is a container for other controls
8583
class ChatbotApp(ft.Column):
8684

8785
def __init__(self, page):
88-
super().__init__()
8986
self.page = page
90-
self.disabled = False
91-
self.header = ft.Text(value=TITLE, size=40)
87+
header = ft.Text(value=TITLE, size=40)
9288

9389
self.streaming = ft.Checkbox(label="streaming", value=False)
9490
self.model = ft.Dropdown(
@@ -102,30 +98,34 @@ def __init__(self, page):
10298
width=100,
10399
)
104100

101+
# need to rename because of the new submit method
105102
self.submit_button = ft.ElevatedButton("Send", on_click=self.submit)
106103

104+
# pass the app parameter to the history
107105
self.history = History(self)
108106

109-
self.controls = [
110-
self.header,
111-
ft.Row(
112-
[self.streaming, self.model, self.server, self.submit_button],
113-
alignment=ft.MainAxisAlignment.CENTER,
114-
),
115-
self.history,
116-
]
117-
self.horizontal_alignment=ft.CrossAxisAlignment.CENTER
107+
row = ft.Row(
108+
[self.streaming, self.model, self.server, self.submit_button],
109+
alignment=ft.MainAxisAlignment.CENTER,
110+
)
111+
super().__init__(
112+
[header, row, self.history],
113+
horizontal_alignment=ft.CrossAxisAlignment.CENTER)
114+
# a local attribute to prevent multiple submissions
115+
self.disabled = False
116+
118117

119118
def submit(self, event):
120119
# and now that the textfield itself is linked to this callback
121120
# we enforce it even further
122121
if self.disabled:
123122
return
124123
# disable the button to prevent double submission
125-
# keep it for the visual effect
124+
# mark the button as disabled for the visual effect
126125
self.submit_button.disabled = True
127126
self.disabled = True
128127
self.send_request(event)
128+
# once the request is completed we can re-enable the button
129129
self.submit_button.disabled = False
130130
self.disabled = False
131131
self.page.update()

0 commit comments

Comments
 (0)