Commit 4db8dde3 authored by Sebastian's avatar Sebastian

renderjs-extension: Update README.md

parent 8827f2ce
# Overview: renderJS for jupyter notebook via extension # Overview: RenderJS for Jupyter Notebook via nbextension
This repo contains two seperate things: This repo contains two things:
1. A [jupyter frontend extension](http://jupyter-notebook.readthedocs.io/en/latest/extending/frontend_extensions.html) 1. A [jupyter frontend extension](http://jupyter-notebook.readthedocs.io/en/latest/extending/frontend_extensions.html)
also called nbextension containing the javascript and html required to load arbitrary gadgets. See folder also called nbextension containing the javascript and html required to load arbitrary gadgets. See folder
`renderjs_nbextension/`. `renderjs_nbextension/`.
2. An [ipython extension](https://ipython.org/ipython-doc/3/config/extensions/index.html) providing necessary python the commands to initiate the renderjs and controll the loaded gadgets. This happens directly from the notebook (cells). See folder `renderjs_ipyextension/`. 2. An [ipython extension](https://ipython.org/ipython-doc/3/config/extensions/index.html) providing
necessary python commands to initiate renderjs and control the loaded gadgets.
This happens directly from the notebook (cells). See folder *renderjs_ipyextension/*.
To make this work both the nbextension and the ipython-extension need to be installed and enabled. The extension needs both the nbextension and the ipython-extension installed and enabled
in order to function.
Right now the ipython extension works with the Python 2 Kernel (tested) and should
also work with the Python 3 Kernel (not tested).
In order to use the extension with the ERP5Kernel, the `renderjs_ipyextension` **cannot**
be used. Instead the ERP5-backend provides the functionality directly.
# Install # Install
TODO
# Use ## Via slapos
nothing needs to be done, as the extension is shipped with the `ipython-notebook` software.
## Manual
the whole directoy */renderjs_nbextension/renderjs_nbextension* needs to be installed
and enabled as jupyter nbextension. Either use `$ jupyter nbextension [install/enable]`, for instance
```
$ jupyter nbextension install path/to/jupyter_renderjs_extension/renderjs_nbextension/renderjs_nbextension --user --symlink
$ jupyter nbextension enable renderjs_nbextension/main --user
```
or copy/symlink manually to the appropriate jupyter directories.
Further, copy the file */renderjs_ipyextension/renderjs_ipyextension/renderjs_extension.py* into the
ipython directory (usually *~/.ipython* for local install). Note, that the file must be placed directly
into the ipython directory and cannot be contained in a directory.
# Usage
All of the following python calls are made from the notebook itself. All of the following python calls are made from the notebook itself.
## Loading the ipython extension: Note that there is a difference between the normal Python 2 Kernel and the ERP5Kernel
regarding loading the extension.
## Python 2 Kernel: Loading the ipython extension:
```python ```python
%load_ext renderjs_extension %load_ext renderjs_extension
import renderjs_extension as rjs
``` ```
## Import and initialize the extension: ## ERP5Kernel: Loading the ipython extension:
```python
def rjs_setup():
rjs = context.Base_loadRenderJSExtension()
return { "rjs": rjs, }
environment.define(rjs_setup, 'rjs_setup')
```
The rest of the functionality is the same from bother Kernels.
## Initialize the extension:
```python ```python
import renderjs_extension as rjs
rjs.init_renderjs() rjs.init_renderjs()
``` ```
## Load a renderjs gadget: ## Load a renderjs gadget:
```python ```python
myGadget = rjs.load_gadget("https://my.gadget.url/gadget.html") rjs.load_gadget("my_gadget_reference", "https://my.gadget.url/gadget.html")
``` ```
Note, that you need to assign a unique reference for each gadget. This reference
is used when calling declared methods and destroying the gadget.
## Destroy a renderjs gadget: ## Destroy a renderjs gadget:
```python ```python
myGadget.destroy() rjs.destroy("my_gadget_reference")
``` ```
If he cell defining `myGadget` is executed again, the current `myGadget` is automatically destroyed and a new one created.
## Call a `declared_method` of a loaded gadget: ## Call a declared_method of a loaded gadget:
```python ```python
arg1 = "Hello" arg1 = "Hello"
arg2 = 'World' arg2 = 'World'
arg3 = 2016 arg3 = 2017
arg4 = { "yes": "no!" } arg4 = { "yes": "no!" }
myGadget.call_declared_method("method_name", arg1, arg2, arg3, arg4) rjs.call_declared_method("my_gadget_reference", "method_name", arg1, arg2, arg3, arg4)
``` ```
Arguments can be arbitrary as long as it is python-compatible. They get converted to js-arguments via pythons JSON command. The number of arguments can is arbitrary as long as it is python-compatible.
They get converted to js-arguments via pythons `json.dumps`. Keep that in mind
when passing more complex arguments.
# Development
The extension is split into a ipython extension and a nbextension für jupyter. This is necessary because both JS in the frontend
and python in the backend are required to load a renderjs gadget.
## ipython extension (backend) # Development Notes
Here all the functionality for interacting with the extension via jupyter notebook cells is exposed. Unfortunately, ipython The extension is split into a ipython extension and a nbextension für jupyter. This is necessary because both
has no knowledge of the kernel and therefore no knowledge of the jupyter frontend. JS in the frontend and python in the backend (client-Kernel/ERP5-backend) are required to
use renderjs gadgets.
## ipython extension (Python 2 Kernel, client-backend)
Here all the functionality for interacting with the extension via jupyter notebook cells is exposed.
Unfortunately, the ipython environment has no knowledge of the kernel and therefore no knowledge of the jupyter frontend.
Still we want to execute javascipt in the frontend. To solve this issue, ipython is used to inject inline Still we want to execute javascipt in the frontend. To solve this issue, ipython is used to inject inline
javascipt into the page via ipython display. This is a rather dirty hack but I could not find a better solution as of now. javascipt into the page via ipython display. This is a rather uncomfortable but there seems to be no better solution
The inject JS code get's executed and fires an event to which the frontend-extension listens to. as of now. The injected JS code gets executed and then fires an event to which the frontend-extension listens to.
Gadgets are represented by a python-object and carry a uid to identify them. ## ERP5Kernel and erp5-server-backend
With the ERP5Kernel all the code of executed cells gets relayed to an actual ERP5-backend and
is processed there. Thus no client-ipython-extension can be used. Instead a server-side script
is in place to respond with `text/html` which contains the inline-javascript code.
## nbextension (frontend) ## nbextension (Frontend)
Nothing happens on-load of the frontend part. Everything is controlled by the backend (mostly via events fired from the ipython). Nothing happens on-load of the frontend part. Everything is controlled by the backend
Exception to event-based communication is the initial and controller gadget (loading_gadget) (mostly via events fired from the ipython). Exception to event-based communication is the initial and controller gadget (loading_gadget)
which is injected into the page directly and which is initialized by a manual bootstrap of renderjs (since the page is which is injected into the page directly and which is initialized by a manual bootstrap of renderjs (since the page is
already loaded; normal bootstrapping happens on-load). already loaded; normal bootstrapping happens on-load).
The loading_gadget is responsible for loading other The loading_gadget is responsible for loading other
(actual) gadgets and pass information from the backend to them. (actual) gadgets and pass information from the backend to them.
The loading_gadget declares a renderjs service for each possible event which could be fired from the backend The loading_gadget declares a renderjs service for each possible event which could be fired from the backend
(such as call_declared_method, destroy_gadget, ...). (such as call_declared_method, destroy_gadget, ...).
Multiple gadgets are possible which are all controlled by the same loading_gadget. To differentiate between gadgets Multiple gadgets are possible but all are controlled by the same loading_gadget. To differentiate between gadgets
each gadget sends along a uid (generated in the backend and member-variable of the python gadget-object) each gadget gets assigned a unique reference
and the loading_gadget determines the right gadget (by .getDeclaredGadget(uid)) and passes along the function call. and the loading_gadget determines the correct gadget (by .getDeclaredGadget(ref)) and passes along the function call.
\ No newline at end of file \ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment