Last active
March 31, 2022 07:16
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
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.
Thanks so much for this!
@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
I did this with Angular 4: