1
00:00:01,170 --> 00:00:02,600
Hi and welcome back.

2
00:00:02,600 --> 00:00:06,760
In this video, we are going to look at Flask-JWT-Extended.

3
00:00:06,760 --> 00:00:08,863
And we are going to do login.

4
00:00:09,720 --> 00:00:13,225
Up to now, we've been using Flask-JWT to do login

5
00:00:13,225 --> 00:00:17,650
via the /auth endpoint that it creates for us.

6
00:00:17,650 --> 00:00:20,290
Let's go here into app.py to remind ourselves

7
00:00:20,290 --> 00:00:21,483
how this all works.

8
00:00:22,711 --> 00:00:27,436
We import Flask-JWT, which gives us this JWT class.

9
00:00:27,436 --> 00:00:30,550
And then when we create that,

10
00:00:30,550 --> 00:00:33,990
we give it our app and the authenticate and identity

11
00:00:33,990 --> 00:00:37,660
functions and it does some magic there to link up

12
00:00:37,660 --> 00:00:41,585
the app with the auth endpoint that it's gonna create

13
00:00:41,585 --> 00:00:44,463
and uses the authenticate and identify functions.

14
00:00:45,580 --> 00:00:47,620
In addition, there's a little bit of magic

15
00:00:47,620 --> 00:00:50,043
going on in the background that Flask-JWT is doing,

16
00:00:50,043 --> 00:00:53,152
and this has been the source of some confusion for

17
00:00:53,152 --> 00:00:54,073
a lot of you.

18
00:00:55,770 --> 00:00:58,523
So JWT, as soon as it's created,

19
00:00:58,523 --> 00:01:01,340
users are asked to add a new endpoint

20
00:01:02,240 --> 00:01:04,620
and it uses these two functions in that endpoint.

21
00:01:04,620 --> 00:01:06,590
So let's go over to security.py where these

22
00:01:06,590 --> 00:01:08,700
functions are defined, and we've got

23
00:01:08,700 --> 00:01:10,053
the authenticate function.

24
00:01:10,970 --> 00:01:13,050
When you send the username and password

25
00:01:13,050 --> 00:01:15,530
to the /auth endpoint,

26
00:01:15,530 --> 00:01:18,500
it takes in those two and essentially finds the

27
00:01:18,500 --> 00:01:20,844
user in the database and checks the password

28
00:01:20,844 --> 00:01:23,547
to make sure it's correct and then it returns

29
00:01:23,547 --> 00:01:28,170
the user back to the Flask-JWT,

30
00:01:28,170 --> 00:01:30,060
if the login is valid.

31
00:01:30,060 --> 00:01:32,860
And it returns none, that's a default return value

32
00:01:32,860 --> 00:01:34,401
for any Python function.

33
00:01:34,401 --> 00:01:37,810
Returns none if the authentication failed.

34
00:01:37,810 --> 00:01:41,220
That's how Flask-JWT knows whether the username

35
00:01:41,220 --> 00:01:42,870
and password were correct or not.

36
00:01:44,380 --> 00:01:49,380
Then Flask-JWT is gonna create the JWT token.

37
00:01:50,140 --> 00:01:54,040
And in the JWT it's going to save some data.

38
00:01:54,040 --> 00:01:57,590
The data is the user ID.

39
00:01:57,590 --> 00:02:00,863
And that is defined inside Flask-JWT.

40
00:02:02,460 --> 00:02:06,480
So the users ID property is gonna actually try to get

41
00:02:06,480 --> 00:02:08,650
the user ID, it's gonna try to get the user ID

42
00:02:08,650 --> 00:02:13,020
and put it in the JWT and encrypt it so it's safe.

43
00:02:13,020 --> 00:02:14,173
And returns that.

44
00:02:15,530 --> 00:02:19,200
That is saved as the identity key in the JWT.

45
00:02:19,200 --> 00:02:22,790
So when we decrypt it, which comes back as the

46
00:02:22,790 --> 00:02:25,540
identity function, when we make another request,

47
00:02:25,540 --> 00:02:29,620
we access the user's ID as the payload's identity key.

48
00:02:29,620 --> 00:02:33,060
So this is when we make another request and we send

49
00:02:33,060 --> 00:02:34,893
the JWT to our API.

50
00:02:35,840 --> 00:02:37,658
Using identity we can get the user ID

51
00:02:37,658 --> 00:02:41,200
and then we can return what user model

52
00:02:41,200 --> 00:02:44,210
that ID corresponds to and in the rest of our app,

53
00:02:44,210 --> 00:02:48,359
Flask-JWT can then use these user model that we've returned

54
00:02:48,359 --> 00:02:50,414
if we want.

55
00:02:50,414 --> 00:02:54,230
We've not quite looked at how to use the user model

56
00:02:54,230 --> 00:02:56,523
in our app, but there are ways of doing it.

57
00:02:57,688 --> 00:03:02,688
Now Flask-JWT extended requires a little bit more code

58
00:03:03,090 --> 00:03:06,520
because it doesn't have that magic in the background

59
00:03:06,520 --> 00:03:07,823
doing things for you.

60
00:03:08,900 --> 00:03:12,140
Now it doesn't do things for you, which can be bad.

61
00:03:12,140 --> 00:03:16,450
But at the same time, it actually becomes more explicit.

62
00:03:16,450 --> 00:03:18,480
It becomes clearer of what it's doing and what it's not

63
00:03:18,480 --> 00:03:22,860
doing because you're telling it exactly what should happen.

64
00:03:22,860 --> 00:03:24,879
I actually quite like Flask-JWT extended,

65
00:03:24,879 --> 00:03:28,260
and in this view, we're gonna learn how to do the login.

66
00:03:28,260 --> 00:03:31,760
Let's go ahead and delete security.py.

67
00:03:31,760 --> 00:03:33,450
We're not gonna need security.py any longer

68
00:03:33,450 --> 00:03:36,175
so we can move it to trash, get rid of it.

69
00:03:36,175 --> 00:03:41,079
And of course we are going to go to app.py

70
00:03:41,079 --> 00:03:46,079
and we are going to add here Flask-JWT-Extended.

71
00:03:51,930 --> 00:03:56,930
We are going to import a JWT manager in here.

72
00:04:02,250 --> 00:04:05,790
The JWT manager actually doesn't have to do much.

73
00:04:05,790 --> 00:04:10,790
All it has to do is link up to the app.

74
00:04:10,800 --> 00:04:14,730
Once it links up to the app, it can sort of know a bit of

75
00:04:14,730 --> 00:04:17,970
what's going on in your app.

76
00:04:17,970 --> 00:04:22,003
For example to only live inside a request.

77
00:04:22,860 --> 00:04:25,310
That means that when you get some data from the user,

78
00:04:25,310 --> 00:04:28,080
Flask-JWT-Extended will be able to determine that

79
00:04:28,080 --> 00:04:30,810
you have received the request and it will be able to

80
00:04:30,810 --> 00:04:34,020
give you data regarding the user that made that request

81
00:04:34,020 --> 00:04:35,270
if you request it.

82
00:04:35,270 --> 00:04:37,460
If you want that data.

83
00:04:37,460 --> 00:04:41,570
That's why we are linking the JWT manager with our app.

84
00:04:41,570 --> 00:04:43,700
And notice of course that JWT manager

85
00:04:43,700 --> 00:04:45,350
part of Flask-JWT-Extended

86
00:04:45,350 --> 00:04:47,900
this no longer has anything to do with Flask-JWT.

87
00:04:47,900 --> 00:04:49,870
Completely different libraries

88
00:04:49,870 --> 00:04:52,903
and everything is completely different essentially.

89
00:04:53,990 --> 00:04:56,413
That's the only change we need to do in app.py.

90
00:04:57,400 --> 00:05:02,400
But of course this is not creating the auth endpoint.

91
00:05:04,086 --> 00:05:08,720
This doesn't use the authenticate and identify functions,

92
00:05:08,720 --> 00:05:10,090
which indeed don't exist any longer.

93
00:05:10,090 --> 00:05:11,740
So I actually have to delete them.

94
00:05:11,740 --> 00:05:15,230
This does not create an authentication endpoint.

95
00:05:15,230 --> 00:05:18,490
We have to create that endpoint ourselves.

96
00:05:18,490 --> 00:05:21,813
So let's go ahead and create it in the user Resource.

97
00:05:22,840 --> 00:05:24,840
Here we've got the user register Resource,

98
00:05:24,840 --> 00:05:26,690
that allows us to create new users

99
00:05:26,690 --> 00:05:28,030
and put them into the database.

100
00:05:28,030 --> 00:05:33,030
And we've got the user Resource that we've used to create,

101
00:05:33,510 --> 00:05:35,430
sorry to retrieve and delete users.

102
00:05:35,430 --> 00:05:37,630
We're gonna minimise this one as well, just to give

103
00:05:37,630 --> 00:05:40,160
it a bit more room and we're going to create a

104
00:05:40,160 --> 00:05:43,170
user login Resource.

105
00:05:43,170 --> 00:05:46,420
The user login is going to do exactly what the authenticate

106
00:05:46,420 --> 00:05:48,390
function did before.

107
00:05:48,390 --> 00:05:50,180
We're gonna take in a username and password,

108
00:05:50,180 --> 00:05:52,530
and is going to make sure that they're correct.

109
00:05:53,949 --> 00:05:57,690
So we are going to have of course, we are going to have

110
00:05:57,690 --> 00:05:59,850
a parser, that we're gonna need because we need to

111
00:05:59,850 --> 00:06:01,340
extract the user name and password.

112
00:06:01,340 --> 00:06:03,023
So we're gonna create that first.

113
00:06:04,820 --> 00:06:07,793
And then we're just going to have a post method in here.

114
00:06:08,860 --> 00:06:12,174
This post-method is going to do a few things.

115
00:06:12,174 --> 00:06:15,503
It's going to get data from parser,

116
00:06:16,580 --> 00:06:19,907
then it's going to find the user in the database,

117
00:06:19,907 --> 00:06:23,220
then it's gonna check the password and then it's going to

118
00:06:23,220 --> 00:06:25,840
do something that the authenticate function did not to do,

119
00:06:25,840 --> 00:06:28,550
because Flask-JWT did for us.

120
00:06:28,550 --> 00:06:31,697
It's going to create an access token.

121
00:06:31,697 --> 00:06:35,240
And it's also going to create a refresh token.

122
00:06:35,240 --> 00:06:38,735
And we will look at this later.

123
00:06:38,735 --> 00:06:41,420
Don't worry too much about the refresh token just now.

124
00:06:41,420 --> 00:06:46,420
For now, the access token is the Flask-JWT was creating.

125
00:06:48,030 --> 00:06:51,023
And then of course it's gonna return them and that's it.

126
00:06:52,320 --> 00:06:53,430
Let's start from the beginning.

127
00:06:53,430 --> 00:06:55,500
Let's get some data using the parser.

128
00:06:55,500 --> 00:06:58,560
Well, all we have to do is say data equal

129
00:06:58,560 --> 00:07:00,600
self.parser.parse_args.

130
00:07:03,497 --> 00:07:05,210
You know how to do this, or indeed if you wanted

131
00:07:05,210 --> 00:07:07,820
you could use our login.parser.parse_args.

132
00:07:07,820 --> 00:07:09,040
Totally the same thing.

133
00:07:09,040 --> 00:07:10,140
Doesn't really matter.

134
00:07:12,180 --> 00:07:15,400
And by the way, this could be a class method if you wanted

135
00:07:15,400 --> 00:07:18,000
it may actually be better if this is a class method.

136
00:07:19,330 --> 00:07:23,060
Then there's gonna be a CLS and there's gonna CLS two.

137
00:07:23,060 --> 00:07:24,440
There you go.

138
00:07:24,440 --> 00:07:25,490
Now we've got the data.

139
00:07:25,490 --> 00:07:28,050
We can go ahead and find the user in the database.

140
00:07:28,050 --> 00:07:30,960
So user is usermodel.find_by_username

141
00:07:32,350 --> 00:07:35,470
and we're going to use the data coming back from the parser.

142
00:07:35,470 --> 00:07:38,593
So it's gonna be data username, like that.

143
00:07:40,230 --> 00:07:43,820
Okay so now that we have this data,

144
00:07:43,820 --> 00:07:45,730
sorry this user model, we can go ahead

145
00:07:45,730 --> 00:07:46,680
and check the password.

146
00:07:46,680 --> 00:07:48,307
We're gonna do this in the same way

147
00:07:48,307 --> 00:07:51,610
that the authenticate function did earlier on.

148
00:07:51,610 --> 00:07:55,513
So if the user exists and save string compare,

149
00:07:57,200 --> 00:07:59,330
this is coming from work zoig,

150
00:07:59,330 --> 00:08:02,010
user.password and data.passwrod.

151
00:08:02,010 --> 00:08:04,433
So just gonna compare those two.

152
00:08:06,600 --> 00:08:07,970
And of course we have to import this.

153
00:08:07,970 --> 00:08:09,560
We'll do that in just a moment.

154
00:08:09,560 --> 00:08:12,170
Then we are going to create an access token.

155
00:08:12,170 --> 00:08:16,450
We're gonna say access token is create access token.

156
00:08:16,450 --> 00:08:19,500
So what is this create access token?

157
00:08:19,500 --> 00:08:22,040
Well this is part of Flask-JWT-Extended.

158
00:08:22,040 --> 00:08:25,248
This is what actually creates that JWT

159
00:08:25,248 --> 00:08:29,006
that is going to allow users to send it back to us,

160
00:08:29,006 --> 00:08:30,883
to tell us who they are.

161
00:08:32,070 --> 00:08:33,656
And in telling us who they are,

162
00:08:33,656 --> 00:08:37,841
we need to have some data stored in the JWT,

163
00:08:37,841 --> 00:08:41,530
that will allow us to identify that user.

164
00:08:41,530 --> 00:08:44,960
That's what the identity function did in the security.py

165
00:08:44,960 --> 00:08:48,430
file before, now we just put it here.

166
00:08:48,430 --> 00:08:51,143
Identity is user.id.

167
00:08:52,173 --> 00:08:55,370
We are also going to say fresh equal True

168
00:08:55,370 --> 00:08:58,010
and again don't worry about that just now.

169
00:08:58,010 --> 00:09:00,280
We're gonna look at it in just a couple of videos.

170
00:09:00,280 --> 00:09:02,543
This has to do with token refreshing.

171
00:09:03,887 --> 00:09:07,334
Similarly, we're also going to create a refresh token

172
00:09:07,334 --> 00:09:10,741
which is gonna be create refresh token

173
00:09:10,741 --> 00:09:13,613
and the identity is going to be user.id.

174
00:09:17,350 --> 00:09:19,510
We're gonna delete those two comments.

175
00:09:19,510 --> 00:09:20,920
And then we're gonna return them.

176
00:09:20,920 --> 00:09:24,072
So the access token is going to be the access token

177
00:09:24,072 --> 00:09:28,763
and the refresh token is going to be the refresh token.

178
00:09:29,670 --> 00:09:31,860
The code is 200, which is a default button.

179
00:09:31,860 --> 00:09:34,623
Nonetheless it's also a good idea to put that in there.

180
00:09:36,878 --> 00:09:39,591
Okay now if the user didn't exist

181
00:09:39,591 --> 00:09:42,470
or the password is wrong,

182
00:09:42,470 --> 00:09:45,380
we can also return a nice message there to say

183
00:09:45,380 --> 00:09:48,533
something like message invalid credentials.

184
00:09:50,210 --> 00:09:52,490
And the code for this is gonna be 401.

185
00:09:52,490 --> 00:09:54,203
That means unauthorised.

186
00:09:55,260 --> 00:09:56,750
Okay I'm gonna delete these comments

187
00:09:56,750 --> 00:09:59,820
just to make it a little bit nicer there

188
00:09:59,820 --> 00:10:00,742
and that's it.

189
00:10:00,742 --> 00:10:03,310
Again just a small comment for you.

190
00:10:03,310 --> 00:10:08,310
This is what the authenticate function used to do.

191
00:10:09,660 --> 00:10:13,990
Check the user exists and the password is correct.

192
00:10:13,990 --> 00:10:18,990
And this identity equal is what the identity function

193
00:10:21,190 --> 00:10:22,023
used to do.

194
00:10:23,160 --> 00:10:27,820
But now instead of saving the user's ID by default

195
00:10:27,820 --> 00:10:30,960
into the JWT, and then having our identity function

196
00:10:30,960 --> 00:10:35,960
extracted, we are saving that user ID into the access token

197
00:10:37,290 --> 00:10:38,600
as the identity.

198
00:10:38,600 --> 00:10:41,512
Then we can retrieve it if we want

199
00:10:41,512 --> 00:10:44,973
and I'll teach you how to do that very soon as well.

200
00:10:46,880 --> 00:10:51,343
Okay so now we have this user login Resource.

201
00:10:52,524 --> 00:10:54,320
Small optimization here by the way.

202
00:10:54,320 --> 00:10:57,050
We've got the same parser in the use register

203
00:10:57,050 --> 00:10:58,700
and the use login Resources.

204
00:10:58,700 --> 00:11:00,440
So we can actually extract it

205
00:11:00,440 --> 00:11:03,700
and move it outside the Resources.

206
00:11:03,700 --> 00:11:05,450
And that's just gonna be a little bit nicer.

207
00:11:05,450 --> 00:11:07,683
So I'm gonna rename this.

208
00:11:09,809 --> 00:11:11,209
I was a bit too quick there.

209
00:11:12,910 --> 00:11:17,910
Have it, and we're gonna rename this to _user_parser.

210
00:11:22,910 --> 00:11:24,330
Maybe it can't do that.

211
00:11:24,330 --> 00:11:26,110
Let's go with user_parser.

212
00:11:26,110 --> 00:11:26,943
Sorry about that.

213
00:11:26,943 --> 00:11:29,180
I tried something, but it didn't quite work there.

214
00:11:30,666 --> 00:11:33,863
We are gonna do this like that

215
00:11:36,620 --> 00:11:38,300
and here we're gonna do the same.

216
00:11:38,300 --> 00:11:40,403
Just format this a bit more nicely.

217
00:11:43,250 --> 00:11:45,370
Now we have this _user_parser.

218
00:11:45,370 --> 00:11:49,210
The reason I'm making it underscore is just so it

219
00:11:49,210 --> 00:11:53,040
tells whoever wants to import things from user.py

220
00:11:53,040 --> 00:11:55,220
that this is a private variable,

221
00:11:55,220 --> 00:11:57,720
and you shouldn't import it from somewhere else.

222
00:11:57,720 --> 00:12:00,170
That's what the underscore at the start means in Python.

223
00:12:00,170 --> 00:12:04,210
So now we have a little bit less code duplication,

224
00:12:04,210 --> 00:12:06,797
because we can go ahead into the usual register Resource

225
00:12:06,797 --> 00:12:11,797
and do that instead of using the user register parser.

226
00:12:13,067 --> 00:12:15,320
And the reason why I said doesn't really matter

227
00:12:15,320 --> 00:12:16,910
what you do here with Salesforce CLS

228
00:12:16,910 --> 00:12:19,290
is because we're actually gonna delete that too.

229
00:12:19,290 --> 00:12:23,980
And we are going to use the user parser in there too.

230
00:12:23,980 --> 00:12:26,190
Just removing a bit of duplication is always

231
00:12:26,190 --> 00:12:28,020
a good idea to do that.

232
00:12:28,020 --> 00:12:31,720
Now we've got a single parser that is used to parse

233
00:12:31,720 --> 00:12:34,500
the arguments coming into the request.

234
00:12:34,500 --> 00:12:35,959
The way this works by the way is

235
00:12:35,959 --> 00:12:38,730
when you define the parser, you're not really

236
00:12:38,730 --> 00:12:41,170
getting any data from a request.

237
00:12:41,170 --> 00:12:45,690
All you're saying is, data coming in

238
00:12:45,690 --> 00:12:49,353
is going to have these two pieces of data inside it.

239
00:12:50,190 --> 00:12:53,313
When you are inside this post method,

240
00:12:54,630 --> 00:12:57,940
that means the fact that you're running this means

241
00:12:57,940 --> 00:13:02,120
that a user has sent you, by the way we don't need that,

242
00:13:02,120 --> 00:13:05,036
means that a user has sent you some data.

243
00:13:05,036 --> 00:13:06,557
The fact that you're running this means

244
00:13:06,557 --> 00:13:08,270
the user has sent you some data,

245
00:13:08,270 --> 00:13:11,450
so when you run user parser.parse args

246
00:13:11,450 --> 00:13:13,466
that's going to get that data

247
00:13:13,466 --> 00:13:17,660
that's come through the request and it's going to parse,

248
00:13:17,660 --> 00:13:20,620
and it's gonna try to see where the username and password

249
00:13:20,620 --> 00:13:22,170
are stored in the request.

250
00:13:22,170 --> 00:13:23,570
And it's going to get that data out

251
00:13:23,570 --> 00:13:25,523
and give it to you as a dictionary.

252
00:13:27,510 --> 00:13:29,180
Okay we don't need those things.

253
00:13:29,180 --> 00:13:32,793
Those were just artefacts from before.

254
00:13:34,230 --> 00:13:36,810
That's our user login Resource created.

255
00:13:36,810 --> 00:13:40,450
As you can see, it's very sort of Python code.

256
00:13:40,450 --> 00:13:44,150
It doesn't have any magical stuff.

257
00:13:44,150 --> 00:13:46,830
We parse the data, we find the user,

258
00:13:46,830 --> 00:13:48,200
then we compare the passwords

259
00:13:48,200 --> 00:13:50,750
and then we create our access token or refresh token.

260
00:13:50,750 --> 00:13:53,310
And everything happens here in this function.

261
00:13:53,310 --> 00:13:55,120
It doesn't happen all over the place like it did

262
00:13:55,120 --> 00:13:56,283
with Flask-JWT.

263
00:13:57,280 --> 00:13:59,573
Now we have to import a few things like safe string compare,

264
00:13:59,573 --> 00:14:01,930
create access token and create refresh token.

265
00:14:01,930 --> 00:14:03,500
So let's do that just now.

266
00:14:03,500 --> 00:14:07,270
We're gonna go here and from workzoig.security

267
00:14:09,660 --> 00:14:12,240
we're gonna import safe_str_cmp.

268
00:14:12,240 --> 00:14:15,500
And from Flask-JWT-Extended, we're gonna import

269
00:14:15,500 --> 00:14:19,999
create access token and create refresh token.

270
00:14:19,999 --> 00:14:22,835
Those things are coming from Flask-JWT-Extended

271
00:14:22,835 --> 00:14:27,835
and again we're able to do this in here

272
00:14:28,140 --> 00:14:30,460
and create a valid access token,

273
00:14:30,460 --> 00:14:34,940
because the Flask-JWT-Extended is linked to our app

274
00:14:34,940 --> 00:14:37,320
because of what we did up here.

275
00:14:37,320 --> 00:14:40,070
JWT's are gonna get some information from our app as well,

276
00:14:40,070 --> 00:14:41,360
when they're created.

277
00:14:41,360 --> 00:14:43,340
So that's always nice to do.

278
00:14:43,340 --> 00:14:45,100
Now going back to our app.py,

279
00:14:45,100 --> 00:14:47,820
we have to import the user login Resource of course

280
00:14:47,820 --> 00:14:48,960
and add it in.

281
00:14:48,960 --> 00:14:51,074
So we're gonna do api add Resource

282
00:14:51,074 --> 00:14:52,752
and we're gonna do user login

283
00:14:52,752 --> 00:14:56,020
and this is going to be login.

284
00:14:56,020 --> 00:14:57,307
Okay you can call this auth if you want,

285
00:14:57,307 --> 00:15:00,980
but I'm just gonna call it login to really hammer the point

286
00:15:00,980 --> 00:15:02,916
home that this is a different thing than

287
00:15:02,916 --> 00:15:05,683
Flask-JWT was okay?

288
00:15:07,230 --> 00:15:10,230
Also Flask-JWT comes with its own set of

289
00:15:10,230 --> 00:15:12,800
app.config settings.

290
00:15:12,800 --> 00:15:17,500
Instead of app.secretkey, here you can use if you want

291
00:15:17,500 --> 00:15:20,930
app.config JWT secret key

292
00:15:20,930 --> 00:15:25,930
because this value here jose is used to encrypt the JWT.

293
00:15:27,020 --> 00:15:31,060
So if you wanna keep your app's secretkey and

294
00:15:31,060 --> 00:15:35,030
your jwt secretkey different for security reasons,

295
00:15:35,030 --> 00:15:37,853
you can do that by setting this configuration property.

296
00:15:39,024 --> 00:15:44,024
Okay, now of course we have to do one last thing,

297
00:15:44,100 --> 00:15:46,430
which is modify our requirements.txt,

298
00:15:46,430 --> 00:15:50,463
instead of Flask-JWT, instal Flask-JWT-Extended.

299
00:15:51,520 --> 00:15:53,900
And if you open up your terminal,

300
00:15:53,900 --> 00:15:56,040
which I have open here,

301
00:15:56,040 --> 00:15:59,743
we're gonna do pip instal Flask-JWT-Extended.

302
00:16:01,720 --> 00:16:04,222
Alright, so they're installed in this virtual environment,

303
00:16:04,222 --> 00:16:06,890
but if you don't have it already installed,

304
00:16:06,890 --> 00:16:08,870
it would instal it for you.

305
00:16:08,870 --> 00:16:10,810
Now you should be able to run app.py

306
00:16:10,810 --> 00:16:14,953
and it won't tell you any errors.

307
00:16:16,640 --> 00:16:17,740
That's good.

308
00:16:17,740 --> 00:16:21,280
The last thing to do is to go over to our item Resource,

309
00:16:21,280 --> 00:16:23,360
which is the only other part of our code

310
00:16:23,360 --> 00:16:26,290
that used Flask-JWT up here

311
00:16:27,190 --> 00:16:31,000
and just change this to Flask-JWT-Extended.

312
00:16:31,000 --> 00:16:34,090
JWT required is still the same thing,

313
00:16:34,090 --> 00:16:38,790
except it's no longer decorated with arguments.

314
00:16:38,790 --> 00:16:41,880
So it doesn't need the function call at the end.

315
00:16:41,880 --> 00:16:42,713
That's important.

316
00:16:42,713 --> 00:16:46,424
If you import JWT required from Flask-JWT-Extended,

317
00:16:46,424 --> 00:16:49,220
make sure to use the decorator without

318
00:16:49,220 --> 00:16:50,563
the brackets at the end.

319
00:16:52,810 --> 00:16:54,410
And that's it, that's the only place

320
00:16:54,410 --> 00:16:57,006
where we were using Flask-JWT.

321
00:16:57,006 --> 00:17:02,006
In order still to run the get endpoint of the item Resource,

322
00:17:02,940 --> 00:17:06,260
we still need to provide an access token to JWT.

323
00:17:06,260 --> 00:17:08,420
Okay so that hasn't changed.

324
00:17:08,420 --> 00:17:12,140
Now you can try running your app and testing with Postman,

325
00:17:12,140 --> 00:17:14,480
but you're gonna find that it won't quite

326
00:17:14,480 --> 00:17:15,510
just work out of the box.

327
00:17:15,510 --> 00:17:16,948
There are a couple of more changes we have to make,

328
00:17:16,948 --> 00:17:19,360
so let's make them in the next video.

329
00:17:19,360 --> 00:17:20,310
I'll see you there.

