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