diff --git a/docs/beginning-pyscript.md b/docs/beginning-pyscript.md index b35fe08..78f9983 100644 --- a/docs/beginning-pyscript.md +++ b/docs/beginning-pyscript.md @@ -35,8 +35,8 @@ All PyScript applications need three things: how your application works. Create these files with your favourite code editor on your local file system. -Alternatively, [pyscript.com](https://pyscript.com) will take away all the pain of -organising, previewing and deploying your application. +Alternatively, [pyscript.com](https://pyscript.com) will take away all the pain +of organising, previewing and deploying your application. If you decide to use [pyscript.com](https://pyscript.com) (recommended for first steps), once signed in, create a new project by pressing the "+" button on the @@ -246,6 +246,12 @@ static web host will do (for example, [Google Cloud](https://cloud.google.com/storage/docs/hosting-static-website) or [Microsoft's Azure](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website)). +## Run PyScript Offline + +To run PyScript offline, without the need of a CDN or internet connection, read +the [Run PyScript Offline](user-guide/offline.md) section of the user +guide. + ## Conclusion Congratulations! diff --git a/docs/user-guide/offline.md b/docs/user-guide/offline.md new file mode 100644 index 0000000..ee8abb4 --- /dev/null +++ b/docs/user-guide/offline.md @@ -0,0 +1,283 @@ +# Use PyScript Offline + +Sometimes you want to run PyScript applications offline. + +Both PyScript core and the interpreter used to run code need to be served with +the application itself. Two requirements are needed to create an +offline PyScript are: + +* Download and include PyScript core. +* Download and include the Python interpreters used in your application. + +## Get PyScript core + +You have two choices: + + 1. **Build from source**. Clone the repository, install dependencies, then + build and use the content found in the `./dist/` folder. + 2. **Grab the npm package**. For simplicity this is the method we currently + recommend as the easiest to get started. + +In the following instructions, we assume the existence of a folder called +`pyscript-offline`. All the necessary files needed to use PyScript offline will +eventually find their way in there. + +In your computer's command line shell, create the `pyscript-offline` folder +like this: + +```sh +mkdir -p pyscript-offline +``` + +Now change into the newly created directory: + +```sh +cd pyscript-offline +``` + +### PyScipt core from source + +Build PyScript core by cloning the project repository and follow the +instructions in our [developer guide](/developers) + +Once completed, copy the `build` folder, that was been created by the build +step, into your `pyscript-offline` folder. + +### PyScript core from `npm` + +Ensure you are in the `pyscript-offline` folder created earlier. + +Create a `package.json` file. Even an empty one with just `{}` as content will +suffice. This is needed to make sure our folder will include the local +`npm_modules` folder instead of placing assets elsewhere. Our aim is to ensure +everything is in the same place locally. + +```sh +# only if there is no package.json, create one +echo '{}' > ./package.json +``` + +Assuming you have +[npm installed on your computer](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), +issue the following command in the `pyscript-offline` folder to install the +PyScript core package. + +``` +# install @pyscript/core +npm i @pyscript/core +``` + +Now the folder should contain a `node_module` folder in it, and we can copy the +`dist` folder found within the `@pyscript/core` package wherever we like. + +```sh +# create a public folder to serve locally +mkdir -p public + +# move @pyscript/core dist into such folder +cp -R ./node_modules/@pyscript/core/dist ./public/pyscript +``` + +That's almost it! + +## Set up your application + +Simply create a `./public/index.html` file that loads the local PyScript: + +```html + + + + + + PyScript Offline + + + + + + + +``` + +Run this project directly (after being sure that `index.html` file is saved +into the `public` folder): + +```sh +python3 -m http.server -d ./public/ +``` + +If you would like to test `worker` features, try instead: + +```sh +npx static-handler --coi ./public/ +``` + +## Download a local interpreter + +PyScript officially supports *MicroPython* and *Pyodide* interpreters, so let's +see how to get a local copy for each one of them. + +### Local MicroPython + +Similar to `@pyscript/core`, we can also install *MicroPython* from *npm*: + +```sh +npm i @micropython/micropython-webassembly-pyscript +``` + +Our `node_modules` folder should contain a `@micropython` one and from there we +can move relevant files into our `public` folder. + +Let's be sure we have a target for that: + +```sh +# create a folder in our public space +mkdir -p ./public/micropython + +# copy related files into such folder +cp ./node_modules/@micropython/micropython-webassembly-pyscript/micropython.* ./public/micropython/ +``` + +The folder should contain at least both `micropython.mjs` and +`micropython.wasm` files. These are the files to use locally via a dedicated +config. + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/micropython/micropython.mjs" + + + + +``` + +### Local Pyodide + +Remember, Pyodide uses `micropip` to install third party packages. While the +procedure for offline Pyodide is very similar to the one for MicroPython, +if we want to use 3rd party packages we also need to have these available +locally. We'll start simple and cover such packaging issues at the end. + +```sh +# locally install the pyodide module +npm i pyodide + +# create a folder in our public space +mkdir -p ./public/pyodide + +# move all necessary files into that folder +cp ./node_modules/pyodide/pyodide* ./public/pyodide/ +cp ./node_modules/pyodide/python_stdlib.zip ./public/pyodide/ +``` + +Please **note** that the `pyodide-lock.json` file is needed, so please don't +change that `cp` operation as all `pyodide*` files need to be moved. + +At this point, all we need to do is to change the configuration on our *HTML* +page to use *pyodide* instead: + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/pyodide/pyodide.mjs" + + + + +``` + +## Wrap up + +That's basically it! + +Disconnect from the internet, run the local server, and the page will still +show that very same `Hello from PyScript` message. + +## Local Pyodide packages + +Finally, we need the ability to install Python packages from a local source +when using Pyodide. + +Put simply, we use the packages bundle from +[pyodide releases](https://github.com/pyodide/pyodide/releases/tag/0.24.1). + +!!! warning + + This bundle is more than 200MB! + + It contains each package that is required by Pyodide, and Pyodide will only + load packages when needed. + +Once downloaded and extracted (we're using version `0.24.1` in this example), +we can simply copy the files and folders inside the `pyodide-0.24.1/pyodide/*` +directory into our `./public/pyodide/*` folder. + +Feel free to either skip or replace the content, or even directly move the +`pyodide` folder inside our `./public/` one. + +Now use any package available in via the Pyodide bundle. + +For example: + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/pyodide/pyodide.mjs" + packages = ["pandas"] + + + + +``` + +We should now be able to read `[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]` on the +page *even* if we disconnect from the Internet. + +That's it! diff --git a/docs/user-guide/running-offline.md b/docs/user-guide/running-offline.md new file mode 100644 index 0000000..d4d4395 --- /dev/null +++ b/docs/user-guide/running-offline.md @@ -0,0 +1,235 @@ +# Running PyScript Offline + +Althought users will want to create and share PyScript apps on the internet, there are cases when user want to run PyScript applications offline, in an airgapped fashion. This means that both PyScript core and the interpreter used to run code need to be served with the application itself. In short, the 2 main explicit tasks needed to create an offline PyScript application are: + +* download and include PyScript core (`core.js`) +* download and include the [Python] interpreters you want to use in your Application + +## Downloading and Including PyScript's `core.js` + +There are at least 2 ways to use PyScript offline: + + * by **cloning the repository**, then building and installing dependencies and then run and then reach the `./dist/` folder + * by **grabbing the npm package** which for simplicity sake will be the method used here at least until we find a better place to *pin* our *dist* folder via our CDN and make the procedure even easier than it is now + +In the examples below, we'll assume we are creating a PyScript Application folder called `pyscript-offline` and we'll add all the necessary files to the folder. + +First of all, we are going to create a `pyscript-offline` folder as reference. + +```sh +mkdir -p pyscript-offline +cd pyscript-offline +``` + +### Adding core by Cloning the Repository + +You can build all the PyScript Core files by cloning the project repository and building them yourself. To do so, build the files by following the instructions in our [developer guide](/developers) + +Once you've run the `build` command, copy the `build` folder that has been created into your `pyscript-offline` folder. + +### Adding core by Installing `@pyscript/core` Locally + +First of all, ensure you are in the folder you would like to test PyScirpt locally. In this case, the `pyscript-offline` folder we created earlier. + +Once within the folder, be sure there is a `package.json` file. Even an empty one with just `{}` as content would work. +This is needed to be sure the folder will include locally the `npm_modules` folder instead of placing the package in the parent folder, if any. + +```sh +# only if there is no package.json, create one +echo '{}' > ./package.json + +# install @pyscript/core +npm i @pyscript/core +``` + +At this point the folder should contain a `node_module` in it and we can actually copy its `dist` folder wherever we like. + +```sh +# create a public folder to serve locally +mkdir -p public + +# move @pyscript/core dist into such folder +cp -R ./node_modules/@pyscript/core/dist ./public/pyscript +``` + +## Setting up your application + +Once you've added PyScript code following one of the methods above, that's almost it! We are half way through our goal but we can already create a `./public/index.html` file that loads the project: + +```html + + + + + + PyScript Offline + + + + + + + +``` + +To run this project directly, after being sure that `index.html` file is saved into the `public` folder, you can try: + +```sh +python3 -m http.server -d ./public/ +``` + +Alternatively, if you would like to test also `worker` features, you can try instead: + +```sh +npx static-handler --coi ./public/ +``` +## Downloading and Setting up a Local Interpreter + +Good news! We are almost there. Now that we've: + +* downloaded PyScript locally +* created the skeleton of an initial PyScript App + +we need to download and setup up an interpreter. PyScript officially supports *MicroPython* and *Pyodide* interpreters, so let's see how to do that for each one of them. + +### Download MicroPython locally + +Similarly to what we did for `@pyscript/core`, we can also install *MicroPython* from *npm*: + +```sh +npm i @micropython/micropython-webassembly-pyscript +``` + +Our `node_modules` folder now should contain a `@micropython` one and from there we can move relevant files into our `public` folder, but let's be sure we have a target for that: + +```sh +# create a folder in our public space +mkdir -p ./public/micropython + +# copy related files into such folder +cp ./node_modules/@micropython/micropython-webassembly-pyscript/micropython.* ./public/micropython/ +``` + +That folder should contain at least both `micropython.mjs` and `micropython.wasm` files and these are the files we are going to use locally via our dedicated config. + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/micropython/micropython.mjs" + + + + +``` + +### Install Pyodide locally + +Currently there is a difference between MicroPython and Pyodide: the former does not have (*yet*) a package manager while the latest does, it's called *micropip*. + +This is important to remember because while the procedure to have *pyodide* offline is very similar to the one we've just seen, if we want to use also 3rd party packages we also need to have these running locally ... but let's start simple: + +```sh +# install locally the pyodide module +npm i pyodide + +# create a folder in our public space +mkdir -p ./public/pyodide + +# move all necessary files into that folder +cp ./node_modules/pyodide/pyodide* ./public/pyodide/ +cp ./node_modules/pyodide/python_stdlib.zip ./public/pyodide/ +``` + +Please **note** that also `pyodide-lock.json` file is needed so please don't change that `cp` operation as all `pyodide*` files need to be moved. + +At this point, all we need to do is to change our *HTML* page to use *pyodide* instead: + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/pyodide/pyodide.mjs" + + + + +``` + +## Wrapping it up + +We are basically done! If we try to disconnect from the internet but we still run our local server, the page will still show that very same *Hello from PyScript* message :partying_face: + +We can now drop internet, still keeping the local server running, and everything should be fine :partying_face: + +## Local Pyodide Packages + +There's one last thing that users are probably going to need: the ability to install Python packages when using Pyodide. + +In order to have also 3rd party packages available, we can use the bundle from [pyodide releases](https://github.com/pyodide/pyodide/releases/tag/0.24.1) that contains also packages. + +Please note this bundle is more than 200MB: it not downloaded all at once, it contains each package that is required and it loads only related packages when needed. + +Once downloaded and extracted, where in this case I am using `0.24.1` as reference bundle, we can literally copy and paste, or even move, all those files and folders inside the `pyodide-0.24.1/pyodide/*` directory into our `./public/pyodide/*` folder. + +As the bundle contains files already present, feel free to either skip or replace the content, or even directly move that *pyodide* folder inside our `./public/` one. + +Once it's done, we can now use any package we like that is available in *pyodide*. Let's see an example: + +```html + + + + + + PyScript Offline + + + + + + interpreter = "/pyodide/pyodide.mjs" + packages = ["pandas"] + + + + +``` + +If everything went fine, we should now be able to read `[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]` on the page *even* if we disconnect from the Internet. + +And **that's all folks** :wave: \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index f7fbb14..a3d5827 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -77,4 +77,5 @@ nav: - Python terminal: user-guide/terminal.md - Python editor: user-guide/editor.md - Plugins: user-guide/plugins.md + - Use Offline: user-guide/offline.md - Example apps: user-guide/examples.md