blob: e781a98243c3d831090056e08f1a194d58e1e043 [file] [log] [blame] [view]
---
layout: page
title: "Writing a new Helium Spell"
description: "Spell is a kind of interpreter that runs on browser not on backend. So, technically it's the frontend interpreter. "
group: development/helium
---
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{% include JB/setup %}
# Writing a new Spell
<div id="toc"></div>
## What is Apache Zeppelin Spell
Spell is a kind of interpreter that runs on browser not on backend. So, technically it's the frontend interpreter.
It can provide many benefits.
- Spell is pluggable frontend interpreter. So it can be installed and removed easily using helium registry.
- Every spell is written in javascript. It means you can use existing javascript libraries whatever you want.
- Spell runs on browser like display system (`%html`, `%table`). In other words, every spell can be used as display system as well.
## How it works
Helium Spell works like [Helium Visualization](./writing_visualization_basic.html).
- Every helium packages are loaded from central (online) registry or local registry
- You can see loaded packages in `/helium` page.
- When you enable a spell, it's built from server and sent to client
- Finally it will be loaded into browser.
## How to use spell
### 1. Enabling
Find a spell what you want to use in `/helium` package and click `Enable` button.
<img class="img-responsive" style="width:70%" src="{{BASE_PATH}}/assets/themes/zeppelin/img/docs-img/writing_spell_registered.png" />
### 2. Using
Spell works like an interpreter. Use the `MAGIC` value to execute spell in a note. (you might need to refresh after enabling)
For example, Use `%echo` for the Echo Spell.
<img class="img-responsive" style="width:70%" src="{{BASE_PATH}}/assets/themes/zeppelin/img/docs-img/writing_spell_using.gif" />
## Write a new Spell
Making a new spell is similar to [Helium Visualization#write-new-visualization](./writing_visualization_basic.html#write-new-visualization).
- Add framework dependency called zeppelin-spell into `package.json`
- Write code using framework
- Publish your spell to [npm]("https://www.npmjs.com/")
### 1. Create a npm package
Create a [package.json](https://docs.npmjs.com/files/package.json) in new directory for spell.
- You have to add a framework called `zeppelin-spell` as a dependency to create spell ([zeppelin-spell](https://github.com/apache/zeppelin/tree/master/zeppelin-web/src/app/spell))
- Also, you can add any dependencies you want to utilise.
Here's an example
```json
{
"name": "zeppelin-echo-spell",
"description": "Zeppelin Echo Spell (example)",
"version": "1.0.0",
"main": "index",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"zeppelin-spell": "*"
},
"helium": {
"icon" : "<i class='fa fa-repeat'></i>",
"spell": {
"magic": "%echo",
"usage": "%echo <TEXT>"
}
}
}
```
### 2. Write spell using framework
Here are some examples you can refer
- [Echo Spell](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-echo/index.js)
- [Markdown Spell: Using library](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-markdown/index.js)
- [Flowchart Spell: Using DOM](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-flowchart/index.js)
- [Google Translation API Spell: Using API (returning promise)](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-translator/index.js)
Now, you need to write code to create spell which processing text.
```js
import {
SpellBase,
SpellResult,
DefaultDisplayType,
} from 'zeppelin-spell';
export default class EchoSpell extends SpellBase {
constructor() {
/** pass magic to super class's constructor parameter */
super("%echo");
}
interpret(paragraphText) {
const processed = paragraphText + '!';
/**
* should return `SpellResult` which including `data` and `type`
* default type is `TEXT` if you don't specify.
*/
return new SpellResult(processed);
}
}
```
Here is another example. Let's say we want to create markdown spell. First of all, we should add a dependency for markdown in package.json
```json
// package.json
"dependencies": {
"markdown": "0.5.0",
"zeppelin-spell": "*"
},
```
And here is spell code.
```js
import {
SpellBase,
SpellResult,
DefaultDisplayType,
} from 'zeppelin-spell';
import md from 'markdown';
const markdown = md.markdown;
export default class MarkdownSpell extends SpellBase {
constructor() {
super("%markdown");
}
interpret(paragraphText) {
const parsed = markdown.toHTML(paragraphText);
/**
* specify `DefaultDisplayType.HTML` since `parsed` will contain DOM
* otherwise it will be rendered as `DefaultDisplayType.TEXT` (default)
*/
return new SpellResult(parsed, DefaultDisplayType.HTML);
}
}
```
- You might want to manipulate DOM directly (e.g google d3.js), then refer [Flowchart Spell](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-flowchart/index.js)
- You might want to return promise not string (e.g API call), then refer [Google Translation API Spell](https://github.com/apache/zeppelin/blob/master/zeppelin-examples/zeppelin-example-spell-translator/index.js)
### 3. Create __Helium package file__ for local deployment
You don't want to publish your package every time you make a change in your spell. Zeppelin provides local deploy.
The only thing you need to do is creating a __Helium Package file__ (JSON) for local deploy.
It's automatically created when you publish to npm repository but in local case, you should make it by yourself.
```json
{
"type" : "SPELL",
"name" : "zeppelin-echo-spell",
"version": "1.0.0",
"description" : "Return just what receive (example)",
"artifact" : "./zeppelin-examples/zeppelin-example-spell-echo",
"license" : "Apache-2.0",
"spell": {
"magic": "%echo",
"usage": "%echo <TEXT>"
}
}
```
- Place this file in your local registry directory (default `$ZEPPELIN_HOME/helium`).
- `type` should be `SPELL`
- Make sure that `artifact` should be same as your spell directory.
- You can get information about other fields in [Helium Visualization#3-create-helium-package-file-and-locally-deploy](./writing_visualization_basic.html#3-create-helium-package-file-and-locally-deploy).
### 4. Run in dev mode
```bash
cd zeppelin-web
yarn run dev:helium
```
You can browse localhost:9000. Every time refresh your browser, Zeppelin will rebuild your spell and reload changes.
### 5. Publish your spell to the npm repository
See [Publishing npm packages](https://docs.npmjs.com/getting-started/publishing-npm-packages)