Skulpt profile

Skulpt is a system that compiles Python(around version 3.7) to Javascript. It compiles code that runs Python syntax directly in the browser in real time, but Python itself was not designed to run in the browser, so the browser-provided jsAPI does not work well with Python syntax. Conversely, Python’s ability to manage files on the client and schedule system resources cannot be implemented in the browser.

Although there are similar projects (Brython, Transcrypt), Skulpt is positioned not to call the browser API with Python syntax, but to do as much python as possible in the browser in order to run Python online, Skulpt is a widely used and flexible scheme at present. At present, the running system of online Python editors on the market (cat and turtle editor, Python lab of Tencent) all use Skulpt.

Skulpt can develop third party modules in addition to basic Python running, write module functions in javascript, and implement python syntax calls. For example, you can use JS echarts to implement PyEcharts, and then run Pyecharts online. Tencent’s Python lab has a CPGZero library that encapsulates a js game library in accordance with the usage of PyGame-Zero, with very high flexibility.

Quick start

Here is a snippet of HTML that shows Skulpt in action, and you can copy it to a file and run it in your browser.

<html>
  <head>
    <script
      src="https://cdn.jsdelivr.net/gh/skulpt/skulpt-dist/skulpt.min.js"
      type="text/javascript"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/gh/skulpt/skulpt-dist/skulpt-stdlib.js"
      type="text/javascript"
    ></script>
  </head>

  <body>
    <h3>Try This</h3>
    <form>
      <textarea id="yourcode" cols="80" rows="10">
import turtle
print('hello')
t = turtle.Turtle()
t.color('red')
t.forward(75)
  </textarea
      ><br />
      <button type="button" onclick="runit()">Run</button>
    </form>
    <pre id="output"></pre>
    <div id="mycanvas"></div>
    <script>
      function outf(text) {
        var mypre = document.getElementById("output");
        mypre.innerHTML = mypre.innerHTML + text;
      }
      function builtinRead(file) {
        console.log("Attempting file: " + Sk.ffi.remapToJs(file));
        if (
          Sk.builtinFiles === undefined ||
          Sk.builtinFiles.files[file] === undefined
        ) {
          throw "File not found: '" + file + "'";
        }

        return Sk.builtinFiles.files[file];
      }
      function runit() {
        var prog = document.getElementById("yourcode").value;
        var mypre = document.getElementById("output");
        mypre.innerHTML = "";
        Sk.pre = "output";
        Sk.configure({
          output: outf,
          read: builtinRead,
          __future__: Sk.python3,
        });

        (Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = "mycanvas";
        var myPromise = Sk.misceval.asyncToPromise(function() {
          return Sk.importMainWithBody("<stdin>".false, prog, true);
        });

        myPromise.then(
          function(mod) {
            console.log("success");
          },
          function(err) {
            console.log(err.toString()); }); }</script>
  </body>
</html>

Copy the code

Skulpt built-in module

Skulpt has some common modules built into it:

  • turtle
  • math
  • random
  • time
  • sys
  • .

There are also many modules that are not implemented, or only partially implemented:

  • urllib2
  • md5
  • os
  • .

If you want to see all the built-in modules you can print sk.builtinfiles.files on the browser console after running the sample code above

The.py suffix is unimplemented, the.js suffix is implemented, and you can see how few built-in modules are implemented. Many of python’s built-in modules are not yet implemented.

Third-party modules

I’ve only seen two or three of skulpt’s third party modules on Github, and the Skulpt community isn’t very active, probably because the project is so old and so few people are following it, that if we want to use a Python library we’ll have to do it ourselves.

Another reason WHY SKULpt has so few third party modules is that the documentation is abstract and incomplete, making it hard for beginners to know where to start. Here’s the skulpt development documentation. Feel it: skulpt.org/docs/index.

The first page is quite good, it introduces the comparison of skulpt before and after compilation in detail, and the difference between the two languages, which is very helpful for understanding skulpt. However, the first page is just an introduction, and the documents to be read in real development are not very careful. The API is not clear, and it is also incomplete, which is almost not helpful for development. I can only look at the source code to find some API usage.

As the development of skulpt official document did not play a role, and the community is not active, and no one had sent this online tutorial, so I will write this development guidelines, to help people just contact skulpt want development module provides some guidance, this guide will be considered to design a proper module should grasp those skulpt API, You just need to know what you need.

The simplest module

  1. So let’s create a new onemod.js, fill in the following code:
var $builtinmodule = function (name) {
	var mod = {__name__: new Sk.builtin.str("mod")}
	mod.add = new Sk.builtin.func(function(a, b) {
        return Sk.ffi.remapToJs(a) + Sk.ffi.remapToJs(b);
    });
	return mod;
}
Copy the code
  1. Add the following code to the HTML in the same directory:
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/gh/skulpt/skulpt-dist/skulpt.min.js" type="text/javascript"></script>
    <script src="https://cdn.jsdelivr.net/gh/skulpt/skulpt-dist/skulpt-stdlib.js" type="text/javascript"></script>
  </head>

  <body>

    <h3>Try This</h3>
    <form>
      <textarea id="yourcode" cols="80" rows="10">Import mod print(mod.add(1,2)) </textarea ><br />
      <button type="button" onclick="runit()">Run</button>
    </form>
    <pre id="output"></pre>
    <div id="mycanvas"></div>
    <script>
      // List of third-party modules
      var externalLibs = {
        // Make sure the module path is accessible, I'm using relative path here./mod.js
        "./mod/__init__.js": "./mod.js"};function outf(text) {
        var mypre = document.getElementById("output");
        mypre.innerHTML = mypre.innerHTML + text;
      }
      function builtinRead(file) {
        console.log("Attempting file: " + Sk.ffi.remapToJs(file));

        if(externalLibs[file] ! = =undefined) {
          return Sk.misceval.promiseToSuspension(
            fetch(externalLibs[file]).then(
              function (resp){ returnresp.text(); })); }if (Sk.builtinFiles === undefined || Sk.builtinFiles.files[file] === undefined) {
          throw "File not found: '" + file + "'";
        }
        
        return Sk.builtinFiles.files[file];
      }
      function runit() {
        var prog = document.getElementById("yourcode").value;
        var mypre = document.getElementById("output");
        mypre.innerHTML = "";
        Sk.pre = "output";
        Sk.configure({
          output: outf,
          read: builtinRead,
          __future__: Sk.python3,
        });

        (Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = "mycanvas";
        var myPromise = Sk.misceval.asyncToPromise(function() {
          return Sk.importMainWithBody("<stdin>".false, prog, true);
        });

        myPromise.then(
          function(mod) {
            console.log("success");
          },
          function(err) {
            console.log(err.toString()); }); }</script>
  </body>
</html>

Copy the code

We get the result of running this code:

If not, check that mod.js is accessible and correctly configured as described above.

Another way to load a module is to write a built-in module in skulpt’s source code and then compile a new skulpt-stdlib.js file to use as a built-in module, but this is not recommended.

It is not difficult to see from the above module code and the Python code in the browser that there is a corresponding relationship. By calling skulpt specific API, the ability of calling JS module in The Python code can be achieved.

summary

This article is a quick introduction to skulpt, and the next article will explain which skulpt apis you should use to build a decent module. There are no specifications for skulpt apis that are hard to remember, so just copy them when you need them.

Want to continue to understand the skulpt module development can enter the next skulpt development guide (ii) module development

In addition, I would like to declare again that I have only explored some SKULpt API usage, and my understanding of skulpt is not deep enough. If the article is wrong, please put forward correction, if there is a better learning article, welcome to share.

Possibly the first skulpt Chinese tutorial 🙃