From d117ca7a2a4dfda62e46f448a219828db3c7b1a5 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 10 Oct 2019 10:37:29 +0200 Subject: [PATCH 01/30] simple extension example --- examples/simple/README.md | 34 ++++++++++++ .../server_simple.json | 7 +++ .../simple/jupyter_server_simple/__init__.py | 8 +++ .../jupyter_server_simple/application.py | 52 ++++++++++++++++++ .../simple/jupyter_server_simple/handler.py | 11 ++++ .../jupyter_server_simple/handler_template.py | 11 ++++ .../jupyter_server_simple/static/favicon.ico | Bin 0 -> 32038 bytes .../jupyter_server_simple/static/test.html | 1 + .../jupyter_server_simple/templates/404.html | 5 ++ .../templates/browser-open.html | 18 ++++++ .../templates/error.html | 21 +++++++ .../jupyter_server_simple/templates/main.html | 5 ++ .../jupyter_server_simple/templates/page.html | 20 +++++++ .../templates/server_simple.html | 5 ++ examples/simple/setup.py | 38 +++++++++++++ 15 files changed, 236 insertions(+) create mode 100644 examples/simple/README.md create mode 100644 examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json create mode 100644 examples/simple/jupyter_server_simple/__init__.py create mode 100644 examples/simple/jupyter_server_simple/application.py create mode 100644 examples/simple/jupyter_server_simple/handler.py create mode 100644 examples/simple/jupyter_server_simple/handler_template.py create mode 100644 examples/simple/jupyter_server_simple/static/favicon.ico create mode 100644 examples/simple/jupyter_server_simple/static/test.html create mode 100644 examples/simple/jupyter_server_simple/templates/404.html create mode 100644 examples/simple/jupyter_server_simple/templates/browser-open.html create mode 100644 examples/simple/jupyter_server_simple/templates/error.html create mode 100644 examples/simple/jupyter_server_simple/templates/main.html create mode 100644 examples/simple/jupyter_server_simple/templates/page.html create mode 100644 examples/simple/jupyter_server_simple/templates/server_simple.html create mode 100755 examples/simple/setup.py diff --git a/examples/simple/README.md b/examples/simple/README.md new file mode 100644 index 0000000000..c6259a12b9 --- /dev/null +++ b/examples/simple/README.md @@ -0,0 +1,34 @@ +# Jupyter Server Simple Extension Example + +This folder contains an example to develop an simple extension on top of Jupyter Server. + +```bash +# Install the server simple extension. +python setup.py develop +``` + +```bash +# Start the jupyter server simple extension. +jupyter server-simple +``` + +Render server content in your browser. + +```bash +# Default server page. +open http://localhost:8888 +# Default favicon. +open http://localhost:8888/favicon.ico +# HTML static page. +open http://localhost:8888/static/server_simple/test.html +# Content from Handlers. +open http://localhost:8888/server_simple +open http://localhost:8888/server_simple/something?var1=foo +# Content from Template. +open http://localhost:8888/template +``` + +## TO FIX + ++ The token created in `browser-open.html` is `None` - http://localhost:8888/?token=None ++ This static favicon request fails with `403 : Forbidden - favicon.ico is not in root static directory` - http://localhost:8888/static/server_simple/favicon.ico diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json b/examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json new file mode 100644 index 0000000000..607ec527aa --- /dev/null +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json @@ -0,0 +1,7 @@ +{ + "ServerApp": { + "jpserver_extensions": { + "server_simple": true + } + } +} diff --git a/examples/simple/jupyter_server_simple/__init__.py b/examples/simple/jupyter_server_simple/__init__.py new file mode 100644 index 0000000000..21752c111f --- /dev/null +++ b/examples/simple/jupyter_server_simple/__init__.py @@ -0,0 +1,8 @@ +from .application import ServerSimple + +EXTENSION_NAME = "server_simple" + +def _jupyter_server_extension_paths(): + return [{"module": EXTENSION_NAME}] + +load_jupyter_server_extension = ServerSimple.load_jupyter_server_extension diff --git a/examples/simple/jupyter_server_simple/application.py b/examples/simple/jupyter_server_simple/application.py new file mode 100644 index 0000000000..430baa8167 --- /dev/null +++ b/examples/simple/jupyter_server_simple/application.py @@ -0,0 +1,52 @@ +import os, jinja2 +from .handler import ServerSimpleHandler +from .handler_template import ServerSimpleTemplateHandler +from jupyter_server.extension.application import ExtensionApp + +DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") +DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") + +class ServerSimple(ExtensionApp): + + # Name of the extension + extension_name = "server_simple" + + # Local path to static files directory. + static_paths = [ + DEFAULT_STATIC_FILES_PATH + ] + + # Local path to templates directory. + template_paths = [ + DEFAULT_TEMPLATE_FILES_PATH + ] + + def initialize_handlers(self): + self.handlers.append( + (r'/server_simple', ServerSimpleHandler, {}) + ) + self.handlers.append( + (r'/server_simple/(.+)$', ServerSimpleHandler, {}) + ) + self.handlers.append( + (r'/template', ServerSimpleTemplateHandler, {}) + ) + + def initialize_templates(self): + jenv_opt = {"autoescape": True} + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(self.template_paths), + extensions=["jinja2.ext.i18n"], + **jenv_opt + ) + template_settings = {"server_simple_jinja2_env": env} + self.settings.update(**template_settings) + + def initialize_settings(self): + pass + +#----------------------------------------------------------------------------- +# Main entry point +#----------------------------------------------------------------------------- + +main = launch_new_instance = ServerSimple.launch_instance diff --git a/examples/simple/jupyter_server_simple/handler.py b/examples/simple/jupyter_server_simple/handler.py new file mode 100644 index 0000000000..d8de78605f --- /dev/null +++ b/examples/simple/jupyter_server_simple/handler.py @@ -0,0 +1,11 @@ +from jupyter_server.extension.handler import ExtensionHandler + +class ServerSimpleHandler(ExtensionHandler): + + def get(self, matched_part=None, *args, **kwargs): + var1 = self.get_argument('var1', default=None) + components = [x for x in self.request.path.split("/") if x] + self.write('

Hello Server Simple from Handler.

') + self.write('

matched_part: {}

'.format(matched_part)) + self.write('

var1: {}

'.format(var1)) + self.write('

components: {}

'.format(components)) diff --git a/examples/simple/jupyter_server_simple/handler_template.py b/examples/simple/jupyter_server_simple/handler_template.py new file mode 100644 index 0000000000..9966ea22a5 --- /dev/null +++ b/examples/simple/jupyter_server_simple/handler_template.py @@ -0,0 +1,11 @@ +from jupyter_server.extension.handler import ExtensionHandler + +class ServerSimpleTemplateHandler(ExtensionHandler): + + def get_template(self, name): + """Return the jinja template object for a given name""" + return self.settings['server_simple_jinja2_env'].get_template(name) + + def get(self): +# print(self.get_template('server_simple.html')) + self.write(self.render_template('server_simple.html')) diff --git a/examples/simple/jupyter_server_simple/static/favicon.ico b/examples/simple/jupyter_server_simple/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2d1bcff7ca0ed6c77fdf1b016986f9137a43d31a GIT binary patch literal 32038 zcmeI4U5FG{7ROsAA|fG?5JY4_k?9XRYJ%itpLE5Qd5}CTSqV$nU6$YuB0hvnSGNw% z5*9HcG7rljAx|Of2kb(SAVHR88S)UqAR>zoOCCg)ARz>&t7k?;dw>7xx;=NQtGcVF zKWDlc&eW}2_nxnN>fUqDJvFJ+medQWmtRit+nf6R3#ru4RoYv-{|oj1pzih8{rmA$ z>X)ykQb&*0?z2BjrJnyZmCAA}6nlX!-e20#FZiogt6PGQF1WkXh4N{j-~(lMcd%XX zp0?w_-+`wNviJo^c=^??1z);#+$d~?5U`?YYa`~5LEYVy==z5f1&y%TDiN>!_!faaOK zz)`@=Gc(@YMTPaV`5WePw!nPgxXgFuS>S8nAt2ijsI0nKwNcw{$&x9S_k(v1u;)56 z=S5xBc20fQ%SXQWMDyQeKsFskr&YcBUKXx)_{ccree}EA0o@>9cZD+!56sA4(YRvcV_c;7|FUkpY1j9noOLR1dbFTv@I&_u>sHrgHu!^A=)D5GXX^9L zO2c@VXT7=(f@ZH|N$@uA6%w5!I*DrogP03!nwkqWC&uNs({`Hcp?AjMG3$@k22We+K#J_PrGf7)ViZ3WZF61JvUb#7=|1Zp*z<@#RZPFS3Rl1{Bx& zE%V~J@q$|vaDPs9dZspNI}CF2K5U1t6YzSC>pY-+?sveCfZ{h=_XH}dPS4b4KJAp% z=Y(+dQvQYSH6& zyudZ0JU&&EPkcv}(^KH8;k+Um-IjqhXFEE2CtX^A5LTJ9&JynXT3Z)210ufdf^#%=BL9M%57^x`)52zg|A zS2TQDPi?#McxoX7d!23Y_5p3po<#b8m?@Osr~YuJu=G+C58bNIK?B_!gzkCdu-BKe zcoUCNw9-@V1pTx|J_Qz7BhR9jp7R{ZPsx3eF`0yyZ#M+T)x0O_Vxqw z)(zhKd|10d)WKH{8<^v&_hUXiQ*Brq;P({IIB#+%50tvUPw!OjytA|u`#B>X#jA}k zH@&=*_jWE_baQt7FqWA=a_IO^;@R*=d}hDie{(iB!(_YKozlc|}f7BjLd$nQXKj$b13N3ho?lW72VNEc;`Pz-6VHZ-4KYT+_?2Qv=h<@} z%oQs=j|C}4hJ7n;{60WDq!w$X?8mQ`BI8${3{J(1AKEcU`f5BB^ZXe3-bI$&f$4Hn zJi-+h6pQ4&%PTes4aMs3`!>M2NIeGoX}VB}6$8yWWy!E$%V3pdgT$E^ZxOGXhUUp^ zF^?r2CLKbbVZT=9LvQ zMXuKIbK0n_>F48az^8iAZaaQ184i84dVXQ)-lruUSu(XMw|egBJQSaIesS<>`{x(+ zafm!W3e{J*PW>}7Pv>#UT{u57{Oh`Ue#hBb!8>E~&KS(N=o(e7@f@n#hA|}G|AhAb z`Ca#OXLBWUe!BQAHvh~!H}&6*sIteuC*SIL1>17}jCSBGUl9#kcik@6&#!BF0p9sS zOa1#Y8d(BYaBvphhx6;8E||ADGjLnx4k3vA(kJc(~tW# z`5RNU{0&d9-Z;7EC=Xr!MnCk@ibgFTNZ&;1mt6a;2jyuU1!e$~rTnr8g+GKrn&>a`&h=QT)?OPD|7olnKSR;BkN3d*@Ig7j-GjKXsbTzyAgHjXGc09z{zu2mOBJO67NWe|e94FLO8z_n~;`w=J-5$`k*Y59etBx_}q))DJym zi%Y*C_SQFBkE>(xB;I&iRiR>fntb>PkIPWkh=V=?G<=-~5itr16V zRQ3NcZmnM?d>n@upyS?zuQ`02t7)fliP+)?d}}o+P+4`*xvCgF*PGZGaYOk>>zhx+ zvv}{+7QmzY+PF6VBl6usCgP{%jK=MfdyCA)l}uRQe%5hb zIxbyccXm$h8he#2?eIh{?>_J;HWk3*E-=o&Iy%$&d({pSNB%5S3_4ZZ%63_of9>j!QznRL|!36W;!!X}4TdcfCF2#w> zByX53l2Nh-pJ^Qp)@|1NQId7Dj$tBKW2`;VNura)1`-=cY#_0L#0C-@NNganfy4$9 z8%S&*v4O+}n%lrA#e~9S9rgI97yl+UtQhfTeODCQSByU_{wIy>6vw(wfX-G$t@1_N&h7y__Q}eEax-{u^-b>Dyp1;VA3Pm2 z$$vqY572S(wTmnJ2W<<=!NIPlb*>qd+uXOC|6*iP?vTL|d3D@7%D+)glIhp$t8%Th zMlsfRBl+@eKr(c~4>V%uztwUr+%LR*By!f2yVeP9^;HgCEuRH>$*n`)zU9A(epm7z z$z?>3H~rkk==?`=BbjICSg&r@=C8r$KS~Gkm*8t8^IvWIMF%69|7`1El=I(>9!B~5 z2crXBNA>#`TL**q{)x5W@i2VHello Server Simple from test HTML page. diff --git a/examples/simple/jupyter_server_simple/templates/404.html b/examples/simple/jupyter_server_simple/templates/404.html new file mode 100644 index 0000000000..e29646af1a --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/404.html @@ -0,0 +1,5 @@ +{% extends "error.html" %} +{% block error_detail %} +

{% trans %}You are requesting a page that does not exist!{% endtrans %}

+{% endblock %} + diff --git a/examples/simple/jupyter_server_simple/templates/browser-open.html b/examples/simple/jupyter_server_simple/templates/browser-open.html new file mode 100644 index 0000000000..6f277967fc --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/browser-open.html @@ -0,0 +1,18 @@ +{# This template is not served, but written as a file to open in the browser, + passing the token without putting it in a command-line argument. #} + + + + + + Opening Jupyter Notebook + + + +

+ This page should redirect you to Jupyter Notebook. If it doesn't, + click here to go to Jupyter. +

+ + + diff --git a/examples/simple/jupyter_server_simple/templates/error.html b/examples/simple/jupyter_server_simple/templates/error.html new file mode 100644 index 0000000000..1e3fae6225 --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/error.html @@ -0,0 +1,21 @@ +{% extends "page.html" %} + +{% block site %} + +
+ {% block h1_error %} +

{{status_code}} : {{status_message}}

+ {% endblock h1_error %} + + {% block error_detail %} + {% if message %} +

{% trans %}The error was:{% endtrans %}

+
+
{{message}}
+
+ {% endif %} + {% endblock error_detail %} +
+ +{% endblock %} + diff --git a/examples/simple/jupyter_server_simple/templates/main.html b/examples/simple/jupyter_server_simple/templates/main.html new file mode 100644 index 0000000000..51f8be1c07 --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/main.html @@ -0,0 +1,5 @@ +{% extends "page.html" %} + +{% block site %} +

Server 1 is running.

+{% endblock site %} diff --git a/examples/simple/jupyter_server_simple/templates/page.html b/examples/simple/jupyter_server_simple/templates/page.html new file mode 100644 index 0000000000..cf01c9a0b0 --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/page.html @@ -0,0 +1,20 @@ + + + + + {% block title %}Jupyter Server 1{% endblock %} + {% block favicon %}{% endblock %} + + + {% block meta %} + {% endblock %} + + +
+ {% block site %} + {% endblock site %} +
+ {% block after_site %} + {% endblock after_site %} + + diff --git a/examples/simple/jupyter_server_simple/templates/server_simple.html b/examples/simple/jupyter_server_simple/templates/server_simple.html new file mode 100644 index 0000000000..36190d42c6 --- /dev/null +++ b/examples/simple/jupyter_server_simple/templates/server_simple.html @@ -0,0 +1,5 @@ +{% extends "page.html" %} + +{% block site %} +

Hello Server Simple from Template.

+{% endblock site %} diff --git a/examples/simple/setup.py b/examples/simple/setup.py new file mode 100755 index 0000000000..9ef276ee28 --- /dev/null +++ b/examples/simple/setup.py @@ -0,0 +1,38 @@ +import setuptools + +VERSION = '0.0.1' + +setuptools.setup( + name = 'jupyter_server_simple', + version = VERSION, + description = 'Datalayer', + long_description = open('README.md').read(), + packages = [ + 'jupyter_server_simple', + ], + package_data = { + 'jupyter_server_simple': [ + '*', + ], + }, + setup_requires = [ + ], + install_requires = [ + 'jupyter_server==0.2.0.dev0', + 'jinja2', + ], + tests_requires = [ + 'pytest', + 'pytest-cov', + 'pylint', + ], + python_requires = '>=3.5', + data_files = [ + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/server_simple.json']), + ], + entry_points = { + 'console_scripts': [ + 'jupyter-server-simple = jupyter_server_simple.application:main' + ] + }, +) From 8ea90328105409eadb810ca9924718c616095da5 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Fri, 11 Oct 2019 19:04:56 +0200 Subject: [PATCH 02/30] add typescript example --- .gitignore | 3 +- examples/simple/Makefile | 11 ++ examples/simple/README.md | 32 ++--- .../{server_simple.json => simple_ext.json} | 2 +- .../simple/jupyter_server_simple/__init__.py | 8 -- .../simple/jupyter_server_simple/handler.py | 11 -- .../jupyter_server_simple/handler_template.py | 11 -- .../jupyter_server_simple/static/test.html | 1 - .../templates/server_simple.html | 5 - .../simple/jupyter_simple_ext/__init__.py | 8 ++ .../application.py | 37 +++--- .../simple/jupyter_simple_ext/handlers.py | 38 ++++++ .../jupyter_simple_ext/static/bundle.js | 111 ++++++++++++++++++ .../static/favicon.ico | Bin .../jupyter_simple_ext/static/index.d.ts | 1 + .../simple/jupyter_simple_ext/static/index.js | 5 + .../jupyter_simple_ext/static/test.html | 1 + .../static/tsconfig.tsbuildinfo | 98 ++++++++++++++++ .../templates/404.html | 0 .../templates/browser-open.html | 0 .../templates/error.html | 1 - .../jupyter_simple_ext/templates/index.html | 21 ++++ .../templates/main.html | 0 .../templates/page.html | 0 .../jupyter_simple_ext/templates/page1.html | 19 +++ .../templates/simple_ext.html | 21 ++++ examples/simple/package.json | 18 +++ examples/simple/setup.py | 12 +- examples/simple/webpack.config.js | 8 ++ 29 files changed, 407 insertions(+), 76 deletions(-) create mode 100644 examples/simple/Makefile rename examples/simple/etc/jupyter/jupyter_server_config.d/{server_simple.json => simple_ext.json} (67%) delete mode 100644 examples/simple/jupyter_server_simple/__init__.py delete mode 100644 examples/simple/jupyter_server_simple/handler.py delete mode 100644 examples/simple/jupyter_server_simple/handler_template.py delete mode 100644 examples/simple/jupyter_server_simple/static/test.html delete mode 100644 examples/simple/jupyter_server_simple/templates/server_simple.html create mode 100644 examples/simple/jupyter_simple_ext/__init__.py rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/application.py (53%) create mode 100644 examples/simple/jupyter_simple_ext/handlers.py create mode 100644 examples/simple/jupyter_simple_ext/static/bundle.js rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/static/favicon.ico (100%) create mode 100644 examples/simple/jupyter_simple_ext/static/index.d.ts create mode 100644 examples/simple/jupyter_simple_ext/static/index.js create mode 100644 examples/simple/jupyter_simple_ext/static/test.html create mode 100644 examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/templates/404.html (100%) rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/templates/browser-open.html (100%) rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/templates/error.html (99%) create mode 100644 examples/simple/jupyter_simple_ext/templates/index.html rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/templates/main.html (100%) rename examples/simple/{jupyter_server_simple => jupyter_simple_ext}/templates/page.html (100%) create mode 100644 examples/simple/jupyter_simple_ext/templates/page1.html create mode 100644 examples/simple/jupyter_simple_ext/templates/simple_ext.html create mode 100644 examples/simple/package.json create mode 100644 examples/simple/webpack.config.js diff --git a/.gitignore b/.gitignore index 28a83b48fd..b9a436dd76 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,8 @@ notebook/static/*/built/ notebook/static/built/ notebook/static/*/js/main.min.js* notebook/static/lab/*bundle.js -node_modules +**/node_modules +**/yarn.lock *.py[co] __pycache__ *.egg-info diff --git a/examples/simple/Makefile b/examples/simple/Makefile new file mode 100644 index 0000000000..4292cafbb1 --- /dev/null +++ b/examples/simple/Makefile @@ -0,0 +1,11 @@ +default: all ## default target is all. + +install: + yarn install + +build: + yarn build + pip install -e . + +start: + jupyter simple-ext diff --git a/examples/simple/README.md b/examples/simple/README.md index c6259a12b9..92d0ef9518 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -1,15 +1,18 @@ # Jupyter Server Simple Extension Example -This folder contains an example to develop an simple extension on top of Jupyter Server. +This folder contains an example of a simple extension on top of Jupyter Server. + +You need yarn and python3. ```bash -# Install the server simple extension. -python setup.py develop +# Install and build. +make install +make build ``` ```bash # Start the jupyter server simple extension. -jupyter server-simple +make start ``` Render server content in your browser. @@ -17,18 +20,17 @@ Render server content in your browser. ```bash # Default server page. open http://localhost:8888 -# Default favicon. -open http://localhost:8888/favicon.ico +# Favicon static content. +open http://localhost:8888/static/simple_ext/favicon.ico # HTML static page. -open http://localhost:8888/static/server_simple/test.html +open http://localhost:8888/static/simple_ext/test.html # Content from Handlers. -open http://localhost:8888/server_simple -open http://localhost:8888/server_simple/something?var1=foo +open http://localhost:8888/simple_ext/params/test?var1=foo # Content from Template. -open http://localhost:8888/template +open http://localhost:8888/simple_ext/page1/test +# Content from Template with Typescript. +open http://localhost:8888/simple_ext +open http://localhost:8888/simple_ext/template +# Error content. +open http://localhost:8888/simple_ext/nope ``` - -## TO FIX - -+ The token created in `browser-open.html` is `None` - http://localhost:8888/?token=None -+ This static favicon request fails with `403 : Forbidden - favicon.ico is not in root static directory` - http://localhost:8888/static/server_simple/favicon.ico diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json similarity index 67% rename from examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json rename to examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json index 607ec527aa..f58607d536 100644 --- a/examples/simple/etc/jupyter/jupyter_server_config.d/server_simple.json +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json @@ -1,7 +1,7 @@ { "ServerApp": { "jpserver_extensions": { - "server_simple": true + "simple_ext": true } } } diff --git a/examples/simple/jupyter_server_simple/__init__.py b/examples/simple/jupyter_server_simple/__init__.py deleted file mode 100644 index 21752c111f..0000000000 --- a/examples/simple/jupyter_server_simple/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .application import ServerSimple - -EXTENSION_NAME = "server_simple" - -def _jupyter_server_extension_paths(): - return [{"module": EXTENSION_NAME}] - -load_jupyter_server_extension = ServerSimple.load_jupyter_server_extension diff --git a/examples/simple/jupyter_server_simple/handler.py b/examples/simple/jupyter_server_simple/handler.py deleted file mode 100644 index d8de78605f..0000000000 --- a/examples/simple/jupyter_server_simple/handler.py +++ /dev/null @@ -1,11 +0,0 @@ -from jupyter_server.extension.handler import ExtensionHandler - -class ServerSimpleHandler(ExtensionHandler): - - def get(self, matched_part=None, *args, **kwargs): - var1 = self.get_argument('var1', default=None) - components = [x for x in self.request.path.split("/") if x] - self.write('

Hello Server Simple from Handler.

') - self.write('

matched_part: {}

'.format(matched_part)) - self.write('

var1: {}

'.format(var1)) - self.write('

components: {}

'.format(components)) diff --git a/examples/simple/jupyter_server_simple/handler_template.py b/examples/simple/jupyter_server_simple/handler_template.py deleted file mode 100644 index 9966ea22a5..0000000000 --- a/examples/simple/jupyter_server_simple/handler_template.py +++ /dev/null @@ -1,11 +0,0 @@ -from jupyter_server.extension.handler import ExtensionHandler - -class ServerSimpleTemplateHandler(ExtensionHandler): - - def get_template(self, name): - """Return the jinja template object for a given name""" - return self.settings['server_simple_jinja2_env'].get_template(name) - - def get(self): -# print(self.get_template('server_simple.html')) - self.write(self.render_template('server_simple.html')) diff --git a/examples/simple/jupyter_server_simple/static/test.html b/examples/simple/jupyter_server_simple/static/test.html deleted file mode 100644 index 0d8106c290..0000000000 --- a/examples/simple/jupyter_server_simple/static/test.html +++ /dev/null @@ -1 +0,0 @@ -

Hello Server Simple from test HTML page.

diff --git a/examples/simple/jupyter_server_simple/templates/server_simple.html b/examples/simple/jupyter_server_simple/templates/server_simple.html deleted file mode 100644 index 36190d42c6..0000000000 --- a/examples/simple/jupyter_server_simple/templates/server_simple.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "page.html" %} - -{% block site %} -

Hello Server Simple from Template.

-{% endblock site %} diff --git a/examples/simple/jupyter_simple_ext/__init__.py b/examples/simple/jupyter_simple_ext/__init__.py new file mode 100644 index 0000000000..41a687982b --- /dev/null +++ b/examples/simple/jupyter_simple_ext/__init__.py @@ -0,0 +1,8 @@ +from .application import SimpleServer + +EXTENSION_NAME = "simple_ext" + +def _jupyter_server_extension_paths(): + return [{"module": EXTENSION_NAME}] + +load_jupyter_server_extension = SimpleServer.load_jupyter_server_extension diff --git a/examples/simple/jupyter_server_simple/application.py b/examples/simple/jupyter_simple_ext/application.py similarity index 53% rename from examples/simple/jupyter_server_simple/application.py rename to examples/simple/jupyter_simple_ext/application.py index 430baa8167..8ff8c5ed68 100644 --- a/examples/simple/jupyter_server_simple/application.py +++ b/examples/simple/jupyter_simple_ext/application.py @@ -1,15 +1,22 @@ import os, jinja2 -from .handler import ServerSimpleHandler -from .handler_template import ServerSimpleTemplateHandler from jupyter_server.extension.application import ExtensionApp +from .handlers import ParameterHandler, TemplateHandler, Page1Handler, IndexHandler, ErrorHandler DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -class ServerSimple(ExtensionApp): +print(DEFAULT_TEMPLATE_FILES_PATH) + +class SimpleServer(ExtensionApp): - # Name of the extension - extension_name = "server_simple" + # The name of the extension + extension_name = "simple_ext" + + # default_url: the url that your extension will serve its homepage. + default_url = '/simple_ext' + + # load_other_extensions: should your extension expose other server extensions when launched directly? + load_other_extensions = True # Local path to static files directory. static_paths = [ @@ -22,15 +29,13 @@ class ServerSimple(ExtensionApp): ] def initialize_handlers(self): - self.handlers.append( - (r'/server_simple', ServerSimpleHandler, {}) - ) - self.handlers.append( - (r'/server_simple/(.+)$', ServerSimpleHandler, {}) - ) - self.handlers.append( - (r'/template', ServerSimpleTemplateHandler, {}) - ) + self.handlers.extend([ + (r'/simple_ext/params/(.+)$', ParameterHandler), + (r'/simple_ext/template', TemplateHandler), + (r'/simple_ext/page1/(.*)$', Page1Handler), + (r'/simple_ext/?', IndexHandler), + (r'/simple_ext/(.*)', ErrorHandler) + ]) def initialize_templates(self): jenv_opt = {"autoescape": True} @@ -39,7 +44,7 @@ def initialize_templates(self): extensions=["jinja2.ext.i18n"], **jenv_opt ) - template_settings = {"server_simple_jinja2_env": env} + template_settings = {"simple_ext_jinja2_env": env} self.settings.update(**template_settings) def initialize_settings(self): @@ -49,4 +54,4 @@ def initialize_settings(self): # Main entry point #----------------------------------------------------------------------------- -main = launch_new_instance = ServerSimple.launch_instance +main = launch_new_instance = SimpleServer.launch_instance diff --git a/examples/simple/jupyter_simple_ext/handlers.py b/examples/simple/jupyter_simple_ext/handlers.py new file mode 100644 index 0000000000..b5b92cf499 --- /dev/null +++ b/examples/simple/jupyter_simple_ext/handlers.py @@ -0,0 +1,38 @@ +from jupyter_server.extension.handler import ExtensionHandler + +class TemplateHandler(ExtensionHandler): + + def get_template(self, name): + """Return the jinja template object for a given name""" + return self.settings['simple_ext_jinja2_env'].get_template(name) + +class IndexHandler(TemplateHandler): + + def get(self): + self.write(self.render_template("index.html")) + +class ParameterHandler(TemplateHandler): + + def get(self, matched_part=None, *args, **kwargs): + var1 = self.get_argument('var1', default=None) + components = [x for x in self.request.path.split("/") if x] + self.write('

Hello Simple Server from Handler.

') + self.write('

matched_part: {}

'.format(matched_part)) + self.write('

var1: {}

'.format(var1)) + self.write('

components: {}

'.format(components)) + +class TemplateHandler(TemplateHandler): + + def get(self): + print(self.get_template('simple_ext.html')) + self.write(self.render_template('simple_ext.html')) + +class Page1Handler(TemplateHandler): + + def get(self, path): + self.write(self.render_template('page1.html', text=path)) + +class ErrorHandler(TemplateHandler): + + def get(self, path): + self.write(self.render_template('error.html')) diff --git a/examples/simple/jupyter_simple_ext/static/bundle.js b/examples/simple/jupyter_simple_ext/static/bundle.js new file mode 100644 index 0000000000..eedfa23390 --- /dev/null +++ b/examples/simple/jupyter_simple_ext/static/bundle.js @@ -0,0 +1,111 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./jupyter_simple_ext/static/index.js": +/*!********************************************!*\ + !*** ./jupyter_simple_ext/static/index.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("function main() {\n let div = document.getElementById(\"mydiv\");\n div.innerText = \"

Hello from Typescript

\";\n}\nwindow.addEventListener('load', main);\n\n\n//# sourceURL=webpack:///./jupyter_simple_ext/static/index.js?"); + +/***/ }), + +/***/ 0: +/*!**************************************************!*\ + !*** multi ./jupyter_simple_ext/static/index.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("module.exports = __webpack_require__(/*! ./jupyter_simple_ext/static/index.js */\"./jupyter_simple_ext/static/index.js\");\n\n\n//# sourceURL=webpack:///multi_./jupyter_simple_ext/static/index.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/examples/simple/jupyter_server_simple/static/favicon.ico b/examples/simple/jupyter_simple_ext/static/favicon.ico similarity index 100% rename from examples/simple/jupyter_server_simple/static/favicon.ico rename to examples/simple/jupyter_simple_ext/static/favicon.ico diff --git a/examples/simple/jupyter_simple_ext/static/index.d.ts b/examples/simple/jupyter_simple_ext/static/index.d.ts new file mode 100644 index 0000000000..1be3002bfe --- /dev/null +++ b/examples/simple/jupyter_simple_ext/static/index.d.ts @@ -0,0 +1 @@ +declare function main(): void; diff --git a/examples/simple/jupyter_simple_ext/static/index.js b/examples/simple/jupyter_simple_ext/static/index.js new file mode 100644 index 0000000000..b18e39c21d --- /dev/null +++ b/examples/simple/jupyter_simple_ext/static/index.js @@ -0,0 +1,5 @@ +function main() { + let div = document.getElementById("mydiv"); + div.innerText = "

Hello from Typescript

"; +} +window.addEventListener('load', main); diff --git a/examples/simple/jupyter_simple_ext/static/test.html b/examples/simple/jupyter_simple_ext/static/test.html new file mode 100644 index 0000000000..7426bcb9c6 --- /dev/null +++ b/examples/simple/jupyter_simple_ext/static/test.html @@ -0,0 +1 @@ +

Hello Simple Server from test HTML page.

diff --git a/examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo b/examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo new file mode 100644 index 0000000000..bd022041a6 --- /dev/null +++ b/examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo @@ -0,0 +1,98 @@ +{ + "program": { + "fileInfos": { + "../../node_modules/typescript/lib/lib.es5.d.ts": { + "version": "ff5688d6b2fcfef06842a395d7ff4d5730d45b724d4c48913118c889829052a1", + "signature": "ff5688d6b2fcfef06842a395d7ff4d5730d45b724d4c48913118c889829052a1" + }, + "../../node_modules/typescript/lib/lib.es2015.d.ts": { + "version": "7994d44005046d1413ea31d046577cdda33b8b2470f30281fd9c8b3c99fe2d96", + "signature": "7994d44005046d1413ea31d046577cdda33b8b2470f30281fd9c8b3c99fe2d96" + }, + "../../node_modules/typescript/lib/lib.dom.d.ts": { + "version": "2d53f3741e5a4f78a90f623387d71a1cc809bb258f10cdaec034b67cbf71022f", + "signature": "2d53f3741e5a4f78a90f623387d71a1cc809bb258f10cdaec034b67cbf71022f" + }, + "../../node_modules/typescript/lib/lib.es2015.core.d.ts": { + "version": "4ab19088d508f9e62bfc61c157e8a65b2afaefa251ecca315e7d20b5b97b256f", + "signature": "4ab19088d508f9e62bfc61c157e8a65b2afaefa251ecca315e7d20b5b97b256f" + }, + "../../node_modules/typescript/lib/lib.es2015.collection.d.ts": { + "version": "dd94d8ef48c562389eb58af8df3a3a34d11367f7c818192aa5f16470d469e3f0", + "signature": "dd94d8ef48c562389eb58af8df3a3a34d11367f7c818192aa5f16470d469e3f0" + }, + "../../node_modules/typescript/lib/lib.es2015.generator.d.ts": { + "version": "765e0e9c9d74cf4d031ca8b0bdb269a853e7d81eda6354c8510218d03db12122", + "signature": "765e0e9c9d74cf4d031ca8b0bdb269a853e7d81eda6354c8510218d03db12122" + }, + "../../node_modules/typescript/lib/lib.es2015.iterable.d.ts": { + "version": "285958e7699f1babd76d595830207f18d719662a0c30fac7baca7df7162a9210", + "signature": "285958e7699f1babd76d595830207f18d719662a0c30fac7baca7df7162a9210" + }, + "../../node_modules/typescript/lib/lib.es2015.promise.d.ts": { + "version": "e6b8ff2798f8ebd7a1c7afd8671f2cb67ee1901c422f5964d74b0b34c6574ea2", + "signature": "e6b8ff2798f8ebd7a1c7afd8671f2cb67ee1901c422f5964d74b0b34c6574ea2" + }, + "../../node_modules/typescript/lib/lib.es2015.proxy.d.ts": { + "version": "5e72f949a89717db444e3bd9433468890068bb21a5638d8ab15a1359e05e54fe", + "signature": "5e72f949a89717db444e3bd9433468890068bb21a5638d8ab15a1359e05e54fe" + }, + "../../node_modules/typescript/lib/lib.es2015.reflect.d.ts": { + "version": "f5b242136ae9bfb1cc99a5971cccc44e99947ae6b5ef6fd8aa54b5ade553b976", + "signature": "f5b242136ae9bfb1cc99a5971cccc44e99947ae6b5ef6fd8aa54b5ade553b976" + }, + "../../node_modules/typescript/lib/lib.es2015.symbol.d.ts": { + "version": "9ae2860252d6b5f16e2026d8a2c2069db7b2a3295e98b6031d01337b96437230", + "signature": "9ae2860252d6b5f16e2026d8a2c2069db7b2a3295e98b6031d01337b96437230" + }, + "../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts": { + "version": "3e0a459888f32b42138d5a39f706ff2d55d500ab1031e0988b5568b0f67c2303", + "signature": "3e0a459888f32b42138d5a39f706ff2d55d500ab1031e0988b5568b0f67c2303" + }, + "../../src/index.ts": { + "version": "03d69b24d41bd5bd41aecc996c31b8e908696cebbae569924ed26916a10924a9", + "signature": "ed4b087ea2a2e4a58647864cf512c7534210bfc2f9d236a2f9ed5245cf7a0896" + } + }, + "options": { + "outDir": "./", + "allowSyntheticDefaultImports": true, + "composite": true, + "declaration": true, + "noImplicitAny": true, + "noEmitOnError": true, + "noUnusedLocals": true, + "esModuleInterop": true, + "preserveWatchOutput": true, + "module": 1, + "moduleResolution": 2, + "target": 2, + "lib": [ + "lib.dom.d.ts", + "lib.es2015.d.ts" + ], + "jsx": 2, + "types": [], + "project": "../../src", + "configFilePath": "../../src/tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../../node_modules/typescript/lib/lib.es5.d.ts", + "../../node_modules/typescript/lib/lib.es2015.d.ts", + "../../node_modules/typescript/lib/lib.dom.d.ts", + "../../node_modules/typescript/lib/lib.es2015.core.d.ts", + "../../node_modules/typescript/lib/lib.es2015.collection.d.ts", + "../../node_modules/typescript/lib/lib.es2015.generator.d.ts", + "../../node_modules/typescript/lib/lib.es2015.iterable.d.ts", + "../../node_modules/typescript/lib/lib.es2015.promise.d.ts", + "../../node_modules/typescript/lib/lib.es2015.proxy.d.ts", + "../../node_modules/typescript/lib/lib.es2015.reflect.d.ts", + "../../node_modules/typescript/lib/lib.es2015.symbol.d.ts", + "../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts", + "../../src/index.ts" + ] + }, + "version": "3.6.4" +} \ No newline at end of file diff --git a/examples/simple/jupyter_server_simple/templates/404.html b/examples/simple/jupyter_simple_ext/templates/404.html similarity index 100% rename from examples/simple/jupyter_server_simple/templates/404.html rename to examples/simple/jupyter_simple_ext/templates/404.html diff --git a/examples/simple/jupyter_server_simple/templates/browser-open.html b/examples/simple/jupyter_simple_ext/templates/browser-open.html similarity index 100% rename from examples/simple/jupyter_server_simple/templates/browser-open.html rename to examples/simple/jupyter_simple_ext/templates/browser-open.html diff --git a/examples/simple/jupyter_server_simple/templates/error.html b/examples/simple/jupyter_simple_ext/templates/error.html similarity index 99% rename from examples/simple/jupyter_server_simple/templates/error.html rename to examples/simple/jupyter_simple_ext/templates/error.html index 1e3fae6225..7426beb571 100644 --- a/examples/simple/jupyter_server_simple/templates/error.html +++ b/examples/simple/jupyter_simple_ext/templates/error.html @@ -18,4 +18,3 @@

{{status_code}} : {{status_message}}

{% endblock %} - diff --git a/examples/simple/jupyter_simple_ext/templates/index.html b/examples/simple/jupyter_simple_ext/templates/index.html new file mode 100644 index 0000000000..e825cf31cb --- /dev/null +++ b/examples/simple/jupyter_simple_ext/templates/index.html @@ -0,0 +1,21 @@ + + + + + + + + +
+

Hello world!

+
+ diff --git a/examples/simple/jupyter_server_simple/templates/main.html b/examples/simple/jupyter_simple_ext/templates/main.html similarity index 100% rename from examples/simple/jupyter_server_simple/templates/main.html rename to examples/simple/jupyter_simple_ext/templates/main.html diff --git a/examples/simple/jupyter_server_simple/templates/page.html b/examples/simple/jupyter_simple_ext/templates/page.html similarity index 100% rename from examples/simple/jupyter_server_simple/templates/page.html rename to examples/simple/jupyter_simple_ext/templates/page.html diff --git a/examples/simple/jupyter_simple_ext/templates/page1.html b/examples/simple/jupyter_simple_ext/templates/page1.html new file mode 100644 index 0000000000..7fba4842ae --- /dev/null +++ b/examples/simple/jupyter_simple_ext/templates/page1.html @@ -0,0 +1,19 @@ + + + + + + + +

Hello from Page 1 Template.

+

Path: {{text}}

+ diff --git a/examples/simple/jupyter_simple_ext/templates/simple_ext.html b/examples/simple/jupyter_simple_ext/templates/simple_ext.html new file mode 100644 index 0000000000..e825cf31cb --- /dev/null +++ b/examples/simple/jupyter_simple_ext/templates/simple_ext.html @@ -0,0 +1,21 @@ + + + + + + + + +
+

Hello world!

+
+ diff --git a/examples/simple/package.json b/examples/simple/package.json new file mode 100644 index 0000000000..26ae47510f --- /dev/null +++ b/examples/simple/package.json @@ -0,0 +1,18 @@ +{ + "name": "jupyter-server-simple-ext", + "version": "0.0.1", + "private": true, + "scripts": { + "build": "tsc -p src && webpack", + "clean": "rimraf build", + "prepublishOnly": "npm run build" + }, + "dependencies": {}, + "devDependencies": { + "rifraf": "2.0.3", + "webpack": "~4.29.6", + "webpack-cli": "^3.3.0", + "whatwg-fetch": "~2.0.3", + "typescript": "3.6.4" + } +} diff --git a/examples/simple/setup.py b/examples/simple/setup.py index 9ef276ee28..c2eacc8dbe 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -3,22 +3,22 @@ VERSION = '0.0.1' setuptools.setup( - name = 'jupyter_server_simple', + name = 'jupyter_simple_ext', version = VERSION, description = 'Datalayer', long_description = open('README.md').read(), packages = [ - 'jupyter_server_simple', + 'jupyter_simple_ext', ], package_data = { - 'jupyter_server_simple': [ + 'jupyter_simple_ext': [ '*', ], }, setup_requires = [ ], install_requires = [ - 'jupyter_server==0.2.0.dev0', + 'jupyter_server==0.1.1', 'jinja2', ], tests_requires = [ @@ -28,11 +28,11 @@ ], python_requires = '>=3.5', data_files = [ - ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/server_simple.json']), + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext.json']), ], entry_points = { 'console_scripts': [ - 'jupyter-server-simple = jupyter_server_simple.application:main' + 'jupyter-simple-ext = jupyter_simple_ext.application:main' ] }, ) diff --git a/examples/simple/webpack.config.js b/examples/simple/webpack.config.js new file mode 100644 index 0000000000..f39d5e004c --- /dev/null +++ b/examples/simple/webpack.config.js @@ -0,0 +1,8 @@ +module.exports = { + entry: ['./jupyter_simple_ext/static/index.js'], + output: { + path: require('path').join(__dirname, 'jupyter_simple_ext', 'static'), + filename: 'bundle.js' + }, + mode: 'development' +} From ec3d1968ad92eb560e6b6eba591d1a841da5c651 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Fri, 11 Oct 2019 19:07:50 +0200 Subject: [PATCH 03/30] force pr refresh --- examples/simple/test | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/simple/test diff --git a/examples/simple/test b/examples/simple/test new file mode 100644 index 0000000000..e69de29bb2 From de57ab24ff5a7d815590889805737698a6f2414c Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Fri, 11 Oct 2019 19:08:03 +0200 Subject: [PATCH 04/30] force pr refresh --- examples/simple/test | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/simple/test diff --git a/examples/simple/test b/examples/simple/test deleted file mode 100644 index e69de29bb2..0000000000 From 51c3a65ce1246a89d5c82424b3ee736cab0b60f8 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 12 Oct 2019 10:30:45 +0200 Subject: [PATCH 05/30] 2 apps --- .gitignore | 4 +- examples/simple/Makefile | 29 +++++-- examples/simple/README.md | 72 ++++++++++++++---- .../jupyter_server_config.d/simple_ext.json | 3 +- .../simple/jupyter_simple_ext/__init__.py | 8 -- .../jupyter_simple_ext/static/test.html | 1 - .../jupyter_simple_ext/templates/404.html | 5 -- .../templates/browser-open.html | 18 ----- .../jupyter_simple_ext/templates/main.html | 5 -- examples/simple/package.json | 2 +- examples/simple/setup.py | 44 ++++++----- examples/simple/simple_ext1/__init__.py | 8 ++ .../application.py | 26 +++---- .../handlers.py | 10 +-- .../static/bundle.js | 18 ++--- .../static/favicon.ico | Bin .../static/index.d.ts | 0 .../static/index.js | 2 +- examples/simple/simple_ext1/static/test.html | 1 + .../static/tsconfig.tsbuildinfo | 2 +- .../templates/error.html | 0 .../templates/index.html | 0 .../templates/page.html | 0 .../templates/page1.html | 0 .../templates/simple_ext1.html} | 0 examples/simple/simple_ext2/__init__.py | 8 ++ examples/simple/simple_ext2/application.py | 56 ++++++++++++++ examples/simple/simple_ext2/handlers.py | 33 ++++++++ .../simple/simple_ext2/static/favicon.ico | Bin 0 -> 32038 bytes examples/simple/simple_ext2/static/test.html | 1 + .../simple/simple_ext2/templates/error.html | 20 +++++ .../simple/simple_ext2/templates/index.html | 1 + .../simple/simple_ext2/templates/page.html | 20 +++++ .../simple_ext2/templates/simple_ext2.html | 1 + examples/simple/webpack.config.js | 4 +- 35 files changed, 292 insertions(+), 110 deletions(-) delete mode 100644 examples/simple/jupyter_simple_ext/__init__.py delete mode 100644 examples/simple/jupyter_simple_ext/static/test.html delete mode 100644 examples/simple/jupyter_simple_ext/templates/404.html delete mode 100644 examples/simple/jupyter_simple_ext/templates/browser-open.html delete mode 100644 examples/simple/jupyter_simple_ext/templates/main.html create mode 100644 examples/simple/simple_ext1/__init__.py rename examples/simple/{jupyter_simple_ext => simple_ext1}/application.py (63%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/handlers.py (77%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/static/bundle.js (83%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/static/favicon.ico (100%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/static/index.d.ts (100%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/static/index.js (66%) create mode 100644 examples/simple/simple_ext1/static/test.html rename examples/simple/{jupyter_simple_ext => simple_ext1}/static/tsconfig.tsbuildinfo (98%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/templates/error.html (100%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/templates/index.html (100%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/templates/page.html (100%) rename examples/simple/{jupyter_simple_ext => simple_ext1}/templates/page1.html (100%) rename examples/simple/{jupyter_simple_ext/templates/simple_ext.html => simple_ext1/templates/simple_ext1.html} (100%) create mode 100644 examples/simple/simple_ext2/__init__.py create mode 100644 examples/simple/simple_ext2/application.py create mode 100644 examples/simple/simple_ext2/handlers.py create mode 100644 examples/simple/simple_ext2/static/favicon.ico create mode 100644 examples/simple/simple_ext2/static/test.html create mode 100644 examples/simple/simple_ext2/templates/error.html create mode 100644 examples/simple/simple_ext2/templates/index.html create mode 100644 examples/simple/simple_ext2/templates/page.html create mode 100644 examples/simple/simple_ext2/templates/simple_ext2.html diff --git a/.gitignore b/.gitignore index b9a436dd76..5f0aa534df 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,7 @@ notebook/static/*/built/ notebook/static/built/ notebook/static/*/js/main.min.js* notebook/static/lab/*bundle.js -**/node_modules -**/yarn.lock +node_modules *.py[co] __pycache__ *.egg-info @@ -42,3 +41,4 @@ config.rst package-lock.json geckodriver.log +yarn.lock diff --git a/examples/simple/Makefile b/examples/simple/Makefile index 4292cafbb1..b7324ebfd0 100644 --- a/examples/simple/Makefile +++ b/examples/simple/Makefile @@ -1,11 +1,28 @@ -default: all ## default target is all. +.PHONY: clean build install uninstall -install: - yarn install +clean: + npm clean + +install-ts: + npm install +build-ts: + npm run build + build: - yarn build pip install -e . -start: - jupyter simple-ext +install: + python setup.py install + +uninstall: + pip uninstall -y simple_ext + +start1+2: + jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" + +start1: + jupyter simple-ext1 + +start2: + jupyter simple-ext2 diff --git a/examples/simple/README.md b/examples/simple/README.md index 92d0ef9518..766869b98e 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -1,36 +1,80 @@ # Jupyter Server Simple Extension Example -This folder contains an example of a simple extension on top of Jupyter Server. +This folder contains an example of 2 simple extensions on top of Jupyter Server. -You need yarn and python3. +OPTIONAL (compiled js is provided) If you want to build the typescript code, you need npm installed. ```bash -# Install and build. -make install +make install-ts +make build-ts +``` + +You need python3 to build and run the extensions. + +```bash +conda create -y -n jext python=3.7 +conda activate jext make build ``` ```bash -# Start the jupyter server simple extension. -make start +# Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. +make start1+2 +``` + +Optionally, you can copy `simple_ext.json` configuration to your env `etc` folder and start only App 1. + +```bash +make uninstall +make install +cp -r ./etc $(dirname $(which jupyter))/.. +# Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. +make start1 ``` -Render server content in your browser. +Render default Server content in your browser. ```bash # Default server page. open http://localhost:8888 +``` + +Render Extension 1 Server content in your browser. + +```bash # Favicon static content. -open http://localhost:8888/static/simple_ext/favicon.ico +open http://localhost:8888/static/simple_ext1/favicon.ico # HTML static page. -open http://localhost:8888/static/simple_ext/test.html +open http://localhost:8888/static/simple_ext1/test.html # Content from Handlers. -open http://localhost:8888/simple_ext/params/test?var1=foo +open http://localhost:8888/simple_ext1/params/test?var1=foo # Content from Template. -open http://localhost:8888/simple_ext/page1/test +open http://localhost:8888/simple_ext1/page1/test # Content from Template with Typescript. -open http://localhost:8888/simple_ext -open http://localhost:8888/simple_ext/template +open http://localhost:8888/simple_ext1 +open http://localhost:8888/simple_ext1/template # Error content. -open http://localhost:8888/simple_ext/nope +open http://localhost:8888/simple_ext1/nope ``` + +Render Extension 2 Server content in your browser. + +```bash +# HTML static page. +open http://localhost:8888/static/simple_ext2/test.html +# Content from Handlers. +open http://localhost:8888/simple_ext2/params/test?var1=foo +``` + +Now stop the server and start again with only Extension 2. + +```bash +# Start the jupyter server extension simple_ext2, it will NOT load simple_ext1 because of load_other_extensions = False. +make start2 +``` + +Try with the above links to check that only Extension 2 is responding. + +## TODO + ++ Automatic redirect on the default home page. diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json index f58607d536..b3e2f07b59 100644 --- a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json @@ -1,7 +1,8 @@ { "ServerApp": { "jpserver_extensions": { - "simple_ext": true + "simple_ext1": true, + "simple_ext2": true } } } diff --git a/examples/simple/jupyter_simple_ext/__init__.py b/examples/simple/jupyter_simple_ext/__init__.py deleted file mode 100644 index 41a687982b..0000000000 --- a/examples/simple/jupyter_simple_ext/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .application import SimpleServer - -EXTENSION_NAME = "simple_ext" - -def _jupyter_server_extension_paths(): - return [{"module": EXTENSION_NAME}] - -load_jupyter_server_extension = SimpleServer.load_jupyter_server_extension diff --git a/examples/simple/jupyter_simple_ext/static/test.html b/examples/simple/jupyter_simple_ext/static/test.html deleted file mode 100644 index 7426bcb9c6..0000000000 --- a/examples/simple/jupyter_simple_ext/static/test.html +++ /dev/null @@ -1 +0,0 @@ -

Hello Simple Server from test HTML page.

diff --git a/examples/simple/jupyter_simple_ext/templates/404.html b/examples/simple/jupyter_simple_ext/templates/404.html deleted file mode 100644 index e29646af1a..0000000000 --- a/examples/simple/jupyter_simple_ext/templates/404.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "error.html" %} -{% block error_detail %} -

{% trans %}You are requesting a page that does not exist!{% endtrans %}

-{% endblock %} - diff --git a/examples/simple/jupyter_simple_ext/templates/browser-open.html b/examples/simple/jupyter_simple_ext/templates/browser-open.html deleted file mode 100644 index 6f277967fc..0000000000 --- a/examples/simple/jupyter_simple_ext/templates/browser-open.html +++ /dev/null @@ -1,18 +0,0 @@ -{# This template is not served, but written as a file to open in the browser, - passing the token without putting it in a command-line argument. #} - - - - - - Opening Jupyter Notebook - - - -

- This page should redirect you to Jupyter Notebook. If it doesn't, - click here to go to Jupyter. -

- - - diff --git a/examples/simple/jupyter_simple_ext/templates/main.html b/examples/simple/jupyter_simple_ext/templates/main.html deleted file mode 100644 index 51f8be1c07..0000000000 --- a/examples/simple/jupyter_simple_ext/templates/main.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "page.html" %} - -{% block site %} -

Server 1 is running.

-{% endblock site %} diff --git a/examples/simple/package.json b/examples/simple/package.json index 26ae47510f..a1b2132753 100644 --- a/examples/simple/package.json +++ b/examples/simple/package.json @@ -1,5 +1,5 @@ { - "name": "jupyter-server-simple-ext", + "name": "jupyter-simple-ext", "version": "0.0.1", "private": true, "scripts": { diff --git a/examples/simple/setup.py b/examples/simple/setup.py index c2eacc8dbe..a2e78122df 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -1,22 +1,32 @@ -import setuptools +import os, setuptools +from setuptools import find_packages VERSION = '0.0.1' +def get_data_files(): + """Get the data files for the package. + """ + data_files = [ + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext.json']), + ] + def add_data_files(path): + for (dirpath, dirnames, filenames) in os.walk(path): + if filenames: + data_files.append((dirpath, [os.path.join(dirpath, filename) for filename in filenames])) + # Add all the templates + add_data_files('simple_ext1/static') + add_data_files('simple_ext1/templates') + add_data_files('simple_ext2/static') + add_data_files('simple_ext2/templates') + return data_files + setuptools.setup( - name = 'jupyter_simple_ext', + name = 'simple_ext', version = VERSION, - description = 'Datalayer', + description = 'Jupyter Simple Extension', long_description = open('README.md').read(), - packages = [ - 'jupyter_simple_ext', - ], - package_data = { - 'jupyter_simple_ext': [ - '*', - ], - }, - setup_requires = [ - ], + packages = find_packages(), + python_requires = '>=3.5', install_requires = [ 'jupyter_server==0.1.1', 'jinja2', @@ -26,13 +36,11 @@ 'pytest-cov', 'pylint', ], - python_requires = '>=3.5', - data_files = [ - ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext.json']), - ], + data_files = get_data_files(), entry_points = { 'console_scripts': [ - 'jupyter-simple-ext = jupyter_simple_ext.application:main' + 'jupyter-simple-ext1 = simple_ext1.application:main', + 'jupyter-simple-ext2 = simple_ext2.application:main' ] }, ) diff --git a/examples/simple/simple_ext1/__init__.py b/examples/simple/simple_ext1/__init__.py new file mode 100644 index 0000000000..cf3068ed96 --- /dev/null +++ b/examples/simple/simple_ext1/__init__.py @@ -0,0 +1,8 @@ +from .application import SimpleApp1 + +def _jupyter_server_extension_paths(): + return [ + {'module': 'simple_ext1'} + ] + +load_jupyter_server_extension = SimpleApp1.load_jupyter_server_extension diff --git a/examples/simple/jupyter_simple_ext/application.py b/examples/simple/simple_ext1/application.py similarity index 63% rename from examples/simple/jupyter_simple_ext/application.py rename to examples/simple/simple_ext1/application.py index 8ff8c5ed68..4a6c74965e 100644 --- a/examples/simple/jupyter_simple_ext/application.py +++ b/examples/simple/simple_ext1/application.py @@ -5,17 +5,17 @@ DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -print(DEFAULT_TEMPLATE_FILES_PATH) +print('--- {}'.format(DEFAULT_STATIC_FILES_PATH)) -class SimpleServer(ExtensionApp): +class SimpleApp1(ExtensionApp): # The name of the extension - extension_name = "simple_ext" + extension_name = "simple_ext1" - # default_url: the url that your extension will serve its homepage. - default_url = '/simple_ext' + # Te url that your extension will serve its homepage. + default_url = '/simple_ext1' - # load_other_extensions: should your extension expose other server extensions when launched directly? + # Should your extension expose other server extensions when launched directly? load_other_extensions = True # Local path to static files directory. @@ -30,11 +30,11 @@ class SimpleServer(ExtensionApp): def initialize_handlers(self): self.handlers.extend([ - (r'/simple_ext/params/(.+)$', ParameterHandler), - (r'/simple_ext/template', TemplateHandler), - (r'/simple_ext/page1/(.*)$', Page1Handler), - (r'/simple_ext/?', IndexHandler), - (r'/simple_ext/(.*)', ErrorHandler) + (r'/simple_ext1/params/(.+)$', ParameterHandler), + (r'/simple_ext1/template', TemplateHandler), + (r'/simple_ext1/page1/(.*)$', Page1Handler), + (r'/simple_ext1/?', IndexHandler), + (r'/simple_ext1/(.*)', ErrorHandler) ]) def initialize_templates(self): @@ -44,7 +44,7 @@ def initialize_templates(self): extensions=["jinja2.ext.i18n"], **jenv_opt ) - template_settings = {"simple_ext_jinja2_env": env} + template_settings = {"simple_ext1_jinja2_env": env} self.settings.update(**template_settings) def initialize_settings(self): @@ -54,4 +54,4 @@ def initialize_settings(self): # Main entry point #----------------------------------------------------------------------------- -main = launch_new_instance = SimpleServer.launch_instance +main = launch_new_instance = SimpleApp1.launch_instance diff --git a/examples/simple/jupyter_simple_ext/handlers.py b/examples/simple/simple_ext1/handlers.py similarity index 77% rename from examples/simple/jupyter_simple_ext/handlers.py rename to examples/simple/simple_ext1/handlers.py index b5b92cf499..67f3c9daab 100644 --- a/examples/simple/jupyter_simple_ext/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -4,19 +4,19 @@ class TemplateHandler(ExtensionHandler): def get_template(self, name): """Return the jinja template object for a given name""" - return self.settings['simple_ext_jinja2_env'].get_template(name) + return self.settings['simple_ext1_jinja2_env'].get_template(name) class IndexHandler(TemplateHandler): def get(self): self.write(self.render_template("index.html")) -class ParameterHandler(TemplateHandler): +class ParameterHandler(ExtensionHandler): def get(self, matched_part=None, *args, **kwargs): var1 = self.get_argument('var1', default=None) components = [x for x in self.request.path.split("/") if x] - self.write('

Hello Simple Server from Handler.

') + self.write('

Hello Simple App 1 from Handler.

') self.write('

matched_part: {}

'.format(matched_part)) self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) @@ -24,8 +24,8 @@ def get(self, matched_part=None, *args, **kwargs): class TemplateHandler(TemplateHandler): def get(self): - print(self.get_template('simple_ext.html')) - self.write(self.render_template('simple_ext.html')) + print(self.get_template('simple_ext1.html')) + self.write(self.render_template('simple_ext1.html')) class Page1Handler(TemplateHandler): diff --git a/examples/simple/jupyter_simple_ext/static/bundle.js b/examples/simple/simple_ext1/static/bundle.js similarity index 83% rename from examples/simple/jupyter_simple_ext/static/bundle.js rename to examples/simple/simple_ext1/static/bundle.js index eedfa23390..f6b8f608a0 100644 --- a/examples/simple/jupyter_simple_ext/static/bundle.js +++ b/examples/simple/simple_ext1/static/bundle.js @@ -86,25 +86,25 @@ /************************************************************************/ /******/ ({ -/***/ "./jupyter_simple_ext/static/index.js": -/*!********************************************!*\ - !*** ./jupyter_simple_ext/static/index.js ***! - \********************************************/ +/***/ "./simple_ext1/static/index.js": +/*!*************************************!*\ + !*** ./simple_ext1/static/index.js ***! + \*************************************/ /*! no static exports found */ /***/ (function(module, exports) { -eval("function main() {\n let div = document.getElementById(\"mydiv\");\n div.innerText = \"

Hello from Typescript

\";\n}\nwindow.addEventListener('load', main);\n\n\n//# sourceURL=webpack:///./jupyter_simple_ext/static/index.js?"); +eval("function main() {\n let div = document.getElementById(\"mydiv\");\n div.innerText = \"Hello from Typescript\";\n}\nwindow.addEventListener('load', main);\n\n\n//# sourceURL=webpack:///./simple_ext1/static/index.js?"); /***/ }), /***/ 0: -/*!**************************************************!*\ - !*** multi ./jupyter_simple_ext/static/index.js ***! - \**************************************************/ +/*!*******************************************!*\ + !*** multi ./simple_ext1/static/index.js ***! + \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("module.exports = __webpack_require__(/*! ./jupyter_simple_ext/static/index.js */\"./jupyter_simple_ext/static/index.js\");\n\n\n//# sourceURL=webpack:///multi_./jupyter_simple_ext/static/index.js?"); +eval("module.exports = __webpack_require__(/*! ./simple_ext1/static/index.js */\"./simple_ext1/static/index.js\");\n\n\n//# sourceURL=webpack:///multi_./simple_ext1/static/index.js?"); /***/ }) diff --git a/examples/simple/jupyter_simple_ext/static/favicon.ico b/examples/simple/simple_ext1/static/favicon.ico similarity index 100% rename from examples/simple/jupyter_simple_ext/static/favicon.ico rename to examples/simple/simple_ext1/static/favicon.ico diff --git a/examples/simple/jupyter_simple_ext/static/index.d.ts b/examples/simple/simple_ext1/static/index.d.ts similarity index 100% rename from examples/simple/jupyter_simple_ext/static/index.d.ts rename to examples/simple/simple_ext1/static/index.d.ts diff --git a/examples/simple/jupyter_simple_ext/static/index.js b/examples/simple/simple_ext1/static/index.js similarity index 66% rename from examples/simple/jupyter_simple_ext/static/index.js rename to examples/simple/simple_ext1/static/index.js index b18e39c21d..a7a67eed18 100644 --- a/examples/simple/jupyter_simple_ext/static/index.js +++ b/examples/simple/simple_ext1/static/index.js @@ -1,5 +1,5 @@ function main() { let div = document.getElementById("mydiv"); - div.innerText = "

Hello from Typescript

"; + div.innerText = "Hello from Typescript"; } window.addEventListener('load', main); diff --git a/examples/simple/simple_ext1/static/test.html b/examples/simple/simple_ext1/static/test.html new file mode 100644 index 0000000000..8c0bb51855 --- /dev/null +++ b/examples/simple/simple_ext1/static/test.html @@ -0,0 +1 @@ +

Hello Simple App 1 from test HTML page.

diff --git a/examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo b/examples/simple/simple_ext1/static/tsconfig.tsbuildinfo similarity index 98% rename from examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo rename to examples/simple/simple_ext1/static/tsconfig.tsbuildinfo index bd022041a6..62d6680e8a 100644 --- a/examples/simple/jupyter_simple_ext/static/tsconfig.tsbuildinfo +++ b/examples/simple/simple_ext1/static/tsconfig.tsbuildinfo @@ -50,7 +50,7 @@ "signature": "3e0a459888f32b42138d5a39f706ff2d55d500ab1031e0988b5568b0f67c2303" }, "../../src/index.ts": { - "version": "03d69b24d41bd5bd41aecc996c31b8e908696cebbae569924ed26916a10924a9", + "version": "fd4f62325debd29128c1990caa4d546f2c48c21ea133fbcbb3e29f9fbef55e49", "signature": "ed4b087ea2a2e4a58647864cf512c7534210bfc2f9d236a2f9ed5245cf7a0896" } }, diff --git a/examples/simple/jupyter_simple_ext/templates/error.html b/examples/simple/simple_ext1/templates/error.html similarity index 100% rename from examples/simple/jupyter_simple_ext/templates/error.html rename to examples/simple/simple_ext1/templates/error.html diff --git a/examples/simple/jupyter_simple_ext/templates/index.html b/examples/simple/simple_ext1/templates/index.html similarity index 100% rename from examples/simple/jupyter_simple_ext/templates/index.html rename to examples/simple/simple_ext1/templates/index.html diff --git a/examples/simple/jupyter_simple_ext/templates/page.html b/examples/simple/simple_ext1/templates/page.html similarity index 100% rename from examples/simple/jupyter_simple_ext/templates/page.html rename to examples/simple/simple_ext1/templates/page.html diff --git a/examples/simple/jupyter_simple_ext/templates/page1.html b/examples/simple/simple_ext1/templates/page1.html similarity index 100% rename from examples/simple/jupyter_simple_ext/templates/page1.html rename to examples/simple/simple_ext1/templates/page1.html diff --git a/examples/simple/jupyter_simple_ext/templates/simple_ext.html b/examples/simple/simple_ext1/templates/simple_ext1.html similarity index 100% rename from examples/simple/jupyter_simple_ext/templates/simple_ext.html rename to examples/simple/simple_ext1/templates/simple_ext1.html diff --git a/examples/simple/simple_ext2/__init__.py b/examples/simple/simple_ext2/__init__.py new file mode 100644 index 0000000000..f9d5935153 --- /dev/null +++ b/examples/simple/simple_ext2/__init__.py @@ -0,0 +1,8 @@ +from .application import SimpleApp2 + +def _jupyter_server_extension_paths(): + return [ + {'module': 'simple_ext2'}, + ] + +load_jupyter_server_extension = SimpleApp2.load_jupyter_server_extension diff --git a/examples/simple/simple_ext2/application.py b/examples/simple/simple_ext2/application.py new file mode 100644 index 0000000000..fd914237a6 --- /dev/null +++ b/examples/simple/simple_ext2/application.py @@ -0,0 +1,56 @@ +import os, jinja2 +from jupyter_server.extension.application import ExtensionApp +from .handlers import ParameterHandler, TemplateHandler, IndexHandler, ErrorHandler + +DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") +DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") + +print('--- {}'.format(DEFAULT_STATIC_FILES_PATH)) + +class SimpleApp2(ExtensionApp): + + # The name of the extension + extension_name = "simple_ext2" + + # Te url that your extension will serve its homepage. + default_url = '/simple_ext2' + + # Should your extension expose other server extensions when launched directly? + load_other_extensions = False + + # Local path to static files directory. + static_paths = [ + DEFAULT_STATIC_FILES_PATH + ] + + # Local path to templates directory. + template_paths = [ + DEFAULT_TEMPLATE_FILES_PATH + ] + + def initialize_handlers(self): + self.handlers.extend([ + (r'/simple_ext2/params/(.+)$', ParameterHandler), + (r'/simple_ext2/template', TemplateHandler), + (r'/simple_ext2/?', IndexHandler), + (r'/simple_ext2/(.*)', ErrorHandler) + ]) + + def initialize_templates(self): + jenv_opt = {"autoescape": True} + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(self.template_paths), + extensions=["jinja2.ext.i18n"], + **jenv_opt + ) + template_settings = {"simple_ext2_jinja2_env": env} + self.settings.update(**template_settings) + + def initialize_settings(self): + pass + +#----------------------------------------------------------------------------- +# Main entry point +#----------------------------------------------------------------------------- + +main = launch_new_instance = SimpleApp2.launch_instance diff --git a/examples/simple/simple_ext2/handlers.py b/examples/simple/simple_ext2/handlers.py new file mode 100644 index 0000000000..21fcec1732 --- /dev/null +++ b/examples/simple/simple_ext2/handlers.py @@ -0,0 +1,33 @@ +from jupyter_server.extension.handler import ExtensionHandler + +class TemplateHandler(ExtensionHandler): + + def get_template(self, name): + """Return the jinja template object for a given name""" + return self.settings['simple_ext2_jinja2_env'].get_template(name) + +class IndexHandler(TemplateHandler): + + def get(self): + self.write(self.render_template("index.html")) + +class ParameterHandler(ExtensionHandler): + + def get(self, matched_part=None, *args, **kwargs): + var1 = self.get_argument('var1', default=None) + components = [x for x in self.request.path.split("/") if x] + self.write('

Hello Simple App 2 from Handler.

') + self.write('

matched_part: {}

'.format(matched_part)) + self.write('

var1: {}

'.format(var1)) + self.write('

components: {}

'.format(components)) + +class TemplateHandler(TemplateHandler): + + def get(self): + print(self.get_template('simple_ext2.html')) + self.write(self.render_template('simple_ext2.html')) + +class ErrorHandler(TemplateHandler): + + def get(self, path): + self.write(self.render_template('error.html')) diff --git a/examples/simple/simple_ext2/static/favicon.ico b/examples/simple/simple_ext2/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2d1bcff7ca0ed6c77fdf1b016986f9137a43d31a GIT binary patch literal 32038 zcmeI4U5FG{7ROsAA|fG?5JY4_k?9XRYJ%itpLE5Qd5}CTSqV$nU6$YuB0hvnSGNw% z5*9HcG7rljAx|Of2kb(SAVHR88S)UqAR>zoOCCg)ARz>&t7k?;dw>7xx;=NQtGcVF zKWDlc&eW}2_nxnN>fUqDJvFJ+medQWmtRit+nf6R3#ru4RoYv-{|oj1pzih8{rmA$ z>X)ykQb&*0?z2BjrJnyZmCAA}6nlX!-e20#FZiogt6PGQF1WkXh4N{j-~(lMcd%XX zp0?w_-+`wNviJo^c=^??1z);#+$d~?5U`?YYa`~5LEYVy==z5f1&y%TDiN>!_!faaOK zz)`@=Gc(@YMTPaV`5WePw!nPgxXgFuS>S8nAt2ijsI0nKwNcw{$&x9S_k(v1u;)56 z=S5xBc20fQ%SXQWMDyQeKsFskr&YcBUKXx)_{ccree}EA0o@>9cZD+!56sA4(YRvcV_c;7|FUkpY1j9noOLR1dbFTv@I&_u>sHrgHu!^A=)D5GXX^9L zO2c@VXT7=(f@ZH|N$@uA6%w5!I*DrogP03!nwkqWC&uNs({`Hcp?AjMG3$@k22We+K#J_PrGf7)ViZ3WZF61JvUb#7=|1Zp*z<@#RZPFS3Rl1{Bx& zE%V~J@q$|vaDPs9dZspNI}CF2K5U1t6YzSC>pY-+?sveCfZ{h=_XH}dPS4b4KJAp% z=Y(+dQvQYSH6& zyudZ0JU&&EPkcv}(^KH8;k+Um-IjqhXFEE2CtX^A5LTJ9&JynXT3Z)210ufdf^#%=BL9M%57^x`)52zg|A zS2TQDPi?#McxoX7d!23Y_5p3po<#b8m?@Osr~YuJu=G+C58bNIK?B_!gzkCdu-BKe zcoUCNw9-@V1pTx|J_Qz7BhR9jp7R{ZPsx3eF`0yyZ#M+T)x0O_Vxqw z)(zhKd|10d)WKH{8<^v&_hUXiQ*Brq;P({IIB#+%50tvUPw!OjytA|u`#B>X#jA}k zH@&=*_jWE_baQt7FqWA=a_IO^;@R*=d}hDie{(iB!(_YKozlc|}f7BjLd$nQXKj$b13N3ho?lW72VNEc;`Pz-6VHZ-4KYT+_?2Qv=h<@} z%oQs=j|C}4hJ7n;{60WDq!w$X?8mQ`BI8${3{J(1AKEcU`f5BB^ZXe3-bI$&f$4Hn zJi-+h6pQ4&%PTes4aMs3`!>M2NIeGoX}VB}6$8yWWy!E$%V3pdgT$E^ZxOGXhUUp^ zF^?r2CLKbbVZT=9LvQ zMXuKIbK0n_>F48az^8iAZaaQ184i84dVXQ)-lruUSu(XMw|egBJQSaIesS<>`{x(+ zafm!W3e{J*PW>}7Pv>#UT{u57{Oh`Ue#hBb!8>E~&KS(N=o(e7@f@n#hA|}G|AhAb z`Ca#OXLBWUe!BQAHvh~!H}&6*sIteuC*SIL1>17}jCSBGUl9#kcik@6&#!BF0p9sS zOa1#Y8d(BYaBvphhx6;8E||ADGjLnx4k3vA(kJc(~tW# z`5RNU{0&d9-Z;7EC=Xr!MnCk@ibgFTNZ&;1mt6a;2jyuU1!e$~rTnr8g+GKrn&>a`&h=QT)?OPD|7olnKSR;BkN3d*@Ig7j-GjKXsbTzyAgHjXGc09z{zu2mOBJO67NWe|e94FLO8z_n~;`w=J-5$`k*Y59etBx_}q))DJym zi%Y*C_SQFBkE>(xB;I&iRiR>fntb>PkIPWkh=V=?G<=-~5itr16V zRQ3NcZmnM?d>n@upyS?zuQ`02t7)fliP+)?d}}o+P+4`*xvCgF*PGZGaYOk>>zhx+ zvv}{+7QmzY+PF6VBl6usCgP{%jK=MfdyCA)l}uRQe%5hb zIxbyccXm$h8he#2?eIh{?>_J;HWk3*E-=o&Iy%$&d({pSNB%5S3_4ZZ%63_of9>j!QznRL|!36W;!!X}4TdcfCF2#w> zByX53l2Nh-pJ^Qp)@|1NQId7Dj$tBKW2`;VNura)1`-=cY#_0L#0C-@NNganfy4$9 z8%S&*v4O+}n%lrA#e~9S9rgI97yl+UtQhfTeODCQSByU_{wIy>6vw(wfX-G$t@1_N&h7y__Q}eEax-{u^-b>Dyp1;VA3Pm2 z$$vqY572S(wTmnJ2W<<=!NIPlb*>qd+uXOC|6*iP?vTL|d3D@7%D+)glIhp$t8%Th zMlsfRBl+@eKr(c~4>V%uztwUr+%LR*By!f2yVeP9^;HgCEuRH>$*n`)zU9A(epm7z z$z?>3H~rkk==?`=BbjICSg&r@=C8r$KS~Gkm*8t8^IvWIMF%69|7`1El=I(>9!B~5 z2crXBNA>#`TL**q{)x5W@i2VHello Simple App 2 from test HTML page. diff --git a/examples/simple/simple_ext2/templates/error.html b/examples/simple/simple_ext2/templates/error.html new file mode 100644 index 0000000000..7426beb571 --- /dev/null +++ b/examples/simple/simple_ext2/templates/error.html @@ -0,0 +1,20 @@ +{% extends "page.html" %} + +{% block site %} + +
+ {% block h1_error %} +

{{status_code}} : {{status_message}}

+ {% endblock h1_error %} + + {% block error_detail %} + {% if message %} +

{% trans %}The error was:{% endtrans %}

+
+
{{message}}
+
+ {% endif %} + {% endblock error_detail %} +
+ +{% endblock %} diff --git a/examples/simple/simple_ext2/templates/index.html b/examples/simple/simple_ext2/templates/index.html new file mode 100644 index 0000000000..a42a0ab378 --- /dev/null +++ b/examples/simple/simple_ext2/templates/index.html @@ -0,0 +1 @@ +

Hello Extension 2 from HTML Index Static Page

diff --git a/examples/simple/simple_ext2/templates/page.html b/examples/simple/simple_ext2/templates/page.html new file mode 100644 index 0000000000..cf01c9a0b0 --- /dev/null +++ b/examples/simple/simple_ext2/templates/page.html @@ -0,0 +1,20 @@ + + + + + {% block title %}Jupyter Server 1{% endblock %} + {% block favicon %}{% endblock %} + + + {% block meta %} + {% endblock %} + + +
+ {% block site %} + {% endblock site %} +
+ {% block after_site %} + {% endblock after_site %} + + diff --git a/examples/simple/simple_ext2/templates/simple_ext2.html b/examples/simple/simple_ext2/templates/simple_ext2.html new file mode 100644 index 0000000000..0c7df48e9a --- /dev/null +++ b/examples/simple/simple_ext2/templates/simple_ext2.html @@ -0,0 +1 @@ +

Hello Extension 2 from Simple HTML Static Page

diff --git a/examples/simple/webpack.config.js b/examples/simple/webpack.config.js index f39d5e004c..6016ce5260 100644 --- a/examples/simple/webpack.config.js +++ b/examples/simple/webpack.config.js @@ -1,7 +1,7 @@ module.exports = { - entry: ['./jupyter_simple_ext/static/index.js'], + entry: ['./simple_ext1/static/index.js'], output: { - path: require('path').join(__dirname, 'jupyter_simple_ext', 'static'), + path: require('path').join(__dirname, 'simple_ext1', 'static'), filename: 'bundle.js' }, mode: 'development' From c3f9c286ef22e761d2a88c683da0fa7be00cbec6 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 12 Oct 2019 10:54:14 +0200 Subject: [PATCH 06/30] rm print static path --- examples/simple/simple_ext1/application.py | 2 -- examples/simple/simple_ext2/application.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 4a6c74965e..8e7512a399 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -5,8 +5,6 @@ DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -print('--- {}'.format(DEFAULT_STATIC_FILES_PATH)) - class SimpleApp1(ExtensionApp): # The name of the extension diff --git a/examples/simple/simple_ext2/application.py b/examples/simple/simple_ext2/application.py index fd914237a6..f7cf0ad619 100644 --- a/examples/simple/simple_ext2/application.py +++ b/examples/simple/simple_ext2/application.py @@ -5,8 +5,6 @@ DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -print('--- {}'.format(DEFAULT_STATIC_FILES_PATH)) - class SimpleApp2(ExtensionApp): # The name of the extension From 08c126689d7fdb10e3b15fc0c4cd5b16fe094ef0 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Mon, 14 Oct 2019 08:56:09 +0200 Subject: [PATCH 07/30] mention https://github.com/markellekelly/jupyter-server-example in the README --- examples/simple/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 766869b98e..0f8d9e23b4 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -2,14 +2,14 @@ This folder contains an example of 2 simple extensions on top of Jupyter Server. -OPTIONAL (compiled js is provided) If you want to build the typescript code, you need npm installed. +OPTIONAL If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifcat in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. ```bash make install-ts make build-ts ``` -You need python3 to build and run the extensions. +You need `python3` to build and run the server extensions. ```bash conda create -y -n jext python=3.7 From 7aa92631a2c3a678c862b8e8414cbfa1e80e28c1 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Mon, 14 Oct 2019 09:15:39 +0200 Subject: [PATCH 08/30] add default redirect --- examples/simple/README.md | 30 ++++++++++++---------- examples/simple/simple_ext1/application.py | 3 ++- examples/simple/simple_ext1/handlers.py | 4 +++ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 0f8d9e23b4..e08d16e52d 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -2,12 +2,7 @@ This folder contains an example of 2 simple extensions on top of Jupyter Server. -OPTIONAL If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifcat in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. - -```bash -make install-ts -make build-ts -``` +## Install You need `python3` to build and run the server extensions. @@ -17,12 +12,21 @@ conda activate jext make build ``` +**OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifcat in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. + +```bash +make install-ts +make build-ts +``` + +## Start Extension 1 and Extension 2 + ```bash # Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. make start1+2 ``` -Optionally, you can copy `simple_ext.json` configuration to your env `etc` folder and start only App 1. +Optionally, you can copy `simple_ext.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. ```bash make uninstall @@ -32,10 +36,10 @@ cp -r ./etc $(dirname $(which jupyter))/.. make start1 ``` -Render default Server content in your browser. +Now you can render Server content in your browser. ```bash -# Default server page. +# Default server page should redirect to `/static/simple_ext1/favicon.ico`. open http://localhost:8888 ``` @@ -66,6 +70,8 @@ open http://localhost:8888/static/simple_ext2/test.html open http://localhost:8888/simple_ext2/params/test?var1=foo ``` +## Start only Extension 2 + Now stop the server and start again with only Extension 2. ```bash @@ -73,8 +79,4 @@ Now stop the server and start again with only Extension 2. make start2 ``` -Try with the above links to check that only Extension 2 is responding. - -## TODO - -+ Automatic redirect on the default home page. +Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an error). diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 8e7512a399..727056b506 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,6 +1,6 @@ import os, jinja2 from jupyter_server.extension.application import ExtensionApp -from .handlers import ParameterHandler, TemplateHandler, Page1Handler, IndexHandler, ErrorHandler +from .handlers import RedirectHandler, ParameterHandler, TemplateHandler, Page1Handler, IndexHandler, ErrorHandler DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") @@ -28,6 +28,7 @@ class SimpleApp1(ExtensionApp): def initialize_handlers(self): self.handlers.extend([ + (r'/', RedirectHandler), (r'/simple_ext1/params/(.+)$', ParameterHandler), (r'/simple_ext1/template', TemplateHandler), (r'/simple_ext1/page1/(.*)$', Page1Handler), diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index 67f3c9daab..ad64c9df31 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -6,6 +6,10 @@ def get_template(self, name): """Return the jinja template object for a given name""" return self.settings['simple_ext1_jinja2_env'].get_template(name) +class RedirectHandler(ExtensionHandler): + def get(self): + self.redirect("/static/simple_ext1/favicon.ico") + class IndexHandler(TemplateHandler): def get(self): From f6b8d479862752b264d367a1c1a1ea2cc80547ad Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Mon, 14 Oct 2019 21:37:09 +0200 Subject: [PATCH 09/30] migrate make to README + split simple_ext.json --- examples/simple/Makefile | 28 ------------------- examples/simple/README.md | 20 ++++++------- .../jupyter_server_config.d/simple_ext1.json | 7 +++++ .../{simple_ext.json => simple_ext2.json} | 1 - 4 files changed, 17 insertions(+), 39 deletions(-) delete mode 100644 examples/simple/Makefile create mode 100644 examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext1.json rename examples/simple/etc/jupyter/jupyter_server_config.d/{simple_ext.json => simple_ext2.json} (75%) diff --git a/examples/simple/Makefile b/examples/simple/Makefile deleted file mode 100644 index b7324ebfd0..0000000000 --- a/examples/simple/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -.PHONY: clean build install uninstall - -clean: - npm clean - -install-ts: - npm install - -build-ts: - npm run build - -build: - pip install -e . - -install: - python setup.py install - -uninstall: - pip uninstall -y simple_ext - -start1+2: - jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" - -start1: - jupyter simple-ext1 - -start2: - jupyter simple-ext2 diff --git a/examples/simple/README.md b/examples/simple/README.md index e08d16e52d..f373d84db5 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -9,31 +9,31 @@ You need `python3` to build and run the server extensions. ```bash conda create -y -n jext python=3.7 conda activate jext -make build +pip install -e . ``` -**OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifcat in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. +**OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifact in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. ```bash -make install-ts -make build-ts +npm install +npm run build ``` ## Start Extension 1 and Extension 2 ```bash # Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. -make start1+2 +jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" ``` -Optionally, you can copy `simple_ext.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. +Optionally, you can copy `simple_ext1.json` and `simple_ext2.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. ```bash -make uninstall -make install +pip uninstall -y simple_ext +python setup.py install cp -r ./etc $(dirname $(which jupyter))/.. # Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. -make start1 +jupyter simple-ext1 ``` Now you can render Server content in your browser. @@ -76,7 +76,7 @@ Now stop the server and start again with only Extension 2. ```bash # Start the jupyter server extension simple_ext2, it will NOT load simple_ext1 because of load_other_extensions = False. -make start2 +jupyter simple-ext2 ``` Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an error). diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext1.json b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext1.json new file mode 100644 index 0000000000..42e7565113 --- /dev/null +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext1.json @@ -0,0 +1,7 @@ +{ + "ServerApp": { + "jpserver_extensions": { + "simple_ext1": true + } + } +} diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext2.json similarity index 75% rename from examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json rename to examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext2.json index b3e2f07b59..8104acace1 100644 --- a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext.json +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext2.json @@ -1,7 +1,6 @@ { "ServerApp": { "jpserver_extensions": { - "simple_ext1": true, "simple_ext2": true } } From beff8056208d1004163907c8f9cb500fde53e5ee Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Wed, 16 Oct 2019 07:59:06 +0200 Subject: [PATCH 10/30] relax jupyter_server version --- examples/simple/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/setup.py b/examples/simple/setup.py index a2e78122df..87ea4963ba 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -28,7 +28,7 @@ def add_data_files(path): packages = find_packages(), python_requires = '>=3.5', install_requires = [ - 'jupyter_server==0.1.1', + 'jupyter_server', 'jinja2', ], tests_requires = [ From d92fb550d9f0bd5aa0b69bb676de5a584500c0be Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Wed, 16 Oct 2019 08:00:47 +0200 Subject: [PATCH 11/30] add -f src --- examples/simple/src/index.ts | 6 ++++++ examples/simple/src/tsconfig.json | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 examples/simple/src/index.ts create mode 100644 examples/simple/src/tsconfig.json diff --git a/examples/simple/src/index.ts b/examples/simple/src/index.ts new file mode 100644 index 0000000000..3137216e29 --- /dev/null +++ b/examples/simple/src/index.ts @@ -0,0 +1,6 @@ +function main() { + let div = document.getElementById("mydiv"); + div.innerText = "Hello from Typescript"; +} + +window.addEventListener('load', main); diff --git a/examples/simple/src/tsconfig.json b/examples/simple/src/tsconfig.json new file mode 100644 index 0000000000..711f9c1afc --- /dev/null +++ b/examples/simple/src/tsconfig.json @@ -0,0 +1,21 @@ + +{ + "compilerOptions": { + "outDir": "../simple_ext1/static", + "allowSyntheticDefaultImports": true, + "composite": true, + "declaration": true, + "noImplicitAny": true, + "noEmitOnError": true, + "noUnusedLocals": true, + "esModuleInterop": true, + "preserveWatchOutput": true, + "module": "commonjs", + "moduleResolution": "node", + "target": "es2015", + "lib": ["dom", "es2015"], + "jsx": "react", + "types": [] + }, + "include": ["*"] +} From 7181ebbd762775674ea2dde12a2e8e3ff5d6fb14 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 19 Oct 2019 09:03:23 +0200 Subject: [PATCH 12/30] refactor handlers and add a TODO fix default URL --- examples/simple/README.md | 18 +++++++---- examples/simple/simple_ext1/application.py | 11 +++---- examples/simple/simple_ext1/handlers.py | 31 ++++++++----------- examples/simple/simple_ext1/static/home.html | 1 + .../simple/simple_ext1/templates/error.html | 1 + .../templates/{page1.html => simple1.html} | 4 +-- .../simple_ext1/templates/simple_ext1.html | 21 ------------- .../templates/{index.html => typescript.html} | 0 examples/simple/simple_ext2/handlers.py | 28 ++++++++--------- 9 files changed, 48 insertions(+), 67 deletions(-) create mode 100644 examples/simple/simple_ext1/static/home.html rename examples/simple/simple_ext1/templates/{page1.html => simple1.html} (85%) delete mode 100644 examples/simple/simple_ext1/templates/simple_ext1.html rename examples/simple/simple_ext1/templates/{index.html => typescript.html} (100%) diff --git a/examples/simple/README.md b/examples/simple/README.md index f373d84db5..584b435780 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -44,21 +44,27 @@ open http://localhost:8888 ``` Render Extension 1 Server content in your browser. - +x ```bash -# Favicon static content. -open http://localhost:8888/static/simple_ext1/favicon.ico +# Jupyter Server Home Page +open http://localhost:8888/ +# TODO Fix Default URL. +# Home page as defined by default_url = '/template1/home'. +open http://localhost:8888/simple_ext1/ # HTML static page. open http://localhost:8888/static/simple_ext1/test.html # Content from Handlers. open http://localhost:8888/simple_ext1/params/test?var1=foo # Content from Template. -open http://localhost:8888/simple_ext1/page1/test +open http://localhost:8888/simple_ext1/template1/test # Content from Template with Typescript. -open http://localhost:8888/simple_ext1 -open http://localhost:8888/simple_ext1/template +open http://localhost:8888/simple_ext1/typescript # Error content. open http://localhost:8888/simple_ext1/nope +# Redirect. +open http://localhost:8888/simple_ext1/redirect +# Favicon static content. +open http://localhost:8888/static/simple_ext1/favicon.ico ``` Render Extension 2 Server content in your browser. diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 727056b506..a843a99548 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,6 +1,6 @@ import os, jinja2 from jupyter_server.extension.application import ExtensionApp -from .handlers import RedirectHandler, ParameterHandler, TemplateHandler, Page1Handler, IndexHandler, ErrorHandler +from .handlers import RedirectHandler, ParameterHandler, TemplateHandler, TypescriptHandler, ErrorHandler DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") @@ -11,7 +11,7 @@ class SimpleApp1(ExtensionApp): extension_name = "simple_ext1" # Te url that your extension will serve its homepage. - default_url = '/simple_ext1' + default_url = '/template/home' # Should your extension expose other server extensions when launched directly? load_other_extensions = True @@ -28,11 +28,10 @@ class SimpleApp1(ExtensionApp): def initialize_handlers(self): self.handlers.extend([ - (r'/', RedirectHandler), (r'/simple_ext1/params/(.+)$', ParameterHandler), - (r'/simple_ext1/template', TemplateHandler), - (r'/simple_ext1/page1/(.*)$', Page1Handler), - (r'/simple_ext1/?', IndexHandler), + (r'/simple_ext1/template1/(.*)$', TemplateHandler), + (r'/simple_ext1/redirect', RedirectHandler), + (r'/simple_ext1/typescript/?', TypescriptHandler), (r'/simple_ext1/(.*)', ErrorHandler) ]) diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index ad64c9df31..3abd642595 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -1,20 +1,9 @@ from jupyter_server.extension.handler import ExtensionHandler -class TemplateHandler(ExtensionHandler): - - def get_template(self, name): - """Return the jinja template object for a given name""" - return self.settings['simple_ext1_jinja2_env'].get_template(name) - class RedirectHandler(ExtensionHandler): def get(self): self.redirect("/static/simple_ext1/favicon.ico") -class IndexHandler(TemplateHandler): - - def get(self): - self.write(self.render_template("index.html")) - class ParameterHandler(ExtensionHandler): def get(self, matched_part=None, *args, **kwargs): @@ -25,18 +14,24 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class TemplateHandler(TemplateHandler): +class BaseTemplateHandler(ExtensionHandler): + + def get_template(self, path): + """Return the jinja template object for a given name""" + return self.settings['simple_ext1_jinja2_env'].get_template(path) + +class TypescriptHandler(BaseTemplateHandler): def get(self): - print(self.get_template('simple_ext1.html')) - self.write(self.render_template('simple_ext1.html')) + self.write(self.render_template("typescript.html")) -class Page1Handler(TemplateHandler): +class TemplateHandler(BaseTemplateHandler): def get(self, path): - self.write(self.render_template('page1.html', text=path)) +# print(self.get_template('simple1.html')) + self.write(self.render_template('simple1.html', path=path)) -class ErrorHandler(TemplateHandler): +class ErrorHandler(BaseTemplateHandler): def get(self, path): - self.write(self.render_template('error.html')) + self.write(self.render_template('error.html', path=path)) diff --git a/examples/simple/simple_ext1/static/home.html b/examples/simple/simple_ext1/static/home.html new file mode 100644 index 0000000000..27fffd9e37 --- /dev/null +++ b/examples/simple/simple_ext1/static/home.html @@ -0,0 +1 @@ +

Welcome to Simple App 1 Home Page.

diff --git a/examples/simple/simple_ext1/templates/error.html b/examples/simple/simple_ext1/templates/error.html index 7426beb571..1379574a58 100644 --- a/examples/simple/simple_ext1/templates/error.html +++ b/examples/simple/simple_ext1/templates/error.html @@ -4,6 +4,7 @@
{% block h1_error %} +

Error Page

{{status_code}} : {{status_message}}

{% endblock h1_error %} diff --git a/examples/simple/simple_ext1/templates/page1.html b/examples/simple/simple_ext1/templates/simple1.html similarity index 85% rename from examples/simple/simple_ext1/templates/page1.html rename to examples/simple/simple_ext1/templates/simple1.html index 7fba4842ae..95d8403ce0 100644 --- a/examples/simple/simple_ext1/templates/page1.html +++ b/examples/simple/simple_ext1/templates/simple1.html @@ -14,6 +14,6 @@ -

Hello from Page 1 Template.

-

Path: {{text}}

+

Hello Simple App 1 from Template.

+

Path: {{path}}

diff --git a/examples/simple/simple_ext1/templates/simple_ext1.html b/examples/simple/simple_ext1/templates/simple_ext1.html deleted file mode 100644 index e825cf31cb..0000000000 --- a/examples/simple/simple_ext1/templates/simple_ext1.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - -
-

Hello world!

-
- diff --git a/examples/simple/simple_ext1/templates/index.html b/examples/simple/simple_ext1/templates/typescript.html similarity index 100% rename from examples/simple/simple_ext1/templates/index.html rename to examples/simple/simple_ext1/templates/typescript.html diff --git a/examples/simple/simple_ext2/handlers.py b/examples/simple/simple_ext2/handlers.py index 21fcec1732..07249393a9 100644 --- a/examples/simple/simple_ext2/handlers.py +++ b/examples/simple/simple_ext2/handlers.py @@ -1,16 +1,5 @@ from jupyter_server.extension.handler import ExtensionHandler -class TemplateHandler(ExtensionHandler): - - def get_template(self, name): - """Return the jinja template object for a given name""" - return self.settings['simple_ext2_jinja2_env'].get_template(name) - -class IndexHandler(TemplateHandler): - - def get(self): - self.write(self.render_template("index.html")) - class ParameterHandler(ExtensionHandler): def get(self, matched_part=None, *args, **kwargs): @@ -21,13 +10,24 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class TemplateHandler(TemplateHandler): +class BaseTemplateHandler(ExtensionHandler): + + def get_template(self, name): + """Return the jinja template object for a given name""" + return self.settings['simple_ext2_jinja2_env'].get_template(name) + +class IndexHandler(BaseTemplateHandler): def get(self): + self.write(self.render_template("index.html")) + +class TemplateHandler(BaseTemplateHandler): + + def get(self, path): print(self.get_template('simple_ext2.html')) - self.write(self.render_template('simple_ext2.html')) + self.write(self.render_template('simple_ext2.html', path=path)) -class ErrorHandler(TemplateHandler): +class ErrorHandler(BaseTemplateHandler): def get(self, path): self.write(self.render_template('error.html')) From b5c371387a5e00bd52f8bbfda5db3a52b25e75ac Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Tue, 22 Oct 2019 11:13:28 +0200 Subject: [PATCH 13/30] be more precise on returned error --- examples/simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 584b435780..c5f3bfd0a0 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -85,4 +85,4 @@ Now stop the server and start again with only Extension 2. jupyter simple-ext2 ``` -Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an error). +Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an 404 error). From ea0555afe5e478bce6811d844de1241ec4a5f3ce Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Wed, 30 Oct 2019 16:44:27 +0100 Subject: [PATCH 14/30] more examples related to settings and extension --- examples/simple/README.md | 74 ++++++++++++++----- .../jupyter_server_config.d/simple_ext11.json | 7 ++ examples/simple/jupyter_server_config.py | 11 +++ examples/simple/setup.py | 3 +- examples/simple/simple_ext1/application.py | 27 ++++--- examples/simple/simple_ext1/handlers.py | 22 ++++-- examples/simple/simple_ext11/__init__.py | 8 ++ examples/simple/simple_ext11/application.py | 35 +++++++++ examples/simple/simple_ext2/application.py | 2 +- examples/simple/simple_ext2/handlers.py | 5 -- 10 files changed, 154 insertions(+), 40 deletions(-) create mode 100644 examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext11.json create mode 100644 examples/simple/jupyter_server_config.py create mode 100644 examples/simple/simple_ext11/__init__.py create mode 100644 examples/simple/simple_ext11/application.py diff --git a/examples/simple/README.md b/examples/simple/README.md index c5f3bfd0a0..d9287a0034 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -7,9 +7,9 @@ This folder contains an example of 2 simple extensions on top of Jupyter Server. You need `python3` to build and run the server extensions. ```bash -conda create -y -n jext python=3.7 -conda activate jext -pip install -e . +conda create -y -n jext python=3.7 && \ + conda activate jext && \ + pip install -e . ``` **OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifact in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. @@ -36,21 +36,14 @@ cp -r ./etc $(dirname $(which jupyter))/.. jupyter simple-ext1 ``` -Now you can render Server content in your browser. +Now you can render Extension 1 Server content in your browser. ```bash -# Default server page should redirect to `/static/simple_ext1/favicon.ico`. -open http://localhost:8888 -``` - -Render Extension 1 Server content in your browser. -x -```bash -# Jupyter Server Home Page +# Jupyter Server Home Page. open http://localhost:8888/ -# TODO Fix Default URL. -# Home page as defined by default_url = '/template1/home'. -open http://localhost:8888/simple_ext1/ +# TODO Fix Default URL, it does not show on startup. +# Home page as defined by default_url = '/default'. +open http://localhost:8888/simple_ext1/default # HTML static page. open http://localhost:8888/static/simple_ext1/test.html # Content from Handlers. @@ -67,7 +60,7 @@ open http://localhost:8888/simple_ext1/redirect open http://localhost:8888/static/simple_ext1/favicon.ico ``` -Render Extension 2 Server content in your browser. +You can also render Extension 2 Server content in your browser. ```bash # HTML static page. @@ -76,8 +69,25 @@ open http://localhost:8888/static/simple_ext2/test.html open http://localhost:8888/simple_ext2/params/test?var1=foo ``` -## Start only Extension 2 +## Settings + +Start with additional settings. + +```bash +jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" --SimpleApp1.cli=OK +``` + +Check the log, it should return on startup something like the following base on the trait you have defined in the CLI and in the `jupyter_server_config.py`. +``` +[SimpleApp1] SimpleApp1.app OK +[SimpleApp1] SimpleApp1.file OK +[SimpleApp1] SimpleApp1.cli OK +[SimpleApp1] Complete Settings {'simple_ext1_config': {}, 'simple_ext1_template_paths': ['/home/datalayer/repos/jupyter-server/examples/simple/simple_ext1/templates'], 'simple_ext1_jinja2_env': , 'log_function': , 'base_url': '/', 'default_url': '/', 'template_path': ['/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server', '/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/templates'], 'static_path': ['/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/static'], 'static_custom_path': ['/home/datalayer/.jupyter/custom', '/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/static/custom'], 'static_handler_class': , 'static_url_prefix': ... +``` + +## Start only Extension 2 +` Now stop the server and start again with only Extension 2. ```bash @@ -86,3 +96,33 @@ jupyter simple-ext2 ``` Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an 404 error). + +## Extension 11 extending Extension 1 + +```bash +jupyter simple-ext11 +# or... +jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" +``` + +```bash +# Jupyter Server Home Page. +open http://localhost:8888/ +# TODO Fix Default URL, it does not show on startup. +# Home page as defined by default_url = '/default'. +open http://localhost:8888/simple_ext11/default +# HTML static page. +open http://localhost:8888/static/simple_ext11/test.html +# Content from Handlers. +open http://localhost:8888/simple_ext11/params/test?var1=foo +# Content from Template. +open http://localhost:8888/simple_ext11/template1/test +# Content from Template with Typescript. +open http://localhost:8888/simple_ext11/typescript +# Error content. +open http://localhost:8888/simple_ext11/nope +# Redirect. +open http://localhost:8888/simple_ext11/redirect +# Favicon static content. +open http://localhost:8888/static/simple_ext11/favicon.ico +``` diff --git a/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext11.json b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext11.json new file mode 100644 index 0000000000..4f9cbbbfac --- /dev/null +++ b/examples/simple/etc/jupyter/jupyter_server_config.d/simple_ext11.json @@ -0,0 +1,7 @@ +{ + "ServerApp": { + "jpserver_extensions": { + "simple_ext11": true + } + } +} diff --git a/examples/simple/jupyter_server_config.py b/examples/simple/jupyter_server_config.py new file mode 100644 index 0000000000..fd1ad65bbe --- /dev/null +++ b/examples/simple/jupyter_server_config.py @@ -0,0 +1,11 @@ +# Configuration file for jupyter-server extensions. + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ + +## The date format used by logging formatters for %(asctime)s +c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S Simple_Extensions' + +c.SimpleApp1.file = 'OK' +c.SimpleApp2.file = 'OK' diff --git a/examples/simple/setup.py b/examples/simple/setup.py index 87ea4963ba..d20af9a90c 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -13,7 +13,7 @@ def add_data_files(path): for (dirpath, dirnames, filenames) in os.walk(path): if filenames: data_files.append((dirpath, [os.path.join(dirpath, filename) for filename in filenames])) - # Add all the templates + # Add all static and templates folders. add_data_files('simple_ext1/static') add_data_files('simple_ext1/templates') add_data_files('simple_ext2/static') @@ -40,6 +40,7 @@ def add_data_files(path): entry_points = { 'console_scripts': [ 'jupyter-simple-ext1 = simple_ext1.application:main', + 'jupyter-simple-ext11 = simple_ext11.application:main', 'jupyter-simple-ext2 = simple_ext2.application:main' ] }, diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index a843a99548..209e5f7b0a 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,17 +1,18 @@ import os, jinja2 from jupyter_server.extension.application import ExtensionApp -from .handlers import RedirectHandler, ParameterHandler, TemplateHandler, TypescriptHandler, ErrorHandler +from .handlers import (DefaultHandler, RedirectHandler, ParameterHandler, + TemplateHandler, TypescriptHandler, ErrorHandler) DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") class SimpleApp1(ExtensionApp): - # The name of the extension + # The name of the extension. extension_name = "simple_ext1" # Te url that your extension will serve its homepage. - default_url = '/template/home' + default_url = '/default' # Should your extension expose other server extensions when launched directly? load_other_extensions = True @@ -28,11 +29,12 @@ class SimpleApp1(ExtensionApp): def initialize_handlers(self): self.handlers.extend([ - (r'/simple_ext1/params/(.+)$', ParameterHandler), - (r'/simple_ext1/template1/(.*)$', TemplateHandler), - (r'/simple_ext1/redirect', RedirectHandler), - (r'/simple_ext1/typescript/?', TypescriptHandler), - (r'/simple_ext1/(.*)', ErrorHandler) + (r'/{}/default'.format(self.extension_name), DefaultHandler), + (r'/{}/params/(.+)$'.format(self.extension_name), ParameterHandler), + (r'/{}/template1/(.*)$'.format(self.extension_name), TemplateHandler), + (r'/{}/redirect'.format(self.extension_name), RedirectHandler), + (r'/{}/typescript/?'.format(self.extension_name), TypescriptHandler), + (r'/{}/(.*)', ErrorHandler) ]) def initialize_templates(self): @@ -45,8 +47,15 @@ def initialize_templates(self): template_settings = {"simple_ext1_jinja2_env": env} self.settings.update(**template_settings) + def get_conf(self, key): + return self.settings.get('config').get('SimpleApp1').get(key, None) + def initialize_settings(self): - pass + self.settings.get('config').get('SimpleApp1').update({'app': 'OK'}) + self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) + self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) + self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) + self.log.info('Complete Settings {}'.format(self.settings)) #----------------------------------------------------------------------------- # Main entry point diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index 3abd642595..ffe1752c96 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -1,11 +1,23 @@ from jupyter_server.extension.handler import ExtensionHandler +class DefaultHandler(ExtensionHandler): + def get(self): + # The ExtensionApp’s config object. + self.log.info("Settings: {}".format(self.settings)) + self.log.info("Config: {}".format(self.config)) + # TODO The ServerApp’s config object. + # self.log.info(self.server_config) + # The name of the extension to which this handler is linked. + self.log.info("Extension Name: {}".format(self.extension_name)) + # A method for getting the url to static files (prefixed with /static/). + self.log.info("Static URL for /:".format(self.static_url(path='/'))) + self.write('

Hello Simple 1 - I am the default...

') + class RedirectHandler(ExtensionHandler): def get(self): - self.redirect("/static/simple_ext1/favicon.ico") + self.redirect("/static/{}/favicon.ico".format(self.extension_name)) -class ParameterHandler(ExtensionHandler): - +class ParameterHandler(ExtensionHandler): def get(self, matched_part=None, *args, **kwargs): var1 = self.get_argument('var1', default=None) components = [x for x in self.request.path.split("/") if x] @@ -15,23 +27,19 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

components: {}

'.format(components)) class BaseTemplateHandler(ExtensionHandler): - def get_template(self, path): """Return the jinja template object for a given name""" return self.settings['simple_ext1_jinja2_env'].get_template(path) class TypescriptHandler(BaseTemplateHandler): - def get(self): self.write(self.render_template("typescript.html")) class TemplateHandler(BaseTemplateHandler): - def get(self, path): # print(self.get_template('simple1.html')) self.write(self.render_template('simple1.html', path=path)) class ErrorHandler(BaseTemplateHandler): - def get(self, path): self.write(self.render_template('error.html', path=path)) diff --git a/examples/simple/simple_ext11/__init__.py b/examples/simple/simple_ext11/__init__.py new file mode 100644 index 0000000000..cf3068ed96 --- /dev/null +++ b/examples/simple/simple_ext11/__init__.py @@ -0,0 +1,8 @@ +from .application import SimpleApp1 + +def _jupyter_server_extension_paths(): + return [ + {'module': 'simple_ext1'} + ] + +load_jupyter_server_extension = SimpleApp1.load_jupyter_server_extension diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py new file mode 100644 index 0000000000..b15a659889 --- /dev/null +++ b/examples/simple/simple_ext11/application.py @@ -0,0 +1,35 @@ +import os +from simple_ext1.application import SimpleApp1 + +DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/static") +DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/templates") + +class SimpleApp11(SimpleApp1): + + # The name of the extension. + extension_name = "simple_ext11" + + # Local path to static files directory. + static_paths = [ + DEFAULT_STATIC_FILES_PATH + ] + + # Local path to templates directory. + template_paths = [ + DEFAULT_TEMPLATE_FILES_PATH + ] + + def initialize_handlers(self): + super().initialize_handlers() + + def initialize_templates(self): + super().initialize_templates() + + def initialize_settings(self): + super().initialize_templates() + +#----------------------------------------------------------------------------- +# Main entry point +#----------------------------------------------------------------------------- + +main = launch_new_instance = SimpleApp11.launch_instance diff --git a/examples/simple/simple_ext2/application.py b/examples/simple/simple_ext2/application.py index f7cf0ad619..5aca43b9fb 100644 --- a/examples/simple/simple_ext2/application.py +++ b/examples/simple/simple_ext2/application.py @@ -7,7 +7,7 @@ class SimpleApp2(ExtensionApp): - # The name of the extension + # The name of the extension. extension_name = "simple_ext2" # Te url that your extension will serve its homepage. diff --git a/examples/simple/simple_ext2/handlers.py b/examples/simple/simple_ext2/handlers.py index 07249393a9..490333ced6 100644 --- a/examples/simple/simple_ext2/handlers.py +++ b/examples/simple/simple_ext2/handlers.py @@ -1,7 +1,6 @@ from jupyter_server.extension.handler import ExtensionHandler class ParameterHandler(ExtensionHandler): - def get(self, matched_part=None, *args, **kwargs): var1 = self.get_argument('var1', default=None) components = [x for x in self.request.path.split("/") if x] @@ -11,23 +10,19 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

components: {}

'.format(components)) class BaseTemplateHandler(ExtensionHandler): - def get_template(self, name): """Return the jinja template object for a given name""" return self.settings['simple_ext2_jinja2_env'].get_template(name) class IndexHandler(BaseTemplateHandler): - def get(self): self.write(self.render_template("index.html")) class TemplateHandler(BaseTemplateHandler): - def get(self, path): print(self.get_template('simple_ext2.html')) self.write(self.render_template('simple_ext2.html', path=path)) class ErrorHandler(BaseTemplateHandler): - def get(self, path): self.write(self.render_template('error.html')) From e9d1a6951e1f81cff83651413aca6b5a7cbf44f3 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 31 Oct 2019 17:22:56 +0100 Subject: [PATCH 15/30] extension 11 has flags and aliases --- examples/simple/README.md | 10 ++++++++-- examples/simple/simple_ext11/application.py | 22 +++++++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index d9287a0034..bbf6877e3f 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -99,12 +99,18 @@ Try with the above links to check that only Extension 2 is responding (Extension ## Extension 11 extending Extension 1 +`Extension 11` extends `Extension 1`. It also implemnets additional flags and aliases. + +The `--hello` flag will log on startup `Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True`. + ```bash -jupyter simple-ext11 +jupyter simple-ext11 --hello # or... -jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" +jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" --hello ``` +Ensure the following URLs give respond correctly. + ```bash # Jupyter Server Home Page. open http://localhost:8888/ diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index b15a659889..3c76cc78f8 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -1,10 +1,18 @@ import os from simple_ext1.application import SimpleApp1 +from jupyter_server.serverapp import aliases, flags DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/templates") class SimpleApp11(SimpleApp1): + flags['hello']=( + {'SimpleApp11' : {'hello' : True}}, + "Say hello on startup." + ) + aliases.update({ + 'notebook-dir': 'ServerApp.notebook_dir', + }) # The name of the extension. extension_name = "simple_ext11" @@ -19,14 +27,16 @@ class SimpleApp11(SimpleApp1): DEFAULT_TEMPLATE_FILES_PATH ] - def initialize_handlers(self): - super().initialize_handlers() - - def initialize_templates(self): - super().initialize_templates() + def get_conf(self, key): + simple_app_11 = self.settings.get('config').get('SimpleApp11') + if simple_app_11: + return simple_app_11.get(key, None) + return None def initialize_settings(self): - super().initialize_templates() + if self.get_conf('hello') == True: + self.log.info('Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True') + super().initialize_settings() #----------------------------------------------------------------------------- # Main entry point From b5f57669450db43e33f8b40d2216ca422974db47 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 31 Oct 2019 18:10:43 +0100 Subject: [PATCH 16/30] default_url --- examples/simple/simple_ext1/application.py | 2 +- examples/simple/simple_ext11/application.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 209e5f7b0a..7c9bdd70f5 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -12,7 +12,7 @@ class SimpleApp1(ExtensionApp): extension_name = "simple_ext1" # Te url that your extension will serve its homepage. - default_url = '/default' + default_url = '/simple_ext1/default' # Should your extension expose other server extensions when launched directly? load_other_extensions = True diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index 3c76cc78f8..2e219f000b 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -17,6 +17,9 @@ class SimpleApp11(SimpleApp1): # The name of the extension. extension_name = "simple_ext11" + # Te url that your extension will serve its homepage. + default_url = '/simple_ext11/default' + # Local path to static files directory. static_paths = [ DEFAULT_STATIC_FILES_PATH From 0a215bd6a6991e418b385718ee97833101adf6c9 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Tue, 5 Nov 2019 16:33:05 +0100 Subject: [PATCH 17/30] more settings example based on flags and file configs --- examples/simple/README.md | 25 +++++++----- examples/simple/jupyter_server_config.py | 2 + examples/simple/simple_ext1/application.py | 2 + examples/simple/simple_ext11/application.py | 44 +++++++++++++++++---- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index bbf6877e3f..979d072665 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -7,8 +7,8 @@ This folder contains an example of 2 simple extensions on top of Jupyter Server. You need `python3` to build and run the server extensions. ```bash -conda create -y -n jext python=3.7 && \ - conda activate jext && \ +conda create -y -n jupyter_server_example python=3.7 && \ + conda activate jupyter_server_example && \ pip install -e . ``` @@ -33,10 +33,11 @@ pip uninstall -y simple_ext python setup.py install cp -r ./etc $(dirname $(which jupyter))/.. # Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. +# When you invoke with the entrypoint, the default url will be opened in your browser. jupyter simple-ext1 ``` -Now you can render Extension 1 Server content in your browser. +Now you can render `Extension 1` Server content in your browser. ```bash # Jupyter Server Home Page. @@ -60,7 +61,7 @@ open http://localhost:8888/simple_ext1/redirect open http://localhost:8888/static/simple_ext1/favicon.ico ``` -You can also render Extension 2 Server content in your browser. +You can also render `Extension 2` Server content in your browser. ```bash # HTML static page. @@ -71,7 +72,7 @@ open http://localhost:8888/simple_ext2/params/test?var1=foo ## Settings -Start with additional settings. +Stop any running server (with CTRL+C) and start with additional settings on the command line. ```bash jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" --SimpleApp1.cli=OK @@ -83,12 +84,12 @@ Check the log, it should return on startup something like the following base on [SimpleApp1] SimpleApp1.app OK [SimpleApp1] SimpleApp1.file OK [SimpleApp1] SimpleApp1.cli OK -[SimpleApp1] Complete Settings {'simple_ext1_config': {}, 'simple_ext1_template_paths': ['/home/datalayer/repos/jupyter-server/examples/simple/simple_ext1/templates'], 'simple_ext1_jinja2_env': , 'log_function': , 'base_url': '/', 'default_url': '/', 'template_path': ['/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server', '/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/templates'], 'static_path': ['/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/static'], 'static_custom_path': ['/home/datalayer/.jupyter/custom', '/opt/datalayer/opt/miniconda3/envs/datalayer/lib/python3.7/site-packages/jupyter_server/static/custom'], 'static_handler_class': , 'static_url_prefix': ... +[SimpleApp1] Complete Settings {'simple_ext1_config': {}, 'simple_ext1_template_paths': ['/home/datalayer/repos/jupyter-server/examples/simple/simple_ext1/templates'], 'simple_ext1_jinja2_env': , 'log_function': , 'base_url': '/', 'default_url': '/', 'template_path': ... ``` ## Start only Extension 2 -` -Now stop the server and start again with only Extension 2. + +Now stop agin the server and start with only `Extension 2`. ```bash # Start the jupyter server extension simple_ext2, it will NOT load simple_ext1 because of load_other_extensions = False. @@ -103,10 +104,14 @@ Try with the above links to check that only Extension 2 is responding (Extension The `--hello` flag will log on startup `Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True`. +The `--simple11-dir` alias will set `SimpleExt11.simple11_dir` settings. + +Stop any running server and then start the simple-ext11. + ```bash -jupyter simple-ext11 --hello +jupyter simple-ext11 --hello --simple11-dir any_folder # or... -jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" --hello +jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" --hello --simple11-dir any_folder ``` Ensure the following URLs give respond correctly. diff --git a/examples/simple/jupyter_server_config.py b/examples/simple/jupyter_server_config.py index fd1ad65bbe..b761706893 100644 --- a/examples/simple/jupyter_server_config.py +++ b/examples/simple/jupyter_server_config.py @@ -9,3 +9,5 @@ c.SimpleApp1.file = 'OK' c.SimpleApp2.file = 'OK' + +c.SimpleApp11.ignore_js = True diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 7c9bdd70f5..a37adc63c1 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -56,6 +56,8 @@ def initialize_settings(self): self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) self.log.info('Complete Settings {}'.format(self.settings)) + # TODO Check this setting/config handling... Updating does not look to be fine here... + self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp1')) #----------------------------------------------------------------------------- # Main entry point diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index 2e219f000b..a007a64b80 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -1,17 +1,17 @@ import os from simple_ext1.application import SimpleApp1 from jupyter_server.serverapp import aliases, flags +from traitlets import Bool, Unicode, observe DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "./../simple_ext1/templates") class SimpleApp11(SimpleApp1): flags['hello']=( - {'SimpleApp11' : {'hello' : True}}, - "Say hello on startup." + { 'SimpleApp11' : {'hello' : False} }, "Say hello on startup." ) aliases.update({ - 'notebook-dir': 'ServerApp.notebook_dir', + 'simple11-dir': 'SimpleApp11.simple11_dir', }) # The name of the extension. @@ -30,15 +30,43 @@ class SimpleApp11(SimpleApp1): DEFAULT_TEMPLATE_FILES_PATH ] + simple11_dir = Unicode('', + config=True, + help='Simple directory' + ) + + hello = Bool(False, + config=True, + help='Say hello', + ) + + ignore_js = Bool(False, + config=True, + help='Ignore Javascript', + ) + + @observe('ignore_js') + def _update_ignore_js(self, change): + """TODO The observe does not work""" + self.log.info('ignore_js has just changed: {}'.format(change)) + + @property + def simple11_dir_formatted(self): + return "/" + self.simple11_dir + def get_conf(self, key): - simple_app_11 = self.settings.get('config').get('SimpleApp11') - if simple_app_11: - return simple_app_11.get(key, None) - return None + return self.settings.get('config').get('SimpleApp11').get(key, None) def initialize_settings(self): + self.log.info('SimpleApp11.hello: {}'.format(self.get_conf('hello'))) + self.log.info('hello: {}'.format(self.hello)) if self.get_conf('hello') == True: - self.log.info('Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True') + self.log.info("Hello Simple11 - You have provided the --hello flag or defined 'c.SimpleApp1.hello == True' in jupyter_server_config.py") + self.log.info('SimpleApp11.simple11_dir: {}'.format(self.get_conf('simple11_dir'))) + self.log.info('SimpleApp11.ignore_js: {}'.format(self.get_conf('ignore_js'))) + self.log.info('ignore_js: {}'.format(self.ignore_js)) + # TODO Check this setting/config handling... Updating does not look to be fine here... + self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp11')) super().initialize_settings() #----------------------------------------------------------------------------- From b462e9d04cfed0e7d69c6da3cc84e43a953429b7 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 7 Nov 2019 18:39:32 +0100 Subject: [PATCH 18/30] add a link to static home --- examples/simple/README.md | 2 +- examples/simple/simple_ext1/application.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 979d072665..d86bc4939c 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -42,10 +42,10 @@ Now you can render `Extension 1` Server content in your browser. ```bash # Jupyter Server Home Page. open http://localhost:8888/ -# TODO Fix Default URL, it does not show on startup. # Home page as defined by default_url = '/default'. open http://localhost:8888/simple_ext1/default # HTML static page. +open http://localhost:8888/static/simple_ext1/home.html open http://localhost:8888/static/simple_ext1/test.html # Content from Handlers. open http://localhost:8888/simple_ext1/params/test?var1=foo diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index a37adc63c1..4b2f08fd0a 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,7 +1,7 @@ import os, jinja2 from jupyter_server.extension.application import ExtensionApp -from .handlers import (DefaultHandler, RedirectHandler, ParameterHandler, - TemplateHandler, TypescriptHandler, ErrorHandler) +from .handlers import (DefaultHandler, RedirectHandler, + ParameterHandler, TemplateHandler, TypescriptHandler, ErrorHandler) DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") From 81e99d8270f7ab2ba5f409af9528b60d3c80ed56 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 16 Nov 2019 11:19:13 +0100 Subject: [PATCH 19/30] more details on SimpleExt11 configs --- examples/simple/README.md | 44 ++++++++++++++++++++-- examples/simple/simple_ext1/application.py | 4 +- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index d86bc4939c..bf3cbd3528 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -100,11 +100,49 @@ Try with the above links to check that only Extension 2 is responding (Extension ## Extension 11 extending Extension 1 -`Extension 11` extends `Extension 1`. It also implemnets additional flags and aliases. +`Extension 11` extends `Extension 1`. -The `--hello` flag will log on startup `Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True`. +It brings a few more configs. Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. -The `--simple11-dir` alias will set `SimpleExt11.simple11_dir` settings. +The generated configuration should contains the following. + +```bash +... +# Can be used to override templates from notebook.templates. +#c.ExtensionApp.template_paths = [] + +#------------------------------------------------------------------------------ +# SimpleApp1(ExtensionApp) configuration +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# SimpleApp11(SimpleApp1) configuration +#------------------------------------------------------------------------------ + +## Say hello +#c.SimpleApp11.hello = False + +## Ignore Javascript +#c.SimpleApp11.ignore_js = False + +## Simple directory +#c.SimpleApp11.simple11_dir = '' + +#------------------------------------------------------------------------------ +# ServerApp(JupyterApp) configuration +#------------------------------------------------------------------------------ + +## Set the Access-Control-Allow-Credentials: true header +#c.ServerApp.allow_credentials = False +... +``` + +The `hello`, `ignoare_js` and `simple11_dir` are traits defined on the SimpleApp11 class. + +It also implements additional flags and aliases for these traits. + ++ The `--hello` flag will log on startup `Hello Simple11 - You have provided the --hello flag or defined a c.SimpleApp1.hello == True`. ++ The `--simple11-dir` alias will set `SimpleExt11.simple11_dir` settings. Stop any running server and then start the simple-ext11. diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 4b2f08fd0a..4159fcf14f 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -51,13 +51,13 @@ def get_conf(self, key): return self.settings.get('config').get('SimpleApp1').get(key, None) def initialize_settings(self): - self.settings.get('config').get('SimpleApp1').update({'app': 'OK'}) self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) self.log.info('Complete Settings {}'.format(self.settings)) # TODO Check this setting/config handling... Updating does not look to be fine here... - self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp1')) +# self.settings.get('config').get(self.extension_name).update({'app': 'OK'}) +# self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp1')) #----------------------------------------------------------------------------- # Main entry point From edc21fc9f75a954c2934db9039a1246a89a94f05 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 16 Nov 2019 16:16:20 +0100 Subject: [PATCH 20/30] simple_app11: hello flag set True to hell config --- examples/simple/simple_ext11/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index a007a64b80..c0ae7c8fd9 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -8,7 +8,7 @@ class SimpleApp11(SimpleApp1): flags['hello']=( - { 'SimpleApp11' : {'hello' : False} }, "Say hello on startup." + { 'SimpleApp11' : {'hello' : True} }, "Say hello on startup." ) aliases.update({ 'simple11-dir': 'SimpleApp11.simple11_dir', From ae3d27c84a06adfd306eec8374f824db82c626a1 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Fri, 22 Nov 2019 06:01:37 +0100 Subject: [PATCH 21/30] add the correct json in setup.py --- examples/simple/setup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/simple/setup.py b/examples/simple/setup.py index d20af9a90c..5d06d98bdf 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -7,7 +7,9 @@ def get_data_files(): """Get the data files for the package. """ data_files = [ - ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext.json']), + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext1.json']), + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext2.json']), + ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d/simple_ext11.json']), ] def add_data_files(path): for (dirpath, dirnames, filenames) in os.walk(path): @@ -36,6 +38,7 @@ def add_data_files(path): 'pytest-cov', 'pylint', ], + include_package_data=True, data_files = get_data_files(), entry_points = { 'console_scripts': [ From f65c74e25ae73860078add435b43bd6b5c3f3c96 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Tue, 3 Dec 2019 15:18:49 -0600 Subject: [PATCH 22/30] more work on settings --- examples/simple/README.md | 6 ++-- examples/simple/jupyter_server_config.py | 5 ---- examples/simple/setup.py | 2 +- examples/simple/simple_ext1/application.py | 32 +++++++++++++++++---- examples/simple/simple_ext1/handlers.py | 9 +++--- examples/simple/simple_ext11/application.py | 12 ++++---- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index bf3cbd3528..ec22f511c0 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -29,7 +29,7 @@ jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ex Optionally, you can copy `simple_ext1.json` and `simple_ext2.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. ```bash -pip uninstall -y simple_ext +pip uninstall -y jupyter_simple_ext python setup.py install cp -r ./etc $(dirname $(which jupyter))/.. # Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. @@ -100,9 +100,9 @@ Try with the above links to check that only Extension 2 is responding (Extension ## Extension 11 extending Extension 1 -`Extension 11` extends `Extension 1`. +`Extension 11` extends `Extension 1` and brings a few more configs. -It brings a few more configs. Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. +Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. The generated configuration should contains the following. diff --git a/examples/simple/jupyter_server_config.py b/examples/simple/jupyter_server_config.py index b761706893..d7cc88f800 100644 --- a/examples/simple/jupyter_server_config.py +++ b/examples/simple/jupyter_server_config.py @@ -6,8 +6,3 @@ ## The date format used by logging formatters for %(asctime)s c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S Simple_Extensions' - -c.SimpleApp1.file = 'OK' -c.SimpleApp2.file = 'OK' - -c.SimpleApp11.ignore_js = True diff --git a/examples/simple/setup.py b/examples/simple/setup.py index 5d06d98bdf..061cc3a792 100755 --- a/examples/simple/setup.py +++ b/examples/simple/setup.py @@ -23,7 +23,7 @@ def add_data_files(path): return data_files setuptools.setup( - name = 'simple_ext', + name = 'jupyter_simple_ext', version = VERSION, description = 'Jupyter Simple Extension', long_description = open('README.md').read(), diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 4159fcf14f..5c2a1c72e9 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,4 +1,5 @@ import os, jinja2 +from traitlets import Unicode from jupyter_server.extension.application import ExtensionApp from .handlers import (DefaultHandler, RedirectHandler, ParameterHandler, TemplateHandler, TypescriptHandler, ErrorHandler) @@ -27,6 +28,21 @@ class SimpleApp1(ExtensionApp): DEFAULT_TEMPLATE_FILES_PATH ] + file = Unicode('', + config=True, + help='File path' + ) + + app = Unicode('', + config=True, + help='File path' + ) + + cli = Unicode('', + config=True, + help='File path' + ) + def initialize_handlers(self): self.handlers.extend([ (r'/{}/default'.format(self.extension_name), DefaultHandler), @@ -48,14 +64,18 @@ def initialize_templates(self): self.settings.update(**template_settings) def get_conf(self, key): - return self.settings.get('config').get('SimpleApp1').get(key, None) + c = self.settings.get('config').get(type(self).__name__) + if c: + return c.get(key, None) + else: + return None def initialize_settings(self): - self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) - self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) - self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) - self.log.info('Complete Settings {}'.format(self.settings)) - # TODO Check this setting/config handling... Updating does not look to be fine here... + self.log.info('333 {}'.format(self.config)) +# self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) +# self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) +# self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) +# self.log.info('Complete Settings {}'.format(self.settings)) # self.settings.get('config').get(self.extension_name).update({'app': 'OK'}) # self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp1')) diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index ffe1752c96..9062e5e64e 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -3,14 +3,13 @@ class DefaultHandler(ExtensionHandler): def get(self): # The ExtensionApp’s config object. - self.log.info("Settings: {}".format(self.settings)) - self.log.info("Config: {}".format(self.config)) - # TODO The ServerApp’s config object. +# self.log.info("Settings in {} Default Handler: {}".format(self.extension_name, self.settings)) + self.log.info("Config in {} Default Handler: {}".format(self.extension_name, self.config)) # self.log.info(self.server_config) # The name of the extension to which this handler is linked. - self.log.info("Extension Name: {}".format(self.extension_name)) + self.log.info("Extension Name in {} Default Handler: {}".format(self.extension_name, self.extension_name)) # A method for getting the url to static files (prefixed with /static/). - self.log.info("Static URL for /:".format(self.static_url(path='/'))) + self.log.info("Static URL for / in simple_ext1 Default Handler:".format(self.static_url(path='/'))) self.write('

Hello Simple 1 - I am the default...

') class RedirectHandler(ExtensionHandler): diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index c0ae7c8fd9..ddeeadad1e 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -54,20 +54,18 @@ def _update_ignore_js(self, change): def simple11_dir_formatted(self): return "/" + self.simple11_dir - def get_conf(self, key): - return self.settings.get('config').get('SimpleApp11').get(key, None) - def initialize_settings(self): - self.log.info('SimpleApp11.hello: {}'.format(self.get_conf('hello'))) + self.log.info('SimpleApp11.hello: {}'.format(super().get_conf('hello'))) self.log.info('hello: {}'.format(self.hello)) if self.get_conf('hello') == True: self.log.info("Hello Simple11 - You have provided the --hello flag or defined 'c.SimpleApp1.hello == True' in jupyter_server_config.py") self.log.info('SimpleApp11.simple11_dir: {}'.format(self.get_conf('simple11_dir'))) self.log.info('SimpleApp11.ignore_js: {}'.format(self.get_conf('ignore_js'))) self.log.info('ignore_js: {}'.format(self.ignore_js)) - # TODO Check this setting/config handling... Updating does not look to be fine here... - self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp11')) - super().initialize_settings() + c = self.settings.get('config').get(type(self).__name__) + if c: + self.settings["{}_config".format(self.extension_name)].update(**c) +# super().initialize_settings() #----------------------------------------------------------------------------- # Main entry point From 25504c8f19e5cd6b619009b2610cd7540c32aa1f Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Tue, 3 Dec 2019 15:19:57 -0600 Subject: [PATCH 23/30] add configuration files --- examples/simple/jupyter_simple_ext11_config.py | 1 + examples/simple/jupyter_simple_ext1_config.py | 3 +++ examples/simple/jupyter_simple_ext2_config.py | 1 + 3 files changed, 5 insertions(+) create mode 100644 examples/simple/jupyter_simple_ext11_config.py create mode 100644 examples/simple/jupyter_simple_ext1_config.py create mode 100644 examples/simple/jupyter_simple_ext2_config.py diff --git a/examples/simple/jupyter_simple_ext11_config.py b/examples/simple/jupyter_simple_ext11_config.py new file mode 100644 index 0000000000..d2baa1360a --- /dev/null +++ b/examples/simple/jupyter_simple_ext11_config.py @@ -0,0 +1 @@ +c.SimpleApp11.ignore_js = True diff --git a/examples/simple/jupyter_simple_ext1_config.py b/examples/simple/jupyter_simple_ext1_config.py new file mode 100644 index 0000000000..dc7cd842ec --- /dev/null +++ b/examples/simple/jupyter_simple_ext1_config.py @@ -0,0 +1,3 @@ +c.SimpleApp1.app = 'an app' +c.SimpleApp1.cli = 'a cli' +c.SimpleApp1.file = 'a file' diff --git a/examples/simple/jupyter_simple_ext2_config.py b/examples/simple/jupyter_simple_ext2_config.py new file mode 100644 index 0000000000..36b3b6751c --- /dev/null +++ b/examples/simple/jupyter_simple_ext2_config.py @@ -0,0 +1 @@ +c.SimpleApp2.file = 'OK' From 1b58d296ef0b4dfb4090aa738b662cca191d62b6 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Wed, 4 Dec 2019 11:01:54 -0600 Subject: [PATCH 24/30] comment logs --- examples/simple/simple_ext1/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 5c2a1c72e9..24b6b7f104 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -71,7 +71,7 @@ def get_conf(self, key): return None def initialize_settings(self): - self.log.info('333 {}'.format(self.config)) + self.log.info('Config {}'.format(self.config)) # self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) # self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) # self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) From ff341a1841577687f7724707bd32222036b155a2 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Wed, 4 Dec 2019 11:49:17 -0600 Subject: [PATCH 25/30] update readme --- examples/simple/README.md | 64 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index ec22f511c0..a8e7f83b72 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -1,13 +1,15 @@ # Jupyter Server Simple Extension Example -This folder contains an example of 2 simple extensions on top of Jupyter Server. +This folder contains example of simple extensions on top of Jupyter Server and review configuration aspects. ## Install You need `python3` to build and run the server extensions. ```bash -conda create -y -n jupyter_server_example python=3.7 && \ +git clone https://github.com/jupyter/jupyter_server && \ + cd examples/simple && \ + conda create -y -n jupyter_server_example python=3.7 && \ conda activate jupyter_server_example && \ pip install -e . ``` @@ -15,26 +17,15 @@ conda create -y -n jupyter_server_example python=3.7 && \ **OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifact in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. ```bash -npm install -npm run build +npm install && \ + npm run build ``` -## Start Extension 1 and Extension 2 +## Start Extension 1 ```bash -# Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. -jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" -``` - -Optionally, you can copy `simple_ext1.json` and `simple_ext2.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. - -```bash -pip uninstall -y jupyter_simple_ext -python setup.py install -cp -r ./etc $(dirname $(which jupyter))/.. -# Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. -# When you invoke with the entrypoint, the default url will be opened in your browser. -jupyter simple-ext1 +# Start the jupyter server activating simple_ext1 extension. +jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True}" ``` Now you can render `Extension 1` Server content in your browser. @@ -61,6 +52,15 @@ open http://localhost:8888/simple_ext1/redirect open http://localhost:8888/static/simple_ext1/favicon.ico ``` +## Start Extension 2 + +The following command starts both `simple_ext1` and `simple_ext2` extensions. + +```bash +# Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. +jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" +``` + You can also render `Extension 2` Server content in your browser. ```bash @@ -70,12 +70,29 @@ open http://localhost:8888/static/simple_ext2/test.html open http://localhost:8888/simple_ext2/params/test?var1=foo ``` -## Settings +## Start with Entrypoints + +Optionally, you can copy `simple_ext1.json` and `simple_ext2.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. + +```bash +pip uninstall -y jupyter_simple_ext && \ + python setup.py install && \ + cp -r ./etc $(dirname $(which jupyter))/.. +# Start the jupyter server extension simple_ext1, it will also load simple_ext2 because of load_other_extensions = True.. +# When you invoke with the entrypoint, the default url will be opened in your browser. +jupyter simple-ext1 +``` + +## Configuration + +Stop any running server (with `CTRL+C`) and start with additional configuration on the command line. -Stop any running server (with CTRL+C) and start with additional settings on the command line. +The provided settings via CLI will override the configuration that reside in the files (`jupyter_simple_ext1_config.py`...) ```bash -jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" --SimpleApp1.cli=OK +jupyter server \ + --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" \ + --SimpleApp1.cli=OK ``` Check the log, it should return on startup something like the following base on the trait you have defined in the CLI and in the `jupyter_server_config.py`. @@ -84,7 +101,6 @@ Check the log, it should return on startup something like the following base on [SimpleApp1] SimpleApp1.app OK [SimpleApp1] SimpleApp1.file OK [SimpleApp1] SimpleApp1.cli OK -[SimpleApp1] Complete Settings {'simple_ext1_config': {}, 'simple_ext1_template_paths': ['/home/datalayer/repos/jupyter-server/examples/simple/simple_ext1/templates'], 'simple_ext1_jinja2_env': , 'log_function': , 'base_url': '/', 'default_url': '/', 'template_path': ... ``` ## Start only Extension 2 @@ -137,7 +153,7 @@ The generated configuration should contains the following. ... ``` -The `hello`, `ignoare_js` and `simple11_dir` are traits defined on the SimpleApp11 class. +The `hello`, `ignore_js` and `simple11_dir` are traits defined on the SimpleApp11 class. It also implements additional flags and aliases for these traits. @@ -152,7 +168,7 @@ jupyter simple-ext11 --hello --simple11-dir any_folder jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" --hello --simple11-dir any_folder ``` -Ensure the following URLs give respond correctly. +Ensure the following URLs respond correctly. ```bash # Jupyter Server Home Page. From 43b744758b7f06ace2eb933cd3d5f57ac1cf9fbc Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 9 Jan 2020 14:38:33 +0100 Subject: [PATCH 26/30] rename configs --- examples/simple/README.md | 80 ++++++++----------- examples/simple/jupyter_server_config.py | 2 +- examples/simple/jupyter_simple_ext1_config.py | 6 +- examples/simple/jupyter_simple_ext2_config.py | 2 +- examples/simple/simple_ext1/application.py | 35 ++------ examples/simple/simple_ext1/handlers.py | 9 +-- examples/simple/simple_ext11/application.py | 10 +-- examples/simple/simple_ext2/application.py | 18 ++--- 8 files changed, 58 insertions(+), 104 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index a8e7f83b72..5733f54fea 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -7,6 +7,7 @@ This folder contains example of simple extensions on top of Jupyter Server and r You need `python3` to build and run the server extensions. ```bash +# Clone, create a conda env and install from source. git clone https://github.com/jupyter/jupyter_server && \ cd examples/simple && \ conda create -y -n jupyter_server_example python=3.7 && \ @@ -14,14 +15,30 @@ git clone https://github.com/jupyter/jupyter_server && \ pip install -e . ``` -**OPTIONAL** If you want to build the Typescript code, you need `npm` on your local env. Compiled javascript is provided as artifact in this repository, so this Typescript build step is optional. The Typescript source and configuration has been taken from https://github.com/markellekelly/jupyter-server-example. +**OPTIONAL** If you want to build the Typescript code, you need [npm](https://www.npmjs.com) on your local environement. Compiled javascript is provided as artifact in this repository, so this Typescript build step is optional. The Typescript source and configuration have been taken from https://github.com/markellekelly/jupyter-server-example. ```bash npm install && \ npm run build ``` -## Start Extension 1 +## No Extension + +Ensure Jupyter Server is starting without any extension enabled. + +```bash +# Run this command from a shell. +jupyter server +``` + +Browse the default home page, it should show a white page in your browser with the following content: `A Jupyter Server is running.` + +```bash +# Jupyter Server default Home Page. +open http://localhost:8888 +``` + +## Extension 1 ```bash # Start the jupyter server activating simple_ext1 extension. @@ -31,8 +48,6 @@ jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True}" Now you can render `Extension 1` Server content in your browser. ```bash -# Jupyter Server Home Page. -open http://localhost:8888/ # Home page as defined by default_url = '/default'. open http://localhost:8888/simple_ext1/default # HTML static page. @@ -52,16 +67,16 @@ open http://localhost:8888/simple_ext1/redirect open http://localhost:8888/static/simple_ext1/favicon.ico ``` -## Start Extension 2 +## Extension 1 and Extension 2 -The following command starts both `simple_ext1` and `simple_ext2` extensions. +The following command starts both the `simple_ext1` and `simple_ext2` extensions. ```bash # Start the jupyter server, it will load both simple_ext1 and simple_ext2 based on the provided trait. jupyter server --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" ``` -You can also render `Extension 2` Server content in your browser. +Check that the previous `Extension 1` content is still available ant that you can also render `Extension 2` Server content in your browser. ```bash # HTML static page. @@ -70,7 +85,7 @@ open http://localhost:8888/static/simple_ext2/test.html open http://localhost:8888/simple_ext2/params/test?var1=foo ``` -## Start with Entrypoints +## Work with Entrypoints Optionally, you can copy `simple_ext1.json` and `simple_ext2.json` configuration to your env `etc` folder and start only Extension 1, which will also start Extension 2. @@ -90,20 +105,20 @@ Stop any running server (with `CTRL+C`) and start with additional configuration The provided settings via CLI will override the configuration that reside in the files (`jupyter_simple_ext1_config.py`...) ```bash -jupyter server \ - --ServerApp.jpserver_extensions="{'simple_ext1': True, 'simple_ext2': True}" \ - --SimpleApp1.cli=OK +jupyter simple-ext1 --SimpleApp1.configA "ConfigA from command line" ``` -Check the log, it should return on startup something like the following base on the trait you have defined in the CLI and in the `jupyter_server_config.py`. +Check the log, it should return on startup something like the following base on the trait you have defined in the CLI and in the `jupyter_simple_ext1_config.py`. ``` -[SimpleApp1] SimpleApp1.app OK -[SimpleApp1] SimpleApp1.file OK -[SimpleApp1] SimpleApp1.cli OK +[SimpleApp1] Config {'SimpleApp1': {'configA': 'ConfigA from file', 'configB': 'ConfigB from file', 'configC': 'ConfigC from file'}} +[SimpleApp1] Config {'SimpleApp1': {'configA': 'ConfigA from file', 'configB': 'ConfigB from file', 'configC': 'ConfigC from file'}} +[SimpleApp2] WARNING | Config option `configD` not recognized by `SimpleApp2`. Did you mean `config_file`? +[SimpleApp2] Config {'SimpleApp2': {'configD': 'ConfigD from file'}} +[SimpleApp1] Config {'SimpleApp1': {'configA': 'ConfigA from command line', 'configB': 'ConfigB from file', 'configC': 'ConfigC from file'}} ``` -## Start only Extension 2 +## Only Extension 2 Now stop agin the server and start with only `Extension 2`. @@ -114,43 +129,18 @@ jupyter simple-ext2 Try with the above links to check that only Extension 2 is responding (Extension 1 URLs should give you an 404 error). -## Extension 11 extending Extension 1 +## Extension 11 extends Extension 1 `Extension 11` extends `Extension 1` and brings a few more configs. Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. +> --generate-config returns an execption `"The ExtensionApp has not ServerApp "` + The generated configuration should contains the following. ```bash -... -# Can be used to override templates from notebook.templates. -#c.ExtensionApp.template_paths = [] - -#------------------------------------------------------------------------------ -# SimpleApp1(ExtensionApp) configuration -#------------------------------------------------------------------------------ - -#------------------------------------------------------------------------------ -# SimpleApp11(SimpleApp1) configuration -#------------------------------------------------------------------------------ - -## Say hello -#c.SimpleApp11.hello = False - -## Ignore Javascript -#c.SimpleApp11.ignore_js = False - -## Simple directory -#c.SimpleApp11.simple11_dir = '' - -#------------------------------------------------------------------------------ -# ServerApp(JupyterApp) configuration -#------------------------------------------------------------------------------ - -## Set the Access-Control-Allow-Credentials: true header -#c.ServerApp.allow_credentials = False -... +TBD ``` The `hello`, `ignore_js` and `simple11_dir` are traits defined on the SimpleApp11 class. diff --git a/examples/simple/jupyter_server_config.py b/examples/simple/jupyter_server_config.py index d7cc88f800..d8f9314192 100644 --- a/examples/simple/jupyter_server_config.py +++ b/examples/simple/jupyter_server_config.py @@ -5,4 +5,4 @@ #------------------------------------------------------------------------------ ## The date format used by logging formatters for %(asctime)s -c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S Simple_Extensions' +c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S Simple_Extensions_Example' diff --git a/examples/simple/jupyter_simple_ext1_config.py b/examples/simple/jupyter_simple_ext1_config.py index dc7cd842ec..bf4624a486 100644 --- a/examples/simple/jupyter_simple_ext1_config.py +++ b/examples/simple/jupyter_simple_ext1_config.py @@ -1,3 +1,3 @@ -c.SimpleApp1.app = 'an app' -c.SimpleApp1.cli = 'a cli' -c.SimpleApp1.file = 'a file' +c.SimpleApp1.configA = 'ConfigA from file' +c.SimpleApp1.configB = 'ConfigB from file' +c.SimpleApp1.configC = 'ConfigC from file' diff --git a/examples/simple/jupyter_simple_ext2_config.py b/examples/simple/jupyter_simple_ext2_config.py index 36b3b6751c..6bdbc06089 100644 --- a/examples/simple/jupyter_simple_ext2_config.py +++ b/examples/simple/jupyter_simple_ext2_config.py @@ -1 +1 @@ -c.SimpleApp2.file = 'OK' +c.SimpleApp2.configD = 'ConfigD from file' diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 24b6b7f104..83868c0651 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -28,19 +28,19 @@ class SimpleApp1(ExtensionApp): DEFAULT_TEMPLATE_FILES_PATH ] - file = Unicode('', + configA = Unicode('', config=True, - help='File path' + help='Config A example.' ) - app = Unicode('', + configB = Unicode('', config=True, - help='File path' + help='Config B example.' ) - cli = Unicode('', + configC = Unicode('', config=True, - help='File path' + help='Config C example.' ) def initialize_handlers(self): @@ -53,31 +53,8 @@ def initialize_handlers(self): (r'/{}/(.*)', ErrorHandler) ]) - def initialize_templates(self): - jenv_opt = {"autoescape": True} - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(self.template_paths), - extensions=["jinja2.ext.i18n"], - **jenv_opt - ) - template_settings = {"simple_ext1_jinja2_env": env} - self.settings.update(**template_settings) - - def get_conf(self, key): - c = self.settings.get('config').get(type(self).__name__) - if c: - return c.get(key, None) - else: - return None - def initialize_settings(self): self.log.info('Config {}'.format(self.config)) -# self.log.info('SimpleApp1.app {}'.format(self.get_conf('app'))) -# self.log.info('SimpleApp1.file {}'.format(self.get_conf('file'))) -# self.log.info('SimpleApp1.cli {}'.format(self.get_conf('cli'))) -# self.log.info('Complete Settings {}'.format(self.settings)) -# self.settings.get('config').get(self.extension_name).update({'app': 'OK'}) -# self.settings["{}_config".format(self.extension_name)].update(**self.settings.get('config').get('SimpleApp1')) #----------------------------------------------------------------------------- # Main entry point diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index 9062e5e64e..5f21e0220a 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -2,15 +2,12 @@ class DefaultHandler(ExtensionHandler): def get(self): - # The ExtensionApp’s config object. -# self.log.info("Settings in {} Default Handler: {}".format(self.extension_name, self.settings)) - self.log.info("Config in {} Default Handler: {}".format(self.extension_name, self.config)) - # self.log.info(self.server_config) # The name of the extension to which this handler is linked. self.log.info("Extension Name in {} Default Handler: {}".format(self.extension_name, self.extension_name)) # A method for getting the url to static files (prefixed with /static/). self.log.info("Static URL for / in simple_ext1 Default Handler:".format(self.static_url(path='/'))) self.write('

