1
00:00:06,320 --> 00:00:11,499
[Music]

2
00:00:16,320 --> 00:00:20,880
good afternoon or other time of day as

3
00:00:18,720 --> 00:00:24,480
appropriate to your time zone everyone

4
00:00:20,880 --> 00:00:27,359
um welcome back to kaya theatre for the

5
00:00:24,480 --> 00:00:29,439
second half of saturday of linux

6
00:00:27,359 --> 00:00:32,000
conference um

7
00:00:29,439 --> 00:00:34,800
next up we have katie bell telling us

8
00:00:32,000 --> 00:00:36,880
about how to run python in the browser

9
00:00:34,800 --> 00:00:38,879
katie's 10 plus year career as a

10
00:00:36,880 --> 00:00:40,960
software engineer has been pretty darn

11
00:00:38,879 --> 00:00:43,440
fun you should read her full bio in the

12
00:00:40,960 --> 00:00:45,440
program because it's pretty cool

13
00:00:43,440 --> 00:00:47,520
fluent in several programming languages

14
00:00:45,440 --> 00:00:49,200
she's at home both in both the web

15
00:00:47,520 --> 00:00:50,719
browser and deep in the cloud she's been

16
00:00:49,200 --> 00:00:52,719
teaching programming to beginners for a

17
00:00:50,719 --> 00:00:54,239
long time and is now an instructor at

18
00:00:52,719 --> 00:00:56,320
general assembly

19
00:00:54,239 --> 00:00:58,719
after her talk katie will be taking

20
00:00:56,320 --> 00:01:00,559
questions so please put any questions

21
00:00:58,719 --> 00:01:04,239
you want me to read to katie at the end

22
00:01:00,559 --> 00:01:06,560
if there's time in the questions tab

23
00:01:04,239 --> 00:01:10,080
above the chat in venulis

24
00:01:06,560 --> 00:01:12,240
and uh over to you katie

25
00:01:10,080 --> 00:01:14,960
cool thank you so yes this talk is about

26
00:01:12,240 --> 00:01:17,360
how to run python in the browser

27
00:01:14,960 --> 00:01:19,680
and that title is actually a little bit

28
00:01:17,360 --> 00:01:22,320
misleading because actually running

29
00:01:19,680 --> 00:01:23,840
python in the browser is very easy so

30
00:01:22,320 --> 00:01:26,400
this talk is going to be basically

31
00:01:23,840 --> 00:01:28,400
structured as firstly an introduction

32
00:01:26,400 --> 00:01:30,159
to why we want to do this and what

33
00:01:28,400 --> 00:01:32,799
different approaches you can take we'll

34
00:01:30,159 --> 00:01:34,799
spend two minutes showing you the entire

35
00:01:32,799 --> 00:01:35,759
code for actually running python in the

36
00:01:34,799 --> 00:01:37,600
browser

37
00:01:35,759 --> 00:01:39,759
uh and then the rest of the talk is

38
00:01:37,600 --> 00:01:40,640
gonna be about making really basic

39
00:01:39,759 --> 00:01:43,040
things

40
00:01:40,640 --> 00:01:45,360
like standard input and standard output

41
00:01:43,040 --> 00:01:47,040
work in the browser so that's the vast

42
00:01:45,360 --> 00:01:50,159
majority of this talk actually running

43
00:01:47,040 --> 00:01:52,799
python in the browser is the easy part

44
00:01:50,159 --> 00:01:56,000
but let's start off with a little bit of

45
00:01:52,799 --> 00:01:58,799
why you would want to run python in the

46
00:01:56,000 --> 00:02:00,560
browser uh to which i ask you why not

47
00:01:58,799 --> 00:02:02,560
but possibly maybe you don't like

48
00:02:00,560 --> 00:02:03,759
javascript i don't mind javascript i

49
00:02:02,560 --> 00:02:05,920
write a lot of it

50
00:02:03,759 --> 00:02:07,200
um but if someone doesn't want to learn

51
00:02:05,920 --> 00:02:09,119
javascript and you would rather write

52
00:02:07,200 --> 00:02:11,599
python then sure let's make that run in

53
00:02:09,119 --> 00:02:14,319
the browser uh there might be some

54
00:02:11,599 --> 00:02:16,480
python libraries that you want to use in

55
00:02:14,319 --> 00:02:18,879
the browser or maybe

56
00:02:16,480 --> 00:02:20,720
you have python code on the server and

57
00:02:18,879 --> 00:02:23,760
you want to share it with the python

58
00:02:20,720 --> 00:02:24,640
code in the client

59
00:02:23,760 --> 00:02:25,680
or

60
00:02:24,640 --> 00:02:27,599
possibly

61
00:02:25,680 --> 00:02:30,640
you want someone to be able to write

62
00:02:27,599 --> 00:02:33,360
python and run python without having to

63
00:02:30,640 --> 00:02:35,200
install python on their own machine or

64
00:02:33,360 --> 00:02:37,200
set it up or install the libraries like

65
00:02:35,200 --> 00:02:40,000
you want it to be stupidly easy to like

66
00:02:37,200 --> 00:02:41,920
get started running python by just

67
00:02:40,000 --> 00:02:43,280
opening a browser window

68
00:02:41,920 --> 00:02:45,920
and in particular that's useful for

69
00:02:43,280 --> 00:02:48,160
something like a web ide

70
00:02:45,920 --> 00:02:49,200
where you can just open up a browser tab

71
00:02:48,160 --> 00:02:50,560
and have your full development

72
00:02:49,200 --> 00:02:51,760
environment you could share code with

73
00:02:50,560 --> 00:02:52,879
other people because it's some kind of

74
00:02:51,760 --> 00:02:55,040
web service

75
00:02:52,879 --> 00:02:57,040
and this is particularly useful for

76
00:02:55,040 --> 00:02:59,519
education purposes where you might have

77
00:02:57,040 --> 00:03:01,120
like a tiny web ide that lets you learn

78
00:02:59,519 --> 00:03:03,760
python without having to go through the

79
00:03:01,120 --> 00:03:05,840
process of like using like installing an

80
00:03:03,760 --> 00:03:08,239
ide and setting everything up

81
00:03:05,840 --> 00:03:10,720
uh so for my own purposes i've been

82
00:03:08,239 --> 00:03:13,440
working on a project called split code

83
00:03:10,720 --> 00:03:15,440
uh which is an in-browser ide with a

84
00:03:13,440 --> 00:03:17,200
graphical uh structured programming

85
00:03:15,440 --> 00:03:18,800
language and in order to be able to

86
00:03:17,200 --> 00:03:20,480
write python code with this language and

87
00:03:18,800 --> 00:03:23,360
run python code i needed to be able to

88
00:03:20,480 --> 00:03:24,080
run python in the browser

89
00:03:23,360 --> 00:03:26,080
so

90
00:03:24,080 --> 00:03:27,920
to run python in the browser or have

91
00:03:26,080 --> 00:03:30,480
some kind of python environment running

92
00:03:27,920 --> 00:03:32,560
in the browser there are three sort of

93
00:03:30,480 --> 00:03:34,000
categories of ways that you can approach

94
00:03:32,560 --> 00:03:36,000
this problem

95
00:03:34,000 --> 00:03:37,599
uh the first one running python on the

96
00:03:36,000 --> 00:03:39,120
server we're not really going to talk

97
00:03:37,599 --> 00:03:41,519
about much today because this is a talk

98
00:03:39,120 --> 00:03:43,840
about running python in the browser

99
00:03:41,519 --> 00:03:45,599
but if you see a kind of a python

100
00:03:43,840 --> 00:03:48,000
interface or a way to run python code

101
00:03:45,599 --> 00:03:50,239
through some kind of website like replit

102
00:03:48,000 --> 00:03:52,480
or python anywhere uh it's not running

103
00:03:50,239 --> 00:03:55,040
python in the browser it is running that

104
00:03:52,480 --> 00:03:57,280
instance of python on some kind of

105
00:03:55,040 --> 00:03:59,680
uh sandbox environment on a server

106
00:03:57,280 --> 00:04:01,920
somewhere and it's connecting to it uh

107
00:03:59,680 --> 00:04:04,400
via a websocket probably

108
00:04:01,920 --> 00:04:06,080
and so you can have a beautiful you know

109
00:04:04,400 --> 00:04:07,360
python environment with the python code

110
00:04:06,080 --> 00:04:09,439
actually running on the server and not

111
00:04:07,360 --> 00:04:12,400
in the uh browser and that works well

112
00:04:09,439 --> 00:04:14,319
for some kind of cloud ide thing

113
00:04:12,400 --> 00:04:15,920
um but that's not what i wanted to do

114
00:04:14,319 --> 00:04:17,759
because i wanted the

115
00:04:15,920 --> 00:04:19,919
python to be a lot more tightly

116
00:04:17,759 --> 00:04:21,680
integrated within the browser

117
00:04:19,919 --> 00:04:23,680
environment that i was using

118
00:04:21,680 --> 00:04:25,759
and it didn't exactly serve my purposes

119
00:04:23,680 --> 00:04:27,199
also if you provide that kind of service

120
00:04:25,759 --> 00:04:28,639
you have to pay for all of the compute

121
00:04:27,199 --> 00:04:30,000
power to run that python and it's

122
00:04:28,639 --> 00:04:31,600
expensive to run the service if you want

123
00:04:30,000 --> 00:04:33,280
to provide the service for free it's a

124
00:04:31,600 --> 00:04:34,479
lot easier if people are running python

125
00:04:33,280 --> 00:04:36,320
on their own machine in their own

126
00:04:34,479 --> 00:04:37,120
browser

127
00:04:36,320 --> 00:04:40,160
so

128
00:04:37,120 --> 00:04:41,600
the second option is to instead of

129
00:04:40,160 --> 00:04:43,360
sort of taking python and putting it in

130
00:04:41,600 --> 00:04:45,759
the browser you build a version of

131
00:04:43,360 --> 00:04:49,840
python that is specifically designed to

132
00:04:45,759 --> 00:04:52,320
work with javascript uh in the browser

133
00:04:49,840 --> 00:04:54,320
and it's not uncommon to have like

134
00:04:52,320 --> 00:04:56,240
multiple versions of the python

135
00:04:54,320 --> 00:04:57,840
interpreter so there are different

136
00:04:56,240 --> 00:05:00,080
pipeline python implementations that are

137
00:04:57,840 --> 00:05:02,639
designed to run in different contexts or

138
00:05:00,080 --> 00:05:05,360
have different purposes uh see python

139
00:05:02,639 --> 00:05:07,440
being the reference implementation for

140
00:05:05,360 --> 00:05:09,680
python the language so

141
00:05:07,440 --> 00:05:12,080
pi pi iron python jython micropython

142
00:05:09,680 --> 00:05:14,400
they are other implementations that have

143
00:05:12,080 --> 00:05:16,479
mostly started from scratch to implement

144
00:05:14,400 --> 00:05:19,840
python

145
00:05:16,479 --> 00:05:22,160
and these implementations take a lot of

146
00:05:19,840 --> 00:05:24,720
time and energy to keep up to date

147
00:05:22,160 --> 00:05:26,479
whenever the python language releases a

148
00:05:24,720 --> 00:05:28,479
new part of the standard library or

149
00:05:26,479 --> 00:05:30,320
whenever there's a new language feature

150
00:05:28,479 --> 00:05:32,960
each one of these implementations has to

151
00:05:30,320 --> 00:05:35,759
do the work to implement that feature so

152
00:05:32,960 --> 00:05:36,880
they do tend to lag behind the latest

153
00:05:35,759 --> 00:05:38,800
versions

154
00:05:36,880 --> 00:05:40,320
of the python language

155
00:05:38,800 --> 00:05:42,880
just because it takes a lot of effort to

156
00:05:40,320 --> 00:05:44,320
maintain and some of these projects are

157
00:05:42,880 --> 00:05:45,840
largely uh

158
00:05:44,320 --> 00:05:47,600
behind now

159
00:05:45,840 --> 00:05:50,560
uh there are three

160
00:05:47,600 --> 00:05:52,479
implementations of python in javascript

161
00:05:50,560 --> 00:05:56,000
already these are the three that i found

162
00:05:52,479 --> 00:05:58,960
that are still actively maintained uh so

163
00:05:56,000 --> 00:06:02,000
transcript brighton and sculpt

164
00:05:58,960 --> 00:06:02,880
transcript is very much a tool designed

165
00:06:02,000 --> 00:06:05,039
for

166
00:06:02,880 --> 00:06:07,440
someone who wants to write python syntax

167
00:06:05,039 --> 00:06:09,120
but really they're writing javascript

168
00:06:07,440 --> 00:06:10,880
you don't really have a lot of the

169
00:06:09,120 --> 00:06:13,600
python standard library you're expected

170
00:06:10,880 --> 00:06:15,280
to just use javascript functions

171
00:06:13,600 --> 00:06:17,360
javascript functions are just available

172
00:06:15,280 --> 00:06:18,880
in the global namespace for you to use

173
00:06:17,360 --> 00:06:21,759
and things like

174
00:06:18,880 --> 00:06:24,000
using python style truthiness versus

175
00:06:21,759 --> 00:06:27,039
javascript style truthiness on your if

176
00:06:24,000 --> 00:06:28,639
statements is an optional flag that

177
00:06:27,039 --> 00:06:30,479
increases the size of the javascript

178
00:06:28,639 --> 00:06:32,880
that's generated from it so it takes

179
00:06:30,479 --> 00:06:35,520
python generates javascript from it um

180
00:06:32,880 --> 00:06:38,479
brython also takes python and sort of

181
00:06:35,520 --> 00:06:41,520
transpiles it into javascript uh as well

182
00:06:38,479 --> 00:06:44,240
but it has a lot more emphasis on a sort

183
00:06:41,520 --> 00:06:45,600
of true implementation of python and a

184
00:06:44,240 --> 00:06:47,680
full and complete implementation of

185
00:06:45,600 --> 00:06:49,919
python it has a surprisingly

186
00:06:47,680 --> 00:06:52,240
large proportion of the standard library

187
00:06:49,919 --> 00:06:53,520
implemented um with obvious exceptions

188
00:06:52,240 --> 00:06:54,560
for things that don't work well in a

189
00:06:53,520 --> 00:06:57,199
browser

190
00:06:54,560 --> 00:06:59,680
it even lets you import and use

191
00:06:57,199 --> 00:07:02,639
pip packages that are

192
00:06:59,680 --> 00:07:05,199
native python code that are pure python

193
00:07:02,639 --> 00:07:06,560
code and not you know native c modules

194
00:07:05,199 --> 00:07:08,319
uh so you can do a surprising amount of

195
00:07:06,560 --> 00:07:10,160
python that is probably the one i would

196
00:07:08,319 --> 00:07:13,199
use if you wanted to

197
00:07:10,160 --> 00:07:14,080
have um a transpiled version of python

198
00:07:13,199 --> 00:07:16,800
that

199
00:07:14,080 --> 00:07:18,160
very closely matches uh what c python

200
00:07:16,800 --> 00:07:20,639
would do in pretty much every

201
00:07:18,160 --> 00:07:22,479
circumstance you could use it to uh

202
00:07:20,639 --> 00:07:24,240
share code between the client and server

203
00:07:22,479 --> 00:07:26,800
its primary purpose though is to replace

204
00:07:24,240 --> 00:07:29,120
javascript for the language that you can

205
00:07:26,800 --> 00:07:32,000
build web apps in you can use react with

206
00:07:29,120 --> 00:07:33,840
bryton you can build uis it's focused on

207
00:07:32,000 --> 00:07:36,720
uis manipulating the dom sort of

208
00:07:33,840 --> 00:07:38,720
fulfilling that purpose of javascript uh

209
00:07:36,720 --> 00:07:41,440
but with python instead

210
00:07:38,720 --> 00:07:43,680
and it is kept up to date uh

211
00:07:41,440 --> 00:07:44,960
and actively maintained and kept in line

212
00:07:43,680 --> 00:07:46,080
with the latest versions of python which

213
00:07:44,960 --> 00:07:47,840
is really cool

214
00:07:46,080 --> 00:07:50,240
uh sculpt you'll find as well is still

215
00:07:47,840 --> 00:07:51,520
maintained although they don't seem to

216
00:07:50,240 --> 00:07:53,599
be putting a lot

217
00:07:51,520 --> 00:07:56,319
of um

218
00:07:53,599 --> 00:07:58,240
time into it uh it's still used it's

219
00:07:56,319 --> 00:07:58,960
used by educational institutions mostly

220
00:07:58,240 --> 00:08:01,039
and

221
00:07:58,960 --> 00:08:03,599
uh its particular feature is that it has

222
00:08:01,039 --> 00:08:06,319
like python total support so you can do

223
00:08:03,599 --> 00:08:08,240
uh logo total graphics and stuff uh in

224
00:08:06,319 --> 00:08:10,080
the browser using sculpt but it has a

225
00:08:08,240 --> 00:08:12,560
bit of a different focus because it's

226
00:08:10,080 --> 00:08:14,960
not designed to be a you know a full

227
00:08:12,560 --> 00:08:17,199
python implementation

228
00:08:14,960 --> 00:08:20,160
uh so for bryton uh the way that it

229
00:08:17,199 --> 00:08:23,120
works is it takes your python code and

230
00:08:20,160 --> 00:08:25,440
transpiles it into somewhat lengthy uh

231
00:08:23,120 --> 00:08:28,319
javascript code um because it needs that

232
00:08:25,440 --> 00:08:29,360
much work to be able to accurately

233
00:08:28,319 --> 00:08:31,520
execute

234
00:08:29,360 --> 00:08:33,200
python code in a way that is consistent

235
00:08:31,520 --> 00:08:35,680
with the way that it would work in the

236
00:08:33,200 --> 00:08:37,039
python language spec

237
00:08:35,680 --> 00:08:38,640
so python is actually a pretty good

238
00:08:37,039 --> 00:08:39,680
choice if you want to run python in the

239
00:08:38,640 --> 00:08:40,560
browser

240
00:08:39,680 --> 00:08:43,279
but it's not the one we're going to

241
00:08:40,560 --> 00:08:46,320
focus on today uh because uh we're

242
00:08:43,279 --> 00:08:49,680
focusing on the approach that i decided

243
00:08:46,320 --> 00:08:51,360
to take uh which is compiling c python

244
00:08:49,680 --> 00:08:52,320
so the reference implementation of

245
00:08:51,360 --> 00:08:54,399
python

246
00:08:52,320 --> 00:08:56,800
into webassembly and just straight up

247
00:08:54,399 --> 00:08:59,120
running that in the browser

248
00:08:56,800 --> 00:09:02,240
so to introduce this uh we need to talk

249
00:08:59,120 --> 00:09:04,080
a little bit about web assembly and what

250
00:09:02,240 --> 00:09:06,160
web assembly is

251
00:09:04,080 --> 00:09:08,560
um a browser essentially supports

252
00:09:06,160 --> 00:09:10,800
running two kinds of code it runs

253
00:09:08,560 --> 00:09:13,120
javascript and it also runs

254
00:09:10,800 --> 00:09:14,959
webassembly binaries or webassembly

255
00:09:13,120 --> 00:09:17,279
instructions

256
00:09:14,959 --> 00:09:20,399
as an example you can take other

257
00:09:17,279 --> 00:09:23,680
languages in this case we have a

258
00:09:20,399 --> 00:09:26,080
little c function that checks if a

259
00:09:23,680 --> 00:09:29,519
number is a prime number or not

260
00:09:26,080 --> 00:09:31,680
and what we can do is compile that c

261
00:09:29,519 --> 00:09:34,480
function into webassembly and it might

262
00:09:31,680 --> 00:09:36,560
look like this if you lay it out in

263
00:09:34,480 --> 00:09:37,920
text form this is mostly for debugging

264
00:09:36,560 --> 00:09:39,519
purposes you wouldn't really use this

265
00:09:37,920 --> 00:09:41,600
text form you wouldn't write this text

266
00:09:39,519 --> 00:09:45,120
form just helps you see

267
00:09:41,600 --> 00:09:47,760
what instructions uh the webassembly

268
00:09:45,120 --> 00:09:49,040
runtime has available to it

269
00:09:47,760 --> 00:09:52,399
but more often

270
00:09:49,040 --> 00:09:55,120
you would compile it into a binary form

271
00:09:52,399 --> 00:09:56,399
or you can even include it as an array

272
00:09:55,120 --> 00:09:58,240
of bytes

273
00:09:56,399 --> 00:10:00,959
in your javascript code

274
00:09:58,240 --> 00:10:03,120
and straight up run that so if you want

275
00:10:00,959 --> 00:10:05,680
to play around with this and get an idea

276
00:10:03,120 --> 00:10:06,480
of what uh webassembly is like to work

277
00:10:05,680 --> 00:10:09,279
with

278
00:10:06,480 --> 00:10:10,880
from a development perspective uh i

279
00:10:09,279 --> 00:10:14,079
would highly recommend

280
00:10:10,880 --> 00:10:16,079
uh wasm fiddle

281
00:10:14,079 --> 00:10:18,640
uh wasn't fiddle so this is what i've

282
00:10:16,079 --> 00:10:20,399
used to like write a little c function

283
00:10:18,640 --> 00:10:22,160
which is the is prime function

284
00:10:20,399 --> 00:10:24,560
uh you can build it

285
00:10:22,160 --> 00:10:26,800
uh and it generates uh you can download

286
00:10:24,560 --> 00:10:30,399
the binary file or you can see the code

287
00:10:26,800 --> 00:10:31,360
here in binary or text format

288
00:10:30,399 --> 00:10:33,760
and

289
00:10:31,360 --> 00:10:35,360
uh you can and here is some javascript

290
00:10:33,760 --> 00:10:38,720
code which

291
00:10:35,360 --> 00:10:40,880
loads the webassembly module and

292
00:10:38,720 --> 00:10:43,440
accesses the is prime function to run it

293
00:10:40,880 --> 00:10:45,120
and call it uh so if i run this it tells

294
00:10:43,440 --> 00:10:46,399
me one as a prime number oh sorry it's

295
00:10:45,120 --> 00:10:48,320
not a prime number

296
00:10:46,399 --> 00:10:51,360
uh 2 is prime

297
00:10:48,320 --> 00:10:53,839
7 907 is prime

298
00:10:51,360 --> 00:10:55,279
um and so we can build

299
00:10:53,839 --> 00:10:56,720
a c function

300
00:10:55,279 --> 00:10:57,920
compile it into webassembly and then

301
00:10:56,720 --> 00:11:00,399
just call it

302
00:10:57,920 --> 00:11:02,399
from javascript and it's running

303
00:11:00,399 --> 00:11:04,959
in the same javascript

304
00:11:02,399 --> 00:11:07,200
thread in the browser

305
00:11:04,959 --> 00:11:08,079
so that's a fairly quick introduction to

306
00:11:07,200 --> 00:11:10,480
what

307
00:11:08,079 --> 00:11:12,160
webassembly is

308
00:11:10,480 --> 00:11:15,200
but we want to use this

309
00:11:12,160 --> 00:11:16,880
to run python in the browser

310
00:11:15,200 --> 00:11:18,880
so what i originally thought i would

311
00:11:16,880 --> 00:11:20,480
have to do uh would be to check out the

312
00:11:18,880 --> 00:11:22,880
c python source code

313
00:11:20,480 --> 00:11:25,600
and use a tool called m scriptin which

314
00:11:22,880 --> 00:11:29,040
is a tool for compiling c code and other

315
00:11:25,600 --> 00:11:31,920
languages that are llvm compatible uh

316
00:11:29,040 --> 00:11:34,480
into webassembly uh you probably need to

317
00:11:31,920 --> 00:11:36,399
patch some things or modify some things

318
00:11:34,480 --> 00:11:38,560
to get it to fully work in emscripton

319
00:11:36,399 --> 00:11:40,959
get it to compile and then you have

320
00:11:38,560 --> 00:11:43,519
a webassembly binary that you can run in

321
00:11:40,959 --> 00:11:45,360
the browser now this is a long process

322
00:11:43,519 --> 00:11:47,360
unfortunately you can actually just use

323
00:11:45,360 --> 00:11:51,120
one that someone else has made

324
00:11:47,360 --> 00:11:52,720
so shout out to the piodide project

325
00:11:51,120 --> 00:11:55,200
this originally started as just one

326
00:11:52,720 --> 00:11:57,760
piece of the iodide project

327
00:11:55,200 --> 00:12:00,079
and iodide is kind of jupyter notebooks

328
00:11:57,760 --> 00:12:02,720
but for the browser a tool for doing

329
00:12:00,079 --> 00:12:05,279
data science uh in the browser and as

330
00:12:02,720 --> 00:12:07,680
part of that it needed to run python

331
00:12:05,279 --> 00:12:09,839
iodide is now its own project was just

332
00:12:07,680 --> 00:12:12,720
focused around python but it does have a

333
00:12:09,839 --> 00:12:15,440
very strong focus on data science so

334
00:12:12,720 --> 00:12:18,880
numpy and scipy and like common data

335
00:12:15,440 --> 00:12:22,320
science libraries are ported to iodide

336
00:12:18,880 --> 00:12:24,880
and are usable from pyodide as well

337
00:12:22,320 --> 00:12:27,360
so the way that iodide works

338
00:12:24,880 --> 00:12:30,079
it starts with the official c python

339
00:12:27,360 --> 00:12:32,800
code applies a couple of patches add

340
00:12:30,079 --> 00:12:35,279
some little uh utilities for interfacing

341
00:12:32,800 --> 00:12:36,720
with javascript um and interfacing with

342
00:12:35,279 --> 00:12:38,720
the browser environment a couple of

343
00:12:36,720 --> 00:12:40,320
extra c files

344
00:12:38,720 --> 00:12:43,040
it compiles it with

345
00:12:40,320 --> 00:12:44,160
amscriptan uh and generates a web

346
00:12:43,040 --> 00:12:47,360
assembly

347
00:12:44,160 --> 00:12:49,200
and then has a javascript wrapper around

348
00:12:47,360 --> 00:12:52,560
that webassembly that makes it very easy

349
00:12:49,200 --> 00:12:54,000
to access and use uh which is really

350
00:12:52,560 --> 00:12:57,120
cool

351
00:12:54,000 --> 00:12:59,440
so this is how pyrodine works uh and so

352
00:12:57,120 --> 00:13:01,040
if we wanted to summarize my entire talk

353
00:12:59,440 --> 00:13:04,160
uh this is how to run python in the

354
00:13:01,040 --> 00:13:05,440
browser uh this is the entire code that

355
00:13:04,160 --> 00:13:07,440
you would need

356
00:13:05,440 --> 00:13:10,160
most of this is just sort of html

357
00:13:07,440 --> 00:13:11,360
boilerplate stuff so if we zoom in

358
00:13:10,160 --> 00:13:13,519
um

359
00:13:11,360 --> 00:13:14,959
iodide has a couple of javascript

360
00:13:13,519 --> 00:13:19,440
functions to

361
00:13:14,959 --> 00:13:23,279
load the piodide webassembly binary

362
00:13:19,440 --> 00:13:24,959
and run python just by passing in

363
00:13:23,279 --> 00:13:26,480
a string

364
00:13:24,959 --> 00:13:28,320
so let's see that

365
00:13:26,480 --> 00:13:30,720
working

366
00:13:28,320 --> 00:13:32,639
go to the next demo uh so this is the pi

367
00:13:30,720 --> 00:13:34,880
di test page this is exactly the same

368
00:13:32,639 --> 00:13:36,639
code that i showed you in the slides i

369
00:13:34,880 --> 00:13:38,160
copied it pasted it from the slides

370
00:13:36,639 --> 00:13:39,040
rather than the other way around

371
00:13:38,160 --> 00:13:40,959
um

372
00:13:39,040 --> 00:13:42,880
but if i refresh this

373
00:13:40,959 --> 00:13:45,360
it loads python

374
00:13:42,880 --> 00:13:48,639
and it prints out the sort of version

375
00:13:45,360 --> 00:13:51,519
info and then prints out the number 42.

376
00:13:48,639 --> 00:13:53,440
uh if we go back to code we can see that

377
00:13:51,519 --> 00:13:55,360
it does import this from the standard

378
00:13:53,440 --> 00:13:57,760
library prints out the version and

379
00:13:55,360 --> 00:13:59,199
prints out the result of 40 plus 2 which

380
00:13:57,760 --> 00:14:01,040
is 42.

381
00:13:59,199 --> 00:14:03,120
so we now have

382
00:14:01,040 --> 00:14:06,240
with just a tiny bit of work

383
00:14:03,120 --> 00:14:08,639
uh run python

384
00:14:06,240 --> 00:14:10,959
in the browser done end of talk

385
00:14:08,639 --> 00:14:13,199
uh we have now successfully run python

386
00:14:10,959 --> 00:14:14,720
in the browser so that was the that was

387
00:14:13,199 --> 00:14:15,600
the easy part

388
00:14:14,720 --> 00:14:18,399
uh

389
00:14:15,600 --> 00:14:19,199
we need to integrate this into the rest

390
00:14:18,399 --> 00:14:22,800
of

391
00:14:19,199 --> 00:14:25,839
javascript uh because we want a ui that

392
00:14:22,800 --> 00:14:28,079
lets us write python run python and see

393
00:14:25,839 --> 00:14:29,519
the output and and stuff like that from

394
00:14:28,079 --> 00:14:32,320
python and this is

395
00:14:29,519 --> 00:14:34,079
the hard part of the talk this uh code

396
00:14:32,320 --> 00:14:36,560
for running python you can basically

397
00:14:34,079 --> 00:14:38,720
pull straight from the piodide getting

398
00:14:36,560 --> 00:14:39,920
started guide uh on the piodi

399
00:14:38,720 --> 00:14:41,600
documentation

400
00:14:39,920 --> 00:14:44,000
so actually getting running

401
00:14:41,600 --> 00:14:45,920
python in the browser uh very very

402
00:14:44,000 --> 00:14:47,600
simple

403
00:14:45,920 --> 00:14:48,959
uh and it is a

404
00:14:47,600 --> 00:14:50,959
like

405
00:14:48,959 --> 00:14:53,199
straight port of c python uh it's not

406
00:14:50,959 --> 00:14:56,320
its own thing

407
00:14:53,199 --> 00:14:59,920
okay so building building a ui uh is a

408
00:14:56,320 --> 00:15:02,240
bit trickier and we needed to have a

409
00:14:59,920 --> 00:15:04,079
kind of terminal where we could see the

410
00:15:02,240 --> 00:15:04,800
output uh and have it sort of printed

411
00:15:04,079 --> 00:15:07,440
out

412
00:15:04,800 --> 00:15:09,920
so i used uh xterm

413
00:15:07,440 --> 00:15:12,160
which is the same terminal library that

414
00:15:09,920 --> 00:15:15,120
vs code uses if you see a terminal in a

415
00:15:12,160 --> 00:15:16,639
web page it's probably xterm js

416
00:15:15,120 --> 00:15:19,360
then

417
00:15:16,639 --> 00:15:21,680
so i have not shown all of the the work

418
00:15:19,360 --> 00:15:23,760
that went into making the terminal

419
00:15:21,680 --> 00:15:27,199
vaguely usable which was a surprising

420
00:15:23,760 --> 00:15:30,399
amount of work uh but here we have when

421
00:15:27,199 --> 00:15:32,639
we load piodide we can hook up

422
00:15:30,399 --> 00:15:34,800
javascript functions for standard out

423
00:15:32,639 --> 00:15:36,880
and standard error so that when

424
00:15:34,800 --> 00:15:39,199
something in the python code writes to

425
00:15:36,880 --> 00:15:40,959
standard out it will call this function

426
00:15:39,199 --> 00:15:43,120
with the string that has been written to

427
00:15:40,959 --> 00:15:44,720
stand it out or standard error

428
00:15:43,120 --> 00:15:47,440
aside from that we just need a little

429
00:15:44,720 --> 00:15:49,839
bit of javascript code that has a button

430
00:15:47,440 --> 00:15:51,839
when the button is clicked it pulls the

431
00:15:49,839 --> 00:15:53,600
code and runs it so this will make a bit

432
00:15:51,839 --> 00:15:55,279
more sense if we can see

433
00:15:53,600 --> 00:15:56,959
the ui

434
00:15:55,279 --> 00:15:59,199
so we have a text area

435
00:15:56,959 --> 00:16:01,600
and a terminal and so

436
00:15:59,199 --> 00:16:03,759
the text area is where we write the code

437
00:16:01,600 --> 00:16:05,440
when we click the run button it grabs

438
00:16:03,759 --> 00:16:08,000
the code from the text area and throws

439
00:16:05,440 --> 00:16:10,720
it into iodide so this code is

440
00:16:08,000 --> 00:16:12,800
simplified in the slides but it's really

441
00:16:10,720 --> 00:16:14,480
not that much more complicated than that

442
00:16:12,800 --> 00:16:16,160
so i have a text box here i can write

443
00:16:14,480 --> 00:16:17,519
whoops

444
00:16:16,160 --> 00:16:21,000
print

445
00:16:17,519 --> 00:16:21,000
hello world

446
00:16:22,480 --> 00:16:27,680
i hit run and it says hello world sweet

447
00:16:25,600 --> 00:16:29,440
we now have uh standard out from our

448
00:16:27,680 --> 00:16:31,360
python running in the browser

449
00:16:29,440 --> 00:16:32,639
uh if you want to try this and we have

450
00:16:31,360 --> 00:16:34,720
things like

451
00:16:32,639 --> 00:16:36,639
the standard libraries if we want if we

452
00:16:34,720 --> 00:16:37,680
want to import random

453
00:16:36,639 --> 00:16:39,600
we can

454
00:16:37,680 --> 00:16:41,199
generate a bunch of random numbers using

455
00:16:39,600 --> 00:16:42,720
the random library

456
00:16:41,199 --> 00:16:45,600
if we want to use

457
00:16:42,720 --> 00:16:48,079
some some of the other python libraries

458
00:16:45,600 --> 00:16:51,040
like the ast module i can use the asd

459
00:16:48,079 --> 00:16:53,920
module to pass some python code and

460
00:16:51,040 --> 00:16:56,000
dump out the ast of that python code you

461
00:16:53,920 --> 00:16:56,959
can write functions and run functions

462
00:16:56,000 --> 00:16:59,839
and

463
00:16:56,959 --> 00:17:02,320
all kinds of things it's a just

464
00:16:59,839 --> 00:17:04,480
straight up c python port

465
00:17:02,320 --> 00:17:06,240
if you try to do things like make

466
00:17:04,480 --> 00:17:07,839
requests to

467
00:17:06,240 --> 00:17:08,880
using sockets you might have a bit more

468
00:17:07,839 --> 00:17:11,039
of a problem

469
00:17:08,880 --> 00:17:13,280
um or things that are not

470
00:17:11,039 --> 00:17:15,600
super supported by the browser

471
00:17:13,280 --> 00:17:19,120
but for generally what you want to do it

472
00:17:15,600 --> 00:17:21,199
just does work and

473
00:17:19,120 --> 00:17:22,799
oops

474
00:17:21,199 --> 00:17:25,760
just does work

475
00:17:22,799 --> 00:17:27,760
uh it even has a file system which i can

476
00:17:25,760 --> 00:17:30,000
show you so i have a little bit of

477
00:17:27,760 --> 00:17:34,880
example code here where

478
00:17:30,000 --> 00:17:37,840
we uh write to a file uh and then

479
00:17:34,880 --> 00:17:39,760
read from that file again so uh

480
00:17:37,840 --> 00:17:41,919
reasonably simple like it opens a file

481
00:17:39,760 --> 00:17:43,679
it writes hello this is a file uh and

482
00:17:41,919 --> 00:17:46,559
then it opens the file again to read

483
00:17:43,679 --> 00:17:48,080
from it and prints out line by line

484
00:17:46,559 --> 00:17:49,520
and if you're wondering

485
00:17:48,080 --> 00:17:51,600
wait a minute browsers don't have access

486
00:17:49,520 --> 00:17:53,039
to the file system uh you would be

487
00:17:51,600 --> 00:17:55,919
absolutely right

488
00:17:53,039 --> 00:17:57,039
the file system is kind of supplied as

489
00:17:55,919 --> 00:18:00,080
part of

490
00:17:57,039 --> 00:18:01,760
m scriptin when m scriptin uh sees that

491
00:18:00,080 --> 00:18:04,720
you're accessing the file system in the

492
00:18:01,760 --> 00:18:06,480
c code it will bundle in its own uh file

493
00:18:04,720 --> 00:18:08,559
system implementation

494
00:18:06,480 --> 00:18:10,880
uh under libsy

495
00:18:08,559 --> 00:18:12,720
so emscripton during the compile process

496
00:18:10,880 --> 00:18:14,240
goes oh python has access to the file

497
00:18:12,720 --> 00:18:17,360
system has code that accesses the file

498
00:18:14,240 --> 00:18:19,600
system uh it will sub in its own

499
00:18:17,360 --> 00:18:22,320
in-memory file system there are options

500
00:18:19,600 --> 00:18:24,640
in enscriptum to use like the

501
00:18:22,320 --> 00:18:26,400
browser local storage or browser

502
00:18:24,640 --> 00:18:28,559
indexeddb to store things in the file

503
00:18:26,400 --> 00:18:29,919
system uh the only rule is it has to be

504
00:18:28,559 --> 00:18:32,160
synchronous

505
00:18:29,919 --> 00:18:34,080
uh it cannot sort of asynchronously

506
00:18:32,160 --> 00:18:35,840
start writing to the file system and

507
00:18:34,080 --> 00:18:38,640
then like wait for it in the javascript

508
00:18:35,840 --> 00:18:42,400
land uh it has to synchronously write

509
00:18:38,640 --> 00:18:45,520
and read from the file system

510
00:18:42,400 --> 00:18:46,480
oops uh emscripten kind of subs out the

511
00:18:45,520 --> 00:18:48,480
things that

512
00:18:46,480 --> 00:18:51,360
your c code might normally get from the

513
00:18:48,480 --> 00:18:53,440
operating system uh inscription supports

514
00:18:51,360 --> 00:18:56,320
uh replacements for those depending on

515
00:18:53,440 --> 00:18:59,440
what c libraries you're using so it

516
00:18:56,320 --> 00:19:01,840
supplies this fake in-memory file system

517
00:18:59,440 --> 00:19:03,679
uh it supplies overreads for uh standard

518
00:19:01,840 --> 00:19:05,919
and standard out standard error uh it

519
00:19:03,679 --> 00:19:08,640
has a sockets implementation you have to

520
00:19:05,919 --> 00:19:11,120
turn on which uses a proxy server and a

521
00:19:08,640 --> 00:19:13,280
web socket to kind of get past

522
00:19:11,120 --> 00:19:14,720
the browser implementation i haven't

523
00:19:13,280 --> 00:19:17,120
seen anyone actually using the sockets

524
00:19:14,720 --> 00:19:18,160
implementation in anger

525
00:19:17,120 --> 00:19:19,919
it has

526
00:19:18,160 --> 00:19:21,760
bindings for sdl so you can use keyboard

527
00:19:19,919 --> 00:19:25,039
and mouse input and joysticks and stuff

528
00:19:21,760 --> 00:19:28,160
and you can draw to a canvas uh using

529
00:19:25,039 --> 00:19:29,360
webgl uh through like the opengl uh

530
00:19:28,160 --> 00:19:31,919
libraries and

531
00:19:29,360 --> 00:19:33,760
so emscripton supplies like a lot of the

532
00:19:31,919 --> 00:19:35,840
bindings that you would need to sort of

533
00:19:33,760 --> 00:19:38,080
run applications that would normally be

534
00:19:35,840 --> 00:19:40,720
interfacing with the operating system

535
00:19:38,080 --> 00:19:42,240
for raw c code that does not interface

536
00:19:40,720 --> 00:19:44,880
with the operating system uh it should

537
00:19:42,240 --> 00:19:47,600
just work uh but the uh the ports are

538
00:19:44,880 --> 00:19:49,919
needed for everything else

539
00:19:47,600 --> 00:19:51,360
so we have two problems freezing the ui

540
00:19:49,919 --> 00:19:53,280
and blocking on students so let me demo

541
00:19:51,360 --> 00:19:54,720
those problems before we uh before we

542
00:19:53,280 --> 00:19:57,280
start to fix them

543
00:19:54,720 --> 00:19:59,919
uh if i write some code

544
00:19:57,280 --> 00:20:00,640
which takes quite a while to run so here

545
00:19:59,919 --> 00:20:02,960
is

546
00:20:00,640 --> 00:20:04,880
just some python code that counts from 0

547
00:20:02,960 --> 00:20:06,320
to 10 million

548
00:20:04,880 --> 00:20:08,000
it doesn't print out too much because i

549
00:20:06,320 --> 00:20:09,840
found that this was actually the like

550
00:20:08,000 --> 00:20:12,400
printing to the the terminal was the the

551
00:20:09,840 --> 00:20:13,760
slow part of this um but if i run this

552
00:20:12,400 --> 00:20:16,320
code

553
00:20:13,760 --> 00:20:18,400
it just kind of freezes the ui for a

554
00:20:16,320 --> 00:20:19,840
couple of seconds like if we see that

555
00:20:18,400 --> 00:20:21,840
again like normally i can select this

556
00:20:19,840 --> 00:20:24,000
text i could edit the text i can use

557
00:20:21,840 --> 00:20:25,760
these buttons but while the code is

558
00:20:24,000 --> 00:20:27,679
running the buttons are unresponsive the

559
00:20:25,760 --> 00:20:29,760
text is unresponsive

560
00:20:27,679 --> 00:20:32,559
if you accidentally do a

561
00:20:29,760 --> 00:20:34,640
like infinite loop you'll basically lock

562
00:20:32,559 --> 00:20:35,760
up the tab permanently and you'll need

563
00:20:34,640 --> 00:20:37,919
to get

564
00:20:35,760 --> 00:20:39,360
chrome to kill it

565
00:20:37,919 --> 00:20:41,679
and you'll also notice

566
00:20:39,360 --> 00:20:43,760
that while it's running it's not

567
00:20:41,679 --> 00:20:46,000
actually printing to stand it out

568
00:20:43,760 --> 00:20:48,000
until it gets to the end and that's not

569
00:20:46,000 --> 00:20:49,360
because it's not trying to print a

570
00:20:48,000 --> 00:20:51,600
standard out and it's not because the

571
00:20:49,360 --> 00:20:56,320
standard out isn't working it's because

572
00:20:51,600 --> 00:20:58,480
it is locking up the main browser thread

573
00:20:56,320 --> 00:21:00,720
while it's processing and so

574
00:20:58,480 --> 00:21:02,400
the browser thread cannot update the dom

575
00:21:00,720 --> 00:21:03,600
and cannot update the ui until it's

576
00:21:02,400 --> 00:21:05,120
finished

577
00:21:03,600 --> 00:21:06,640
so this is obviously a little bit less

578
00:21:05,120 --> 00:21:08,320
than ideal

579
00:21:06,640 --> 00:21:10,000
for running python code in the browser

580
00:21:08,320 --> 00:21:12,000
you don't want your whole ui to lock up

581
00:21:10,000 --> 00:21:13,760
just because your python code is taking

582
00:21:12,000 --> 00:21:15,600
a while

583
00:21:13,760 --> 00:21:18,000
and the same time if we want to do

584
00:21:15,600 --> 00:21:20,640
something with standard input

585
00:21:18,000 --> 00:21:21,840
by default standard input is implemented

586
00:21:20,640 --> 00:21:25,600
like this

587
00:21:21,840 --> 00:21:27,600
uh it uses the browser prompt

588
00:21:25,600 --> 00:21:29,440
and brings up the prompt so if you

589
00:21:27,600 --> 00:21:31,919
wanted to say it's saying enter your

590
00:21:29,440 --> 00:21:33,840
name so i enter my name

591
00:21:31,919 --> 00:21:34,960
um and then it can continue on with the

592
00:21:33,840 --> 00:21:37,840
program

593
00:21:34,960 --> 00:21:38,799
the reason it uses a prompt uh is

594
00:21:37,840 --> 00:21:42,159
because

595
00:21:38,799 --> 00:21:43,679
the prompt will pause the thread while

596
00:21:42,159 --> 00:21:45,760
it waits for the result of the prompt

597
00:21:43,679 --> 00:21:48,159
the prompt is synchronous

598
00:21:45,760 --> 00:21:49,919
and it blocks the whole browser thread

599
00:21:48,159 --> 00:21:50,880
while waiting for input

600
00:21:49,919 --> 00:21:51,919
uh

601
00:21:50,880 --> 00:21:53,039
it's

602
00:21:51,919 --> 00:21:55,120
non

603
00:21:53,039 --> 00:21:57,840
like you know you can't have

604
00:21:55,120 --> 00:22:00,080
a browser ui that accepts input while

605
00:21:57,840 --> 00:22:01,679
the main thread is blocked in in any

606
00:22:00,080 --> 00:22:03,360
other way

607
00:22:01,679 --> 00:22:04,720
because the ui needs to be working for

608
00:22:03,360 --> 00:22:06,960
it to accept input

609
00:22:04,720 --> 00:22:09,280
so we have these two problems

610
00:22:06,960 --> 00:22:12,640
uh one is whenever we're running python

611
00:22:09,280 --> 00:22:15,200
code it freezes the ui and two uh we

612
00:22:12,640 --> 00:22:15,919
can't like block and wait for standard

613
00:22:15,200 --> 00:22:17,520
in

614
00:22:15,919 --> 00:22:18,720
input when we're running the python

615
00:22:17,520 --> 00:22:20,960
program

616
00:22:18,720 --> 00:22:23,360
uh so we need to solve both of these so

617
00:22:20,960 --> 00:22:26,240
normally when you're running a regular

618
00:22:23,360 --> 00:22:28,720
python application

619
00:22:26,240 --> 00:22:28,720
and

620
00:22:28,880 --> 00:22:32,159
uh and we have a little

621
00:22:30,559 --> 00:22:33,039
demo here

622
00:22:32,159 --> 00:22:34,880
um

623
00:22:33,039 --> 00:22:37,039
oops i need to get

624
00:22:34,880 --> 00:22:38,480
out of full screen for this to work

625
00:22:37,039 --> 00:22:39,520
um

626
00:22:38,480 --> 00:22:41,200
whoops

627
00:22:39,520 --> 00:22:42,480
so if i do

628
00:22:41,200 --> 00:22:45,440
uh

629
00:22:42,480 --> 00:22:47,840
a read from standard in in python

630
00:22:45,440 --> 00:22:50,559
then that python process is now blocked

631
00:22:47,840 --> 00:22:51,600
the python thread is is blocked until

632
00:22:50,559 --> 00:22:53,760
i

633
00:22:51,600 --> 00:22:55,919
until i finish entering the input and

634
00:22:53,760 --> 00:22:57,360
then it continues on

635
00:22:55,919 --> 00:22:59,600
so

636
00:22:57,360 --> 00:23:01,760
the way that python works in terms of

637
00:22:59,600 --> 00:23:04,159
making a blocking system call just

638
00:23:01,760 --> 00:23:06,000
doesn't really work in the browser land

639
00:23:04,159 --> 00:23:08,559
especially not on the main thread

640
00:23:06,000 --> 00:23:12,000
because it will block up your whole ui

641
00:23:08,559 --> 00:23:14,480
uh so there's two ways to make python

642
00:23:12,000 --> 00:23:17,600
execution stop and wait

643
00:23:14,480 --> 00:23:19,039
uh emscripton has a tool called asyncify

644
00:23:17,600 --> 00:23:21,360
which

645
00:23:19,039 --> 00:23:23,520
allows you to add into the c code hooks

646
00:23:21,360 --> 00:23:26,080
to let it stop and and wait

647
00:23:23,520 --> 00:23:27,679
um it does this by kind of unwinding the

648
00:23:26,080 --> 00:23:30,000
whole like

649
00:23:27,679 --> 00:23:32,080
call stack and then when it resumes it

650
00:23:30,000 --> 00:23:34,400
will like reload the call stack it has a

651
00:23:32,080 --> 00:23:35,679
fairly big performance overhead even

652
00:23:34,400 --> 00:23:38,320
when you're not

653
00:23:35,679 --> 00:23:39,280
actively using it and and stopping and

654
00:23:38,320 --> 00:23:40,960
waiting

655
00:23:39,280 --> 00:23:42,640
um but option two is the one we're going

656
00:23:40,960 --> 00:23:46,240
to look at which is having a separate

657
00:23:42,640 --> 00:23:47,520
thread a separate process uh which does

658
00:23:46,240 --> 00:23:49,520
blocking

659
00:23:47,520 --> 00:23:50,799
and in order to do that we need to use

660
00:23:49,520 --> 00:23:53,039
three different

661
00:23:50,799 --> 00:23:55,039
browser features that you might not have

662
00:23:53,039 --> 00:23:57,360
used before even if you do

663
00:23:55,039 --> 00:23:59,679
a fair amount of web development

664
00:23:57,360 --> 00:24:02,080
and that is web workers a shared array

665
00:23:59,679 --> 00:24:03,760
buffer and the atomics

666
00:24:02,080 --> 00:24:05,840
library

667
00:24:03,760 --> 00:24:06,799
so if we have a look at these a web

668
00:24:05,840 --> 00:24:09,440
worker

669
00:24:06,799 --> 00:24:12,480
is a way in javascript uh or in

670
00:24:09,440 --> 00:24:13,760
webassembly in the future to load

671
00:24:12,480 --> 00:24:16,240
a

672
00:24:13,760 --> 00:24:19,840
separate thread and a separate

673
00:24:16,240 --> 00:24:20,960
javascript execution context so

674
00:24:19,840 --> 00:24:23,120
the main thread which is where your

675
00:24:20,960 --> 00:24:25,520
javascript is normally running can call

676
00:24:23,120 --> 00:24:27,679
new worker and specify the javascript

677
00:24:25,520 --> 00:24:30,640
file that it should use for that new

678
00:24:27,679 --> 00:24:32,960
worker and it starts a separate thread

679
00:24:30,640 --> 00:24:35,120
which is executing javascript and the

680
00:24:32,960 --> 00:24:36,960
main thread and the worker thread can

681
00:24:35,120 --> 00:24:39,039
communicate with each other with this

682
00:24:36,960 --> 00:24:40,480
post message

683
00:24:39,039 --> 00:24:43,200
event that they can send each other

684
00:24:40,480 --> 00:24:45,520
which they can listen for asynchronously

685
00:24:43,200 --> 00:24:47,840
and at any time the main thread can

686
00:24:45,520 --> 00:24:49,360
terminate the worker thread so this is

687
00:24:47,840 --> 00:24:51,840
really useful if you want to say have

688
00:24:49,360 --> 00:24:54,000
some heavy number crunching that if you

689
00:24:51,840 --> 00:24:56,000
were to run it in the main thread that

690
00:24:54,000 --> 00:24:57,600
heavy number crunching would

691
00:24:56,000 --> 00:24:59,840
lock up the main thread and cause your

692
00:24:57,600 --> 00:25:01,360
ui to freeze uh you could instead run

693
00:24:59,840 --> 00:25:03,360
that in a worker

694
00:25:01,360 --> 00:25:04,880
and have it send the result back when

695
00:25:03,360 --> 00:25:06,799
it's done

696
00:25:04,880 --> 00:25:10,000
so this worker thread doesn't have any

697
00:25:06,799 --> 00:25:12,080
access to the ui to the document

698
00:25:10,000 --> 00:25:13,679
but it is there to do sort of background

699
00:25:12,080 --> 00:25:15,279
processing without locking up the main

700
00:25:13,679 --> 00:25:16,799
thread

701
00:25:15,279 --> 00:25:17,919
which is super useful

702
00:25:16,799 --> 00:25:19,600
for us

703
00:25:17,919 --> 00:25:21,840
as we do

704
00:25:19,600 --> 00:25:23,679
python because we can run our python in

705
00:25:21,840 --> 00:25:25,120
that worker thread

706
00:25:23,679 --> 00:25:26,480
or in a worker thread you can have many

707
00:25:25,120 --> 00:25:28,960
workers

708
00:25:26,480 --> 00:25:30,880
so the code for this uh simplified again

709
00:25:28,960 --> 00:25:32,559
uh is in the main thread we create a

710
00:25:30,880 --> 00:25:33,440
worker which is a separate javascript

711
00:25:32,559 --> 00:25:36,480
file

712
00:25:33,440 --> 00:25:37,919
uh and we wait for messages from it uh

713
00:25:36,480 --> 00:25:39,200
and we're assuming that the messages

714
00:25:37,919 --> 00:25:40,799
come from it that come from it are

715
00:25:39,200 --> 00:25:41,760
strings that are our standard out and

716
00:25:40,799 --> 00:25:43,520
we'll just put them straight to the

717
00:25:41,760 --> 00:25:45,880
terminal

718
00:25:43,520 --> 00:25:48,640
and when we want to run code we can say

719
00:25:45,880 --> 00:25:50,640
worker.postmessage and send it the code

720
00:25:48,640 --> 00:25:53,200
as a string as well

721
00:25:50,640 --> 00:25:55,120
and on the worker side it loads our

722
00:25:53,200 --> 00:25:57,520
python context

723
00:25:55,120 --> 00:26:00,000
and loads our python web assembly and

724
00:25:57,520 --> 00:26:03,440
when it receives some code it runs the

725
00:26:00,000 --> 00:26:05,600
code and when it has standard out uh

726
00:26:03,440 --> 00:26:07,360
strings then it will post those back to

727
00:26:05,600 --> 00:26:08,640
the main thread so the main thread is

728
00:26:07,360 --> 00:26:11,039
sending the code to the worker and the

729
00:26:08,640 --> 00:26:14,640
worker is sending the standard output

730
00:26:11,039 --> 00:26:17,840
back to the main thread

731
00:26:14,640 --> 00:26:20,480
and so if i bring another terminal up

732
00:26:17,840 --> 00:26:22,799
we can do the same code that we were

733
00:26:20,480 --> 00:26:24,880
running before that was just a fairly

734
00:26:22,799 --> 00:26:27,360
busy loop that takes a while

735
00:26:24,880 --> 00:26:29,600
and when we run it our ui keeps working

736
00:26:27,360 --> 00:26:32,159
and it can output and update the ui with

737
00:26:29,600 --> 00:26:33,440
the standard output as it goes because

738
00:26:32,159 --> 00:26:36,720
this python code is running in a

739
00:26:33,440 --> 00:26:39,360
separate thread and it is not blocking

740
00:26:36,720 --> 00:26:40,720
or tying up the the main worker thread

741
00:26:39,360 --> 00:26:42,799
so if we run that again

742
00:26:40,720 --> 00:26:45,120
oh look it's so beautiful

743
00:26:42,799 --> 00:26:47,520
um it's printing out all kinds of stuff

744
00:26:45,120 --> 00:26:50,000
which is really helpful

745
00:26:47,520 --> 00:26:51,919
uh it also means that because our ui

746
00:26:50,000 --> 00:26:54,080
isn't locked up i haven't implemented it

747
00:26:51,919 --> 00:26:56,159
here but you can have a kill button that

748
00:26:54,080 --> 00:26:57,840
you know if you accidentally write an

749
00:26:56,159 --> 00:26:59,520
infinite loop in your python you can

750
00:26:57,840 --> 00:27:00,320
still have a ui with a button where you

751
00:26:59,520 --> 00:27:02,880
can click the button and it will

752
00:27:00,320 --> 00:27:04,799
terminate the worker process uh so you

753
00:27:02,880 --> 00:27:07,279
don't have to worry about an infinite

754
00:27:04,799 --> 00:27:09,919
loop kind of completely crashing uh the

755
00:27:07,279 --> 00:27:09,919
browser tab

756
00:27:10,000 --> 00:27:14,159
uh

757
00:27:11,279 --> 00:27:16,559
but this doesn't help us with

758
00:27:14,159 --> 00:27:19,600
standard in because in order for

759
00:27:16,559 --> 00:27:21,679
standard in to work we need to block

760
00:27:19,600 --> 00:27:23,919
that worker thread

761
00:27:21,679 --> 00:27:25,840
and so we do this with the other two

762
00:27:23,919 --> 00:27:28,399
browser features that we need

763
00:27:25,840 --> 00:27:31,679
uh which is the shared array buffer and

764
00:27:28,399 --> 00:27:32,640
the atomics library

765
00:27:31,679 --> 00:27:34,399
and so

766
00:27:32,640 --> 00:27:38,159
with these two things

767
00:27:34,399 --> 00:27:40,960
we can set up a system which lets our

768
00:27:38,159 --> 00:27:42,880
worker process wait for the main thread

769
00:27:40,960 --> 00:27:44,559
and the ui to capture some standard in

770
00:27:42,880 --> 00:27:46,480
and send it back

771
00:27:44,559 --> 00:27:49,279
so we start off with the main thread

772
00:27:46,480 --> 00:27:51,039
launching the worker thread

773
00:27:49,279 --> 00:27:53,520
like we did before

774
00:27:51,039 --> 00:27:56,399
but this time our main thread can send a

775
00:27:53,520 --> 00:27:58,399
post message to the worker thread with a

776
00:27:56,399 --> 00:27:59,600
shared array buffer now this is

777
00:27:58,399 --> 00:28:01,279
simplified code that doesn't actually

778
00:27:59,600 --> 00:28:03,760
work but it's sort of pseudo code in

779
00:28:01,279 --> 00:28:05,360
javascript like pseudocode

780
00:28:03,760 --> 00:28:08,640
our main thread and our worker thread

781
00:28:05,360 --> 00:28:10,880
now both have a reference to the same

782
00:28:08,640 --> 00:28:13,520
uh block of memory right that shared

783
00:28:10,880 --> 00:28:15,679
array buffer is memory that can be

784
00:28:13,520 --> 00:28:18,080
shared between the main thread and the

785
00:28:15,679 --> 00:28:19,440
worker thread so it's under the buff

786
00:28:18,080 --> 00:28:21,760
variable and the main thread it's under

787
00:28:19,440 --> 00:28:24,080
the buffer variable in the worker thread

788
00:28:21,760 --> 00:28:26,240
but they are using the same

789
00:28:24,080 --> 00:28:28,320
bit of memory inside that shared array

790
00:28:26,240 --> 00:28:30,559
buffer

791
00:28:28,320 --> 00:28:33,360
and if in the worker thread we call

792
00:28:30,559 --> 00:28:36,080
atomics.wait using that buffer

793
00:28:33,360 --> 00:28:37,440
that worker thread is now blocked it

794
00:28:36,080 --> 00:28:39,120
will wait

795
00:28:37,440 --> 00:28:40,880
for that if there's other javascript

796
00:28:39,120 --> 00:28:43,200
that's running or other

797
00:28:40,880 --> 00:28:45,279
uh webassembly that's running all of

798
00:28:43,200 --> 00:28:48,000
that will just wait

799
00:28:45,279 --> 00:28:50,240
uh until something else happens uh this

800
00:28:48,000 --> 00:28:51,520
worker thread is now not using the cpu

801
00:28:50,240 --> 00:28:52,799
it's not a busy loop or anything it is

802
00:28:51,520 --> 00:28:54,880
just blocked

803
00:28:52,799 --> 00:28:55,679
and in this case it's blocking on

804
00:28:54,880 --> 00:28:58,240
that

805
00:28:55,679 --> 00:29:01,440
buffer at index zero and blocking

806
00:28:58,240 --> 00:29:03,279
waiting until it is no longer uh zero no

807
00:29:01,440 --> 00:29:05,600
longer has a zero value

808
00:29:03,279 --> 00:29:08,159
so on the main thread we can

809
00:29:05,600 --> 00:29:09,520
modify that memory we can store the

810
00:29:08,159 --> 00:29:10,840
number 42

811
00:29:09,520 --> 00:29:15,760
in that uh that

812
00:29:10,840 --> 00:29:17,039
index but when we call atomics.notify

813
00:29:15,760 --> 00:29:18,159
on that buffer

814
00:29:17,039 --> 00:29:19,840
that

815
00:29:18,159 --> 00:29:22,480
finishes this weight operation it

816
00:29:19,840 --> 00:29:24,159
unlocks unblocks this worker thread and

817
00:29:22,480 --> 00:29:25,760
this worker thread can now continue on

818
00:29:24,159 --> 00:29:27,919
with the next line of code or the next

819
00:29:25,760 --> 00:29:30,240
thing that it was about to do

820
00:29:27,919 --> 00:29:31,600
so the worker thread waits for the main

821
00:29:30,240 --> 00:29:33,840
thread to

822
00:29:31,600 --> 00:29:36,000
finish for the user to like type in some

823
00:29:33,840 --> 00:29:37,840
input or something and then uh and all

824
00:29:36,000 --> 00:29:39,279
of that stuff can happen asynchronously

825
00:29:37,840 --> 00:29:42,640
and the worker thread will block until

826
00:29:39,279 --> 00:29:44,320
the main thread calls notify

827
00:29:42,640 --> 00:29:45,919
and so using this

828
00:29:44,320 --> 00:29:48,080
we can implement

829
00:29:45,919 --> 00:29:50,799
standard in

830
00:29:48,080 --> 00:29:53,279
so if we use this example

831
00:29:50,799 --> 00:29:56,000
and i bring back the example code i had

832
00:29:53,279 --> 00:29:58,000
so again super simple code it uses input

833
00:29:56,000 --> 00:30:00,000
to prompt the user to enter the name

834
00:29:58,000 --> 00:30:01,120
waits for that input uh and then prints

835
00:30:00,000 --> 00:30:03,919
the name

836
00:30:01,120 --> 00:30:06,720
so if we run this uh the worker thread

837
00:30:03,919 --> 00:30:09,840
starts processing the python code um our

838
00:30:06,720 --> 00:30:12,640
python code is now blocked it's now

839
00:30:09,840 --> 00:30:14,640
at that atomic.weight point and it is

840
00:30:12,640 --> 00:30:17,440
waiting for the main thread to call

841
00:30:14,640 --> 00:30:20,640
notify for it to wake up again so

842
00:30:17,440 --> 00:30:23,200
uh my ui still works uh i can enter my

843
00:30:20,640 --> 00:30:25,200
name here

844
00:30:23,200 --> 00:30:27,360
and when i finish entering the standard

845
00:30:25,200 --> 00:30:28,960
input and when i hit enter that's when

846
00:30:27,360 --> 00:30:30,559
it's the main thread is going to call

847
00:30:28,960 --> 00:30:33,440
atomics.notify

848
00:30:30,559 --> 00:30:36,240
and then my python code can continue to

849
00:30:33,440 --> 00:30:37,279
execute with that standard input uh

850
00:30:36,240 --> 00:30:40,159
coming in

851
00:30:37,279 --> 00:30:41,679
so very simple program just being able

852
00:30:40,159 --> 00:30:44,159
to enter your name and have it come back

853
00:30:41,679 --> 00:30:44,799
to you uh using standard in and stand it

854
00:30:44,159 --> 00:30:46,559
out

855
00:30:44,799 --> 00:30:49,279
was using a lot of browser features and

856
00:30:46,559 --> 00:30:51,360
a surprising amount of work uh but uh it

857
00:30:49,279 --> 00:30:54,159
does work uh which is cool

858
00:30:51,360 --> 00:30:56,640
and because we now have actually working

859
00:30:54,159 --> 00:30:59,200
standard in and standard out uh it means

860
00:30:56,640 --> 00:31:01,279
we can use uh a python

861
00:30:59,200 --> 00:31:02,240
repo using the actual python ripple if

862
00:31:01,279 --> 00:31:06,399
you find

863
00:31:02,240 --> 00:31:08,159
a um the piodide website has a a repel

864
00:31:06,399 --> 00:31:10,640
example on it but the

865
00:31:08,159 --> 00:31:13,039
uh ui the rebel itself is implemented in

866
00:31:10,640 --> 00:31:15,200
javascript and it just sort of sends one

867
00:31:13,039 --> 00:31:16,720
line at a time of python code into the

868
00:31:15,200 --> 00:31:19,279
into the um

869
00:31:16,720 --> 00:31:20,720
into actual python so but this is a

870
00:31:19,279 --> 00:31:22,720
python interpreter

871
00:31:20,720 --> 00:31:24,159
actually running in python um just

872
00:31:22,720 --> 00:31:25,600
reading from standard in and printing to

873
00:31:24,159 --> 00:31:26,320
stand it up

874
00:31:25,600 --> 00:31:28,080
so

875
00:31:26,320 --> 00:31:28,880
you know we can you can do all kinds of

876
00:31:28,080 --> 00:31:30,880
things

877
00:31:28,880 --> 00:31:33,039
input

878
00:31:30,880 --> 00:31:34,320
something like that

879
00:31:33,039 --> 00:31:37,760
so

880
00:31:34,320 --> 00:31:39,840
uh yeah we have a working python repo uh

881
00:31:37,760 --> 00:31:41,440
and if you it is it is live on the

882
00:31:39,840 --> 00:31:43,760
internet and i have the link uh in the

883
00:31:41,440 --> 00:31:45,440
slides later on if you want to try that

884
00:31:43,760 --> 00:31:46,480
out yourself

885
00:31:45,440 --> 00:31:49,120
uh so

886
00:31:46,480 --> 00:31:51,440
we now have working standard in uh and

887
00:31:49,120 --> 00:31:54,320
standard out and a full working repo

888
00:31:51,440 --> 00:31:56,480
uh in the python in python using c

889
00:31:54,320 --> 00:31:58,799
python uh and sort of working seamlessly

890
00:31:56,480 --> 00:32:02,080
with the terminal in the ui

891
00:31:58,799 --> 00:32:03,840
so we needed a web worker to run python

892
00:32:02,080 --> 00:32:05,200
in a separate thread

893
00:32:03,840 --> 00:32:06,640
away from the main

894
00:32:05,200 --> 00:32:08,559
ui thread

895
00:32:06,640 --> 00:32:10,880
we have a shared buffer to share memory

896
00:32:08,559 --> 00:32:13,039
between them uh and atomics to kind of

897
00:32:10,880 --> 00:32:15,600
block and wait for that shared buffer to

898
00:32:13,039 --> 00:32:16,720
be filled with the standard input

899
00:32:15,600 --> 00:32:19,360
okay

900
00:32:16,720 --> 00:32:21,600
so as a side note browser support for

901
00:32:19,360 --> 00:32:23,279
these features for shared buffer array

902
00:32:21,600 --> 00:32:25,279
shadow ray buffer

903
00:32:23,279 --> 00:32:27,200
and atomics in particular

904
00:32:25,279 --> 00:32:28,559
is a little bit patchy and that's

905
00:32:27,200 --> 00:32:30,399
largely because

906
00:32:28,559 --> 00:32:32,880
the browser started supporting it and

907
00:32:30,399 --> 00:32:34,320
then when spectre happens they realized

908
00:32:32,880 --> 00:32:35,919
that this was actually a very big

909
00:32:34,320 --> 00:32:38,240
security concern

910
00:32:35,919 --> 00:32:40,000
and browsers removed support for the

911
00:32:38,240 --> 00:32:42,960
shared array buffer

912
00:32:40,000 --> 00:32:44,240
and atomics was generally still there um

913
00:32:42,960 --> 00:32:46,240
but is not very useful without the

914
00:32:44,240 --> 00:32:47,440
shared array buffer

915
00:32:46,240 --> 00:32:49,600
and so

916
00:32:47,440 --> 00:32:51,600
uh bit by bit browsers have been

917
00:32:49,600 --> 00:32:52,640
re-adding support for shared array

918
00:32:51,600 --> 00:32:55,039
buffer

919
00:32:52,640 --> 00:32:56,399
but with a bit more security uh

920
00:32:55,039 --> 00:32:58,480
implemented in it

921
00:32:56,399 --> 00:33:01,039
so in particular in order to use shared

922
00:32:58,480 --> 00:33:03,919
array buffer the page must be running in

923
00:33:01,039 --> 00:33:07,200
a cross-origin isolated context and this

924
00:33:03,919 --> 00:33:09,600
is mostly to stop uh something like oh i

925
00:33:07,200 --> 00:33:11,519
embed some ads in an iframe but that

926
00:33:09,600 --> 00:33:13,919
iframe can use shared array buffer to

927
00:33:11,519 --> 00:33:15,679
spy on the rest of the process

928
00:33:13,919 --> 00:33:18,080
and spy on what's happening in the main

929
00:33:15,679 --> 00:33:20,480
the main thread

930
00:33:18,080 --> 00:33:22,080
so you can only use shadowraybuffer in

931
00:33:20,480 --> 00:33:23,279
context where

932
00:33:22,080 --> 00:33:24,960
you can guarantee everything is coming

933
00:33:23,279 --> 00:33:26,559
from the same origin or at least was

934
00:33:24,960 --> 00:33:27,919
specifically allowed

935
00:33:26,559 --> 00:33:29,600
uh so

936
00:33:27,919 --> 00:33:32,080
um

937
00:33:29,600 --> 00:33:34,000
the support across browsers now once you

938
00:33:32,080 --> 00:33:36,480
have added these headers for your site

939
00:33:34,000 --> 00:33:38,960
uh is is pretty good uh edge firefox

940
00:33:36,480 --> 00:33:42,080
chrome they'll support it safari only

941
00:33:38,960 --> 00:33:43,200
just recently re-added support for it a

942
00:33:42,080 --> 00:33:45,840
couple of weeks ago so if you're on the

943
00:33:43,200 --> 00:33:48,320
latest version of safari uh then you'll

944
00:33:45,840 --> 00:33:49,279
have it uh it's pretty good on mobile as

945
00:33:48,320 --> 00:33:52,880
well

946
00:33:49,279 --> 00:33:55,200
uh now but if you look at atomics

947
00:33:52,880 --> 00:33:57,760
uh the atomics library which is very

948
00:33:55,200 --> 00:33:59,039
necessary for this whole approach um

949
00:33:57,760 --> 00:34:01,360
doesn't look like it's very well

950
00:33:59,039 --> 00:34:04,399
supported uh at all

951
00:34:01,360 --> 00:34:06,480
uh this actually is because the can i

952
00:34:04,399 --> 00:34:09,280
use data is out of date

953
00:34:06,480 --> 00:34:10,960
um it hasn't been updated for

954
00:34:09,280 --> 00:34:13,119
uh like the latest safari did add

955
00:34:10,960 --> 00:34:14,720
support for it but it's not there

956
00:34:13,119 --> 00:34:16,560
so i've been going through trying to

957
00:34:14,720 --> 00:34:18,960
find all of the browsers uh that do

958
00:34:16,560 --> 00:34:20,960
support it even though the mdn data

959
00:34:18,960 --> 00:34:22,159
doesn't say that it's supported and it

960
00:34:20,960 --> 00:34:24,000
is actually supported across more

961
00:34:22,159 --> 00:34:25,040
browsers uh than you would think and i'm

962
00:34:24,000 --> 00:34:27,599
working on

963
00:34:25,040 --> 00:34:29,599
i have one pr sent already to update it

964
00:34:27,599 --> 00:34:31,440
uh and i need to work on a couple more

965
00:34:29,599 --> 00:34:33,359
to trace down

966
00:34:31,440 --> 00:34:34,800
exactly what versions it was added in so

967
00:34:33,359 --> 00:34:36,240
the browser support for shader ray

968
00:34:34,800 --> 00:34:37,440
buffer and atomics is actually better

969
00:34:36,240 --> 00:34:39,599
than it looks

970
00:34:37,440 --> 00:34:41,440
uh at the moment um and it has pretty

971
00:34:39,599 --> 00:34:42,240
wide support

972
00:34:41,440 --> 00:34:44,720
uh

973
00:34:42,240 --> 00:34:46,079
looking forward um i am working i want

974
00:34:44,720 --> 00:34:49,599
to work on more

975
00:34:46,079 --> 00:34:51,919
python library support uh in

976
00:34:49,599 --> 00:34:53,679
uh in the browser

977
00:34:51,919 --> 00:34:56,879
i want to be able to do things like

978
00:34:53,679 --> 00:34:58,640
uh graphics drawing to a canvas um

979
00:34:56,879 --> 00:35:00,960
making sure all of the audio stuff works

980
00:34:58,640 --> 00:35:02,880
a lot of that stuff will already work uh

981
00:35:00,960 --> 00:35:05,440
thanks to emscripton's

982
00:35:02,880 --> 00:35:06,720
libraries but making that easier making

983
00:35:05,440 --> 00:35:09,520
sure it all works

984
00:35:06,720 --> 00:35:11,599
um as well as supporting making network

985
00:35:09,520 --> 00:35:14,000
requests uh which is gonna be an

986
00:35:11,599 --> 00:35:15,040
interesting security question um

987
00:35:14,000 --> 00:35:16,560
there is

988
00:35:15,040 --> 00:35:18,720
progress in

989
00:35:16,560 --> 00:35:21,760
underway to add support for threads and

990
00:35:18,720 --> 00:35:23,520
atomics uh into webassembly itself so

991
00:35:21,760 --> 00:35:25,440
you don't need to sort of drop out into

992
00:35:23,520 --> 00:35:27,599
javascript to be able to do those things

993
00:35:25,440 --> 00:35:29,200
you generally don't need to do that now

994
00:35:27,599 --> 00:35:31,280
um but it's not

995
00:35:29,200 --> 00:35:32,720
this uh threads in atomics is not an

996
00:35:31,280 --> 00:35:34,720
official part of

997
00:35:32,720 --> 00:35:37,520
uh the webassembly standard yet even

998
00:35:34,720 --> 00:35:38,400
though a lot of browsers do support it

999
00:35:37,520 --> 00:35:39,920
um

1000
00:35:38,400 --> 00:35:42,240
there is another project which i only

1001
00:35:39,920 --> 00:35:44,640
found out about recently uh where a

1002
00:35:42,240 --> 00:35:46,720
couple of c python core developers are

1003
00:35:44,640 --> 00:35:49,599
working on building support for

1004
00:35:46,720 --> 00:35:51,760
compiling c python to webassembly oops

1005
00:35:49,599 --> 00:35:53,280
without any patches

1006
00:35:51,760 --> 00:35:56,320
there's also a proposal to add

1007
00:35:53,280 --> 00:35:58,240
atomics.weight async which would allow

1008
00:35:56,320 --> 00:36:00,800
the main thread to sort of

1009
00:35:58,240 --> 00:36:03,040
asynchronously wait on a shared array

1010
00:36:00,800 --> 00:36:04,480
buffer which would remove some of the

1011
00:36:03,040 --> 00:36:07,280
necessity of

1012
00:36:04,480 --> 00:36:09,119
uh using post message to

1013
00:36:07,280 --> 00:36:11,200
send standard out back from the main

1014
00:36:09,119 --> 00:36:13,440
thread you'd be able to have the ui

1015
00:36:11,200 --> 00:36:15,359
update without the overhead of using a

1016
00:36:13,440 --> 00:36:16,320
post message and serializing everything

1017
00:36:15,359 --> 00:36:17,680
um

1018
00:36:16,320 --> 00:36:20,480
and there's also some really interesting

1019
00:36:17,680 --> 00:36:21,839
work going on for using web assembly for

1020
00:36:20,480 --> 00:36:23,280
sort of quote unquote native apps

1021
00:36:21,839 --> 00:36:25,200
running webassembly outside of the

1022
00:36:23,280 --> 00:36:27,520
browser with access to the operating

1023
00:36:25,200 --> 00:36:30,240
system uh which has a really cool

1024
00:36:27,520 --> 00:36:32,720
potential for sort of native-like speeds

1025
00:36:30,240 --> 00:36:35,119
but allowing the same binary code to be

1026
00:36:32,720 --> 00:36:36,800
portable across uh architectures uh

1027
00:36:35,119 --> 00:36:37,520
which would be really cool

1028
00:36:36,800 --> 00:36:39,440
so

1029
00:36:37,520 --> 00:36:41,760
in building this a lot of credit goes to

1030
00:36:39,440 --> 00:36:44,480
ben taylor uh who helped a lot with

1031
00:36:41,760 --> 00:36:46,480
getting the terminal ui set up because

1032
00:36:44,480 --> 00:36:47,920
he also has his own project uh and greg

1033
00:36:46,480 --> 00:36:50,480
dark was super helpful explaining things

1034
00:36:47,920 --> 00:36:51,520
like uh blocking system calls to me

1035
00:36:50,480 --> 00:36:53,520
um

1036
00:36:51,520 --> 00:36:56,480
ben has his own project which you should

1037
00:36:53,520 --> 00:36:58,000
absolutely check out are called runner

1038
00:36:56,480 --> 00:37:01,599
runner.dev

1039
00:36:58,000 --> 00:37:04,480
it is an embeddable editor and execution

1040
00:37:01,599 --> 00:37:07,119
environment that you can include in any

1041
00:37:04,480 --> 00:37:09,359
website just by including an iframe

1042
00:37:07,119 --> 00:37:10,320
and that also uses webassembly to run

1043
00:37:09,359 --> 00:37:11,760
python

1044
00:37:10,320 --> 00:37:12,960
but it is not an enscripted version of

1045
00:37:11,760 --> 00:37:15,200
python it's a different version of

1046
00:37:12,960 --> 00:37:18,720
python and is built using

1047
00:37:15,200 --> 00:37:21,280
uh wazi instead of inscriptin okay

1048
00:37:18,720 --> 00:37:25,200
so yeah that's my talk uh and i do

1049
00:37:21,280 --> 00:37:25,200
believe we have some time for questions

1050
00:37:32,560 --> 00:37:36,160
uh i can't hear you betsy i don't know

1051
00:37:34,079 --> 00:37:39,040
if everyone else can

1052
00:37:36,160 --> 00:37:40,640
that's because i had myself muted

1053
00:37:39,040 --> 00:37:42,079
it was bound to happen

1054
00:37:40,640 --> 00:37:44,000
um

1055
00:37:42,079 --> 00:37:46,960
thanks for telling me katie or i would

1056
00:37:44,000 --> 00:37:48,720
have kept going um yes we have plenty of

1057
00:37:46,960 --> 00:37:52,160
time for questions and we have a few

1058
00:37:48,720 --> 00:37:54,720
questions there um so thanks again katie

1059
00:37:52,160 --> 00:37:57,680
for that talk um that was just as fun as

1060
00:37:54,720 --> 00:38:00,480
i was hoping it would be um

1061
00:37:57,680 --> 00:38:04,240
i love seeing things run in places where

1062
00:38:00,480 --> 00:38:05,839
they were never designed to be run um

1063
00:38:04,240 --> 00:38:08,880
and speaking of

1064
00:38:05,839 --> 00:38:11,440
um our top question is

1065
00:38:08,880 --> 00:38:13,520
can inscription itself run in the

1066
00:38:11,440 --> 00:38:15,760
browser

1067
00:38:13,520 --> 00:38:15,760
oh

1068
00:38:16,160 --> 00:38:19,359
that's a good question i don't think

1069
00:38:17,599 --> 00:38:21,119
i've ever really looked into like how

1070
00:38:19,359 --> 00:38:23,200
inscription itself

1071
00:38:21,119 --> 00:38:25,040
is run um

1072
00:38:23,200 --> 00:38:28,079
if it takes

1073
00:38:25,040 --> 00:38:29,359
itself written in c then maybe

1074
00:38:28,079 --> 00:38:30,800
it's not really doing much except sort

1075
00:38:29,359 --> 00:38:33,760
of reading files and doing a lot of

1076
00:38:30,800 --> 00:38:37,040
processing so i imagine it would but i

1077
00:38:33,760 --> 00:38:37,040
have never tried

1078
00:38:37,119 --> 00:38:40,560
i don't even know if it's written in c

1079
00:38:41,440 --> 00:38:47,680
something for the asco to play with

1080
00:38:45,280 --> 00:38:50,079
uh how large is the web assembly

1081
00:38:47,680 --> 00:38:51,680
executable of python executable in

1082
00:38:50,079 --> 00:38:53,119
quotes oh that's a great question

1083
00:38:51,680 --> 00:38:56,000
because the pioneer team has put a lot

1084
00:38:53,119 --> 00:38:57,839
of work into this uh it's surprisingly

1085
00:38:56,000 --> 00:39:01,599
small it does take a noticeable amount

1086
00:38:57,839 --> 00:39:03,200
of time time to download um but it's

1087
00:39:01,599 --> 00:39:05,040
something like

1088
00:39:03,200 --> 00:39:07,200
like the whole download would be

1089
00:39:05,040 --> 00:39:10,640
in the order of six or seven megabytes

1090
00:39:07,200 --> 00:39:14,320
so it is less stuff to download than

1091
00:39:10,640 --> 00:39:16,880
loading the new york times home page

1092
00:39:14,320 --> 00:39:18,160
and it's like you can sort of see it if

1093
00:39:16,880 --> 00:39:20,480
i open it up

1094
00:39:18,160 --> 00:39:22,720
and we open the inspector

1095
00:39:20,480 --> 00:39:25,520
and the network tab

1096
00:39:22,720 --> 00:39:29,200
alright let's have a look

