1
1

00:00:00,780  -->  00:00:01,940
<v Tutor>Hi and welcome back.</v>
2

2

00:00:01,940  -->  00:00:04,140
In this video we're going to bring decorators
3

3

00:00:04,140  -->  00:00:05,870
over to our web application
4

4

00:00:05,870  -->  00:00:07,520
so that we can use them
5

5

00:00:07,520  -->  00:00:10,713
to limit who can access certain endpoints.
6

6

00:00:11,640  -->  00:00:16,640
What am gonna do is am gonna go over to my alerts views.
7

7

00:00:17,010  -->  00:00:19,550
And here we're gonna apply the decorator
8

8

00:00:19,550  -->  00:00:20,950
to a bunch of these.
9

9

00:00:20,950  -->  00:00:22,590
And we haven't defined the decorator yet,
10

10

00:00:22,590  -->  00:00:23,700
we gonna do that in just a moment.
11

11

00:00:23,700  -->  00:00:28,440
So we gonna say from models.user input requires login.
12

12

00:00:28,440  -->  00:00:30,950
That's what our decorator is gonna be called.
13

13

00:00:30,950  -->  00:00:32,493
And now you're under the last video.
14

14

00:00:32,493  -->  00:00:36,880
What we going to do is we're gonna say the index function
15

15

00:00:37,780  -->  00:00:41,510
is the index function but passed through
16

16

00:00:41,510  -->  00:00:44,006
the requires login decorator.
17

17

00:00:44,006  -->  00:00:45,210
And what that's gonna do
18

18

00:00:45,210  -->  00:00:47,610
is before running the index function,
19

19

00:00:47,610  -->  00:00:50,310
we're going to check whether the users logged in
20

20

00:00:50,310  -->  00:00:54,170
and only if they are will we run the original function.
21

21

00:00:54,170  -->  00:00:57,923
If they are not, we will send them over to the login page.
22

22

00:00:58,810  -->  00:01:01,220
And then we gonna do the same for new alert.
23

23

00:01:01,220  -->  00:01:03,810
The new alert function will be the new alert function
24

24

00:01:03,810  -->  00:01:07,480
but passed through the requires login decorator.
25

25

00:01:07,480  -->  00:01:08,820
Which once again will do the same thing,
26

26

00:01:08,820  -->  00:01:11,240
it'll check to see if the users logged in.
27

27

00:01:11,240  -->  00:01:14,460
And if they are, we will run the original function,
28

28

00:01:14,460  -->  00:01:16,110
and so on for the others as well.
29

29

00:01:17,220  -->  00:01:20,340
So how do we apply a decorator in the real world?
30

30

00:01:20,340  -->  00:01:21,770
Because we're not gonna do
31

31

00:01:24,540  -->  00:01:28,670
index equal requires login index.
32

32

00:01:28,670  -->  00:01:31,990
Although I'm not entirely unconvinced this wouldn't work.
33

33

00:01:31,990  -->  00:01:33,170
But there's a better way
34

34

00:01:33,170  -->  00:01:35,960
of applying decorators of doing essentially that.
35

35

00:01:35,960  -->  00:01:39,100
And that is this syntax up here.
36

36

00:01:39,100  -->  00:01:42,840
The at syntax in front of a function is a decorator.
37

37

00:01:42,840  -->  00:01:46,240
And what it does is it passes the index function
38

38

00:01:46,240  -->  00:01:47,423
through the decorator.
39

39

00:01:48,430  -->  00:01:51,130
And then this function only runs
40

40

00:01:51,130  -->  00:01:53,690
when the decorator allows it to essentially,
41

41

00:01:53,690  -->  00:01:56,260
the decorator is used to extend it.
42

42

00:01:56,260  -->  00:01:58,040
The decorator can also do other things
43

43

00:01:58,040  -->  00:02:00,610
other than prevent access to a function.
44

44

00:02:00,610  -->  00:02:02,210
It can do a number of things
45

45

00:02:02,210  -->  00:02:04,880
run other functions before this function runs
46

46

00:02:04,880  -->  00:02:07,810
or run other functions after this function runs,
47

47

00:02:07,810  -->  00:02:12,393
for example to do logging or anything else.
48

48

00:02:13,770  -->  00:02:17,760
So we gonna to apply our requires login decorator
49

49

00:02:17,760  -->  00:02:19,400
to this function.
50

50