Hello Simple 1 - I am the default...

') + self.write('Config in {} Default Handler: {}'.format(self.extension_name, self.config)) class RedirectHandler(ExtensionHandler): def get(self): @@ -28,7 +25,7 @@ def get(self, matched_part=None, *args, **kwargs): class BaseTemplateHandler(ExtensionHandler): def get_template(self, path): """Return the jinja template object for a given name""" - return self.settings['simple_ext1_jinja2_env'].get_template(path) + return self.settings['{}_jinja2_env'.format(self.extension_name)].get_template(path) class TypescriptHandler(BaseTemplateHandler): def get(self): @@ -36,7 +33,7 @@ def get(self): class TemplateHandler(BaseTemplateHandler): def get(self, path): -# print(self.get_template('simple1.html')) + """ Optionaly, you can print(self.get_template('simple1.html'))""" self.write(self.render_template('simple1.html', path=path)) class ErrorHandler(BaseTemplateHandler): diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index ddeeadad1e..2c39cfe955 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -55,17 +55,11 @@ def simple11_dir_formatted(self): return "/" + self.simple11_dir def initialize_settings(self): - self.log.info('SimpleApp11.hello: {}'.format(super().get_conf('hello'))) self.log.info('hello: {}'.format(self.hello)) - if self.get_conf('hello') == True: + if self.config['hello'] == True: self.log.info("Hello Simple11 - You have provided the --hello flag or defined 'c.SimpleApp1.hello == True' in jupyter_server_config.py") - self.log.info('SimpleApp11.simple11_dir: {}'.format(self.get_conf('simple11_dir'))) - self.log.info('SimpleApp11.ignore_js: {}'.format(self.get_conf('ignore_js'))) self.log.info('ignore_js: {}'.format(self.ignore_js)) - c = self.settings.get('config').get(type(self).__name__) - if c: - self.settings["{}_config".format(self.extension_name)].update(**c) -# super().initialize_settings() + super().initialize_settings() #----------------------------------------------------------------------------- # Main entry point diff --git a/examples/simple/simple_ext2/application.py b/examples/simple/simple_ext2/application.py index 5aca43b9fb..1f31b417af 100644 --- a/examples/simple/simple_ext2/application.py +++ b/examples/simple/simple_ext2/application.py @@ -1,4 +1,5 @@ import os, jinja2 +from traitlets import Unicode from jupyter_server.extension.application import ExtensionApp from .handlers import ParameterHandler, TemplateHandler, IndexHandler, ErrorHandler @@ -26,6 +27,11 @@ class SimpleApp2(ExtensionApp): DEFAULT_TEMPLATE_FILES_PATH ] + configD = Unicode('', + config=True, + help='Config D example.' + ) + def initialize_handlers(self): self.handlers.extend([ (r'/simple_ext2/params/(.+)$', ParameterHandler), @@ -34,18 +40,8 @@ def initialize_handlers(self): (r'/simple_ext2/(.*)', ErrorHandler) ]) - def initialize_templates(self): - jenv_opt = {"autoescape": True} - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(self.template_paths), - extensions=["jinja2.ext.i18n"], - **jenv_opt - ) - template_settings = {"simple_ext2_jinja2_env": env} - self.settings.update(**template_settings) - def initialize_settings(self): - pass + self.log.info('Config {}'.format(self.config)) #----------------------------------------------------------------------------- # Main entry point From 295d7c47e9ca01082aa6d4bc7945de6b147cc9ea Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 9 Jan 2020 14:47:00 +0100 Subject: [PATCH 27/30] typo --- examples/simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 5733f54fea..62a458929f 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -135,7 +135,7 @@ Try with the above links to check that only Extension 2 is responding (Extension Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. -> --generate-config returns an execption `"The ExtensionApp has not ServerApp "` +> --generate-config returns an exception `"The ExtensionApp has not ServerApp "` The generated configuration should contains the following. From 269fc01ec0cd871ca7de2254e0b4feba09ae92af Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Tue, 14 Jan 2020 19:57:36 +0100 Subject: [PATCH 28/30] add = when passing the SimpleApp1.configA via CLI --- examples/simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 62a458929f..94b28cde5c 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -105,7 +105,7 @@ Stop any running server (with `CTRL+C`) and start with additional configuration The provided settings via CLI will override the configuration that reside in the files (`jupyter_simple_ext1_config.py`...) ```bash -jupyter simple-ext1 --SimpleApp1.configA "ConfigA from command line" +jupyter simple-ext1 --SimpleApp1.configA="ConfigA from command line" ``` Check the log, it should return on startup something like the following base on the trait you have defined in the CLI and in the `jupyter_simple_ext1_config.py`. From 4a64388dbc02dc83eb3ef8eaa6d048f9194e3cb1 Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Thu, 16 Jan 2020 13:12:35 +0100 Subject: [PATCH 29/30] use JinjaMixin --- examples/simple/README.md | 2 +- examples/simple/simple_ext1/application.py | 4 ++-- examples/simple/simple_ext1/handlers.py | 7 ++----- examples/simple/simple_ext11/application.py | 2 +- examples/simple/simple_ext2/application.py | 4 ++-- examples/simple/simple_ext2/handlers.py | 7 ++----- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 94b28cde5c..708b5bd2d1 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -135,7 +135,7 @@ Try with the above links to check that only Extension 2 is responding (Extension Run `jupyter simple-ext11 --generate-config && vi ~/.jupyter/jupyter_config.py`. -> --generate-config returns an exception `"The ExtensionApp has not ServerApp "` +> TODO `--generate-config` returns an exception `"The ExtensionApp has not ServerApp "` The generated configuration should contains the following. diff --git a/examples/simple/simple_ext1/application.py b/examples/simple/simple_ext1/application.py index 83868c0651..3ba0d18599 100644 --- a/examples/simple/simple_ext1/application.py +++ b/examples/simple/simple_ext1/application.py @@ -1,13 +1,13 @@ import os, jinja2 from traitlets import Unicode -from jupyter_server.extension.application import ExtensionApp +from jupyter_server.extension.application import ExtensionApp, ExtensionAppJinjaMixin from .handlers import (DefaultHandler, RedirectHandler, ParameterHandler, TemplateHandler, TypescriptHandler, ErrorHandler) DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -class SimpleApp1(ExtensionApp): +class SimpleApp1(ExtensionAppJinjaMixin, ExtensionApp): # The name of the extension. extension_name = "simple_ext1" diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index 5f21e0220a..959ef9a8db 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -1,4 +1,4 @@ -from jupyter_server.extension.handler import ExtensionHandler +from jupyter_server.extension.handler import ExtensionHandler, ExtensionHandlerJinjaMixin class DefaultHandler(ExtensionHandler): def get(self): @@ -22,10 +22,7 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class BaseTemplateHandler(ExtensionHandler): - def get_template(self, path): - """Return the jinja template object for a given name""" - return self.settings['{}_jinja2_env'.format(self.extension_name)].get_template(path) +class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandler): pass class TypescriptHandler(BaseTemplateHandler): def get(self): diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index 2c39cfe955..2c4d28b7be 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -47,7 +47,7 @@ class SimpleApp11(SimpleApp1): @observe('ignore_js') def _update_ignore_js(self, change): - """TODO The observe does not work""" + """TODO Does the observe work?""" self.log.info('ignore_js has just changed: {}'.format(change)) @property diff --git a/examples/simple/simple_ext2/application.py b/examples/simple/simple_ext2/application.py index 1f31b417af..2c26ca9c0a 100644 --- a/examples/simple/simple_ext2/application.py +++ b/examples/simple/simple_ext2/application.py @@ -1,12 +1,12 @@ import os, jinja2 from traitlets import Unicode -from jupyter_server.extension.application import ExtensionApp +from jupyter_server.extension.application import ExtensionApp, ExtensionAppJinjaMixin from .handlers import ParameterHandler, TemplateHandler, IndexHandler, ErrorHandler DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static") DEFAULT_TEMPLATE_FILES_PATH = os.path.join(os.path.dirname(__file__), "templates") -class SimpleApp2(ExtensionApp): +class SimpleApp2(ExtensionAppJinjaMixin, ExtensionApp): # The name of the extension. extension_name = "simple_ext2" diff --git a/examples/simple/simple_ext2/handlers.py b/examples/simple/simple_ext2/handlers.py index 490333ced6..50466943b2 100644 --- a/examples/simple/simple_ext2/handlers.py +++ b/examples/simple/simple_ext2/handlers.py @@ -1,4 +1,4 @@ -from jupyter_server.extension.handler import ExtensionHandler +from jupyter_server.extension.handler import ExtensionHandler, ExtensionHandlerJinjaMixin class ParameterHandler(ExtensionHandler): def get(self, matched_part=None, *args, **kwargs): @@ -9,10 +9,7 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class BaseTemplateHandler(ExtensionHandler): - def get_template(self, name): - """Return the jinja template object for a given name""" - return self.settings['simple_ext2_jinja2_env'].get_template(name) +class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandler): pass class IndexHandler(BaseTemplateHandler): def get(self): From c3a19408bd2455a1806300ff4357333ff472fb0c Mon Sep 17 00:00:00 2001 From: Eric Charles Date: Sat, 29 Feb 2020 10:21:36 +0100 Subject: [PATCH 30/30] align examples to mixin --- examples/simple/README.md | 6 +++--- examples/simple/simple_ext1/handlers.py | 11 ++++++----- examples/simple/simple_ext11/application.py | 3 +++ examples/simple/simple_ext2/handlers.py | 7 ++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/simple/README.md b/examples/simple/README.md index 708b5bd2d1..7caa527479 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -10,8 +10,8 @@ You need `python3` to build and run the server extensions. # Clone, create a conda env and install from source. git clone https://github.com/jupyter/jupyter_server && \ cd examples/simple && \ - conda create -y -n jupyter_server_example python=3.7 && \ - conda activate jupyter_server_example && \ + conda create -y -n jupyter-server-example python=3.7 && \ + conda activate jupyter-server-example && \ pip install -e . ``` @@ -154,7 +154,7 @@ Stop any running server and then start the simple-ext11. ```bash jupyter simple-ext11 --hello --simple11-dir any_folder -# or... +# TODO FIX the following command, simple11 does not work launching with jpserver_extensions parameter. jupyter server --ServerApp.jpserver_extensions="{'simple_ext11': True}" --hello --simple11-dir any_folder ``` diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index 959ef9a8db..f635d1e2c1 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -1,6 +1,7 @@ -from jupyter_server.extension.handler import ExtensionHandler, ExtensionHandlerJinjaMixin +from jupyter_server.base.handlers import JupyterHandler +from jupyter_server.extension.handler import ExtensionHandlerMixin, ExtensionHandlerJinjaMixin -class DefaultHandler(ExtensionHandler): +class DefaultHandler(ExtensionHandlerMixin, JupyterHandler): def get(self): # The name of the extension to which this handler is linked. self.log.info("Extension Name in {} Default Handler: {}".format(self.extension_name, self.extension_name)) @@ -9,11 +10,11 @@ def get(self): self.write('