1097
00:39:25,520 --> 00:39:30,800
uh the whole thing is 7.4 megabytes

1098
00:39:29,200 --> 00:39:32,640
of transfer

1099
00:39:30,800 --> 00:39:34,160
stuff so

1100
00:39:32,640 --> 00:39:36,400
a lot of that would be

1101
00:39:34,160 --> 00:39:36,400
um

1102
00:39:36,480 --> 00:39:38,400
here

1103
00:39:37,440 --> 00:39:41,280
in

1104
00:39:38,400 --> 00:39:44,560
the piodide data and webassembly which

1105
00:39:41,280 --> 00:39:47,040
is 3.4 megabytes and 3.6 megabytes

1106
00:39:44,560 --> 00:39:49,440
makes sense could be a lot more

1107
00:39:47,040 --> 00:39:51,200
it could be it was a lot more um but

1108
00:39:49,440 --> 00:39:53,599
it's gotten better

1109
00:39:51,200 --> 00:39:56,960
that's great

1110
00:39:53,599 --> 00:39:59,359
okay next question if standard n is

1111
00:39:56,960 --> 00:40:01,040
blocking execution of the worker thread

1112
00:39:59,359 --> 00:40:04,079
can you launch another worker thread to

1113
00:40:01,040 --> 00:40:05,760
allow continuing execution

1114
00:40:04,079 --> 00:40:08,160
uh yeah you can launch as many worker

1115
00:40:05,760 --> 00:40:11,760
threads as you want to run

1116
00:40:08,160 --> 00:40:14,720
separate uh python

1117
00:40:11,760 --> 00:40:17,119
uh they'd be sort of separate python

1118
00:40:14,720 --> 00:40:18,400
i mean i'm gonna say processors sort of

1119
00:40:17,119 --> 00:40:20,079
they're sort of they wouldn't be able

1120
00:40:18,400 --> 00:40:21,520
they wouldn't be sharing their variables

1121
00:40:20,079 --> 00:40:22,640
between them

1122
00:40:21,520 --> 00:40:24,880
they wouldn't be sharing memory between

1123
00:40:22,640 --> 00:40:27,119
them but yeah you could run two copies

1124
00:40:24,880 --> 00:40:28,560
of python uh in separate worker threads

1125
00:40:27,119 --> 00:40:30,800
uh just fine

1126
00:40:28,560 --> 00:40:32,480
that makes sense

1127
00:40:30,800 --> 00:40:35,520
how easy would it be to get

1128
00:40:32,480 --> 00:40:39,119
non-supported libraries running

1129
00:40:35,520 --> 00:40:41,440
so piodide already has support for

1130
00:40:39,119 --> 00:40:45,040
uh libraries that are written in pure

1131
00:40:41,440 --> 00:40:47,599
python so you can use

1132
00:40:45,040 --> 00:40:48,720
pip packages if the pit packages are

1133
00:40:47,599 --> 00:40:50,800
implemented

1134
00:40:48,720 --> 00:40:54,480
in pure python

1135
00:40:50,800 --> 00:40:57,040
it will there are some python libraries

1136
00:40:54,480 --> 00:40:59,680
that uh iodide has specifically built

1137
00:40:57,040 --> 00:41:02,160
support for uh things like numpy uh that

1138
00:40:59,680 --> 00:41:04,480
have a lot of native code as well but

1139
00:41:02,160 --> 00:41:06,720
you would have to separately compile

1140
00:41:04,480 --> 00:41:07,760
any native code into webassembly for it

1141
00:41:06,720 --> 00:41:09,599
to work

1142
00:41:07,760 --> 00:41:12,480
um i've not gone through that process

1143
00:41:09,599 --> 00:41:13,520
myself um it probably depends

1144
00:41:12,480 --> 00:41:15,200
on

1145
00:41:13,520 --> 00:41:17,760
uh how easy or hard it like what what

1146
00:41:15,200 --> 00:41:19,760
the library does and how easy or hard it

1147
00:41:17,760 --> 00:41:22,400
is to to why them if

1148
00:41:19,760 --> 00:41:24,000
um but if it is just doing something

1149
00:41:22,400 --> 00:41:25,839
like calculations and not relying on the

1150
00:41:24,000 --> 00:41:27,760
operating system then i imagine it's

1151
00:41:25,839 --> 00:41:30,800
pretty doable um that being said i have

1152
00:41:27,760 --> 00:41:32,160
not attempted to do that myself

1153
00:41:30,800 --> 00:41:34,640
i'm very glad to hear that they've

1154
00:41:32,160 --> 00:41:38,240
already sorted out numpy because that

1155
00:41:34,640 --> 00:41:40,960
would be the worst to try yourself yes

1156
00:41:38,240 --> 00:41:42,960
um have you got test results on what

1157
00:41:40,960 --> 00:41:44,160
performance hit the webassembly

1158
00:41:42,960 --> 00:41:46,000
translation

1159
00:41:44,160 --> 00:41:48,400
than execution causes compared with

1160
00:41:46,000 --> 00:41:50,000
native python

1161
00:41:48,400 --> 00:41:52,400
um i haven't done any benchmarking

1162
00:41:50,000 --> 00:41:53,760
myself uh the piodide project quoted

1163
00:41:52,400 --> 00:41:54,640
something like

1164
00:41:53,760 --> 00:41:56,480
uh

1165
00:41:54,640 --> 00:41:58,240
two to three times

1166
00:41:56,480 --> 00:42:01,839
uh as like

1167
00:41:58,240 --> 00:42:03,280
slower than c python um so it is like

1168
00:42:01,839 --> 00:42:06,640
aries a noticeable performance hit

1169
00:42:03,280 --> 00:42:06,640
compared to c python

1170
00:42:07,760 --> 00:42:12,640
um next up why do you need a shared

1171
00:42:10,480 --> 00:42:14,839
buffer to send standard and data rather

1172
00:42:12,640 --> 00:42:18,000
than using the post message function

1173
00:42:14,839 --> 00:42:20,079
again uh the big problem is that

1174
00:42:18,000 --> 00:42:21,680
the post message

1175
00:42:20,079 --> 00:42:24,319
uh

1176
00:42:21,680 --> 00:42:26,240
needs to be asynchronously received by

1177
00:42:24,319 --> 00:42:27,520
the worker

1178
00:42:26,240 --> 00:42:28,960
and so

1179
00:42:27,520 --> 00:42:30,880
once you call

1180
00:42:28,960 --> 00:42:33,040
like while it can't asynchronously

1181
00:42:30,880 --> 00:42:36,240
receive that standard input

1182
00:42:33,040 --> 00:42:39,440
until the worker thread is unblocked

1183
00:42:36,240 --> 00:42:40,240
um it can't kind of store it and then

1184
00:42:39,440 --> 00:42:42,160
uh

1185
00:42:40,240 --> 00:42:45,599
start using it as soon as it it as soon

1186
00:42:42,160 --> 00:42:47,680
as the wait is over um so

1187
00:42:45,599 --> 00:42:50,880
it has to wait for the standard input

1188
00:42:47,680 --> 00:42:52,400
and then get it synchronously as well um

1189
00:42:50,880 --> 00:42:54,240
but if you tried to do that by sending a

1190
00:42:52,400 --> 00:42:57,040
post message

1191
00:42:54,240 --> 00:42:58,560
it wouldn't receive the post message

1192
00:42:57,040 --> 00:43:02,079
asynchronous

1193
00:42:58,560 --> 00:43:04,880
like event until after it had finished

1194
00:43:02,079 --> 00:43:06,079
requesting the standard in synchronously

1195
00:43:04,880 --> 00:43:07,920
i'm not sure i explained that very well

1196
00:43:06,079 --> 00:43:10,160
but it sounds like something that needs

1197
00:43:07,920 --> 00:43:11,520
like diagrams yeah

1198
00:43:10,160 --> 00:43:14,000
maybe i should have added a diagram for

1199
00:43:11,520 --> 00:43:14,000
it yeah

1200
00:43:14,079 --> 00:43:17,920
um that call to like read standard in

1201
00:43:16,319 --> 00:43:21,520
from webassembly

1202
00:43:17,920 --> 00:43:23,040
can't do anything asynchronously yeah

1203
00:43:21,520 --> 00:43:26,319
yeah

1204
00:43:23,040 --> 00:43:28,560
okay um do you know whether any bigger

1205
00:43:26,319 --> 00:43:30,800
sites use existing systems like brythen

1206
00:43:28,560 --> 00:43:33,119
and production

1207
00:43:30,800 --> 00:43:35,599
uh i don't know of any bigger sites that

1208
00:43:33,119 --> 00:43:37,599
do it if you go to the bryton website

1209
00:43:35,599 --> 00:43:40,560
they do have a list of

1210
00:43:37,599 --> 00:43:43,359
projects that use brighton um some of

1211
00:43:40,560 --> 00:43:45,200
which are sort of just regular web apps

1212
00:43:43,359 --> 00:43:46,240
um i didn't notice any big names not

1213
00:43:45,200 --> 00:43:47,680
from memory

1214
00:43:46,240 --> 00:43:49,680
um

1215
00:43:47,680 --> 00:43:51,200
for piodie uh sorry it has a list of

1216
00:43:49,680 --> 00:43:53,359
projects that use brighton a lot of them

1217
00:43:51,200 --> 00:43:54,960
are you know run python in the browser

1218
00:43:53,359 --> 00:43:57,520
educational tools

1219
00:43:54,960 --> 00:43:58,800
um for teaching python uh in the same

1220
00:43:57,520 --> 00:44:01,040
way um

1221
00:43:58,800 --> 00:44:03,680
the piodide site lists projects that use

1222
00:44:01,040 --> 00:44:04,800
piodide and most of them are data

1223
00:44:03,680 --> 00:44:06,720
science

1224
00:44:04,800 --> 00:44:09,280
tools um

1225
00:44:06,720 --> 00:44:10,960
so like that sort of follow the jupiter

1226
00:44:09,280 --> 00:44:13,280
notebook style interface where you have

1227
00:44:10,960 --> 00:44:14,720
chunks of python code uh that you can

1228
00:44:13,280 --> 00:44:16,960
execute

1229
00:44:14,720 --> 00:44:20,480
that makes a lot of sense

1230
00:44:16,960 --> 00:44:23,440
okay we are just about out of time um

1231
00:44:20,480 --> 00:44:27,200
there are there's one more question

1232
00:44:23,440 --> 00:44:30,800
which i'll leave for the chat um in the

1233
00:44:27,200 --> 00:44:32,640
post conference post talk chat i'm

1234
00:44:30,800 --> 00:44:35,520
already not able to say

1235
00:44:32,640 --> 00:44:37,359
the kaya theater post talk text chat um

1236
00:44:35,520 --> 00:44:39,599
i'll paste that one in

1237
00:44:37,359 --> 00:44:41,200
and also quite a lot of people in the

1238
00:44:39,599 --> 00:44:44,560
chat and the questions are asking for a

1239
00:44:41,200 --> 00:44:46,000
copy of your slides katie um so just so

1240
00:44:44,560 --> 00:44:48,319
you know

1241
00:44:46,000 --> 00:44:49,280
but thank you very much katie uh that

1242
00:44:48,319 --> 00:44:51,119
was

1243
00:44:49,280 --> 00:44:52,800
a really interesting look into the

1244
00:44:51,119 --> 00:44:54,640
mechanics of running things in the

1245
00:44:52,800 --> 00:44:57,119
browser

1246
00:44:54,640 --> 00:44:59,359
um and

1247
00:44:57,119 --> 00:45:01,119
that's it for now

1248
00:44:59,359 --> 00:45:04,280
back in 10 minutes

1249
00:45:01,119 --> 00:45:04,280
thank you

1250
00:45:07,359 --> 00:45:09,440
you

