Skip to content

Instantly share code, notes, and snippets.

@disarticulate
Last active March 31, 2022 07:16
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save disarticulate/d06069ff3e71cf828e5329beab8cb084 to your computer and use it in GitHub Desktop.
Save disarticulate/d06069ff3e71cf828e5329beab8cb084 to your computer and use it in GitHub Desktop.
A notebook demonstrating how to use arbitrary frameworks (ie, AngularJS) within Jupyter Notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AngularJS feat. requireJS (as dependency to Jupyter Notebook)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"#standard IPython modules for working with frontend output\n",
"from IPython.display import SVG, Javascript,HTML,display\n",
"#Gotta pimp the package that makes things easier\n",
"import simplejson as json"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A basic partial template file with AngularJS directives"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<div id=\"content\" ng-controller=\"MyController\">\r\n",
" <h1>{{greeting}},{{name}}</h1>\r\n",
" <input type=\"text\" ng-model=\"greeting\" name=\"name\">\r\n",
" <input type=\"text\" ng-model=\"name\" name=\"name\">\r\n",
"</div>"
]
}
],
"source": [
"#We can just read the file with Jupyter's shell commands \"!\"\n",
"!cat templates/input_template.ng"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## We can load the dependencies files by reading into IPython.display.javascript"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"require.config({\r\n",
" paths: {\r\n",
" velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\r\n",
" interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\r\n",
" angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\r\n",
" },\r\n",
" shim: {\r\n",
" 'angular': {\r\n",
" exports: 'angular'\r\n",
" }\r\n",
" }\r\n",
"});"
]
}
],
"source": [
"#Dependency js, although it can't be loaded via Javascript() the file for display\n",
"!cat js/deps.js"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prepare a python dictionary with some values\n",
"`kernel.execute(\"print(python_dict)\")` will be executed by javascript"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"'{\"input\": \"templates/input_template.ng\", \"input_id\": \"content\"}'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"python_dict = {\"input\":\"templates/input_template.ng\",\"input_id\":\"content\"}\n",
"json.dumps(python_dict)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<H2>We just create a container to hold the content of our angular template\n",
"<br> \n",
"(%%html is magic to define html to be rendered)</h2>\n",
"<H3>It'll be empty until we run the below...or until the autosave runs</h3>\n",
"<code>Note the html ID=\"container\"</code>\n",
"<hr/>\n",
"<div id=\"container\">Not Loaded...</div>\n",
"<hr/>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<H2>We just create a container to hold the content of our angular template\n",
"<br> \n",
"(%%html is magic to define html to be rendered)</h2>\n",
"<H3>It'll be empty until we run the below...or until the autosave runs</h3>\n",
"<code>Note the html ID=\"container\"</code>\n",
"<hr/>\n",
"<div id=\"container\">Not Loaded...</div>\n",
"<hr/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Now with some %%javascript magic, read the notes as we step through the levels"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"//require needs to be configed with the dependencies\n",
"require.config({\n",
" paths: {\n",
" velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n",
" interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n",
" angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n",
" },\n",
" shim: {\n",
" 'angular': {\n",
" exports: 'angular'\n",
" }\n",
" }\n",
"});\n",
"//top level function will be fed into our callback\n",
"function handle_output(data){\n",
" //data is the object passed to the callback from the kernel execution\n",
" console.log(data)\n",
" //to get the print statement from the text, we get the content key\n",
" //then we convert it via JSON parse\n",
" //now you can arbitrarily transfer a JSON string using the python_dict variable\n",
" var python_dict = JSON.parse(data.content.text.trim())\n",
" console.log(python_dict)\n",
" //Utilized requireJS built into the frontend of Jupyter Notebook\n",
" //Pass in the modular dependencies you wish to use\n",
" //For this example, we created our own and passed it into the config obj\n",
" // paths: {\n",
" // velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n",
" // interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n",
" // angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n",
" // }\n",
" //jquery is already available\n",
" //find all the modules here\n",
" console.log(require.s.contexts._.defined)\n",
" //now we get to the requirejs -> angular\n",
" require(['angular','jquery'], function(a,$) {\n",
" console.log(a)\n",
" //a and $ are now our variables for the modules\n",
" //we using an ajax call to the jupyter notebook server\n",
" //here we get the variable passed in, and us the input to locate the file\n",
" $.ajax({url: \"http://localhost:8888/files/\"+python_dict.input,\n",
" //once the file is retrieved, we have a callback, so we're one step deeper\n",
" success: function(result) {\n",
" //now we locate the ID=\"contaner\" which is defined above %%html magic\n",
" //pass out file result\n",
" console.log('SUCCESS')\n",
" $(\"#container\").html(result);\n",
" //now select the element we just loaded as the result (we pull from the python_dict)\n",
" var el = document.getElementById(python_dict.input_id);\n",
" //We have to be prepared to teardown and restart our controller\n",
" //if the injector() is available, then angular as been bootstrapped\n",
" //so destroy the scope and tree to reboot.\n",
" if(a.element(el).injector()){\n",
" a.element(el).injector().get('$rootScope').$destroy()\n",
" }\n",
" //Now we get to the actual module, the a here was conntected to the angular module\n",
" //myApp is only connected to the bootstrap\n",
" //at this point, all angular stuff is fair game, and you can define your modules and controllers\n",
" //nothing special for this hello world.\n",
" a.module('myApp', [])\n",
" .controller('MyController', ['$scope', function ($scope) {\n",
" $scope.greeting = 'Hello';\n",
" $scope.name = 'Darling!!!';\n",
" }]);\n",
" //we bootstrap (\"INITIALIZE\") the application so that we can easily keep control\n",
" angular.element(document).ready(function() {\n",
" angular.bootstrap(el, ['myApp']);\n",
" });\n",
" }\n",
" });\n",
" });\n",
" \n",
"}\n",
"//callbacks is an object whose so special, it appears to only have been documented in\n",
"//the source code, as no only google found me a link.\n",
"//callbacks.iopub.output is used to get the data from execute\n",
"var callbacks = {\n",
" iopub : {\n",
" output : handle_output,\n",
" }\n",
"}\n",
"//execute anything you want; if a string value is returned\n",
"//you can print it out and pass it to the callbacks \n",
"//(or do other things, no idea, it's poorly documented online \n",
"//(read the source F12->static/notebook/js/services/kernels/kernel.js)\n",
"//kernel.js/Kernel.prototype.execute \n",
"var kernel = IPython.notebook.kernel;\n",
"kernel.execute(\"print(json.dumps(python_dict))\",callbacks)"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"//require needs to be configed with the dependencies\n",
"require.config({\n",
" paths: {\n",
" velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n",
" interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n",
" angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n",
" },\n",
" shim: {\n",
" 'angular': {\n",
" exports: 'angular'\n",
" }\n",
" }\n",
"});\n",
"//top level function will be fed into our callback\n",
"function handle_output(data){\n",
" //data is the object passed to the callback from the kernel execution\n",
" console.log(data)\n",
" //to get the print statement from the text, we get the content key\n",
" //then we convert it via JSON parse\n",
" //now you can arbitrarily transfer a JSON string using the python_dict variable\n",
" var python_dict = JSON.parse(data.content.text.trim())\n",
" console.log(python_dict)\n",
" //Utilized requireJS built into the frontend of Jupyter Notebook\n",
" //Pass in the modular dependencies you wish to use\n",
" //For this example, we created our own and passed it into the config obj\n",
" // paths: {\n",
" // velocity: \"https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min\",\n",
" // interact: \"https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min\",\n",
" // angular: \"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min\"\n",
" // }\n",
" //jquery is already available\n",
" //find all the modules here\n",
" console.log(require.s.contexts._.defined)\n",
" //now we get to the requirejs -> angular\n",
" require(['angular','jquery'], function(a,$) {\n",
" console.log(a)\n",
" //a and $ are now our variables for the modules\n",
" //we using an ajax call to the jupyter notebook server\n",
" //here we get the variable passed in, and us the input to locate the file\n",
" $.ajax({url: \"http://localhost:8888/files/\"+python_dict.input,\n",
" //once the file is retrieved, we have a callback, so we're one step deeper\n",
" success: function(result) {\n",
" //now we locate the ID=\"contaner\" which is defined above %%html magic\n",
" //pass out file result\n",
" console.log('SUCCESS')\n",
" $(\"#container\").html(result);\n",
" //now select the element we just loaded as the result (we pull from the python_dict)\n",
" var el = document.getElementById(python_dict.input_id);\n",
" //We have to be prepared to teardown and restart our controller\n",
" //if the injector() is available, then angular as been bootstrapped\n",
" //so destroy the scope and tree to reboot.\n",
" if(a.element(el).injector()){\n",
" a.element(el).injector().get('$rootScope').$destroy()\n",
" }\n",
" //Now we get to the actual module, the a here was conntected to the angular module\n",
" //myApp is only connected to the bootstrap\n",
" //at this point, all angular stuff is fair game, and you can define your modules and controllers\n",
" //nothing special for this hello world.\n",
" a.module('myApp', [])\n",
" .controller('MyController', ['$scope', function ($scope) {\n",
" $scope.greeting = 'Hello';\n",
" $scope.name = 'Darling!!!';\n",
" }]);\n",
" //we bootstrap (\"INITIALIZE\") the application so that we can easily keep control\n",
" angular.element(document).ready(function() {\n",
" angular.bootstrap(el, ['myApp']);\n",
" });\n",
" }\n",
" });\n",
" });\n",
" \n",
"}\n",
"//callbacks is an object whose so special, it appears to only have been documented in\n",
"//the source code, as no only google found me a link.\n",
"//callbacks.iopub.output is used to get the data from execute\n",
"var callbacks = {\n",
" iopub : {\n",
" output : handle_output,\n",
" }\n",
"}\n",
"//execute anything you want; if a string value is returned\n",
"//you can print it out and pass it to the callbacks \n",
"//(or do other things, no idea, it's poorly documented online \n",
"//(read the source F12->static/notebook/js/services/kernels/kernel.js)\n",
"//kernel.js/Kernel.prototype.execute \n",
"var kernel = IPython.notebook.kernel;\n",
"kernel.execute(\"print(json.dumps(python_dict))\",callbacks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [conda env:acehole]",
"language": "python",
"name": "conda-env-acehole-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
},
"widgets": {
"state": {},
"version": "1.1.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
require.config({
paths: {
velocity: "https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min",
interact: "https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min",
angular: "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min"
},
shim: {
'angular': {
exports: 'angular'
}
}
});
<div id="content" ng-controller="MyController">
<h1>{{greeting}},{{name}}</h1>
<input type="text" ng-model="greeting" name="name">
<input type="text" ng-model="name" name="name">
</div>
Copy link

ghost commented Jul 16, 2017

I did this with Angular 4:

screen shot 2017-07-16 at 1 04 47 pm

@sargense
Copy link

sargense commented Dec 15, 2017

I think
https://stackoverflow.com/questions/45330160/require-not-working-when-used-in-jupyter-ipython-notebook
is borrowing your code, and I'm not sure that it still works in current jupyter version. I also noticed that it doesn't run in jupyter.

@roemmele
Copy link

Thanks so much for this!

@mardambey
Copy link

@briancullinan can you share the Angular 4 version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment