{ "info": { "author": "Mikko Ohtamaa", "author_email": "mikko@opensourcehacker.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: IPython", "Framework :: Pyramid", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Build Tools", "Topic :: System :: Shells" ], "description": "================\nPyramid Notebook\n================\n\n*pyramid_notebook* embeds IPython Notebook shell on your Pyramid web site. Start a powerful through-the-browser Python shell with a single click.\n\n`IPython Notebook `_ is the de facto tool for researches, data analysts and software developers to perform visual and batch oriented tasks. *pyramid_notebook* puts the power of IPython Notebook inside of a `Pyramid website `_.\n\n.. |ci| image:: https://travis-ci.org/websauna/pyramid_notebook.svg\n :target: https://travis-ci.org/websauna/pyramid_notebook\n\n.. |cov| image:: https://codecov.io/bitbucket/miohtama/pyramid_notebook/coverage.svg?branch=master\n :target: https://codecov.io/bitbucket/miohtama/pyramid_notebook?branch=master\n\n.. |downloads| image:: https://img.shields.io/pypi/dm/pyramid_notebook.svg\n :target: https://pypi.python.org/pypi/pyramid_notebook/\n :alt: Downloads\n\n.. |latest| image:: https://img.shields.io/pypi/v/pyramid_notebook.svg\n :target: https://pypi.python.org/pypi/pyramid_notebook/\n :alt: Latest Version\n\n.. |license| image:: https://img.shields.io/pypi/l/pyramid_notebook.svg\n :target: https://pypi.python.org/pypi/pyramid_notebook/\n :alt: License\n\n.. |versions| image:: https://img.shields.io/pypi/pyversions/pyramid_notebook.svg\n :target: https://pypi.python.org/pypi/pyramid_notebook/\n :alt: Supported Python versions\n\n+-----------+-----------+\n|\u00a0|ci| | |license| |\n+-----------+-----------+\n| |versions|| |latest| |\n+-----------+-----------+\n\n.. contents:: :local:\n\nBenefits\n========\n\n* Easy access: Get powerful shell through a web browser, no additional software installations needed.\n\n* Automatic default variables: Populate Notebook with variables and data depending on the page where you have a shell button.\n\n* Authentication integration: use the same credentials as you use for the site administration. Each Pyramid user gets his/her own IPython Notebook process.\n\n* Rich user interface: Place the cursor with a mouse, use desktop shortcuts for line editing.\n\nHow it works\n------------\n\n.. image :: https://raw.githubusercontent.com/websauna/pyramid_notebook/master/docs/animation.gif\n\nUse cases\n---------\n\n* Visualize and analyze your website data.\n\n* Easier and powerful alternative for normal Python prompt - web browser user interface has more candy over old fashioned terminal.\n\n* Share code sessions and recipes with your team mates.\n\nPrerequisites\n-------------\n\n* `Pyramid web site `_ (can be easily extended to other web frameworks)\n\n* Python 3.5+\n\n* OSX, Linux\n\n* uWSGI (on production server only)\n\nDemo\n====\n\n* Checkout source code repository::\n\n git clone https://github.com/websauna/pyramid_notebook.git\n\n* Create virtualenv for Python 3.5. Install dependencies::\n\n cd pyramid_notebook\n python3 -m venv env # Create virtual environment\n source env/bin/activate # Activate virtual environment\n pip install requirements.txt\n python setup.py develop\n\n* Run demo::\n\n pserve pyramid_notebook/demo/development.ini\n\nThen point your browser at `http://localhost:9999 `_.\n\nCredentials for this demo are:\n\n * User 1:\n\n - username: *user*\n - password: *password*\n\n * User 2:\n\n - username: *user2*\n - password: *password*\n\nInstallation\n============\n\nIt is recommend to install using ``pip`` and ``virtualenv``. `Python guide for package installation `_. ::\n\n pip install pyramid_notebook\n\nOn production server where you use uWSGI websocket support::\n\n pip install pyramid_notebook[uwsgi]\n\nUsage\n=====\n\nYour application needs to configure three custom views.\n\n* One or multiple ``launch_ipython()`` notebook launch points. This does user authentication and authorization and then calls ``pyramid_notebook.views.launch_notebook()`` to open a new Notebook for a user. ``launch_ipython()`` takes in Notebook context parameters (see below), starts a new Notebook kernel if needed and then redirects user to Notebook itself.\n\n* ``shutdown_ipython()`` which does authentication and authorization and calls ``pyramid_notebook.views.shutdown_notebook()`` to force close a notebook for a user.\n\n* ``notebook_proxy()`` which does authentication and authorization and calls ``pyramid_notebook.views.notebook_proxy()`` to proxy HTTP request to upstream IPython Notebook server bind to a localhost port. `notebook_proxy` is mapped to `/notebook/` path in your site URL. Both your site and Notebook upstream server should agree on this location.\n\nExample code\n------------\n\nThe following is an example how to construct ``admin_shell`` view which launches a Notebook for the currently logged in Pyramid user when the view is visited for the first time. For extra security the permission for the notebook view cannot be assigned through normal groups, but the username must be on the whitelist in the INI settings file. This guarantees the shell is initially accessible only by persons who have shell access to the server itself.\n\nFor another approach on these views, please see the demo source code.\n\n``views.py``:\n\n.. code-block:: python\n\n from pyramid.httpexceptions import HTTPFound\n from pyramid.view import view_config\n from pyramid_notebook import startup\n from pyramid_notebook.views import launch_notebook\n from pyramid_notebook.views import shutdown_notebook as _shutdown_notebook\n from pyramid_notebook.views import notebook_proxy as _notebook_proxy\n from pyramid_web20.models import Base\n\n\n #: Include our database session in notebook so it is easy to query stuff right away from the prompt\n SCRIPT = \"\"\"\n from pyramid_web20.models import DBSession as session\n \"\"\"\n\n\n GREETING=\"\"\"\n * **session** - SQLAlchemy database session\n \"\"\"\n\n\n @view_config(route_name=\"notebook_proxy\", permission=\"shell\")\n def notebook_proxy(request):\n \"\"\"Proxy IPython Notebook requests to the upstream server.\"\"\"\n return _notebook_proxy(request, request.user.username)\n\n\n @view_config(route_name=\"admin_shell\", permission=\"shell\")\n def admin_shell(request):\n \"\"\"Open admin shell with default parameters for the user.\"\"\"\n # Make sure we have a logged in user\n nb = {}\n\n # Pass around the Pyramid configuration we used to start this application\n global_config = request.registry.settings[\"pyramid_web20.global_config\"]\n\n # Get the reference to our Pyramid app config file and generate Notebook\n # bootstrap startup.py script for this application\n config_file = global_config[\"__file__\"]\n startup.make_startup(nb, config_file)\n startup.add_script(nb, SCRIPT)\n startup.add_greeting(nb, GREETING)\n\n #: Include all our SQLAlchemy models in the notebook variables\n startup.include_sqlalchemy_models(nb, Base)\n\n return launch_notebook(request, request.user.username, notebook_context=nb)\n\n\n @view_config(route_name=\"shutdown_notebook\", permission=\"shell\")\n def shutdown_notebook(request):\n \"\"\"Shutdown the notebook of the current user.\"\"\"\n _shutdown_notebook(request, request.user.username)\n return HTTPFound(request.route_url(\"home\"))\n\nWe also need to capture the INI settings file on the server start up, so that we can pass it forward to IPython Notebook process. In ``__init__.py``:\n\n.. code-block:: python\n\n def main(global_config, **settings):\n settings[\"pyramid_web20.global_config\"] = global_config\n\nThen we have a custom principals handler granting the ``shell`` permission for users read from the user whitelist in the configuration file:\n\n.. code-block:: python\n\n def find_groups(userid, request):\n \"\"\"Get applied groups and other for the user\"\"\"\n\n from horus.interfaces import IUserModel\n user_class = request.registry.queryUtility(IUserModel)\n\n # Read superuser names from the config\n superusers = aslist(request.registry.settings.get(\"pyramid_web20.superusers\"))\n\n user = models.DBSession.query(user_class).get(userid)\n if user:\n if user.can_login():\n principals = ['group:{}'.format(g.name) for g in user.groups]\n\n # Allow superuser permission\n if user.username in superusers or user.email in superusers:\n principals.append(\"superuser:superuser\")\n\n return principals\n\n # User not found, user disabled\n return None\n\nWe refer to ``superuser:super`` in Pyramid site root object::\n\n class Root:\n\n __acl__ = [\n ...\n (Allow, \"superuser:superuser\", 'shell'),\n ]\n\nAnd here is the configuration file bit::\n\n pyramid_web20.superusers =\n mikko@example.com\n\nPyramid settings\n----------------\n\n*python_notebook* reads following parameters from your Pyramid INI configuration file::\n\n # Where we store IPython Notebook runtime and persistent files\n # (pid, saved notebooks, etc.).\n # Each user will get a personal subfolder in this folder\n pyramid_notebook.notebook_folder = /tmp/pyramid_notebook\n\n # Automatically shutdown IPython Notebook kernel\n # after his many seconds have elapsed since startup\n pyramid_notebook.kill_timeout = 3600\n\n # Websocket proxy launch function.\n # This is a view function that upgrades the current HTTP request to Websocket (101 upgrade protocol)\n # and starts the web server websocket proxy loop. Currently only uWSGI supported\n # (see below).\n pyramid_notebook.websocket_proxy =\n\n # For uWSGI in production\n # pyramid_notebook.websocket_proxy = pyramid_notebook.uwsgi.serve_websocket\n\n # If you need to server websockets from alternative domain (See below).\n # Example value: https://ws.example.com\n pyramid_notebook.alternative_domain =\n\nNotebook context parameters\n---------------------------\n\nNotebooks can be opened with context sensitive parameters. Some are filled in by the framework, some of those you can set yourself.\n\n* You pass in your Notebook context parameters when you call ``launch_notebook()``.\n\n* To have custom context variables change *startup* script.\n\n* To have different info screen change *greeting* text\n\nExample of what context information you can pass below::\n\n {\n\n # Extra Python script executed on notebook startup - this is saved as startup.py\n \"startup\": \"\"\n\n # Markdown text displayed at the beginning of the notebook\n \"greeting\": \"\"\n\n # List of paths where to load IPython Notebook Jinja templates\n # http://ipython.org/ipython-doc/3/config/options/notebook.html\n \"extra_template_paths\": []\n\n # Notebook daemon process id - filled it in by the daemon itself\n \"pid\": 1234,\n\n # Notebook daemon kill timeout in seconds - filled in by the the daemon itself after parsing command line arguments\n \"kill_timeout\": 5,\n\n # Bound localhost port for this notebook - filled in by the daemon itself after parsing command line arguments\n \"http_port\": 9999,\n\n # Set Notebook HTTP Allow Origin header to tell where websockets are allowed to connect\n \"allow_origin\": 'localhost:9999',\n\n # Override websocket URL\n \"websocket_url\": 'ws://localhost:9998',\n\n # Path in URL where Notebook is proxyed, must match notebook_proxy() view\n \"notebook_path\": '/notebook/',\n\n # Hash of this context. This is generated automatically from supplied context dictionary if not given. If the hash changes the notebook is restarted with new context data.\n \"context_hash\": 'foo',\n }\n\n\nDead man switch\n---------------\n\nLaunched Notebook processes have maximum life time after which they terminate themselves. Currently the termation is unconditional seconds since the start up, but in the future versions this is expected to change to a dead man switchs where the process only terminates itself if there has not been recent activity.\n\nWebsocket proxying\n------------------\n\nIPython Notebook needs two different kind of connections to function properly\n\n* HTTP connection for loading the pages, assets\n\n* Websocket for real-time communication with Notebook kernel\n\nWhen you run Pyramid's ``pserve`` development server on your local machine and enter the Notebook shell, the websocket connection is made directly to IPython Notebook port bound localhost. This is because ``pserve`` does not have any kind of support for websockets. This behavior is controlled by ``pyramid_notebook.websocket_proxy`` setting.\n\nOn the production server, you usually run a web server which spawns processes to execute WSGI requests, the Python standard for hosting web applications. Unfortunately, like WSGI for HTTP, there doesn't exist a standard for doing websocket requests in a Python application. Thus, one has to add support for websockets for each web server separately. Currently *pyramid_notebook* supports the following web servers\n\n * `uWSGI `_\n\nIt is ok to have another web server at the front of uWSGI, like Nginx, as these web servers can usually do proxy pass for websocket connections. You might need to add following to your Nginx config::\n\n # include a variable for the upgrade header\n map $http_upgrade $connection_upgrade {\n default upgrade;\n '' close;\n }\n\n server {\n location / {\n include uwsgi_params;\n\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade;\n }\n }\n\nuWSGI\n~~~~~\n\nTo turn on websocket support on your uWSGI production server add following to your production INI settings::\n\n pyramid_notebook.websocket_proxy = pyramid_notebook.uwsgi.serve_websocket\n\nAlso you need to enable websockets in your uWSGI settings::\n\n http-websockets = true\n\n\nWebsocket and reverse proxy services\n------------------------------------\n\nReverse proxy services, like CloudFlare `_, might give only limited or no support for websockets. This may manifest itself in the form of *400 Bad Request* responses from the server because the reverse proxy service strips out ``Connection: Upgrade`` HTTP Request header. In this case it is recommended that you serve IPython Notebook from a separate domain where the websocket connection gets unhindered access to your server.\n\nYou need to\n\n* Configure your naked web server to respond to an alternative domain name (``ws.example.com``).\n\n* Configure ``pyramid_notebook`` to rewrite notebook URLs to come from the alternative domain::\n\n pyramid_notebook.alternative_domain = https://ws.example.com\n\n* Pyramid ``AuthTktAuthenticationPolicy``, by default, supports wildcard authentication cookies.\n\n* You can limit the naked domain to expose ``/notebook/`` URLs only.\n\nArchitecture\n============\n\nEach Pyramid user has a named Notebook process. Each Notebook process gets their own working folder, dynamically created upon the first lanch. Notebooks are managed by ``NotebookManager`` class which detects changes in notebook context and restarts the Notebook process for the user with a new context if needed.\n\nNotebook bind itself to localhost ports. Pyramid view proxyes ``/notebook/`` HTTP requests to Notebook and first checks the HTTP request has necessary permissions by performing authentication and authorization checks. The proxy view is also responsible for starting a web server specific websocket proxy loop.\n\nLaunched Notebook processes are daemonized and separated from the web server process. The communication between the web server and the daemon process happens through command line, PID file and context file (JSON dump of notebook context parameters, as described above).\n\nLocal deployment\n----------------\n\n.. image :: https://raw.githubusercontent.com/websauna/pyramid_notebook/master/docs/localhost_deployment.png\n\n\nProduction deployment\n---------------------\n\n.. image :: https://raw.githubusercontent.com/websauna/pyramid_notebook/master/docs/production_deployment.png\n\n\nScalability\n===========\n\nThe tool is intended for team internal use only. The default settings limit the number of users who can create and access notebooks to 10 people.\n\nCurrently a new daemon process is launched for each user in non-scalable manner. If 100+ users scalability is required there exist several ways to make the tool more lightweight. For example, `you can offload Websockets away from main uWSGI server to a dedicated gevent server `_.\n\nSecurity\n========\n\nWith great power comes great responsibility.\n\n.. note::\n\n Giving a user *pyramid_notebook* access is equal to giving him/her SSH access to a website UNIX user.\n\n*pyramid_notebook* relies on user authorization and authentication by Pyramid web framework. It is your site, so the authentication and authorization system is as good as you made it to be. If you do not feel comfortable exposing this much of power over website authentication, you can still have notebook sessions e.g. over SSH tunneling.\n\nBelow are some security matters you should consider.\n\nHTTPS only\n----------\n\n*pyramid_notebook* accepts HTTPS connections only. HTTP connections are unencrypted and leaking information over HTTP could lead severe compromises.\n\nVPN restrictions\n----------------\n\nYou can configure your web server to allow access to */notebook/* URLs from whitelisted IP networks only.\n\nAccess restricted servers\n-------------------------\n\nYou do not need to run *pyramid_notebook* sessions on the main web servers. You can configure a server with limited data and code separately for running *pyramid_notebook*.\n\nThe access restricted server can have\n\n* Read-only account on the database\n\n* Source code and configuration files containing sensitive secrets removed (HTTPS keys, API tokens, etc.)\n\nLinux containerization\n----------------------\n\nNotebook process can be made to start inside Linux container. Thus, it would still run on the same server, but you can limit the access to file system and network by the kernel. `Read more about Linux cgroups `_.\n\nTwo-factor authentication\n-------------------------\n\nConsider requiring your website admins to use `two-factor authentication `_ to protect against admin credential loss due to malware, keylogging and such nasties. Example `two-factor library for Python `_.\n\nTroubleshooting\n===============\n\nTaking down loose notebooks\n---------------------------\n\nIn the case the notebook daemon processes get stuck, e.g. by user starting a infinite loop and do not terminate properly, you can take them down.\n\n* Any time you launch a notebook with different context (different parameters) for the user, the prior notebook process gets terminated forcefully\n\n* You can manually terminate all notebook processes. Ex::\n\n pkill -f notebook_daemon.py\n\nCrashing Notebooks\n------------------\n\nThe following are indication of crashed Notebook process.\nThe following page on Notebook when you try try to start Notebook through web:\n\n Apparently IPython Notebook daemon process is not running for user\n\n... or the IPython Notebook dialog *Connecting failed* and connecting to kernel does not work.\n\nNotebook has most likely died because of Python exception. There exists a file ``notebook.stderr.log``, one per each user, where you should be able to read traceback what happened.\n\nDebugging Notebook daemon\n-------------------------\n\nThe notebook daemon can be started from a command line and supports normal UNIX daemon ``start``, ``stop`` and ``fg`` commands. You need to give mandatory pid file, working folder, HTTP port and kill timeout arguments.\n\nExample how to start Notebook daemon manually::\n\n python $SOMEWHERE/pyramid_notebook/server/notebook_daemon.py fg /tmp/pyramid_notebook/$USER/notebook.pid /tmp/pyramid_notebook/$USER 8899 3600\n\n\nSeeing startup script exceptions\n--------------------------------\n\nIf the startup script does not populate your Notebook with default variables as you hope, you can always do\n\n* ``print(locals())`` to see what local variables are set\n\n* ``print(gocals())`` to see what global variables are set\n\n* Manually execute startup script inside IPython Notebook, e.g. ``exec(open(\"/tmp/pyramid_notebook/user-1/.jupyter/profile_default/startup/startup.py \").read())`` (check the actual path by exploring ``/tmp/pyramid_notebook`` on your local filesystem).\n\nDevelopment\n===========\n\n* `Source code `_\n\n* `Issue tracker `_\n\n* `Documentation `_\n\nTests\n-----\n\n.. note ::\n\n Due to UI complexity of IPython Notebook interaction browser tests must be executed with full Firefox or Chrome driver.\n\nInstall test dependencies::\n\n pip install -e \".[test]\"\n\nRunning manual instance::\n\n pserve pyramid_notebook/demo/development.ini --reload\n\nUsername is ``username`` and password ``password``.\n\nRunning tests::\n\n py.test tests --splinter-webdriver=chrome --splinter-make-screenshot-on-failure=false --ini=pyramid_notebook/demo/development.ini\n\nRunning a single test::\n\n py.test tests/* --splinter-webdriver=chrome --splinter-make-screenshot-on-failure=false --ini=pyramid_notebook/demo/development.ini -s -k test_notebook_template\n\nRun full test coverage::\n\n py.test tests/* --cov pyramid_notebook --cov-report xml --splinter-webdriver=chrome --splinter-make-screenshot-on-failure=false --ini=pyramid_notebook/demo/development.ini -s -k test_notebook_template\n\nRunning uWSGI server with websockets::\n\n uwsgi --virtualenv=venv --wsgi-file=pyramid_notebook/demo/wsgi.py --pythonpath=venv/bin/python uwsgi.ini\n\nRunning uWSGI under Nginx for manual websocket proxy testing (OSX)::\n\n pkill nginx ; nginx -c `pwd`/nginx.conf\n uwsgi --virtualenv=venv --wsgi-file=pyramid_notebook/demo/wsgi.py --pythonpath=venv/bin/python uwsgi-under-nginx.ini\n\n\n.. note ::\n\n Selenium Firefox has a bug which prevents typing ( on keyboard, preventing running tests on Firefox.\n\nManual testing\n~~~~~~~~~~~~~~\n\nYou can manually launch the process to see any errors from IPython Notebook start.\n\nRun ``test_start_stop`` test and capture log output in stdout::\n\n py.test tests --splinter-webdriver=chrome --splinter-make-screenshot-on-failure=false --ini=pyramid_notebook/demo/development.ini -s -k test_start_stop\n ...\n INFO:pyramid_notebook.notebookmanager:Running notebook command: python ./pyramid_notebook/server/notebook_daemon.py start /tmp/pyramid_notebook_tests/testuser1/notebook.pid /tmp/pyramid_notebook_tests/testuser1 40007 60\n\nYou can::\n\n python ./pyramid_notebook/server/notebook_daemon.py start /tmp/pyramid_notebook_tests/testuser1/notebook.pid /tmp/pyramid_notebook_tests/testuser1 40005 60\n\n\nRelated work\n------------\n\n* https://github.com/jupyter/jupyterhub\n\n* https://github.com/Carreau/IPython-notebook-proxy\n\n* https://github.com/UnataInc/ipydra/tree/master/ipydrar\n\nChangelog for pyramid_notebook\n==============================\n\n0.3.0 (2018-10-09)\n------------------\n\n- Upgraded to IPython 7.0.1 / Jupyter.\n\n- Add support to Python 3.6, 3.7 and 3.8\n\n- Remove support to Python 3.4.\n\n- Enforce Python style checks.\n\n- Update README.\n\n\n0.2.1 (2017-01-29)\n------------------\n\n- Fixed unnecessary \"Enter token\" prompt with the latest Jupyter Notebook versions\n\n\n0.2 (2016-12-06)\n----------------\n\n- Upgraded to IPython 5.1 / Jupyter\n\n- Better error messages in various situations\n\n- Add custom shutdown command by customizing IPython toolbar menu\n\n\n0.1.11 (2016-04-18)\n-------------------\n\n- Upgrade to Daemonocle 1.0\n\n\n0.1.10 (2016-01-31)\n-------------------\n\n- Allow easily override IPython Notebook current working directory.\n\n\n0.1.9 (2016-01-31)\n------------------\n\n- Make it possible to override the default bootstrap scripts and greeting for ``make_startup()``\n\n\n0.1.8 (2016-01-31)\n------------------\n\n- Adding ws4py as a dependency as it is required for uWSGI which is currently the only supported implementation\n\n\n0.1.7 (2016-01-16)\n------------------\n\n- Fixed README reST syntax\n\n\n0.1.6 (2016-01-16)\n------------------\n\n- Switch to xdaemonocle fork of Daemonocle library\n\n\n0.1.5 (2016-01-07)\n------------------\n\n- Keep IPython Notebook in 3.x series now by setup.py pinnings, as IPython 4.0 is not supported yet\n\n\n0.1.4 (2015-12-19)\n------------------\n\n- Fixed relative image links to absolute in README\n\n\n0.1.3 (2015-12-19)\n------------------\n\n- Fixing MANIFEST.in and release issues due to setuptools_git not present\n\n\n0.1.2 (2015-12-19)\n------------------\n\n- Fixed README markup\n\n- Fixed broken drone.io integration which prevented tests to pass on CI\n\n0.1.1 (2015-12-19)\n------------------\n\n- Fixed broken setup.py classifiers\n\n0.1 (2015-12-19)\n----------------\n\n- Initial release.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/websauna/pyramid_notebook", "keywords": "ipython setuptools development shell uwsgi", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pyramid-notebook", "package_url": "https://pypi.org/project/pyramid-notebook/", "platform": "", "project_url": "https://pypi.org/project/pyramid-notebook/", "project_urls": { "Homepage": "https://github.com/websauna/pyramid_notebook" }, "release_url": "https://pypi.org/project/pyramid-notebook/0.3.0/", "requires_dist": [ "ipython[notebook] (>=7.0.1)", "daemonocle (>=1.0.1)", "PasteDeploy", "port-for", "pyramid", "sqlalchemy", "ws4py", "flake8; extra == 'dev'", "flake8-isort; extra == 'dev'", "zest.releaser[recommended]; extra == 'dev'", "codecov; extra == 'test'", "flaky; extra == 'test'", "paste; extra == 'test'", "pyramid-jinja2; extra == 'test'", "pytest; extra == 'test'", "pytest-cov; extra == 'test'", "pytest-splinter; extra == 'test'", "selenium (>3); extra == 'test'", "webtest; extra == 'test'", "uwsgi; extra == 'uwsgi'", "ws4py; extra == 'uwsgi'" ], "requires_python": ">=3.5.2", "summary": "Embed IPython Notebook shell on your Pyramid website", "version": "0.3.0" }, "last_serial": 4354968, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "665535a074984c5c9234a9d5db475b25", "sha256": "3cf6ef076fbdffc89523838d7653f098013002cd83560ab099bab23a3e6c6671" }, "downloads": -1, "filename": "pyramid_notebook-0.1.1.tar.gz", "has_sig": false, "md5_digest": "665535a074984c5c9234a9d5db475b25", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 214422, "upload_time": "2015-12-18T22:21:39", "url": "https://files.pythonhosted.org/packages/af/08/1352b6ee9a69da7ce27fbf487a2bffccc3f1360d80540f07742c83ea8cb7/pyramid_notebook-0.1.1.tar.gz" } ], "0.1.10": [ { "comment_text": "", "digests": { "md5": "b51ec90f354b0f2213eebdaed8d34022", "sha256": "786911eddd719d2381d2841b4dcb1d87de4dbae777e1c3d82c2ff64429d3b15a" }, "downloads": -1, "filename": "pyramid_notebook-0.1.10.tar.gz", "has_sig": false, "md5_digest": "b51ec90f354b0f2213eebdaed8d34022", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 220284, "upload_time": "2016-01-31T19:40:17", "url": "https://files.pythonhosted.org/packages/1b/f7/733339fb8571b1af8327291697c87a65da2c017261e24a3057a1364e0389/pyramid_notebook-0.1.10.tar.gz" } ], "0.1.11": [ { "comment_text": "", "digests": { "md5": "93bded73980691e786259d8c152c80df", "sha256": "13d9233b3c321d93f307e1af48ca2babb76ec2002dabadfe2c6d00d62cf78636" }, "downloads": -1, "filename": "pyramid_notebook-0.1.11.tar.gz", "has_sig": false, "md5_digest": "93bded73980691e786259d8c152c80df", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 220369, "upload_time": "2016-04-19T03:55:46", "url": "https://files.pythonhosted.org/packages/46/31/b8737578bc20879f7c7682371afc4499181108893034446dfe2f14c0c3e9/pyramid_notebook-0.1.11.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "b2eafcf56fec41a2aa8db6fe38609204", "sha256": "58e263e122f4075d9bf2de2d59cb67e2242bb5142db7f4c9635c953c31d23e7d" }, "downloads": -1, "filename": "pyramid_notebook-0.1.2.tar.gz", "has_sig": false, "md5_digest": "b2eafcf56fec41a2aa8db6fe38609204", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 214577, "upload_time": "2015-12-18T23:32:44", "url": "https://files.pythonhosted.org/packages/96/d6/b68dbe821464d7b7d5fb7a60cdb6c980acaedf0fc1d9aedd34c443a34e37/pyramid_notebook-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "9e189fe8858e1b431071a6a56f246064", "sha256": "2a2bf7a95b9af22c9c1ac10c02113c221cbec0272faa6a4dbe39fcf6120adb15" }, "downloads": -1, "filename": "pyramid_notebook-0.1.3.tar.gz", "has_sig": false, "md5_digest": "9e189fe8858e1b431071a6a56f246064", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 215258, "upload_time": "2015-12-18T23:46:19", "url": "https://files.pythonhosted.org/packages/2c/74/3dd4e32bca64a3039e53a68bca735fc5919f7e6f37793275d692d980ef24/pyramid_notebook-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "0713b2321c1f4eca37ed7dfb893ba64c", "sha256": "7104fd8c32441a058cd60262a0d65ce8b1098d5fc3c5cc8be9b45d612a34a008" }, "downloads": -1, "filename": "pyramid_notebook-0.1.4.tar.gz", "has_sig": false, "md5_digest": "0713b2321c1f4eca37ed7dfb893ba64c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 215458, "upload_time": "2015-12-18T23:53:16", "url": "https://files.pythonhosted.org/packages/2b/a0/ad32534701e63e0e6f8751e8e38e9f4e37e24645de3e45a63e18ea8da278/pyramid_notebook-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "05d2d7cd8c5592e370fe9ab8beb15096", "sha256": "668d2939b61b82ac5acb086df418f9fd1d34321540cd30e307502c45b3dfd0d4" }, "downloads": -1, "filename": "pyramid_notebook-0.1.5.tar.gz", "has_sig": false, "md5_digest": "05d2d7cd8c5592e370fe9ab8beb15096", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 217726, "upload_time": "2016-01-07T14:42:17", "url": "https://files.pythonhosted.org/packages/0e/21/4896973d4e5592c7c672737e4bb67c0a94dbebf1feb1cfea0f0b7f8b8d3c/pyramid_notebook-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "842c2cc6e6d3f31bb647ed980c46f0f5", "sha256": "d4ea6bfa172921883e2b49404823e7295cd082d289f84552c193c31381f239c6" }, "downloads": -1, "filename": "pyramid_notebook-0.1.6.tar.gz", "has_sig": false, "md5_digest": "842c2cc6e6d3f31bb647ed980c46f0f5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 217917, "upload_time": "2016-01-16T14:51:41", "url": "https://files.pythonhosted.org/packages/0d/af/a529ef30197b1de74d91b357b970edc676fac66c68f6fc2f31983043a359/pyramid_notebook-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "f6550cfb3a253c424bbf5b72234aed50", "sha256": "99ef8c2ba2ea57f42fc99949f110be2274de05c88e89058f3de700466a037067" }, "downloads": -1, "filename": "pyramid_notebook-0.1.7.tar.gz", "has_sig": false, "md5_digest": "f6550cfb3a253c424bbf5b72234aed50", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 218570, "upload_time": "2016-01-16T15:08:14", "url": "https://files.pythonhosted.org/packages/d9/b2/a267c12504cfb942e69a0b86c2fc262add6f553654cd7ebb5c9c0d884a63/pyramid_notebook-0.1.7.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "581f9b28dafb1649b72695ba7aeae51c", "sha256": "6a8ba4a719a5edd87ce3b7e741c18e94bc0348023000482672ecdac79423a4d1" }, "downloads": -1, "filename": "pyramid_notebook-0.1.8.tar.gz", "has_sig": false, "md5_digest": "581f9b28dafb1649b72695ba7aeae51c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 218739, "upload_time": "2016-01-31T13:56:36", "url": "https://files.pythonhosted.org/packages/20/81/8403c81caedd9aee0cc0b67b6c497a399f5ca4973f4617a3090d57e0ac82/pyramid_notebook-0.1.8.tar.gz" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "eeeac3a3e01510f4f5ddaff8d80dc7ec", "sha256": "a1e6804627c8937aee0f8a0acd77ab04b92d8a0d1302ac392ca752425dfab6e4" }, "downloads": -1, "filename": "pyramid_notebook-0.1.9.tar.gz", "has_sig": false, "md5_digest": "eeeac3a3e01510f4f5ddaff8d80dc7ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 218994, "upload_time": "2016-01-31T15:36:50", "url": "https://files.pythonhosted.org/packages/5f/90/0be80413fe791864f6099b3703045e4fad3a66f49a8c8ad7042984f5b110/pyramid_notebook-0.1.9.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "653b38e64600d01699c883b50997a890", "sha256": "e3cc808ba83b903cdf21097f832519a34f1d5596d2dfe391bd171ce87a2b9f8e" }, "downloads": -1, "filename": "pyramid_notebook-0.2.tar.gz", "has_sig": false, "md5_digest": "653b38e64600d01699c883b50997a890", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 557258, "upload_time": "2016-12-06T14:47:10", "url": "https://files.pythonhosted.org/packages/98/d5/68651a3750662cbf76acc7e2222a52d0eea416b405d5e7e7d51a1156566e/pyramid_notebook-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "43e0db55bb7519b15c1cf4a0668f9cb3", "sha256": "30c938db006984e973a1e3ee75f010ccfb6d9c9892acb58aec675c923f02566f" }, "downloads": -1, "filename": "pyramid_notebook-0.2.1.tar.gz", "has_sig": false, "md5_digest": "43e0db55bb7519b15c1cf4a0668f9cb3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 557656, "upload_time": "2017-01-29T13:37:09", "url": "https://files.pythonhosted.org/packages/e1/42/a08296ec25134e0f9d0077dad4ec64199ac869e793c987328159505a68b7/pyramid_notebook-0.2.1.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "0c4eda4ab294b6b5a23e49ff648152b0", "sha256": "f21930c9aeb976dd0509bca0f63af7dc8883c0140ac96cc763be66eb298cc358" }, "downloads": -1, "filename": "pyramid_notebook-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0c4eda4ab294b6b5a23e49ff648152b0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5.2", "size": 39880, "upload_time": "2018-10-09T08:35:36", "url": "https://files.pythonhosted.org/packages/df/c7/6e3066885386e8bc93af253b387eef0b3af31cb93b930c0a01dc659fd39a/pyramid_notebook-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c123f8d07da1ecf59286facdcfedd5fe", "sha256": "be496a587d9b37b855fa4bf5adb8021c25b2055ca70c0aea9d713b442a9cc889" }, "downloads": -1, "filename": "pyramid_notebook-0.3.0.tar.gz", "has_sig": false, "md5_digest": "c123f8d07da1ecf59286facdcfedd5fe", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.2", "size": 512595, "upload_time": "2018-10-09T08:35:38", "url": "https://files.pythonhosted.org/packages/2b/80/1d9c55ae3fc138fadaf7dd2b9464080d68a7554ce525c122ef56b4646b10/pyramid_notebook-0.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0c4eda4ab294b6b5a23e49ff648152b0", "sha256": "f21930c9aeb976dd0509bca0f63af7dc8883c0140ac96cc763be66eb298cc358" }, "downloads": -1, "filename": "pyramid_notebook-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0c4eda4ab294b6b5a23e49ff648152b0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5.2", "size": 39880, "upload_time": "2018-10-09T08:35:36", "url": "https://files.pythonhosted.org/packages/df/c7/6e3066885386e8bc93af253b387eef0b3af31cb93b930c0a01dc659fd39a/pyramid_notebook-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c123f8d07da1ecf59286facdcfedd5fe", "sha256": "be496a587d9b37b855fa4bf5adb8021c25b2055ca70c0aea9d713b442a9cc889" }, "downloads": -1, "filename": "pyramid_notebook-0.3.0.tar.gz", "has_sig": false, "md5_digest": "c123f8d07da1ecf59286facdcfedd5fe", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.2", "size": 512595, "upload_time": "2018-10-09T08:35:38", "url": "https://files.pythonhosted.org/packages/2b/80/1d9c55ae3fc138fadaf7dd2b9464080d68a7554ce525c122ef56b4646b10/pyramid_notebook-0.3.0.tar.gz" } ] }