00:02:19,400  -->  00:02:20,980
And also to this one, and to this one
51

51

00:02:23,770  -->  00:02:25,490
and to this one.
52

52

00:02:25,490  -->  00:02:27,570
Now it's very important in flask
53

53

00:02:27,570  -->  00:02:29,560
that the requires login decorator
54

54

00:02:29,560  -->  00:02:34,490
goes underneath the route decorator and not above it.
55

55

00:02:34,490  -->  00:02:36,670
So make sure that the order of decorators is like this
56

56

00:02:36,670  -->  00:02:38,390
because it matters.
57

57

00:02:38,390  -->  00:02:41,860
Otherwise, you'd be trying to assert the users logged in
58

58

00:02:41,860  -->  00:02:43,530
before you even know what endpoint
59

59

00:02:43,530  -->  00:02:45,120
they are trying to retrieve,
60

60

00:02:45,120  -->  00:02:47,420
which wouldn't really make sense.
61

61

00:02:47,420  -->  00:02:49,490
So make sure the order is like this.
62

62

00:02:49,490  -->  00:02:53,130
And now we can go ahead and implement our decorator.
63

63

00:02:53,130  -->  00:02:54,810
We gonna go into user
64

64

00:02:54,810  -->  00:02:56,690
and create a new file that am gonna call
65

65

00:02:56,690  -->  00:02:59,350
decorators.py
66

66

00:02:59,350  -->  00:03:02,550
and then here we gonna write our decorator.
67

67

00:03:02,550  -->  00:03:04,350
In order to write a decorator that
68

68

00:03:04,350  -->  00:03:06,990
fully complies with what a decorator should do,
69

69

00:03:06,990  -->  00:03:09,490
we need to import a module that comes with Python
70

70

00:03:09,490  -->  00:03:12,730
called functools for function tools.
71

71

00:03:12,730  -->  00:03:15,083
And from typing we're gonna import callable.
72

72

00:03:15,920  -->  00:03:19,470
Then from flask we're gonna import session, flash,
73

73

00:03:19,470  -->  00:03:22,180
redirect, URL for, and request.
74

74

00:03:22,180  -->  00:03:23,510
We gonna use all of these things
75

75

00:03:23,510  -->  00:03:25,110
in just a few lines.
76

76

00:03:25,110  -->  00:03:27,500
By the way flash, has nothing to do with
77

77

00:03:27,500  -->  00:03:29,990
this technology used for displaying graphics.
78

78

00:03:29,990  -->  00:03:30,990
It's something else.
79

79

00:03:31,990  -->  00:03:35,600
Then we gonna define our requires login decorator,
80

80

00:03:35,600  -->  00:03:38,130
which is gonna take in that funk function,
81

81

00:03:38,130  -->  00:03:41,300
or let me gonna call it F for shortness.
82

82

00:03:41,300  -->  00:03:45,600
And as we know, F is a function
83

83

00:03:45,600  -->  00:03:48,490
and in a typing module functions or other things you can
84

84

00:03:48,490  -->  00:03:51,750
call or execute are called callables.
85

85

00:03:51,750  -->  00:03:55,020
So F is a callable and this requires login decorator
86

86

00:03:55,020  -->  00:03:56,820
as you remember from the last video,
87

87

00:03:56,820  -->  00:03:59,143
will also return a callable.
88

88

00:04:00,530  -->  00:04:03,673
Then we gonna have our decorated function.
89

89

00:04:04,980  -->  00:04:07,240
This decorated function,
90

90

00:04:07,240  -->  00:04:10,110
which is this index function really
91

91

00:04:10,110  -->  00:04:12,890
well this index function will be replaced
92

92

00:04:12,890  -->  00:04:14,823
by this decorated function.
93

93

00:04:16,110  -->  00:04:19,460
Often doesn't take any arguments.
94

94

00:04:19,460  -->  00:04:23,510
But sometimes it does take some arguments like alert ID.
95

95

00:04:23,510  -->  00:04:26,290
So we wanna make sure that these decorated function
96

96

00:04:26,290  -->  00:04:28,880
can also take arguments.
97

97

00:04:28,880  -->  00:04:30,883
The way we do that in Python is we say,
98

98

00:04:32,520  -->  00:04:36,790
asterisk args, an asterisk asterisk kwargs
99

99

00:04:36,790  -->  00:04:39,500
for arguments and keyword arguments
100

100

00:04:39,500  -->  00:04:40,870
and in Python this means that
101

101

00:04:40,870  -->  00:04:43,280
it can have any number of arguments,
102

102

00:04:43,280  -->  00:04:46,293
and it can also have any number of keyword arguments.
103

103

00:04:47,460  -->  00:04:48,620
Why does that matter?
104

104

00:04:48,620  -->  00:04:51,760
Well, because we don't know how many or which arguments
105

105

00:04:51,760  -->  00:04:53,100
a function is gonna have.
106

106

00:04:53,100  -->  00:04:55,580
These ones have an argument called alert ID,
107

107

00:04:55,580  -->  00:04:59,400
but also others have an argument called store ID.
108

108

00:04:59,400  -->  00:05:02,830
So because we don't know exactly what arguments it has,
109

109

00:05:02,830  -->  00:05:06,720
we gonna accept any number of arguments in this function.
110

110

00:05:06,720  -->  00:05:10,100
And then we gonna say,
111

111

00:05:10,100  -->  00:05:12,990
if not session get email,
112

112

00:05:12,990  -->  00:05:17,240
i.e. if there is no email inside the session variable,
113

113

00:05:17,240  -->  00:05:19,253
which again we've imported from flask,
114

114

00:05:20,290  -->  00:05:22,580
then we're going to flash a message
115

115

00:05:22,580  -->  00:05:27,020
saying you need to be signed in for this page.
116

116

00:05:27,020  -->  00:05:30,040
And then this takes in a second argument,
117

117

00:05:30,040  -->  00:05:32,410
which is gonna be danger.
118

118

00:05:32,410  -->  00:05:34,010
Because this is a dangerous message,
119

119

00:05:34,010  -->  00:05:35,180
now because we're gonna just show
120

120

00:05:35,180  -->  00:05:36,940
an error message to the user.
121

121

00:05:36,940  -->  00:05:39,220
And this is what flash is for.
122

122

00:05:39,220  -->  00:05:44,160
Flash, places this message into a queue of messages,
123

123

00:05:44,160  -->  00:05:45,730
and then from your templates,
124

124

00:05:45,730  -->  00:05:48,410
you can get all the messages from the queue
125

125

00:05:48,410  -->  00:05:50,000
and display them to the user.
126

126

00:05:50,000  -->  00:05:52,203
So is actually a pretty handy way of just,
127

127

00:05:53,050  -->  00:05:54,890
putting things out into a queue,
128

128

00:05:54,890  -->  00:05:57,700
so that when the user actually sees them,
129

129

00:05:57,700  -->  00:05:59,060
you can show them all.
130

130

00:05:59,060  -->  00:06:01,060
And here we're just gonna show this one.
131

131

00:06:02,210  -->  00:06:03,820
Once we flash this message,
132

132

00:06:03,820  -->  00:06:06,540
we gonna return a redirect
133

133

00:06:06,540  -->  00:06:11,180
of URL for to users.login user.
134

134

00:06:11,180  -->  00:06:12,370
What this is gonna do
135

135

00:06:12,370  -->  00:06:16,110
is it's going to store this message into this queue
136

136

00:06:16,110  -->  00:06:19,220
and then it's gonna send the user over to the login page.
137

137

00:06:19,220  -->  00:06:20,520
In the login page,
138

138

00:06:20,520  -->  00:06:22,470
we would then show this message.
139

139

00:06:22,470  -->  00:06:24,870
And we have to do that we haven't done that yet.
140

140

00:06:26,110  -->  00:06:28,360
If we don't do this,
141

141

00:06:28,360  -->  00:06:32,350
it means that we do have an email in the session,
142

142

00:06:32,350  -->  00:06:35,000
because this would evaluate to false.
143

143

00:06:35,000  -->  00:06:37,640
So if we do have an email in the session,
144

144

00:06:37,640  -->  00:06:39,470
then we gonna return
145

145

00:06:39,470  -->  00:06:42,317
F with args and kwargs.
146

146

00:06:44,520  -->  00:06:45,353
And what that's gonna do
147

147

00:06:45,353  -->  00:06:47,870
is it's gonna take all the arguments and keyword arguments
148

148

00:06:47,870  -->  00:06:50,200
that this function may have taken,
149

149

00:06:50,200  -->  00:06:53,313
and it's gonna call the original function with all of those.
150

150

00:06:54,250  -->  00:06:58,330
Remember, these decorated function becomes
151