Hello Simple 1 - I am the default...

') self.write('Config in {} Default Handler: {}'.format(self.extension_name, self.config)) -class RedirectHandler(ExtensionHandler): +class RedirectHandler(ExtensionHandlerMixin, JupyterHandler): def get(self): self.redirect("/static/{}/favicon.ico".format(self.extension_name)) -class ParameterHandler(ExtensionHandler): +class ParameterHandler(ExtensionHandlerMixin, JupyterHandler): def get(self, matched_part=None, *args, **kwargs): var1 = self.get_argument('var1', default=None) components = [x for x in self.request.path.split("/") if x] @@ -22,7 +23,7 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandler): pass +class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler): pass class TypescriptHandler(BaseTemplateHandler): def get(self): diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index 2c4d28b7be..d67a211fd9 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -61,6 +61,9 @@ def initialize_settings(self): self.log.info('ignore_js: {}'.format(self.ignore_js)) super().initialize_settings() + def initialize_handlers(self): + super().initialize_handlers() + #----------------------------------------------------------------------------- # Main entry point #----------------------------------------------------------------------------- diff --git a/examples/simple/simple_ext2/handlers.py b/examples/simple/simple_ext2/handlers.py index 50466943b2..fb34834688 100644 --- a/examples/simple/simple_ext2/handlers.py +++ b/examples/simple/simple_ext2/handlers.py @@ -1,6 +1,7 @@ -from jupyter_server.extension.handler import ExtensionHandler, ExtensionHandlerJinjaMixin +from jupyter_server.base.handlers import JupyterHandler +from jupyter_server.extension.handler import ExtensionHandlerMixin, ExtensionHandlerJinjaMixin -class ParameterHandler(ExtensionHandler): +class ParameterHandler(ExtensionHandlerMixin, JupyterHandler): def get(self, matched_part=None, *args, **kwargs): var1 = self.get_argument('var1', default=None) components = [x for x in self.request.path.split("/") if x] @@ -9,7 +10,7 @@ def get(self, matched_part=None, *args, **kwargs): self.write('

var1: {}

'.format(var1)) self.write('

components: {}

'.format(components)) -class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandler): pass +class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler): pass class IndexHandler(BaseTemplateHandler): def get(self):