Giter Club home page Giter Club logo

jupyterlab-blockly's Introduction

jupyterlab-blockly

Github Actions Status lite-badge Binder

Blockly extension for JupyterLab.

Blockly

Blockly is a library from Google for building beginner-friendly block-based programming languages.

Docs: https://developers.google.com/blockly/guides/overview Repo: https://github.com/google/blockly

Requirements

  • JupyterLab >= 4.0.0

Install

To install the extension, execute:

conda install -c conda-forge jupyterlab-blockly

or

pip install jupyterlab-blockly

Kernels

Uninstall

To remove the extension, execute:

conda uninstall -c conda-forge jupyterlab-blockly

or

pip install jupyterlab-blockly

Contributing

Development install

Note: You will need NodeJS to build the extension package.

The jlpm command is JupyterLab's pinned version of yarn that is installed with JupyterLab. You may use yarn or npm in lieu of jlpm below.

micromamba create -n blockly -c conda-forge python nodejs=18 pre-commit jupyterlab jupyter-packaging jupyterlab-language-pack-es-ES jupyterlab-language-pack-fr-FR ipykernel xeus-python xeus-lua
micromamba activate blockly
# Clone the repo to your local environment
# Change directory to the jupyterlab_blockly directory
# Installing pre-commit to run command when adding commits
pre-commit install
# Install package in development mode
pip install -e ".[dev]"
# Link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite
# Rebuild extension Typescript source after making changes
jlpm build

You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.

# Watch the source directory in one terminal, automatically rebuilding when needed
jlpm watch
# Run JupyterLab in another terminal
jupyter lab

With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).

By default, the jlpm build command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:

jupyter lab build --minimize=False

Development uninstall

pip uninstall jupyterlab_blockly

In development mode, you will also need to remove the symlink created by jupyter labextension develop command. To find its location, you can run jupyter labextension list to figure out where the labextensions folder is located. Then you can remove the symlink named jupyterlab-blockly within that folder.

Packaging the extension

See RELEASE

jupyterlab-blockly's People

Contributors

afshin avatar bollwyvl avatar denisacg avatar github-actions[bot] avatar hbcarlos avatar isabelparedes avatar jtpio avatar martinrenou avatar wolfv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jupyterlab-blockly's Issues

Support the light and dark theme

Since we have two themes available in JupyterLab (light and dark) would be great to support themes in blockly, so when changing to the dark theme, the blockly editor changes to follow the same design.

Some documentation to get started:

Make OpenCV blocks

Create custom blocks that use the OpenCV library.

Make blocks for the most used functions that let the user access computer vision or image processing techniques for learning or quick prototyping.

Blockly editor linked to JSON files

Blockly supports importing and exporting the workspace as a JSON or XML. To have better integration with JupyterLab, we should create a new DocumentWidget for JSON files to allow right-click -> 'Open with Blockly' in JSON files, at the same time this will allow us to use shortcuts like ctrl+s for saving directly to disk, plus some other functionalities from documents.

Some documentation to get started:

Design games using blocks

A great feature would be to create some games which the users can play using blocks, such as escaping a maze.

Each game can register a new toolbox, with each own set of blocks needed to play the game. The workspace would need an animation part, where the user can visualize the actions they are taking using the blocks.

This feature can also be an extension built on top of jupyterlab-blockly, e.g: jupuyterlab-blockly-games.

Export and execute the code

To execute the code generated by blockly, we can use kernels. The idea would be to add a button in the toolbar to allow the user to run the code and show the output on another widget.

Some documentation to get started:

We can link the document to a kernel, add a small icon in the toolbar to see the status of the kernel, and select a kernel. Once we have a kernel connection, each time the user modifies the code, we can export it and send a completeness message to the kernel to check whether the code could be executed and add a small indicator for the user.
When the user presses the execution button, we can export the code as Python, send it to the kernel with an execution request and show the response in an OutputAreaWidget.

Kernel status indicator

Include the kernel status indicator next to the kernel name that is being used for the workspace, as it is done in notebooks.

Screenshot from 2024-08-20 12-02-08

Important to note that this feature might need some adapting as the busy status indicator for notebooks also mentions the number of cells that are running, in our case maybe this could be translated to the blocks that are running or removed altogether.

Screenshot from 2024-08-20 11-57-14

This is the relevant code section that defines the KernelStatus class in which the KernelStatusComponent is rendered.

Additionally, the kernel status indicator can also be added to the status bar.

Separate extension for Niryo

Now that we know it works, we should move the Niryo specifics to another extension keeping Blockly as a generic editor that we can extend for multiple purposes.

We can use the cookiecutte to create a new extension for JupyterLab.

We should move the plugin for Niryo

import BlocklyNiryo from './niryo/niryo_one_python_generators';
/**
* Initialization data for the jupyterlab-blocky extension.
*/
const niryo: JupyterFrontEndPlugin<void> = {
id: 'jupyterlab-blocky:niryo',
autoStart: true,
requires: [IBlocklyRegisty],
activate: (app: JupyterFrontEnd, blockly: IBlocklyRegisty): void => {
console.log('JupyterLab extension jupyterlab-blocky-niryo is activated!');
blockly.registerToolbox('niryo', BlocklyNiryo.Toolbox);
}
};
export default [plugin, niryo];

as well as the javascript module where we create the blocks, generators, and toolbox
https://github.com/QuantStack/jupyterlab-blockly/blob/main/src/niryo/niryo_one_python_generators.js

Something to have in mind, by default the cookiecutter doesn't allow javascript, after creating the new extension, we need to configure it to allow javascript by adding these lines to the tsconfig.json

"allowJs": true,

"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.tsx", "style/icons"],

Internationalization

Since Jupyterlab and Blockly support translations and localization would be excellent to support it on the extension.

Some documentation to get started:

The idea would be to add the dependency ITranslator from JupyterLab, listen to the translator and when it changes, load the corresponding language in blockly or default to English in case the language is not supported.

Note: I'm not sure if we can listen for changes in the ITranslator or if there is a way to know what language is loaded in Lab.

For how to import the ITranslator and load it, see the following example:
https://github.com/jupyterlab/extension-examples/blob/8bc09d2839efed8078c9fbc43da0fd39a0b7d0a3/signals/src/index.ts#L55

For every other UI feature, we add to the extension, we need to add the labels using trans.__('Label Example');, see:
https://github.com/jupyterlab/extension-examples/blob/8bc09d2839efed8078c9fbc43da0fd39a0b7d0a3/signals/src/index.ts#L81

Blocky language

Hi,
I installed blockly using 'development install' but the toolkit is not in english language. How do I change that?
Thanks

Make ipycanvas blocks

Create custom blocks that use functionalities from ipycanvas.

ipycanvas is a lightweight, fast and stable library exposing the browser's Canvas API to IPython. It allows you to draw simple primitives directly from Python like text, lines, polygons, arcs, images etc. You can read more about it here.

Notebook with `Blockly` cells

It would be a great advancement to create a notebook which has Blockly cells, instead of the normal space to write code.

The toolbox could be integrated as a side panel and users could drag and drop blocks in the designated cells.

The cells themselves would become stand alone workspaces.

Initial text overlap on blocks

When first launching the extension, the blocks present in the workspace and the blocks inside the toolbox appear distorted, as the text is overlapped on them.

Workspace and toolbar with overlapped text

Once you go through the toolbox categories the blocks contained inside appear normal. It seems that once the user opens a category in which the blocks are fitting inside the original toolbox flyout space (such as the Variables category), the blocks stop having overlapping text and get formatted properly in all other categories as well.

The problem seems to be with the toolbox flyout space which doesn't seem to resize accordingly to what the blocks need, or it might just be coming from how the blocks are rendered originally, as the blocks situated in the workspace when the file is first opened, appear with overlapped text and cannot seem to be fixed.

Make it possible to create blocks from Python?

Potentially we could define some custom blocks from a Python script or from a Notebook if we use some decorators.

Something like:

@block
def myfunction(a: int, b: int) -> int:
    return a + b

Error when importing the `IBlocklyRegistry` token

When importing the IBlocklyRegistry token in another extension, I'm getting the following error:

Plugin 'jupyterlab-lego-boost:plugin' failed to activate.
Error: No provider for: jupyterlab-blockly/registry.
    at e.resolveRequiredService (jlab_core.ace489612104403d9b5e.js?v=ace489612104403d9b5e:2:1343887)
    at jlab_core.ace489612104403d9b5e.js?v=ace489612104403d9b5e:2:1343444
    at Array.map (<anonymous>)
    at e.activatePlugin (jlab_core.ace489612104403d9b5e.js?v=ace489612104403d9b5e:2:1343418)
    at jlab_core.ace489612104403d9b5e.js?v=ace489612104403d9b5e:2:1344610
    at Array.map (<anonymous>)
    at e.start (jlab_core.ace489612104403d9b5e.js?v=ace489612104403d9b5e:2:1344584)
    at G (7796.25a9965c8e0e6c74a3ed.js?v=25a9965c8e0e6c74a3ed:1:8374)

The code used to import the IBlocklyRegistry token in the extension is (code snippet taken from this PR):

import { IBlocklyRegistry } from 'jupyterlab-blockly';

/**
 * Initialization data for the jupyterlab-lego-boost extension.
 */
const plugin: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-lego-boost:plugin',
  autoStart: true,
  requires: [IBlocklyRegistry],
  activate: (app: JupyterFrontEnd, blockly: IBlocklyRegistry) => {
    console.log('JupyterLab extension jupyterlab-lego-boost is activated!');
  }
};

I started getting this error after we made the latest patch release 0.1.1, in order to incorporate this PR #62 which fixes a typo regarding the spelling of the IBlocklyRegistry. As far as I investigated, nothing else was changed regarding the logic of the code. The JupyterLab-Niryo-One extension is using the 0.1.0 version and everything works perfectly, the code base can be seen here.

From the documentation I read it might be a problem from the deduplication of dependencies, but we didn't change anything there in the new release. The package.json file:

"jupyterlab": {
"extension": true,
"outputDir": "../../jupyterlab_blockly/labextension",
"sharedPackages": {
"jupyterlab-blockly": {
"bundled": true,
"singleton": true
},
"blockly": {
"bundled": true,
"singleton": true
}
}
}

I also noticed that when installing the extension locally in my environment, using pip install jupyterlab-blockly, the error is fixed.

NOTE: The IBlocklyRegistry is the class that the JupyterLab-Blockly extension exposes to other plugins. This registry allows other plugins to register new Toolboxes, Blocks and Generators that users can use in the Blockly editor. So, it is essential when creating an extension on top of JupyterLab-Blockly.

Make blocks for Arduino

Create custom blocks to program an Arduino board.

Arduino consists of both a physical programmable circuit board (often referred to as a microcontroller) and a piece of software, or IDE (Integrated Development Environment) that runs on your computer, used to write and upload computer code to the physical board. Arduino boards are able to read inputs - light on a sensor, a finger on a button - and turn it into an output - activating a motor, turning on an LED. You can read more about it here.

Incompatible with JupyterLab 4.1.5

When trying to run jupyterlab-blockly on JupyterLab 4.1.5 (current latest, didn't work with previous 4 versions either) the following errors are printed in the Browser's Javascript console:

image

jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1 Plugin 'jupyterlab-blocky:plugin' failed to activate.
(anonymous) @ jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1
jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1 TypeError: mainMenu.kernelMenu.kernelUsers.add is not a function
    at activate (index.js:163:1)
    at jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1715670
    at async Promise.all (index 164)
(anonymous) @ jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1
jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1 TypeError: Cannot read properties of undefined (reading 'createCellHeader')
    at $e.initializeDOM (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:246971)
    at $e.initializeDOM (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:250923)
    at set placeholder (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:243844)
    at $e.onBeforeAttach (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:247939)
    at $e.processMessage (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1781568)
    at b (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1753611)
    at Object.o [as sendMessage] (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1752442)
    at BlocklyLayout.onBeforeAttach (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1787213)
    at BlocklyLayout.onBeforeAttach (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1795177)
    at BlocklyLayout.processParentMessage (jlab_core.23e8a6b191d1fa15c1b7.js?v=23e8a6b191d1fa15c1b7:1:1786612)

None are shown server-side (I assume because the instructions never reach it due to the browser errors, probably due to interface changes?)

In the browser the blockly interface can be used properly but neither running it nor the code preview screen shows. (It simply stays empty I assume because the JavaScripts fails)

(Using it with JupyterLab 3.16 as indicated by the readme works fine though but being able to use an up to date JupyterLab version would be nice and I didn't find an issue regarding this yet)

Toolbar kernel actions buttons

The toolbar buttons for the kernel actions can be added, so it's easier for users to access them.

Screenshot from 2024-08-20 11-50-11

Currently the actions are only present inside the Kernel Menu. The commands are defined here:

// Register kernel commands.
commands.addCommand(CommandIDs.interruptKernel, {
label: 'Interrupt Kernel',
execute: args => {
const current = getCurrent(args);
if (!current) {
return;
}
const kernel = current.context.sessionContext.session?.kernel;
if (kernel) {
return kernel.interrupt();
}
return Promise.resolve(void 0);
},
isEnabled
});
commands.addCommand(CommandIDs.restartKernel, {
label: 'Restart Kernel…',
execute: args => {
const current = getCurrent(args);
if (!current) {
return;
}
const kernel = current.context.sessionContext.session?.kernel;
if (kernel) {
return kernel.restart();
}
return Promise.resolve(void 0);
},
isEnabled
});
commands.addCommand(CommandIDs.shutdownKernel, {
label: 'Shut Down Kernel',
execute: args => {
const current = getCurrent(args);
if (!current) {
return;
}
return current.context.sessionContext.shutdown();
}
});
commands.addCommand(CommandIDs.reconnectToKernel, {
label: 'Reconnect to Kernel',
execute: args => {
const current = getCurrent(args);
if (!current) {
return;
}
const kernel = current.context.sessionContext.session?.kernel;
if (kernel) {
return kernel.reconnect();
}
return Promise.resolve(void 0);
}
});

Scroll to end of output after execution

After executing the code for a longer output, it would be nice to be able to scroll down to the the end of it faster and not manually. A button could be added which takes the user to the bottom of the output, and a matching one for going back to the top.

Initialize blockly with default blocks

Create the default set of blocks for Python. Investigate if Blockly provides a default toolbox for the supported generators or look into other projects using blockly, to extract a basic set of blocks that we can reuse for Python. If we don't find anything, we can always export the default toolbox from the blockly developer tools web page.

Some documentation to get started:

Kernel controls

When the kernel hangs because of an infinite loop or any error in the code, we can not restart it.
Would be great to support the actions from the Kernel menu.
When closing the kernel, the dropdown to change kernels doesn't change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.