151

00:06:58,330  -->  00:07:00,040
each of these functions.
152

152

00:07:00,040  -->  00:07:03,100
So when flask calls it in order to evaluate
153

153

00:07:03,100  -->  00:07:05,140
what to return for our users,
154

154

00:07:05,140  -->  00:07:07,960
it will pass the alert ID.
155

155

00:07:07,960  -->  00:07:10,430
So that's this function getting the alert ID.
156

156

00:07:10,430  -->  00:07:12,180
So that's why it needs to take in
157

157

00:07:12,180  -->  00:07:13,830
arguments and keyword arguments,
158

158

00:07:13,830  -->  00:07:15,450
but it needs to pass them
159

159

00:07:15,450  -->  00:07:17,310
to our original function which is the one
160

160

00:07:17,310  -->  00:07:19,053
that's actually doing the work.
161

161

00:07:20,920  -->  00:07:24,220
Finally, we return decorated function.
162

162

00:07:24,220  -->  00:07:27,520
Make sure to not include brackets at the end.
163

163

00:07:27,520  -->  00:07:29,870
We wanna return the function itself,
164

164

00:07:29,870  -->  00:07:33,313
not the decorated function execution.
165

165

00:07:34,850  -->  00:07:36,700
Actually thinking we don't need requests anymore,
166

166

00:07:36,700  -->  00:07:38,450
this is everything that we do need.
167

167

00:07:39,820  -->  00:07:43,710
Now, when we apply this decorator to one of these functions,
168

168

00:07:43,710  -->  00:07:46,173
essentially it becomes replaced.
169

169

00:07:47,290  -->  00:07:49,603
And that has some implications.
170

170

00:07:50,600  -->  00:07:53,890
For example, this function is called delete alert.
171

171

00:07:53,890  -->  00:07:58,120
But when it gets replaced by this function,
172

172

00:07:58,120  -->  00:08:00,730
what will the function name be?
173

173

00:08:00,730  -->  00:08:01,760
Well, you guessed it,
174

174

00:08:01,760  -->  00:08:04,163
the function name will be decorated function.
175

175

00:08:05,660  -->  00:08:08,030
Another thing, functions in Python
176

176

00:08:08,030  -->  00:08:09,740
can have documentation applying to them.
177

177

00:08:09,740  -->  00:08:11,710
Not sure if you knew this but
178

178

00:08:11,710  -->  00:08:14,630
for any function you can write how it should be used
179

179

00:08:14,630  -->  00:08:18,810
or who should use it or when it gets cold or anything else.
180

180

00:08:18,810  -->  00:08:20,870
And then from within Python code,
181

181

00:08:20,870  -->  00:08:24,313
you can read this documentation by using help tools.
182

182

00:08:25,890  -->  00:08:26,900
But you guessed it
183

183

00:08:26,900  -->  00:08:29,980
when this function becomes replaced by this one,
184

184

00:08:29,980  -->  00:08:31,460
it does not have documentation
185

185

00:08:31,460  -->  00:08:33,910
because this function doesn't have documentation.
186

186

00:08:35,600  -->  00:08:38,820
That's where funk tools comes into play.
187

187

00:08:38,820  -->  00:08:42,670
We can use funk tools to tell this function
188

188

00:08:42,670  -->  00:08:46,120
to take in the name and documentation
189

189

00:08:46,120  -->  00:08:47,920
of the original function
190

190

00:08:47,920  -->  00:08:51,823
and use those instead of the ones that are here.
191

191

00:08:53,430  -->  00:08:54,263
So it's gonna take
192

192

00:08:54,263  -->  00:08:57,230
any identifying information of the original function
193

193

00:08:57,230  -->  00:09:01,060
and this function will at the time that this is evaluated,
194

194

00:09:01,060  -->  00:09:03,943
use the original functions identifying information.
195

195

00:09:04,810  -->  00:09:08,040
And that is what makes decorators so powerful.
196

196

00:09:08,040  -->  00:09:11,690
Because really, this function no longer gets deleted
197

197

00:09:11,690  -->  00:09:13,760
or ignored or forgotten,
198

198

00:09:13,760  -->  00:09:17,143
it just becomes extended by this stuff here.
199

199

00:09:18,420  -->  00:09:22,343
And funnily enough, the way you use functools
200

200

00:09:23,920  -->  00:09:25,640
is with another decorator.
201

