{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Working Interactively with `NotebookApp`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from uuid import uuid4\n", "import logging\n", "from IPython.display import HTML, IFrame, SVG\n", "from notebook.notebookapp import NotebookApp, web\n", "from notebook.base.handlers import IPythonHandler\n", "import ipywidgets as W\n", "from tornado.httpclient import AsyncHTTPClient" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "PORT = 9999\n", "TOKEN = str(uuid4())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "app = NotebookApp()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Magic Moment" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "app.initialize([\"--port\", f\"{PORT}\", f\"--NotebookApp.token={TOKEN}\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> You're going to want to collapse that output.\n", "\n", "It's actually a little anticlimactic: once `initialize`d, the app is _already_ listening, as the `IOLoop` is already running, and the server is already listening on `PORT`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "SVG(app.contents_manager.get(\"example.svg\")[\"content\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# A little bit about logging\n", "\n", "We'll explore more here later. Extracted from [this issue](https://github.com/jupyter-widgets/ipywidgets/issues/1936)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class LogViewer(logging.Handler):\n", " def __init__(self, output_widget, *args, **kwargs):\n", " logging.Handler.__init__(self, *args)\n", " for key, value in kwargs.items():\n", " if f\"{key}\" == \"format\":\n", " self.setFormatter(value)\n", " self.output_widget = output_widget\n", "\n", " def emit(self, record):\n", " w = self.output_widget\n", " msg = self.format(record)\n", " w.outputs = (dict(name=\"stdout\", output_type=\"stream\", text=f\"{msg}\\n\"),) + w.outputs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output = W.Output()\n", "app.log.addHandler(LogViewer(output))\n", "output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Dynamically Adding a (Dyanmic) Handler" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bar = W.IntSlider(99, description=\"bar\")\n", "bar" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Bar(IPythonHandler):\n", " re = r\"^/foo/?$\"\n", " @web.authenticated\n", " def get(self):\n", " self.finish(\"🍻\" * bar.value)\n", "app.web_app.add_handlers('.*', [[Bar.re, Bar]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Use the right client" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fetch = AsyncHTTPClient().fetch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using a synchronous client, like vanilla `requests`, or the `!curl` magic, will deadlock your kernel (and app!)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(\n", " await fetch(f\"http://localhost:{PORT}/foo/?token={TOKEN}\")\n", ").body.decode(\"utf-8\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bar.value = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(\n", " await fetch(f\"http://localhost:{PORT}/foo/?token={TOKEN}\")\n", ").body.decode(\"utf-8\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }