 Perfect. That's voice recognition for you. So thank you, EuroPython, for having me. So I'm going to be talking about PyScript and the magic of Python in the browser. This talk was actually proposed by my friend and colleague, Fabio. He's a colleague of mine at Anaconda. He's the creator of PyScript. He's also a very special person. He's a former EuroPython chair and is now actually a EuroPython fellow. And from the photo, he's a sort of smoking hot photogenic sort of a gentleman as well, as you can see from the sort of Zoolander look that he's giving us here. But sadly, he's not here for complicated reasons. So hence, you have me instead, giving this talk. So this is me. I'm actually a tuba player. And thank you. You've not actually heard me play. And I used to be a teacher as well before becoming a coder as well. And I'm a principal engineer on the PyScript team at Anaconda. So PyScript. I better explain how Anaconda and PyScript are linked before we go any further. So PyScript is an open source project. So please come join us and contribute and play around and do all the things that we do as a wonderful open source community. But PyScript was announced by Peter Wang, our CEO just over a year ago. And Anaconda have been supporting this open source, this nascent open source project of PyScript. So we wondered we needed a logo and rabbits, as you'll see, make several appearances in this talk. But we have a wabbit. I call it the wasm wabbit, as you'll see. But our wonderful designer, Katie, kind of went berserk with the bunnies. And so we have lots of bunnies in our PyScript talk. I think it's because the way she designed the original logo was like a P, like a speech bubble. And then there was a kind of a Y that looked like bunny ears as well. So anyway, anyway, in this talk, what are we going to recover? We're going to cover how exactly does PyScript work? What exactly do you, as Pythonistas, get in the browser, and what exactly can you do with it? Okay, so those are the three sorts of core questions. So we'll just get straight on. So what is PyScript? It's a platform in the browser. So if that big white box, if the white box is the browser, what's inside that? Well, at the very bottom, you have Python interpreters compiled to WebAssembly. Now WebAssembly is an instruction set for a virtualized sort of CPU. So WebAssembly and Wasm mean the same thing. Wasm is just a sort of shortening of it. And as we'll learn in this talk, what you get is an ability to be able to compile C and C++ code to the WebAssembly target and then run that in your browser. Now Cpython, the clue is in the name, is written in C, and so is MicroPython as well. So we can compile these to WebAssembly, and we can start making use of them. Now on top of that is PyScript. So PyScript is a platform that sits on top of these Python interpreters, and we, as we're going to show you in a second, try and make it as easy as possible for you to actually be able to start writing Python as quickly as possible, too. So we try and take care of the boilerplate and all the other bureaucratic things that we do to get PyDide, which is Cpython, into the browser, and MicroPython. And then on top of that is your code or frameworks that you might have written as well, so you can do useful stuff. And so PyScript makes it simple to get Python in the browser, and that's really it. So how does PyScript work? I'm going to give you an empty example. This is an actual PyScript, as you'll see, but what you'll see is perhaps a simplified version of why we perhaps need PyScript. So we're looking at some HTML here. HTML is the language of the web, and if you look, there is a PyScript tag with some Python embedded in it, print hello world. And for me to make that work, if you look in the head tag of the HTML, you'll see that there is a script tag. We're going to be saying the word tag an awful lot in this presentation. There is a script tag that has a source of PyScript.js, and that's really all you need to reference, and then you get Python in the browser. So let's have a look at that working. Let's see if this works for me. Hello world. There you go. Woo-hoo. You've not seen the implementation yet. So how does this work? So what's in the PyScript.js file that I was referencing? And remember, this is a dumb down example just so that for the purposes of pedagogy, I can sort of show you the sorts of tricks that we have to do. So to create the PyScript element, I need to create a class in JavaScript, because JavaScript is a JavaScript file, and there is a base class called HTML element, and I'm basically declaring I want a new PyScript element, HTML element. And then what I do is I override something called connected callback, which is called whenever the browser encounters this tag in the DOM. Okay. And what do I do? Well, I grab the code, the print hello world, from inside the tag, and then I instantiate my Python interpreter, and then I interpret the code and emit it out to the... I put the answer as the textual content of the PyScript tag. And then right at the very end, I call a built-in function, custom element.define, and this is where I'm saying, well, you see PyScript, Py-Script. I want that to be handled by the PyScript class. Okay. Oh, my. So clearly that's not how we do PyScript, because you can't do a lot with that version of Python, that's Nicholas's Python. So what we're going to do is actually add a Python interpreter. And I'm going to call out Damien George, who's actually in Melbourne, Australia at the moment. But Damien has created a version of Python called MicroPython, which is designed to run in highly constrained environments like microcontrollers. Now, little did he know that you could compile this to WebAssembly, and all of a sudden, people are very interested in using MicroPython for that particular context. So what we're going to do is take MicroPython as a very simple and quick and small Python interpreter and add this to our nascent PyScript, as it were. All told, though, just some interesting facts about MicroPython, actual MicroPython is about 170k to download, which is one of the most images on the website, if you think about it. Okay, so for that size, you get a pretty comprehensive Python interpreter. It's small, it's fast, and this is what we want to use. So, here we go. This is some code that I'm going to run, and if I can find my pointer, boom, boom, boom, where's it gone? Oh, there we go. If I click view, there we go. Hello world from MicroPython. And if I view source, just so that you can see that we do actually have some Python that we're interpreting that. So hello world from MicroPython. So how does that work? Well, back in the land of JavaScript, back in the HTML derived class, I grabbed the textual content of the element, which is the Python file, and then I set it to blank. And then I rebind this to self. Those of you who use JavaScript might be smiling. JavaScript has a complicated relationship with the notion of whatever this keyword might refer to. Okay, so I'm making sure that I've got a handle on that. And then what I'm doing is I am creating a callback function that listens to an event called MicroPython print. And all that call function does is append whatever data is being passed in via that event to the inner text of the element. Okay? Now, MicroPython print is an event that MicroPython itself emits whenever it prints anything to standard out. Okay, so that's how we get stuff from inside the interpreter outside into the browser. And then when this code is evaluated, at this moment in the life cycle of the page, we will have available to us an mpjs-dustra, MicroPython JavaScript version, do this string, and we pass in the code because we've got everything sort of set up. Okay? That's part one. Part two is actually we have to get MicroPython into the web page. Okay? So what do I do? Well, I manually, in my code, create a new script element, then I reference the MicroPython.js file as the source of that script element. Now, MicroPython.js is an asset that is created when we compile MicroPython into WebAssembly, and it does all the boilerplate of setting up the interpreter for us. Okay? And then this new script element that I've created, I create a new callback function that handles the onload, which is called when MicroPython has been downloaded and is sort of running. Okay? And within that event handler, what do I do? Well, it's a bunch of stuff, but lines 33 and 34 are important because that's where I actually instantiate the MicroPython interpreter and give it the huge memory size of one megabyte to work with, which is massive for MicroPython. Okay? What you need to know is that MicroPython has dynamic memory growth as well, so it will grow now to fit whatever strange objects you try and manipulate with it. And then remember how I told the browser about the PyScript tag and to use this class? Now that I know that we have Python ready in the browser, I use custom elements dot define, PyScript, and use the PyScript class that I defined above in part one. Okay? Are you paying attention? This is JavaScript. We're going all over the place here. And at that point, the browser will pick up on the PyScript tags and start to do its stuff as well. But we're not finished because I need to get a reference to the head tag in the document and then insert the script tag that I've just created into the head tag, and only when I do that does all of this kind of stuff unravel, and eventually we get MicroPython in the browser. Okay? So this is kind of stand on one leg, stick your finger in your ear, whistle God save the queen, and you get a Python interpreter in the browser. Okay? So PyScript doesn't work like this, but I hope that you can see some of the more convoluted things that we have to do to actually get Python in the browser is simply for you between two PyScript tags. Okay? But so, yeah, quite. It's quite a process. So why would you want to do this? So this is a question that Fabio likes to ask. You want to share this really complicated Python application with Grandma. Okay? Now Grandma, and the thing against Grandma's, but Grandma is a placeholder for a non-technical person. How would you do that? How confident would you be phoning up your Grandma and going, I've got this print hello world app that I want to test out on you, and she knows nothing about computers. How would you do that? How confident would you be to do that? Well, okay. All the things that we usually say, like, okay, well, first download Python and then you need to open your terminal. What's the terminal, darling? It's that black... Oh, no, never mind. Hang on. Okay? Now pip install this thing. This is complicated stuff, okay? So if we can just say, why don't you go to this website, and in there is your Python app, your print hello world Python app. That allows people to get to your code a lot quicker in a lot less fraught way as, you know, download Python, pip install the thing, condor install the other thing, blah, blah, blah, blah, blah, blah, blah. Okay? So the Python script is just a platform for Python in the browser, and Python runs anywhere now. There is a browser. So this is a short video. This is pyescript.com, which Anaconda has built, and it's a very simple IDE for, well, editing Python in a browser, and you can run Python in the browser. And Antonio, my colleague, Antonio Cooney, who's famous for PyPy, who's down there, is a great artist, you know, Roberto, Giotto, sorry, not Giotto, you know, Leonardo, Michelangelo, and now we can say Antonio, because this is his version of the PyScript rabbit. And now it makes an appearance whenever we do demos and things like that. So there's Antonio's rabbit in a regular web browser, okay? Now, here's the same code running on a browser on my rather old mobile phone, okay? Now, all of a sudden, we now have Python running in a browser on a mobile phone. Now, if you are a child at school and you are learning to code, your primary computing device is one of these, okay? And you can now get your code running on your mobile phone. But that's not all. You can actually run it on any appliance that has a browser in it. I kid you not. Although Fabio said you're going to have a big problem expensing that expense and a condom. But imagine, if you will, what running Python in the browser now gives you a chance to troll a beloved colleague on stage at EuroPython using a silly car. But imagine what you could do, okay? We are bringing the world of the web in all its colorful glory and the world of Python in all its colorful complexity and glory. We are putting together and we are asking, okay, if they had a baby, what would that look like? And our answer is it kind of looks like PyScript. Now, you can yourself run this PyScript bunny on your mobile phone and let's hope that the conference Wi-Fi is working. But just QR code the thing, there's a tiny URL that will redirect you to the source code on PyScript.com. And if you look to the right, you can start to view source and it will take you to an IDE that will let you start to edit that as well. So how is Python able to run on the browser? What about kind of operating system layer? Because it's just a browser, right? How does that work? I can see people still with their phones up. So I'm just going to pause here for three seconds, two seconds, one second. Somebody's got the bunny running. I can see it already. Yeah, just hold it up. It's going to be awesome. Look at that. Antonio, this is a moment. Please give Antonio a round of applause. Stand up! Stand up! No, no, no. He'll sign them later. If you have a pen. So how is Python able to run in a browser when it doesn't have an operating system underneath? Well, the simple hand-wavy answer is we use something called M-scripten, which is a part of the compiler toolchain that also allows us to abstract away things like a file system or sockets or all the other things that one might get from the operating system layer of things. And that is compiled so that when Python source code asks for system calls, there's an equivalent for the browser in there. So it's like libc or posix or the Win32 layer, things like that, okay? So that's M-scripten. It's fast as well, I need to say. So how do you create an environment in which you can run Python? Now, this is a favourite subject for all of us, isn't it? Because some people use poetry, some people use pip, and there's virtual environments, or there's condor, or blah, blah, blah, blah, blah. Well, what's the story here? Well, packaging with Pyscript is mostly like Python. Actually, your browser tab is actually your virtual environment. The browser is probably the best sandboxed computing environment in the universe, because let's face it, it's the most used piece of software in the universe, and we've had a lot of experience securing this particular sandbox so that nefarious people can't do nasty things, because we don't want them to be able to do that. And the web world has spent 27, 28, maybe even 30 years, I'm trying to remember when I was first released, maybe even 30 years ago, gosh, I feel old, because I remember when that happened, I was in university. They've spent a lot of time and effort making sure that these secure computing environments. So your browser tab is like a virtual environment. And then we use a tool called MicroPip which allows you to install packages from PyPI, and it just works. Except, packaging with Pyscript is mostly like packaging with Python, okay? Those packages that have C extensions need to be compiled to WebAssembly. And Hoode and Roman and others involved in PyDide I'll come onto that in a second. I've been making sure that we have some sort of a story so that when you upload packages to PyPI, you can get it compiled to WebAssembly and it should work. Also, every time you open that new tab, you need to install the packages each time you navigate to that URL. Now, there are subtle ways that we can use caching and things like that to speed things up, but we're still working on that sort of thing as well. And actually, sometimes the browser isn't actually a friendly place for some of the popular packages like requests, which works in a blocking way, whereas the browser works in a non-blocking way. Now, there are ways of patching requests and things like that, but it's not just the simple story requests, request.get some URL. Okay? Work is ongoing with these sorts of puzzles. So, let's explore how you go about using packages by exploring the R package that's published on PyPI. R does exactly what it says in the Timp. It's PirateSpeak for Python. And the thing I like about it is that it has a serious code of conduct and a serious conduct, so pirates are greedy, inconsiderate and respectful and so on and so forth. But I wrote R as a teaching project, okay? And so what I need to do is show you the code and I've lost my pointer again. Where's it gone? Okay. So let's explore what happens. So if I go and visit the R website that I built with PyScript and here's hoping that it works loading conference Wi-Fi. Here we go. So this is an older version of PyScript. And we're downloading PyDide, which is the version of Python that we're using. It's probably downloading loads of Antonio's rabbits at the moment, which is why we can't see this happening. Oh, come on, conference Wi-Fi. Anyway, the important thing is that you get a web page. You type some English in here and then you click the translate button. Here we go. So if I type in here, hello. You're a Python, full stop. I hope this works. Let's find out. And then click the translate button. Hoi, you're a Python. I hope this works. Splice the main brace. Let's find out. So we get some pirate speak back. And well, how does that work in Python? So if I go view the code on PyScript.com, we can see I import R and then I grab the input text. I pass it to the R library, okay, to get a translation of what the English text is and just set the inner text to that. But just so that I can set up my environment, which is the point I'm trying to make here, I have a file and inside that I have a name of a package on PyPI and in the background it just works. It grabs the thing that you need, okay? Nice and simple. The black pearl. So what run times do we have available in PyScript? Well, we have Piedite and this is a version of C Python that Hood and Roman, if you're here, could you just wave? He's not here. He said he would be here. Oh, well, never mind. Hood and Roman, you'll see them around. They have done a huge amount of work on Piedite to get C Python working really effectively and efficiently in the browser, okay? We also have MicroPython. Damien has done some magnificent work very recently on getting as MicroPython in the browser. But at the heart of the next version of PyScript is something we're calling PolyScript. I also need to call out my colleague Andrea who's done some incredible work on getting this to work. Now, if you can have more than one run time, you know, perhaps we could have Lua to this. We've also had Ruby working as well, so you can now start to get all sorts of interesting scripting languages into the browser. We're just trying to help make it easier, but clearly this is PyScript on Python in the browser. So the two platforms that we say that we support are Piedite and MicroPython, although we have been experimenting with Lua and Ruby, okay? So we've got Python, A Python in the browser and now we want to use Python to interact with the browser. How does Python get to the DOM, the document object model, the representation in the computer's memory of what's being displayed on the screen that we write as HTML, okay? Well, it's very simple. You just import JS and the JS object point is a proxy to the global this that you get in the browser and off that you actually get the document object and all the other APIs that you have available to you in the browser just from JS that you import there. This is a FFI foreign function interface that's been written in Piedite, that was some fantastic work that Hood did and Damian has used the same API although it's a rewritten version for MicroPython to give us the same capability, okay? So import this, so what can you do? Well, consider this very simple example of HTML, okay? I have a button with an ID of click me. What does that look like now in PyScript? Well, from JS I import the document, okay? I define a handler function in Python, okay? I do some stuff where I create a new span element, I insert a mouse into it and then I append it to the body of the document and then I just use document.query select it to get me the button that I've just created and then I use the button reference to the event listener that I've created in Python. So what does that look like? Where are we? Click me. There we go. Now, did you see how quickly that loaded? That was MicroPython running in the background, okay? And that, as we know, is running on conference Wi-Fi so if it works quickly there, it's going to work quickly anywhere, really, okay? So we have also full access to all of the things, not just interfacing with the DOM and manipulating the DOM, okay? So we can do other things. So consider this. I have a button and a video element, okay? And in this fragment of Python code, okay? I do all the things that I might normally do in JavaScript but do it in Python because we're just using proxy objects from the JavaScript world from Python, okay? And we can do our code that you really need to see, okay? If we go look at it, let's see if I can make this work. Very fast start-up time. Thanks to MicroPython. I've lost my thing again. Let's see. Start camera. Okay. There I am. And just take a photo. Now I need to look gorgeous here. Okay. Good. And then I can, oh gosh, then I can download the whole written in Python. Okay? And it started like that. My point being is that you get full access to all the capabilities of the browser from Python. Now this example is based on some work by a wonderful friend of mine called Professor Chris Rogers at Tufts University. Now, Chris, Chris is the, well, they're all grinning, the insanely grinning gentleman on your right-hand halfway up. That's Chris and there's Ethan and Jen as well. And some photos of some of the stuff that they do at Tufts. He's the head of the CEEO, the Center for Engineering, Education and Outreach. And for perhaps the last 25 to 30 years, Chris and his colleagues have been researching and experimenting how do we teach engineering and computing and robotics and all of those really cool subjects, okay? Whenever I go and visit him in Boston it's like, I don't know, it's like a child in a sweet shop, but for nerds because there's like Lego, there's a robot over here, there's some Python running, blah, blah, blah, blah, blah, it's wonderful. It's really great and he's a very enthusiastic, well, all of them are very enthusiastic teachers and their students are wonderful as well, okay? Now, part of their curriculum is using Internet of Things. So, this is something that they built with PyScript. There's PyScript.com, plug in an egg, press a button, the Lego thing starts and you have an automated killer Easter egg robot thing for decorating Easter eggs. And this was being used at the White House's annual Easter egg roll that Ethan went to and he had a whole bunch of kids lining up to use MicroPython running on the Lego and well, Pythons everywhere, really, in that example as well. I really love that, but it means that because we can use the browser's USB serial API, we can get access to the Internet of Things, we can get access to Bluetooth Things and all the other sorts of good stuff that we have, okay? So, okay, that's the source code for the egg roller, should you be interested, but of course, you need a Lego robot and an egg, actually, and a felt-tip pen to make it work, okay? So, talking of things that spin, have you ever seen this on a webpage? I'm sure you have. When you see that kind of, like, rotating beach ball of doom which is telling you your computer is busy, what you're actually doing is you're blocking the main thread on the browser, okay? You're blocking the piece of code that is consistently updating on the in the viewport that you can see in your browser, okay? And you don't want to do that, okay? If you have an infinite loop in JavaScript in the main thread, you're just going to block, okay? And it's the same with PyScript and Python, okay? So, please, don't block the main thread, okay? So, what do we do? There is a solution. Good, it all fits on the screen. In the world of the web, there is a concept called a web worker and now the equivalent, I guess, is something like having a new sub-process or starting new sub-processes on your webpage, okay? And so, web workers are sort of similar to separate processes running in the background of your webpage. So, you put all your expensive computation on there whilst keeping the main thread unblocked, okay? PyScript's next version supports this. I've been using this and we'll see a demo soon. And it even has a simple API for proxying from the web worker back to the DOM on the main thread so you can start to do inter-process communication and manipulate what's going on in the browser. So, how do they work? Well, there's a sort of a cross-worker proxy between the main thread and the worker and this ex-worker proxy kind of is helping with the message parsing, the conversation. I was trying to think, how do you represent a conversation and I could only think of something like what's out to do that. So, essentially, we've got a kind of conversation going on, okay? And we have transparent message parsing done in a way that will pause the worker allowing for synchronous Python code whilst the main thread remains unblocked, which is an important thing that you need to be able to do because, of course, in this type name equals input what is your name, the Python interpreter on your desktop blocks and you need to be able to have the same capability in the browser as well, okay? It also allows us to have the Python debugger which is another thing Antonio is famous for. It's bunnies, pi, pi and debuggers, okay? So, what does that look like in Python? Well, on the main thread I just import an ex-worker a reference to the ex-worker class and then, I don't know, I'm going to spin up 12 web workers and I just say I want you to run pom-pom.py using that particular configuration file so we know what packages you've got and I want you to run that with MicroPython, okay? And on the worker end of things, we've got the turtle module, which is doing a whole bunch of turtley things, okay? The hint is in the name, pom-pom, okay? That will draw us some pom-poms and then we're doing some communication back to the main thread to say you know what? The stuff that I'm using I'm generating from the turtle module I want you to insert that into the DOM so actually what we get to see is something that looks like this. Lots of pom-poms. There we go. Turtles all the way down, okay? So this is a video. I'm not going to try and attempt this without the aid of a safety net in front of EuroPython with conference Wi-Fi. But there we go. Anyway, you can do this. It's a good example. And here's the QR code. I can see everybody reaching for your mobile phones. Click, click, click, click, okay? Because Firefox hasn't caught up with some of the nascent Web Worker specifications, this only works on recent versions of Chrome and it may melt your laptop, okay? We just had a talk from Sophie. This is a great way of getting it to that rocket engine level of heat, okay? Because the browser is actually doing an awful lot in sub-processes there. So it's very early days and we're only just scratching the surface of PyScrip's potential, both for the Python world and the world of the browser. And PyScrip is what you get if the Web and Python had a baby. We've had the baby and now it needs nurturing, which is kind of where you lot come in as well, okay? So please come and talk to me, come and talk to my Anaconda colleagues as well. Look at the source code, contribute to the source code. Write goofy things on PyScrip.com or maybe use PyScrip to build an app that runs on a mobile phone. That would be interesting to see what you build, okay? So some final thoughts before I end. PyScrip is a platform, so you build things on top of it. PyScrip as a platform looks after a whole bunch of other stuff underneath it. It runs everywhere a browser runs and we've seen that's pretty much everywhere these days. And you write your code and your frameworks on top of PyScrip. It's open source, so please come and play. And as Peter likes to say, it's for the 99%. It's not just for coders. This is why I joined the project really. One of the big motivations here is that we try and make programming an empowering experience rather than okay, Grandma, download Python, now pip install the thing, now do the da-da-da-da-da. PyScrip, if you're a school teacher, is a real blessing because you don't have to bother your sys admin to try and get Python done. You can just tell kids to point their browser at a thing and PyScrip just works. It's a great teaching tool. Okay. These are some of the PyScrip maintenance. It's a lovely bunch of people. So we're friendly. Come say hi. And stay here in this room for the following talks. Running Python packages in the browser with PyScrip, that's Roman, I don't know if he's here. He's here. He's the first person we use in PyScrip. He's immediately after this talk. That's going to be a really interesting talk. And then we have how to draw bunny rabbits by Antonio, sorry. The CPU in your browser, web assembly demystified by Antonio. He's immediately after Roman. And then I have my friend and colleague who is over there. Dr. Russell Keith McGee, all the way from Perth, Australia, is going to be a very fascinating journey. I can tell you. So please say hello in the corridor track and in the sprints and all the other places that we are. And that's it. Any questions? Thank you, Nicholas. So there was one question in Discord and as I read this out there's microphones here. So you may line up by the microphones and ask your question in person. So the very first one is will you be sharing the slides for this? Oh, you read it. Excellent. Okay, please. Yes, a little question. In one of the apps we saw there was a callback for a picture and a callback for video. One was async and the other was a normal Python function. When do we use asynchronous functions? And when do we use normal functions for callbacks in a PyScript? Thank you. That's a very good question. JavaScript is an asynchronous language. You await things in JavaScript. Clearly, you can't await things in a regular function. You have to await things in an async function. So you just define your Python function that awaits the JavaScript thing in an async way and it just works. Yep, next. Hello, Nicholas. Thank you so much for your report, I guess. I have a question. Is the PyScript support some kind of a type hinting or is there any possibility to integrate it with some static linters or something around that? Okay, so what you get is Python in the browser. So if Python can do it and Py died is Cpython, then you can do it in PyScript. That's it. Okay, nice. Cool. You're welcome. Next question. Thank you for the talk as well. You're welcome. Did you make timing tests? So same functionality for JavaScript and Python and what's the ratio for the timing? That's a really good question. And the answer is I don't know because if you imagine software is developed in three stages famously. I can't remember who said this. The first stage is the standard work. And the second stage is just make it work properly. And the third stage is if and only if you need it, now make it work efficiently. And I think where we're at is stage two. With the next version of PyScript, we've kind of ironed out all the kinks and the implementation details. But does it work efficiently? I don't know. We're getting there. I guess the answer. Thank you. We have a gentleman who's stood at the back. Thank you. What are the limitation of PyScript? Do you know examples of the apps that cannot be done with PyScript? Yes. Funnily enough, turtle can't be done with PyScript because it requires tkinter. No browser. So what you saw was a bodge that I hacked together from somebody else's code I found on blah, blah, blah, you know, the typical sort of thing. So there are examples of modules in the standard library that clearly don't make sense in the context of a browser. So tkinter. For example, what about connecting to the database from PyScript? That's a really good question. So usually what you do is you connect to the database through ports. Now, because the browser doesn't give you ports, you have to do either web sockets or an HTTP connection, then you can't directly connect. So you usually have some sort of proxy in between. And that's something that we're going to be adding to the PyScript.com website. So there's a way to allow you to proxy to other things that you might need to connect to, like third-party APIs or whatever else it is. So it will be in JavaScript? I don't know. That part of the team. Okay, and do you have any idea how to store secrets for external API? Again, that's the proxies job because, as you know, if it's in the context of the browser then the user or something in the user space will be available. Okay, do you have any examples of ready proxy in the code? Not right with me. Okay. This is something you should ask on our Discord channel. My colleagues will get back to you. Before we take another question from the front, there's one question on Discord. Did you try running PyTest in PyScript? I imagine it could be useful. Yes, I'm working on a framework that sits on top of PyScript. And the unit tests are refreshed to the page and PyTest works. And you would normally see in PyTest. And we will have time to take one or two more questions, please. Hi, thank you for the inspiring speech. First of all, I have a question. Could we run Python functions directly from JavaScript? Let's say we have a hello world function in a Python script. Can we execute it from the JavaScript? Absolutely. I've been talking about Python in the browser but you could go from the browser and getting into Python as well. Absolutely. And our final question. Hi, thanks for the amazing work. Thank you. I have a question on maintenance on PyScript.com because I would like to share lots of data apps on PyScript.com for the framework and open source framework. But right now I can't maintain that when we update our framework and so on. If I have a lot of apps, how can I efficiently work with that automating stuff, testing stuff and a lot of data apps? Okay, so... The simple answer is you're talking to the wrong person because I'm on the open source team and we have a .com team who manage the features related to the website. But they're probably watching the live stream right now. Martin and Ted and Fabio are probably thinking about this already and it will be addressed. My advice if you have questions about can PyScript do this? PyScript.com is to go on to the Discord server and just ask and we're all on there and the right person from the right team will be able to answer your question. Fantastic. And that is all the time we have for questions. Thank you once again so much Nicholas. Thank you very much. Thank you for listening.