201

00:09:25,640  -->  00:09:28,180
So you need a decorator in order
202

202

00:09:29,350  -->  00:09:31,210
to define a decorator.
203

203

00:09:31,210  -->  00:09:33,100
Well, you don't really need it,
204

204

00:09:33,100  -->  00:09:35,240
you can ignore this line if you want,
205

205

00:09:35,240  -->  00:09:38,090
but it is what keeps the original name and documentation.
206

206

00:09:39,400  -->  00:09:44,400
So that's a pretty interesting quirk about decorators
207

207

00:09:44,620  -->  00:09:47,963
that you need a decorator in order to define one.
208

208

00:09:48,880  -->  00:09:49,713
But that's it.
209

209

00:09:49,713  -->  00:09:51,820
This is our decorator, I hope that makes sense.
210

210

00:09:51,820  -->  00:09:54,400
Decorators are quite mind twisting
211

211

00:09:54,400  -->  00:09:55,610
when you first look at them.
212

212

00:09:55,610  -->  00:09:57,940
So I hope that you're not too confused
213

213

00:09:57,940  -->  00:10:01,300
and I would recommend that you define and use a few of them
214

214

00:10:01,300  -->  00:10:04,103
to get more acquainted with how they work.
215

215

00:10:06,580  -->  00:10:07,850
But that's it.
216

216

00:10:07,850  -->  00:10:10,830
Now these decorators will prevent users
217

217

00:10:10,830  -->  00:10:13,100
from accessing these pages
218

218

00:10:13,100  -->  00:10:15,910
unless they are logged in.
219

219

00:10:15,910  -->  00:10:18,673
And we can verify that by running the app.
220

220

00:10:19,830  -->  00:10:22,260
Oh, we do have something else that we've forgotten,
221

221

00:10:22,260  -->  00:10:26,280
which is that here we've imported from models.user,
222

222

00:10:26,280  -->  00:10:30,300
which means the init method of the models.user folder,
223

223

00:10:30,300  -->  00:10:32,290
we do have to say from
224

224

00:10:32,290  -->  00:10:37,290
models user decorators import requires login.
225

225

00:10:38,010  -->  00:10:39,233
Now we can run our app.
226

226

00:10:40,310  -->  00:10:42,810
Then we can go over to Chrome,
227

227

00:10:42,810  -->  00:10:44,530
which we've got here.
228

228

00:10:44,530  -->  00:10:49,380
And we are going to go over to our alerts page.
229

229

00:10:49,380  -->  00:10:51,100
But as you can see it instantly
230

230

00:10:51,100  -->  00:10:53,003
redirects us to the login page.
231

231

00:10:54,850  -->  00:10:57,860
Because we've got this requires login decorator here
232

232

00:10:57,860  -->  00:11:01,610
before we evaluate any of this,
233

233

00:11:01,610  -->  00:11:04,900
we're actually going through this decorated function.
234

234

00:11:04,900  -->  00:11:07,730
And because we don't have email in the session,
235

235

00:11:07,730  -->  00:11:09,830
we just restarted our app.
236

236

00:11:09,830  -->  00:11:12,463
Then it redirects us to the login user page.
237

237

00:11:13,490  -->  00:11:14,483
And now the question is,
238

238

00:11:14,483  -->  00:11:16,633
well what happened to this flashed message?
239

239

00:11:17,530  -->  00:11:20,360
We haven't shown the flashed message yet.
240

240

00:11:20,360  -->  00:11:22,690
So we're gonna do that just now.
241

241

00:11:22,690  -->  00:11:24,993
In our base.html.
242

242

00:11:27,450  -->  00:11:30,880
We gonna do that in base.html and not in net login.
243

243

00:11:30,880  -->  00:11:33,080
Because just in case another part of our app
244

244

00:11:33,080  -->  00:11:35,020
wants to flash a message as well,
245

245

00:11:35,020  -->  00:11:38,260
we can put it here and then anytime any part of our app
246

246

00:11:38,260  -->  00:11:40,610
flashes a message, it will be displayed
247

247

00:11:40,610  -->  00:11:41,540
and we don't have to like
248

248

00:11:41,540  -->  00:11:44,850
copy this code into everything else that we'll be doing.
249

249

00:11:44,850  -->  00:11:47,650
You'll see what this code does in just a moment.
250

250

00:11:47,650  -->  00:11:48,503
We gonna say,
251

251

00:11:50,220  -->  00:11:55,173
with messages equal get flashed messages.
252

252

00:11:56,770  -->  00:11:58,100
And we gonna pass in with
253

253

00:11:58,100  -->  00:12:00,320
categories equal true endwith.
254

254

00:12:04,387  -->  00:12:07,980
And what this does is it defines a variable called messages,
255

255

00:12:07,980  -->  00:12:10,340
but only the variable only exists
256

256

00:12:10,340  -->  00:12:11,533
inside this block.
257

257

00:12:12,460  -->  00:12:14,880
So this is a ginger way of defining a variable
258

258

00:12:14,880  -->  00:12:16,620
that has a limited lifetime,
259

259

00:12:16,620  -->  00:12:18,910
it only lives within this block.
260

260

00:12:18,910  -->  00:12:21,963
Then we gonna say if messages exists.
261

261

00:12:24,660  -->  00:12:25,810
Now we wanna show them,
262

262

00:12:26,661  -->  00:12:30,823
we gonna say, for category message in messages.
263

263

00:12:34,900  -->  00:12:39,810
And here we will show a div that has a class of alert,
264

264

00:12:39,810  -->  00:12:42,363
alert dash category.
265

265

00:12:44,070  -->  00:12:45,740
And the role is going to be alert.
266

266

00:12:45,740  -->  00:12:47,160
This is for screen reader software
267

267

00:12:47,160  -->  00:12:48,680
to know what this is all about.
268

268

00:12:48,680  -->  00:12:51,743
And inside it, we're gonna put the message.
269

269

00:12:52,860  -->  00:12:56,520
So category is that danger
270

270

00:12:57,700  -->  00:13:00,603
and the message is the content.
271

271

00:13:02,700  -->  00:13:05,260
So for each one of them, as long as there's any of them.
272

272

00:13:05,260  -->  00:13:06,640
We're gonna show these div
273

273

00:13:06,640  -->  00:13:10,610
with two classes alert and alert dash danger.
274

274

00:13:10,610  -->  00:13:12,130
The role is gonna be alert and inside it,
275

275

00:13:12,130  -->  00:13:14,670
we gonna have our message.
276

276

00:13:14,670  -->  00:13:19,090
This is a bootstrap alert when it has these two classes,
277

277

00:13:19,090  -->  00:13:21,270
so it's gonna style it like bootstrap boot.
278

278

00:13:21,270  -->  00:13:24,170
If you don't put the classes in, it'll just show the text.
279

279

00:13:25,060  -->  00:13:29,053
Alright let's restart our app and go back into Chrome.
280

280

00:13:30,200  -->  00:13:32,140
If you refresh this page by the way,
281

281

00:13:32,140  -->  00:13:34,780
you are in users login.
282

282

00:13:34,780  -->  00:13:37,470
So you not actually running the decorator.
283

283

00:13:37,470  -->  00:13:41,670
The decorator only runs when you access the alert endpoints.
284

284

00:13:41,670  -->  00:13:44,170
So you do have to go back to alerts.
285

285

00:13:44,170  -->  00:13:46,900
And there you get the alert.
286

286

00:13:46,900  -->  00:13:49,430
You need to be signed in for this page
287

287

00:13:51,059  -->  00:13:55,120
Let's just gonna make a small edit into this base.html.
288

288

00:13:55,120  -->  00:13:59,800
Am gonna add mt dash two for margin top small.
289

289

00:13:59,800  -->  00:14:02,683
So that when you see the alert,
290

290

00:14:03,700  -->  00:14:06,240
it'll have a small gap at the top.
291

291

00:14:06,240  -->  00:14:08,103
Just looks a little bit nicer and I think.
292

292

00:14:09,060  -->  00:14:10,090
And that's it.
293

293

00:14:10,090  -->  00:14:13,400
That's how you make sure that users are logged in
294

294

00:14:13,400  -->  00:14:16,080
before they access one of your endpoints.
295

295

00:14:16,080  -->  00:14:19,310
And you've also learned about message flashing in flask,
296

296

00:14:19,310  -->  00:14:22,363
which is actually a pretty nice feature of the library.
297

297

00:14:23,780  -->  00:14:25,650
So thank you for joining me in this video.
298

298

00:14:25,650  -->  00:14:27,020
I hope you've learned something.
299

299

00:14:27,020  -->  00:14:28,503
I'll see you on the next one.
