19
.bumpversion.cfg
Normal file
@ -0,0 +1,19 @@
|
||||
[bumpversion]
|
||||
current_version = 7, 0, 0, 'alpha', 0
|
||||
commit = False
|
||||
tag = False
|
||||
parse = (?P<major>\d+)\,\ (?P<minor>\d+)\,\ (?P<patch>\d+)\,\ \'(?P<release>\S+)\'\,\ (?P<build>\d+)
|
||||
serialize =
|
||||
{major}, {minor}, {patch}, '{release}', {build}
|
||||
|
||||
[bumpversion:part:release]
|
||||
optional_value = final
|
||||
values =
|
||||
alpha
|
||||
beta
|
||||
candidate
|
||||
final
|
||||
|
||||
[bumpversion:part:build]
|
||||
|
||||
[bumpversion:file:notebook/_version.py]
|
@ -1,5 +1,22 @@
|
||||
*.min.js
|
||||
*components*
|
||||
*node_modules*
|
||||
*built*
|
||||
*build*
|
||||
lint-staged.config.js
|
||||
.eslintrc.js
|
||||
|
||||
node_modules
|
||||
**/build
|
||||
**/lib
|
||||
**/node_modules
|
||||
**/mock_packages
|
||||
**/static
|
||||
**/typings
|
||||
**/schemas
|
||||
**/themes
|
||||
coverage
|
||||
*.map.js
|
||||
*.bundle.js
|
||||
|
||||
# jetbrains IDE stuff
|
||||
.idea/
|
||||
|
||||
# ms IDE stuff
|
||||
.history/
|
||||
.vscode/
|
||||
|
57
.eslintrc.js
Normal file
@ -0,0 +1,57 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
commonjs: true,
|
||||
node: true,
|
||||
'jest/globals': true
|
||||
},
|
||||
root: true,
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:jest/recommended'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.eslint.json',
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'jest'],
|
||||
rules: {
|
||||
'@typescript-eslint/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: 'interface',
|
||||
format: ['PascalCase'],
|
||||
custom: {
|
||||
regex: '^I[A-Z]',
|
||||
match: true
|
||||
}
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/no-empty-interface': 'off',
|
||||
'@typescript-eslint/quotes': [
|
||||
'error',
|
||||
'single',
|
||||
{ avoidEscape: true, allowTemplateLiterals: false }
|
||||
],
|
||||
'jest/no-done-callback': 'off',
|
||||
curly: ['error', 'all'],
|
||||
eqeqeq: 'error',
|
||||
'prefer-arrow-callback': 'error'
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
}
|
||||
}
|
||||
};
|
@ -1,13 +1,13 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"semi": 1,
|
||||
"no-cond-assign": 2,
|
||||
"no-debugger": 2,
|
||||
"comma-dangle": 0,
|
||||
"no-unreachable" : 2
|
||||
}
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"semi": 1,
|
||||
"no-cond-assign": 2,
|
||||
"no-debugger": 2,
|
||||
"comma-dangle": 0,
|
||||
"no-unreachable": 2
|
||||
}
|
||||
}
|
||||
|
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,13 +1,11 @@
|
||||
---
|
||||
|
||||
name: Is this a bug in Notebook? Open an issue.
|
||||
about: If you're not sure, feel free to post your question on Jupyter's Discourse channel.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
---<!--
|
||||
BEFORE YOU OPEN AN ISSUE, PLEASE READ THIS
|
||||
|
||||
Hello! Thank you for using Jupyter Notebook. We're glad you're here.
|
||||
@ -23,13 +21,14 @@ If you're having issues installing Jupyter Notebook, or you're having another is
|
||||
1. scan the "What to do when things go wrong" (https://jupyter-notebook.readthedocs.io/en/stable/troubleshooting.html#what-to-do-when-things-go-wrong) page in our documentation to see if your question has already been answered
|
||||
|
||||
2. post your question on the Jupyter Notebook discourse channel (https://discourse.jupyter.org/c/notebook/31). There are many more people in the Jupyter community that engage on that channel.
|
||||
-->
|
||||
-->
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
@ -42,9 +41,10 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
44
.github/actions/build-dist/action.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
name: "Build Jupyter Notebook"
|
||||
description: "Build Jupyter Notebook from source"
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Base Setup
|
||||
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade jupyter_packaging~=0.10 "jupyterlab>=4.0.0a20,<5" build
|
||||
|
||||
- name: Build pypi distributions
|
||||
shell: bash
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Build npm distributions
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir pkgs
|
||||
jlpm lerna exec -- npm pack
|
||||
cp packages/*/*.tgz pkgs
|
||||
|
||||
- name: Build checksum file
|
||||
shell: bash
|
||||
run: |
|
||||
cd dist
|
||||
sha256sum * | tee SHA256SUMS
|
||||
cd ../pkgs
|
||||
sha256sum * | tee SHA256SUMS
|
||||
|
||||
- name: Upload distributions
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: notebook-dist-${{ github.run_number }}
|
||||
path: ./dist
|
||||
|
||||
- name: Upload distributions
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: notebook-pkgs-${{ github.run_number }}
|
||||
path: ./pkgs
|
15
.github/workflows/binder.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: Binder Badge
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
binder:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: jupyterlab/maintainer-tools/.github/actions/binder-link@v1
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
url_path: tree
|
110
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents:
|
||||
write
|
||||
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -l {0}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
uses: ./.github/actions/build-dist
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Base Setup
|
||||
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install -U jupyter_packaging~=0.10
|
||||
|
||||
- name: Install the package
|
||||
run: |
|
||||
python -m pip install .
|
||||
jupyter labextension list 2>&1 | grep -ie "@jupyter-notebook/lab-extension.*enabled.*ok" -
|
||||
jupyter server extension list 2>&1 | grep -ie "notebook.*enabled" -
|
||||
python -m jupyterlab.browser_check
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
jlpm
|
||||
jlpm run eslint:check
|
||||
jlpm run prettier:check
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
jlpm run build:test
|
||||
jlpm run test
|
||||
|
||||
install:
|
||||
needs: [build]
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu, macos, windows]
|
||||
python: ['3.7', '3.10']
|
||||
include:
|
||||
- python: '3.7'
|
||||
dist: 'notebook*.tar.gz'
|
||||
- python: '3.10'
|
||||
dist: 'notebook*.whl'
|
||||
- os: windows
|
||||
py_cmd: python
|
||||
- os: macos
|
||||
py_cmd: python3
|
||||
- os: ubuntu
|
||||
py_cmd: python
|
||||
steps:
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
architecture: 'x64'
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: notebook-dist-${{ github.run_number }}
|
||||
path: ./dist
|
||||
- name: Install the prerequisites
|
||||
run: |
|
||||
${{ matrix.py_cmd }} -m pip install pip wheel
|
||||
- name: Install the package
|
||||
run: |
|
||||
cd dist
|
||||
${{ matrix.py_cmd }} -m pip install -vv ${{ matrix.dist }}
|
||||
- name: Validate environment
|
||||
run: |
|
||||
${{ matrix.py_cmd }} -m pip freeze
|
||||
${{ matrix.py_cmd }} -m pip check
|
||||
- name: Validate the install
|
||||
run: |
|
||||
jupyter labextension list
|
||||
jupyter labextension list 2>&1 | grep -ie "@jupyter-notebook/lab-extension.*enabled.*ok" -
|
||||
jupyter server extension list
|
||||
jupyter server extension list 2>&1 | grep -ie "notebook.*enabled" -
|
||||
jupyter notebook --version
|
||||
jupyter notebook --help
|
80
.github/workflows/buildutils.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
name: Build Utilities
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '*'
|
||||
pull_request:
|
||||
branches: '*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -l {0}
|
||||
|
||||
jobs:
|
||||
versioning:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Base Setup
|
||||
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install -U "jupyterlab>=4.0.0a20,<5" jupyter_packaging~=0.10
|
||||
jlpm
|
||||
jlpm run build
|
||||
|
||||
- name: Configure git identity to commit
|
||||
run: |
|
||||
git config --global user.email "you@example.com"
|
||||
git config --global user.name "Your Name"
|
||||
|
||||
- name: Reset version
|
||||
run: |
|
||||
# TODO: improve this with a mock package?
|
||||
# This step is to ensure the workflow always starts with a final version
|
||||
sed -i -E "s/VersionInfo\(.*\)/VersionInfo\(9, 8, 7, 'final', 0\)/" notebook/_version.py
|
||||
sed -i -E "s/current_version = .*/current_version = 9, 8, 7, 'final', 0/" .bumpversion.cfg
|
||||
jlpm run lerna version 9.8.7 --no-push --force-publish --no-git-tag-version --yes
|
||||
git commit -am "Release 9.8.7"
|
||||
|
||||
- name: Patch Release
|
||||
run: |
|
||||
jlpm release:patch --force
|
||||
|
||||
- name: Minor Release
|
||||
run: |
|
||||
jlpm release:bump minor --force
|
||||
|
||||
- name: Release Cycle
|
||||
run: |
|
||||
# beta
|
||||
jlpm release:bump release --force
|
||||
# rc
|
||||
jlpm release:bump release --force
|
||||
# final
|
||||
jlpm release:bump release --force
|
||||
|
||||
- name: Major Release
|
||||
run: |
|
||||
jlpm release:bump major --force
|
||||
|
||||
npm:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.9'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install -U "jupyterlab>=4.0.0a20,<5" jupyter_packaging~=0.10 pip
|
||||
jlpm
|
||||
jlpm run build
|
55
.github/workflows/check-release.yml
vendored
@ -1,9 +1,11 @@
|
||||
name: Check Release
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
branches:
|
||||
- "*"
|
||||
pull_request:
|
||||
branches: ["*"]
|
||||
branches:
|
||||
- "*"
|
||||
|
||||
permissions:
|
||||
contents:
|
||||
@ -12,54 +14,23 @@ permissions:
|
||||
jobs:
|
||||
check_release:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
group: [check_release, link_check]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
architecture: "x64"
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14.x'
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
${{ runner.os }}-pip-
|
||||
- name: Cache checked links
|
||||
if: ${{ matrix.group == 'link_check' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pytest-link-check
|
||||
key: ${{ runner.os }}-linkcheck-${{ hashFiles('**/*.md', '**/*.rst') }}-md-links
|
||||
restore-keys: |
|
||||
${{ runner.os }}-linkcheck-
|
||||
|
||||
- name: Base Setup
|
||||
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
|
||||
|
||||
- name: Upgrade packaging dependencies
|
||||
run: |
|
||||
pip install --upgrade pip setuptools wheel --user
|
||||
pip install --upgrade jupyter-packaging~=0.10 --user
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install -e .
|
||||
pip install .
|
||||
|
||||
- name: Check Release
|
||||
if: ${{ matrix.group == 'check_release' }}
|
||||
env:
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_TOKEN }}
|
||||
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Check Links
|
||||
if: ${{ matrix.group == 'link_check' }}
|
||||
uses: jupyter-server/jupyter_releaser/.github/actions/check-links@v1
|
||||
version_spec: next
|
||||
|
61
.github/workflows/js.yml
vendored
@ -1,61 +0,0 @@
|
||||
name: Linux JS Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '*'
|
||||
pull_request:
|
||||
branches: '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu, macos]
|
||||
group: [notebook, base, services]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-node-modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
${{ runner.os }}-build-
|
||||
${{ runner.os }}-
|
||||
|
||||
- name: Cache pip on Linux
|
||||
uses: actions/cache@v1
|
||||
if: startsWith(runner.os, 'Linux')
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ matrix.python }}-${{ hashFiles('**/requirements.txt', 'setup.py') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-${{ matrix.python }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade setuptools wheel
|
||||
npm install
|
||||
npm install -g casperjs@1.1.3 phantomjs-prebuilt@2.1.7
|
||||
pip install .[test]
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
python -m notebook.jstest ${{ matrix.group }}
|
53
.github/workflows/python-nbconvert.yml
vendored
@ -1,53 +0,0 @@
|
||||
# The NBConvert Service requires pandoc. Instead of testing
|
||||
# Pandoc on every operating system (which should already be
|
||||
# done in nbconvert directly), we'll only test these services
|
||||
# on ubuntu where we can easily load Pandoc from a Github
|
||||
# Actions docker image (this docker image is not on other
|
||||
# operating systems).
|
||||
name: NBConvert Service Tests
|
||||
on:
|
||||
push:
|
||||
branches: '*'
|
||||
pull_request:
|
||||
branches: '*'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Install Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: 'x64'
|
||||
- name: Setup Pandoc
|
||||
uses: r-lib/actions/setup-pandoc@v1
|
||||
- name: Upgrade packaging dependencies
|
||||
run: |
|
||||
pip install --upgrade pip setuptools wheel
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('setup.py') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-${{ matrix.python-version }}-
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install the Python dependencies
|
||||
run: |
|
||||
pip install -e .[test]
|
||||
- name: Run NBConvert Tests
|
||||
run: |
|
||||
pytest notebook/nbconvert/tests/
|
||||
- name: Run NBConvert Service Tests
|
||||
run: |
|
||||
pytest notebook/services/nbconvert/tests/
|
53
.github/workflows/python.yml
vendored
@ -1,53 +0,0 @@
|
||||
name: Python Tests
|
||||
on:
|
||||
push:
|
||||
branches: '*'
|
||||
pull_request:
|
||||
branches: '*'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu, macos, windows]
|
||||
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Install Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: 'x64'
|
||||
- name: Upgrade packaging dependencies
|
||||
run: |
|
||||
pip install --upgrade pip setuptools wheel --user
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('setup.py') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-${{ matrix.python-version }}-
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install the Python dependencies
|
||||
run: |
|
||||
pip install -e .[test] codecov
|
||||
- name: List installed packages
|
||||
run: |
|
||||
pip freeze
|
||||
pip check
|
||||
- name: Run Server-side tests
|
||||
run: |
|
||||
pytest -vv --cov notebook --cov-branch --cov-report term-missing:skip-covered --ignore-glob=notebook/tests/selenium/* --ignore-glob=notebook/nbconvert/tests/* --ignore-glob=notebook/services/nbconvert/tests/*
|
||||
- name: Run Integration Tests
|
||||
run: |
|
||||
pytest -v notebook/tests/test_notebookapp_integration.py --integration_tests
|
||||
- name: Coverage
|
||||
run: |
|
||||
codecov
|
46
.github/workflows/selenium.yml
vendored
@ -1,46 +0,0 @@
|
||||
name: Selenium Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '*'
|
||||
pull_request:
|
||||
branches: '*'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu, macos]
|
||||
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
|
||||
- name: Install JS
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install -U pip setuptools wheel
|
||||
pip install --upgrade selenium
|
||||
pip install pytest
|
||||
pip install .[test]
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
export JUPYTER_TEST_BROWSER=firefox
|
||||
export MOZ_HEADLESS=1
|
||||
pytest -sv notebook/tests/selenium
|
100
.github/workflows/ui-tests.yml
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
name: UI Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
uses: ./.github/actions/build-dist
|
||||
|
||||
ui-tests:
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
browser: [firefox, chromium]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.9'
|
||||
architecture: 'x64'
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: notebook-dist-${{ github.run_number }}
|
||||
path: ./dist
|
||||
|
||||
- name: Install the prerequisites
|
||||
run: |
|
||||
python -m pip install pip wheel
|
||||
|
||||
- name: Install the package
|
||||
run: |
|
||||
cd dist
|
||||
python -m pip install -vv notebook*.whl
|
||||
|
||||
- name: Install the test dependencies
|
||||
run: |
|
||||
cd ui-tests
|
||||
jlpm --frozen-lockfile
|
||||
jlpm playwright install
|
||||
|
||||
- name: Start Jupyter Notebook
|
||||
run: |
|
||||
cd ui-tests
|
||||
jlpm start:detached
|
||||
|
||||
- name: Wait for Jupyter Notebook
|
||||
uses: ifaxity/wait-on-action@v1
|
||||
with:
|
||||
resource: http-get://127.0.0.1:8888/
|
||||
timeout: 360000
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd ui-tests
|
||||
jlpm test --browser ${{ matrix.browser }}
|
||||
|
||||
- name: Upload Playwright Test assets
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: notebook-${{ matrix.browser }}-test-assets
|
||||
path: |
|
||||
ui-tests/test-results
|
||||
|
||||
- name: Upload Playwright Test report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: notebook-${{ matrix.browser }}-test-report
|
||||
path: |
|
||||
ui-tests/playwright-report
|
||||
|
||||
- name: Update snapshots
|
||||
if: failure()
|
||||
run: |
|
||||
cd ui-tests
|
||||
# remove previous snapshots from other browser
|
||||
jlpm rimraf "test/**/*-snapshots/*.png"
|
||||
# generate new snapshots
|
||||
jlpm run test:update --browser ${{ matrix.browser }}
|
||||
|
||||
- name: Upload updated snapshots
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: notebook-${{ matrix.browser }}-updated-snapshots
|
||||
path: ui-tests/test
|
170
.gitignore
vendored
@ -1,58 +1,126 @@
|
||||
MANIFEST
|
||||
build
|
||||
dist
|
||||
_build
|
||||
docs/man/*.gz
|
||||
docs/source/api/generated
|
||||
docs/source/config.rst
|
||||
docs/gh-pages
|
||||
notebook/i18n/*/LC_MESSAGES/*.mo
|
||||
notebook/i18n/*/LC_MESSAGES/nbjs.json
|
||||
notebook/static/components
|
||||
notebook/static/style/*.min.css*
|
||||
notebook/static/*/js/built/
|
||||
notebook/static/*/built/
|
||||
notebook/static/built/
|
||||
notebook/static/*/js/main.min.js*
|
||||
notebook/static/lab/*bundle.js
|
||||
node_modules
|
||||
*.py[co]
|
||||
__pycache__
|
||||
*.egg-info
|
||||
*~
|
||||
*.bak
|
||||
*.bundle.*
|
||||
lib/
|
||||
node_modules/
|
||||
*.egg-info/
|
||||
.ipynb_checkpoints
|
||||
.tox
|
||||
.DS_Store
|
||||
\#*#
|
||||
.#*
|
||||
*.tsbuildinfo
|
||||
|
||||
# Created by https://www.gitignore.io/api/python
|
||||
# Edit at https://www.gitignore.io/?templates=python
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.pytest_cache
|
||||
src
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
*.swp
|
||||
*.map
|
||||
.idea/
|
||||
Read the Docs
|
||||
config.rst
|
||||
*.iml
|
||||
/.project
|
||||
/.pydevproject
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
package-lock.json
|
||||
geckodriver.log
|
||||
*.iml
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# jetbrains IDE stuff
|
||||
*.iml
|
||||
.idea/
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# ms IDE stuff
|
||||
*.code-workspace
|
||||
.history
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# OS X stuff
|
||||
*.DS_Store
|
||||
|
||||
# End of https://www.gitignore.io/api/python
|
||||
|
||||
_temp_extension
|
||||
junit.xml
|
||||
[uU]ntitled*
|
||||
notebook/static/*
|
||||
!notebook/static/favicons
|
||||
notebook/labextension
|
||||
notebook/schemas
|
||||
|
||||
# playwright
|
||||
ui-tests/test-results
|
||||
ui-tests/playwright-report
|
||||
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
# copied changelog
|
||||
docs/source/changelog.md
|
||||
|
||||
.jupyter_releaser_checkout
|
||||
|
149
.mailmap
@ -1,149 +0,0 @@
|
||||
A. J. Holyoake <a.j.holyoake@gmail.com> ajholyoake <a.j.holyoake@gmail.com>
|
||||
Aaron Culich <aculich@gmail.com> Aaron Culich <aculich@eecs.berkeley.edu>
|
||||
Aron Ahmadia <aron@ahmadia.net> ahmadia <aron@ahmadia.net>
|
||||
Benjamin Ragan-Kelley <benjaminrk@gmail.com> <minrk@Mercury.local>
|
||||
Benjamin Ragan-Kelley <benjaminrk@gmail.com> Min RK
|
||||
Benjamin Ragan-Kelley <benjaminrk@gmail.com> MinRK <benjaminrk@gmail.com>
|
||||
Barry Wark <barrywark@gmail.com> Barry Wark <barrywarkatgmaildotcom>
|
||||
Ben Edwards <bedwards@cs.unm.edu> Ben Edwards <bedwards@sausage.(none)>
|
||||
Bradley M. Froehle <brad.froehle@gmail.com> Bradley M. Froehle <bfroehle@math.berkeley.edu>
|
||||
Bradley M. Froehle <brad.froehle@gmail.com> Bradley Froehle <brad.froehle@gmail.com>
|
||||
Brandon Parsons <brandon@parsonstx.com> Brandon Parsons <brandon.parsons@hp.com>
|
||||
Brian E. Granger <ellisonbg@gmail.com> Brian Granger
|
||||
Brian E. Granger <ellisonbg@gmail.com> Brian Granger <>
|
||||
Brian E. Granger <ellisonbg@gmail.com> bgranger <>
|
||||
Brian E. Granger <ellisonbg@gmail.com> bgranger <bgranger@red>
|
||||
Christoph Gohlke <cgohlke@uci.edu> cgohlke <cgohlke@uci.edu>
|
||||
Cyrille Rossant <cyrille.rossant@gmail.com> rossant <rossant@github>
|
||||
Damián Avila <damianavila82@yahoo.com.ar> damianavila <damianavila82@yahoo.com.ar>
|
||||
Damián Avila <damianavila82@yahoo.com.ar> damianavila <damianavila@gmail.com>
|
||||
Damon Allen <damontallen@gmail.com> damontallen <damontallen@gmail.com>
|
||||
Darren Dale <dsdale24@gmail.com> darren.dale <>
|
||||
Darren Dale <dsdale24@gmail.com> Darren Dale <>
|
||||
Dav Clark <davclark@berkeley.edu> Dav Clark <>
|
||||
Dav Clark <davclark@berkeley.edu> Dav Clark <davclark@gmail.com>
|
||||
David Hirschfeld <david.hirschfeld@gazprom-mt.com> dhirschfeld <david.hirschfeld@gazprom-mt.com>
|
||||
David P. Sanders <dpsanders@gmail.com> David P. Sanders <dpsanders@ciencias.unam.mx>
|
||||
David Warde-Farley <wardefar@iro.umontreal.ca> David Warde-Farley <>
|
||||
Doug Blank <dblank@cs.brynmawr.edu> Doug Blank <doug.blank@gmail.com>
|
||||
Eugene Van den Bulke <eugene.van-den-bulke@gmail.com> Eugene Van den Bulke <eugene.vandenbulke@gmail.com>
|
||||
Evan Patterson <epatters@enthought.com> <epatters@EPattersons-MacBook-Pro.local>
|
||||
Evan Patterson <epatters@enthought.com> <epatters@evan-laptop.localdomain>
|
||||
Evan Patterson <epatters@enthought.com> <epatters@caltech.edu>
|
||||
Evan Patterson <epatters@enthought.com> <ejpatters@gmail.com>
|
||||
Evan Patterson <epatters@enthought.com> epatters <ejpatters@gmail.com>
|
||||
Evan Patterson <epatters@enthought.com> epatters <epatters@enthought.com>
|
||||
Ernie French <ernestfrench@gmail.com> Ernie French <ernie@gqpbj.com>
|
||||
Ernie French <ernestfrench@gmail.com> ernie french <ernestfrench@gmail.com>
|
||||
Ernie French <ernestfrench@gmail.com> ernop <ernestfrench@gmail.com>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> <fperez.net@gmail.com>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> Fernando Perez <fernando.perez@berkeley.edu>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> fperez <>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> fptest <>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> fptest1 <>
|
||||
Fernando Perez <Fernando.Perez@berkeley.edu> Fernando Perez <fernando.perez@berkeley.edu>
|
||||
Fernando Perez <fernando.perez@berkeley.edu> Fernando Perez <>
|
||||
Fernando Perez <fernando.perez@berkeley.edu> Fernando Perez <fperez@maqroll>
|
||||
Frank Murphy <fpmurphy@mtu.edu> Frank Murphy <fmurphy@arbor.net>
|
||||
Gabriel Becker <gmbecker@ucdavis.edu> gmbecker <gmbecker@ucdavis.edu>
|
||||
Gael Varoquaux <gael.varoquaux@normalesup.org> gael.varoquaux <>
|
||||
Gael Varoquaux <gael.varoquaux@normalesup.org> gvaroquaux <gvaroquaux@gvaroquaux-desktop>
|
||||
Gael Varoquaux <gael.varoquaux@normalesup.org> Gael Varoquaux <>
|
||||
Ingolf Becker <ingolf.becker@googlemail.com> watercrossing <ingolf.becker@googlemail.com>
|
||||
Jake Vanderplas <jakevdp@gmail.com> Jake Vanderplas <vanderplas@astro.washington.edu>
|
||||
Jakob Gager <jakob.gager@gmail.com> jakobgager <jakob.gager@gmail.com>
|
||||
Jakob Gager <jakob.gager@gmail.com> jakobgager <gager@ilsb.tuwien.ac.at>
|
||||
Jakob Gager <jakob.gager@gmail.com> jakobgager <jakobgager@hotmail.com>
|
||||
Jason Grout <jgrout6@bloomberg.net> <jason.grout@drake.edu>
|
||||
Jason Grout <jgrout6@bloomberg.net> <jason-github@creativetrax.com>
|
||||
Jason Gors <jason.gors.work@gmail.com> jason gors <jason.gors.work@gmail.com>
|
||||
Jason Gors <jason.gors.work@gmail.com> jgors <jason.gors.work@gmail.com>
|
||||
Jens Hedegaard Nielsen <jenshnielsen@gmail.com> Jens Hedegaard Nielsen <jhn@jhn-Znote.(none)>
|
||||
Jens Hedegaard Nielsen <jenshnielsen@gmail.com> Jens H Nielsen <jenshnielsen@gmail.com>
|
||||
Jens Hedegaard Nielsen <jenshnielsen@gmail.com> Jens H. Nielsen <jenshnielsen@gmail.com>
|
||||
Jez Ng <jezreel@gmail.com> Jez Ng <me@jezng.com>
|
||||
Jonathan Frederic <jdfreder@calpoly.edu> Jonathan Frederic <jonathan@LifebookMint.(none)>
|
||||
Jonathan Frederic <jdfreder@calpoly.edu> Jonathan Frederic <jon.freder@gmail.com>
|
||||
Jonathan Frederic <jdfreder@calpoly.edu> Jonathan Frederic <xh3xx.goose@gmail.com>
|
||||
Jonathan Frederic <jdfreder@calpoly.edu> jon <jon.freder@gmail.com>
|
||||
Jonathan Frederic <jdfreder@calpoly.edu> U-Jon-PC\Jon <Jon@Jon-PC.(none)>
|
||||
Jonathan March <jmarch@enthought.com> Jonathan March <JDM@MarchRay.net>
|
||||
Jonathan March <jmarch@enthought.com> jdmarch <JDM@marchRay.net>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> Jörgen Stenarson <jorgen.stenarson@bostream.nu>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> Jorgen Stenarson <jorgen.stenarson@bostream.nu>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> Jorgen Stenarson <>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> jstenar <jorgen.stenarson@bostream.nu>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> jstenar <>
|
||||
Jörgen Stenarson <jorgen.stenarson@kroywen.se> Jörgen Stenarson <jorgen.stenarson@kroywen.se>
|
||||
Juergen Hasch <python@elbonia.de> juhasch <python@elbonia.de>
|
||||
Juergen Hasch <python@elbonia.de> juhasch <hasch@VMBOX.fritz.box>
|
||||
Julia Evans <julia@jvns.ca> Julia Evans <julia@stripe.com>
|
||||
Kester Tong <kestert@google.com> KesterTong <kestert@google.com>
|
||||
Kyle Kelley <rgbkrk@gmail.com> Kyle Kelley <kyle.kelley@rackspace.com>
|
||||
Kyle Kelley <rgbkrk@gmail.com> rgbkrk <rgbkrk@gmail.com>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> <laurent.dufrechou@gmail.com>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> <laurent@Pep>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> laurent dufrechou <>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> laurent.dufrechou <>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> Laurent Dufrechou <>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> laurent.dufrechou@gmail.com <>
|
||||
Laurent Dufréchou <laurent.dufrechou@gmail.com> ldufrechou <ldufrechou@PEP>
|
||||
Lorena Pantano <lorena.pantano@gmail.com> Lorena <lorena.pantano@gmail.com>
|
||||
Luis Pedro Coelho <luis@luispedro.org> Luis Pedro Coelho <lpc@cmu.edu>
|
||||
Marc Molla <marcmolla@gmail.com> marcmolla <marcmolla@gmail.com>
|
||||
Martín Gaitán <gaitan@gmail.com> Martín Gaitán <gaitan@phasety.com>
|
||||
Matthias Bussonnier <bussonniermatthias@gmail.com> Matthias BUSSONNIER <bussonniermatthias@gmail.com>
|
||||
Matthias Bussonnier <bussonniermatthias@gmail.com> Bussonnier Matthias <bussonniermatthias@gmail.com>
|
||||
Matthias Bussonnier <bussonniermatthias@gmail.com> Matthias BUSSONNIER <bussonniermatthias@umr168-curn-1-24x-6561.curie.fr>
|
||||
Matthias Bussonnier <bussonniermatthias@gmail.com> Matthias Bussonnier <carreau@Aspire.(none)>
|
||||
Michael Droettboom <mdboom@gmail.com> Michael Droettboom <mdroe@stsci.edu>
|
||||
Nicholas Bollweg <nick.bollweg@gmail.com> Nicholas Bollweg (Nick) <nick.bollweg@gmail.com>
|
||||
Nicolas Rougier <Nicolas.Rougier@inria.fr> <Nicolas.rougier@inria.fr>
|
||||
Nikolay Koldunov <koldunovn@gmail.com> Nikolay Koldunov <nikolay.koldunov@zmaw.de>
|
||||
Omar Andrés Zapata Mesa <andresete.chaos@gmail.com> Omar Andres Zapata Mesa <andresete.chaos@gmail.com>
|
||||
Omar Andrés Zapata Mesa <andresete.chaos@gmail.com> Omar Andres Zapata Mesa <omazapa@tuxhome>
|
||||
Pankaj Pandey <pankaj86@gmail.com> Pankaj Pandey <pankaj@enthought.com>
|
||||
Pascal Schetelat <pascal.schetelat@gmail.com> pascal-schetelat <pascal.schetelat@gmail.com>
|
||||
Paul Ivanov <pi@berkeley.edu> Paul Ivanov <pivanov314@gmail.com>
|
||||
Pauli Virtanen <pauli.virtanen@iki.fi> Pauli Virtanen <>
|
||||
Pauli Virtanen <pauli.virtanen@iki.fi> Pauli Virtanen <pav@iki.fi>
|
||||
Pierre Gerold <pierre.gerold@laposte.net> Pierre Gerold <gerold@crans.org>
|
||||
Pietro Berkes <pberkes@enthought.com> Pietro Berkes <pietro.berkes@googlemail.com>
|
||||
Piti Ongmongkolkul <piti118@gmail.com> piti118 <piti118@gmail.com>
|
||||
Prabhu Ramachandran <prabhu@enthought.com> Prabhu Ramachandran <>
|
||||
Puneeth Chaganti <punchagan@gmail.com> Puneeth Chaganti <punchagan@muse-amuse.in>
|
||||
Robert Kern <robert.kern@gmail.com> rkern <>
|
||||
Robert Kern <robert.kern@gmail.com> Robert Kern <rkern@enthought.com>
|
||||
Robert Kern <robert.kern@gmail.com> Robert Kern <rkern@Sacrilege.local>
|
||||
Robert Kern <robert.kern@gmail.com> Robert Kern <>
|
||||
Robert Marchman <bo.marchman@gmail.com> Robert Marchman <robert.l.marchman@dartmouth.edu>
|
||||
Satrajit Ghosh <satra@mit.edu> Satrajit Ghosh <satra@ba5.mit.edu>
|
||||
Satrajit Ghosh <satra@mit.edu> Satrajit Ghosh <satrajit.ghosh@gmail.com>
|
||||
Scott Sanderson <scoutoss@gmail.com> Scott Sanderson <ssanderson@quantopian.com>
|
||||
smithj1 <smithj1@LMC-022896.local> smithj1 <smithj1@LMC-022896.swisscom.com>
|
||||
smithj1 <smithj1@LMC-022896.local> smithj1 <smithj1@lmc-022896.local>
|
||||
Steven Johnson <steven.johnson@drake.edu> stevenJohnson <steven.johnson@drake.edu>
|
||||
Steven Silvester <steven.silvester@ieee.org> blink1073 <steven.silvester@ieee.org>
|
||||
S. Weber <s8weber@c4.usr.sh> s8weber <s8weber@c5.usr.sh>
|
||||
Stefan van der Walt <stefan@sun.ac.za> Stefan van der Walt <bzr@mentat.za.net>
|
||||
Silvia Vinyes <silvia.vinyes@gmail.com> Silvia <silvia@silvia-U44SG.(none)>
|
||||
Silvia Vinyes <silvia.vinyes@gmail.com> silviav12 <silvia.vinyes@gmail.com>
|
||||
Sylvain Corlay <scorlay@bloomberg.net> <sylvain.corlay@gmail.com>
|
||||
Sylvain Corlay <scorlay@bloomberg.net> sylvain.corlay <sylvain.corlay@gmail.com>
|
||||
Ted Drain <ted.drain@gmail.com> TD22057 <ted.drain@gmail.com>
|
||||
Théophile Studer <theo.studer@gmail.com> Théophile Studer <studer@users.noreply.github.com>
|
||||
Thomas Kluyver <takowl@gmail.com> Thomas <takowl@gmail.com>
|
||||
Thomas Spura <tomspur@fedoraproject.org> Thomas Spura <thomas.spura@gmail.com>
|
||||
Timo Paulssen <timonator@perpetuum-immobile.de> timo <timonator@perpetuum-immobile.de>
|
||||
vds <vds@VIVIAN> vds2212 <vds2212@VIVIAN>
|
||||
vds <vds@VIVIAN> vds <vds@vivian>
|
||||
Ville M. Vainio <vivainio@gmail.com> <vivainio2@WN-W0941>
|
||||
Ville M. Vainio <vivainio@gmail.com> ville <ville@VILLE-PC>
|
||||
Ville M. Vainio <vivainio@gmail.com> ville <ville@ville-desktop>
|
||||
Ville M. Vainio <vivainio@gmail.com> vivainio <>
|
||||
Ville M. Vainio <vivainio@gmail.com> Ville M. Vainio <vivainio@villev>
|
||||
Ville M. Vainio <vivainio@gmail.com> Ville M. Vainio <vivainio@ville_vmw>
|
||||
Walter Doerwald <walter@livinglogic.de> walter.doerwald <>
|
||||
Walter Doerwald <walter@livinglogic.de> Walter Doerwald <>
|
||||
W. Trevor King <wking@tremily.us> W. Trevor King <wking@drexel.edu>
|
||||
Yoval P. <yoval@gmx.com> y-p <yoval@gmx.com>
|
7
.prettierignore
Normal file
@ -0,0 +1,7 @@
|
||||
node_modules
|
||||
**/node_modules
|
||||
**/lib
|
||||
**/package.json
|
||||
**/static
|
||||
**/labextension
|
||||
build
|
3
.prettierrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"singleQuote": true
|
||||
}
|
340
CHANGELOG.md
@ -203,24 +203,24 @@ Use `pip install pip --upgrade` to upgrade pip. Check pip version with
|
||||
|
||||
### Merged PRs
|
||||
|
||||
* Add square logo and desktop entry files [#6010](https://github.com/jupyter/notebook/pull/6010) ([@befeleme](https://github.com/befeleme))
|
||||
* Modernize Changelog [#6008](https://github.com/jupyter/notebook/pull/6008) ([@afshin](https://github.com/afshin))
|
||||
* Add missing "import inspect" [#5999](https://github.com/jupyter/notebook/pull/5999) ([@mgeier](https://github.com/mgeier))
|
||||
* Add Codecov badge to README [#5989](https://github.com/jupyter/notebook/pull/5989) ([@thomasrockhu](https://github.com/thomasrockhu))
|
||||
* Remove configuration for nosetests from setup.cfg [#5986](https://github.com/jupyter/notebook/pull/5986) ([@frenzymadness](https://github.com/frenzymadness))
|
||||
* Update security.rst [#5978](https://github.com/jupyter/notebook/pull/5978) ([@dlrice](https://github.com/dlrice))
|
||||
* Docs-Translations: Updated Hindi and Chinese Readme.md [#5976](https://github.com/jupyter/notebook/pull/5976) ([@rjn01](https://github.com/rjn01))
|
||||
* Allow /metrics by default if auth is off [#5974](https://github.com/jupyter/notebook/pull/5974) ([@blairdrummond](https://github.com/blairdrummond))
|
||||
* Skip terminal tests on Windows 3.9+ (temporary) [#5968](https://github.com/jupyter/notebook/pull/5968) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* Update GatewayKernelManager to derive from AsyncMappingKernelManager [#5966](https://github.com/jupyter/notebook/pull/5966) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* Drop use of deprecated pyzmq.ioloop [#5965](https://github.com/jupyter/notebook/pull/5965) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* Drop support for Python 3.5 [#5962](https://github.com/jupyter/notebook/pull/5962) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* Allow jupyter_server-based contents managers in notebook [#5957](https://github.com/jupyter/notebook/pull/5957) ([@afshin](https://github.com/afshin))
|
||||
* Russian translation fixes [#5954](https://github.com/jupyter/notebook/pull/5954) ([@insolor](https://github.com/insolor))
|
||||
* Increase culling test idle timeout [#5952](https://github.com/jupyter/notebook/pull/5952) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* Re-enable support for answer_yes flag [#5941](https://github.com/jupyter/notebook/pull/5941) ([@afshin](https://github.com/afshin))
|
||||
* Replace Travis and Appveyor with Github Actions [#5938](https://github.com/jupyter/notebook/pull/5938) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
* DOC: Server extension, extra docs on configuration/authentication. [#5937](https://github.com/jupyter/notebook/pull/5937) ([@Carreau](https://github.com/Carreau))
|
||||
- Add square logo and desktop entry files [#6010](https://github.com/jupyter/notebook/pull/6010) ([@befeleme](https://github.com/befeleme))
|
||||
- Modernize Changelog [#6008](https://github.com/jupyter/notebook/pull/6008) ([@afshin](https://github.com/afshin))
|
||||
- Add missing "import inspect" [#5999](https://github.com/jupyter/notebook/pull/5999) ([@mgeier](https://github.com/mgeier))
|
||||
- Add Codecov badge to README [#5989](https://github.com/jupyter/notebook/pull/5989) ([@thomasrockhu](https://github.com/thomasrockhu))
|
||||
- Remove configuration for nosetests from setup.cfg [#5986](https://github.com/jupyter/notebook/pull/5986) ([@frenzymadness](https://github.com/frenzymadness))
|
||||
- Update security.rst [#5978](https://github.com/jupyter/notebook/pull/5978) ([@dlrice](https://github.com/dlrice))
|
||||
- Docs-Translations: Updated Hindi and Chinese Readme.md [#5976](https://github.com/jupyter/notebook/pull/5976) ([@rjn01](https://github.com/rjn01))
|
||||
- Allow /metrics by default if auth is off [#5974](https://github.com/jupyter/notebook/pull/5974) ([@blairdrummond](https://github.com/blairdrummond))
|
||||
- Skip terminal tests on Windows 3.9+ (temporary) [#5968](https://github.com/jupyter/notebook/pull/5968) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- Update GatewayKernelManager to derive from AsyncMappingKernelManager [#5966](https://github.com/jupyter/notebook/pull/5966) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- Drop use of deprecated pyzmq.ioloop [#5965](https://github.com/jupyter/notebook/pull/5965) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- Drop support for Python 3.5 [#5962](https://github.com/jupyter/notebook/pull/5962) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- Allow jupyter_server-based contents managers in notebook [#5957](https://github.com/jupyter/notebook/pull/5957) ([@afshin](https://github.com/afshin))
|
||||
- Russian translation fixes [#5954](https://github.com/jupyter/notebook/pull/5954) ([@insolor](https://github.com/insolor))
|
||||
- Increase culling test idle timeout [#5952](https://github.com/jupyter/notebook/pull/5952) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- Re-enable support for answer_yes flag [#5941](https://github.com/jupyter/notebook/pull/5941) ([@afshin](https://github.com/afshin))
|
||||
- Replace Travis and Appveyor with Github Actions [#5938](https://github.com/jupyter/notebook/pull/5938) ([@kevin-bates](https://github.com/kevin-bates))
|
||||
- DOC: Server extension, extra docs on configuration/authentication. [#5937](https://github.com/jupyter/notebook/pull/5937) ([@Carreau](https://github.com/Carreau))
|
||||
|
||||
### Contributors to this release
|
||||
|
||||
@ -251,7 +251,7 @@ Thank you to all the contributors:
|
||||
|
||||
## Merged PRs
|
||||
|
||||
- do not require nose for testing ([5826](https://github.com/jupyter/notebook/pull/5826))
|
||||
- do not require nose for testing ([5826](https://github.com/jupyter/notebook/pull/5826))
|
||||
- [docs] Update Chinese and Hindi readme.md ([5823](https://github.com/jupyter/notebook/pull/5823))
|
||||
- Add support for creating terminals via GET ([5813](https://github.com/jupyter/notebook/pull/5813))
|
||||
- Made doc translations in Hindi and Chinese ([5787](https://github.com/jupyter/notebook/pull/5787))
|
||||
@ -521,46 +521,46 @@ it's 1.0 release in preparation for a future transition.
|
||||
- Multiple translation enhancements and bug-fixes.
|
||||
- Remove deprecated ANSI CSS styles.
|
||||
- Native support to forward requests to Jupyter Gateway(s) (Embedded
|
||||
NB2KG).
|
||||
NB2KG).
|
||||
- Use JavaScript to redirect users to notebook homepage.
|
||||
- Enhanced SSL/TLS security by using PROTOCOL_TLS which selects the
|
||||
highest ssl/tls protocol version available that both the client and
|
||||
server support. When PROTOCOL_TLS is not available use
|
||||
PROTOCOL_SSLv23.
|
||||
highest ssl/tls protocol version available that both the client and
|
||||
server support. When PROTOCOL_TLS is not available use
|
||||
PROTOCOL_SSLv23.
|
||||
- Add `?no_track_activity=1` argument to allow API requests. to not be
|
||||
registered as activity (e.g. API calls by external activity
|
||||
monitors).
|
||||
registered as activity (e.g. API calls by external activity
|
||||
monitors).
|
||||
- Kernels shutting down due to an idle timeout is no longer considered
|
||||
an activity-updating event.
|
||||
an activity-updating event.
|
||||
- Further improve compatibility with tornado 6 with improved checks
|
||||
for when websockets are closed.
|
||||
for when websockets are closed.
|
||||
- Launch the browser with a local file which redirects to the server
|
||||
address including the authentication token. This prevents another
|
||||
logged-in user from stealing the token from command line arguments
|
||||
and authenticating to the server. The single-use token previously
|
||||
used to mitigate this has been removed. Thanks to Dr. Owain Kenway
|
||||
for suggesting the local file approach.
|
||||
address including the authentication token. This prevents another
|
||||
logged-in user from stealing the token from command line arguments
|
||||
and authenticating to the server. The single-use token previously
|
||||
used to mitigate this has been removed. Thanks to Dr. Owain Kenway
|
||||
for suggesting the local file approach.
|
||||
- Respect nbconvert entrypoints as sources for exporters
|
||||
- Update to CodeMirror to 5.37, which includes f-string syntax for
|
||||
Python 3.6.
|
||||
Python 3.6.
|
||||
- Update jquery-ui to 1.12
|
||||
- Execute cells by clicking icon in input prompt.
|
||||
- New "Save as" menu option.
|
||||
- When serving on a loopback interface, protect against DNS rebinding
|
||||
by checking the `Host` header from the browser. This check can be
|
||||
disabled if necessary by setting `NotebookApp.allow_remote_access`. (Disabled by default while we work out some Mac issues in
|
||||
[3754](https://github.com/jupyter/notebook/issues/3754)).
|
||||
by checking the `Host` header from the browser. This check can be
|
||||
disabled if necessary by setting `NotebookApp.allow_remote_access`. (Disabled by default while we work out some Mac issues in
|
||||
[3754](https://github.com/jupyter/notebook/issues/3754)).
|
||||
- Add kernel_info_timeout traitlet to enable restarting slow kernels.
|
||||
- Add `custom_display_host` config option to override displayed URL.
|
||||
- Add /metrics endpoint for Prometheus Metrics.
|
||||
- Optimize large file uploads.
|
||||
- Allow access control headers to be overriden in
|
||||
jupyter_notebook_config.py to support greater CORS and proxy
|
||||
configuration flexibility.
|
||||
jupyter_notebook_config.py to support greater CORS and proxy
|
||||
configuration flexibility.
|
||||
- Add support for terminals on windows.
|
||||
- Add a "restart and run all" button to the toolbar.
|
||||
- Frontend/extension-config: allow default json files in a .d
|
||||
directory.
|
||||
directory.
|
||||
- Allow setting token via jupyter_token env.
|
||||
- Cull idle kernels using `--MappingKernelManager.cull_idle_timeout`.
|
||||
- Allow read-only notebooks to be trusted.
|
||||
@ -570,27 +570,27 @@ Security Fixes included in previous minor releases of Jupyter Notebook
|
||||
and also included in version 6.0.
|
||||
|
||||
- Fix Open Redirect vulnerability (CVE-2019-10255) where certain
|
||||
malicious URLs could redirect from the Jupyter login page to a
|
||||
malicious site after a successful login.
|
||||
malicious URLs could redirect from the Jupyter login page to a
|
||||
malicious site after a successful login.
|
||||
- Contains a security fix for a cross-site inclusion (XSSI)
|
||||
vulnerability (CVE-2019--9644), where files at a known URL could be
|
||||
included in a page from an unauthorized website if the user is
|
||||
logged into a Jupyter server. The fix involves setting the
|
||||
`X-Content-Type-Options: nosniff` header, and applying CSRF checks
|
||||
previously on all non-GET API requests to GET requests to API
|
||||
endpoints and the /files/ endpoint.
|
||||
vulnerability (CVE-2019--9644), where files at a known URL could be
|
||||
included in a page from an unauthorized website if the user is
|
||||
logged into a Jupyter server. The fix involves setting the
|
||||
`X-Content-Type-Options: nosniff` header, and applying CSRF checks
|
||||
previously on all non-GET API requests to GET requests to API
|
||||
endpoints and the /files/ endpoint.
|
||||
- Check Host header to more securely protect localhost deployments
|
||||
from DNS rebinding. This is a pre-emptive measure, not fixing a
|
||||
known vulnerability. Use `.NotebookApp.allow_remote_access` and
|
||||
`.NotebookApp.local_hostnames` to configure access.
|
||||
from DNS rebinding. This is a pre-emptive measure, not fixing a
|
||||
known vulnerability. Use `.NotebookApp.allow_remote_access` and
|
||||
`.NotebookApp.local_hostnames` to configure access.
|
||||
- Upgrade bootstrap to 3.4, fixing an XSS vulnerability, which has
|
||||
been assigned
|
||||
[CVE-2018-14041](https://nvd.nist.gov/vuln/detail/CVE-2018-14041).
|
||||
been assigned
|
||||
[CVE-2018-14041](https://nvd.nist.gov/vuln/detail/CVE-2018-14041).
|
||||
- Contains a security fix preventing malicious directory names from
|
||||
being able to execute javascript.
|
||||
being able to execute javascript.
|
||||
- Contains a security fix preventing nbconvert endpoints from
|
||||
executing javascript with access to the server API. CVE request
|
||||
pending.
|
||||
executing javascript with access to the server API. CVE request
|
||||
pending.
|
||||
|
||||
Thanks for all the contributors:
|
||||
|
||||
@ -732,15 +732,15 @@ Thanks for all the contributors:
|
||||
## 5.7.8
|
||||
|
||||
- Fix regression in restarting kernels in 5.7.5. The restart handler
|
||||
would return before restart was completed.
|
||||
would return before restart was completed.
|
||||
- Further improve compatibility with tornado 6 with improved checks
|
||||
for when websockets are closed.
|
||||
for when websockets are closed.
|
||||
- Fix regression in 5.7.6 on Windows where .js files could have the
|
||||
wrong mime-type.
|
||||
wrong mime-type.
|
||||
- Fix Open Redirect vulnerability (CVE-2019-10255) where certain
|
||||
malicious URLs could redirect from the Jupyter login page to a
|
||||
malicious site after a successful login. 5.7.7 contained only a
|
||||
partial fix for this issue.
|
||||
malicious URLs could redirect from the Jupyter login page to a
|
||||
malicious site after a successful login. 5.7.7 contained only a
|
||||
partial fix for this issue.
|
||||
|
||||
## 5.7.6
|
||||
|
||||
@ -761,7 +761,7 @@ demonstrated with other browsers.
|
||||
- Fix compatibility with tornado 6 ([4392](https://github.com/jupyter/notebook/pull/4392), [4449](https://github.com/jupyter/notebook/pull/4449)).
|
||||
- Fix opening integer filedescriptor during startup on Python 2 ([4349](https://github.com/jupyter/notebook/pull/4349))
|
||||
- Fix compatibility with asynchronous
|
||||
[KernelManager.restart_kernel]{.title-ref} methods ([4412](https://github.com/jupyter/notebook/pull/4412))
|
||||
[KernelManager.restart_kernel]{.title-ref} methods ([4412](https://github.com/jupyter/notebook/pull/4412))
|
||||
|
||||
## 5.7.4
|
||||
|
||||
@ -774,14 +774,14 @@ and consequently crashes ([4284](https://github.com/jupyter/notebook/pull/4284))
|
||||
5.7.3 contains one security improvement and one security fix:
|
||||
|
||||
- Launch the browser with a local file which redirects to the server
|
||||
address including the authentication token ([4260](https://github.com/jupyter/notebook/pull/4260)). This prevents another logged-in user from stealing
|
||||
the token from command line arguments and authenticating to the
|
||||
server. The single-use token previously used to mitigate this has
|
||||
been removed. Thanks to Dr. Owain Kenway for suggesting the local
|
||||
file approach.
|
||||
address including the authentication token ([4260](https://github.com/jupyter/notebook/pull/4260)). This prevents another logged-in user from stealing
|
||||
the token from command line arguments and authenticating to the
|
||||
server. The single-use token previously used to mitigate this has
|
||||
been removed. Thanks to Dr. Owain Kenway for suggesting the local
|
||||
file approach.
|
||||
- Upgrade bootstrap to 3.4, fixing an XSS vulnerability, which has
|
||||
been assigned
|
||||
[CVE-2018-14041](https://nvd.nist.gov/vuln/detail/CVE-2018-14041) ([4271](https://github.com/jupyter/notebook/pull/4271)).
|
||||
been assigned
|
||||
[CVE-2018-14041](https://nvd.nist.gov/vuln/detail/CVE-2018-14041) ([4271](https://github.com/jupyter/notebook/pull/4271)).
|
||||
|
||||
## 5.7.2
|
||||
|
||||
@ -798,20 +798,20 @@ executing javascript with access to the server API. CVE request pending.
|
||||
New features:
|
||||
|
||||
- Update to CodeMirror to 5.37, which includes f-string syntax for
|
||||
Python 3.6 ([3816](https://github.com/jupyter/notebook/pull/3816))
|
||||
Python 3.6 ([3816](https://github.com/jupyter/notebook/pull/3816))
|
||||
- Update jquery-ui to 1.12 ([3836](https://github.com/jupyter/notebook/pull/3836))
|
||||
- Check Host header to more securely protect localhost deployments
|
||||
from DNS rebinding. This is a pre-emptive measure, not fixing a
|
||||
known vulnerability ([3766](https://github.com/jupyter/notebook/pull/3766)). Use
|
||||
`.NotebookApp.allow_remote_access` and
|
||||
`.NotebookApp.local_hostnames` to configure access.
|
||||
from DNS rebinding. This is a pre-emptive measure, not fixing a
|
||||
known vulnerability ([3766](https://github.com/jupyter/notebook/pull/3766)). Use
|
||||
`.NotebookApp.allow_remote_access` and
|
||||
`.NotebookApp.local_hostnames` to configure access.
|
||||
- Allow access-control-allow-headers to be overridden ([3886](https://github.com/jupyter/notebook/pull/3886))
|
||||
- Allow configuring max_body_size and max_buffer_size ([3829](https://github.com/jupyter/notebook/pull/3829))
|
||||
- Allow configuring get_secure_cookie keyword-args ([3778](https://github.com/jupyter/notebook/pull/3778))
|
||||
- Respect nbconvert entrypoints as sources for exporters ([3879](https://github.com/jupyter/notebook/pull/3879))
|
||||
- Include translation sources in source distributions ([3925](https://github.com/jupyter/notebook/pull/3925), [3931](https://github.com/jupyter/notebook/pull/3931))
|
||||
- Various improvements to documentation ([3799](https://github.com/jupyter/notebook/pull/3799), [3800](https://github.com/jupyter/notebook/pull/3800),
|
||||
[3806](https://github.com/jupyter/notebook/pull/3806), [3883](https://github.com/jupyter/notebook/pull/3883), [3908](https://github.com/jupyter/notebook/pull/3908))
|
||||
[3806](https://github.com/jupyter/notebook/pull/3806), [3883](https://github.com/jupyter/notebook/pull/3883), [3908](https://github.com/jupyter/notebook/pull/3908))
|
||||
|
||||
Fixing problems:
|
||||
|
||||
@ -819,7 +819,7 @@ Fixing problems:
|
||||
- Fix possible type error when closing activity stream ([3907](https://github.com/jupyter/notebook/pull/3907))
|
||||
- Disable metadata editing for non-editable cells ([3744](https://github.com/jupyter/notebook/pull/3744))
|
||||
- Fix some styling and alignment of prompts caused by regressions in
|
||||
5.6.0.
|
||||
5.6.0.
|
||||
- Enter causing page reload in shortcuts editor ([3871](https://github.com/jupyter/notebook/pull/3871))
|
||||
- Fix uploading to the same file twice ([3712](https://github.com/jupyter/notebook/pull/3712))
|
||||
|
||||
@ -860,9 +860,9 @@ New features:
|
||||
- Execute cells by clicking icon in input prompt ([3535](https://github.com/jupyter/notebook/pull/3535), [3687](https://github.com/jupyter/notebook/pull/3687))
|
||||
- New "Save as" menu option ([3289](https://github.com/jupyter/notebook/pull/3289))
|
||||
- When serving on a loopback interface, protect against DNS rebinding
|
||||
by checking the `Host` header from the browser ([3714](https://github.com/jupyter/notebook/pull/3714)). This check can be
|
||||
disabled if necessary by setting `NotebookApp.allow_remote_access`. (Disabled by default while we work out some Mac issues in
|
||||
[3754](https://github.com/jupyter/notebook/issues/3754)).
|
||||
by checking the `Host` header from the browser ([3714](https://github.com/jupyter/notebook/pull/3714)). This check can be
|
||||
disabled if necessary by setting `NotebookApp.allow_remote_access`. (Disabled by default while we work out some Mac issues in
|
||||
[3754](https://github.com/jupyter/notebook/issues/3754)).
|
||||
- Add kernel_info_timeout traitlet to enable restarting slow kernels ([3665](https://github.com/jupyter/notebook/pull/3665))
|
||||
- Add `custom_display_host` config option to override displayed URL ([3668](https://github.com/jupyter/notebook/pull/3668))
|
||||
- Add /metrics endpoint for Prometheus Metrics ([3490](https://github.com/jupyter/notebook/pull/3490))
|
||||
@ -906,13 +906,13 @@ New features:
|
||||
- Display hostname in the terminal when running remotely ([3356](https://github.com/jupyter/notebook/pull/3356), [3593](https://github.com/jupyter/notebook/pull/3593))
|
||||
- Add slides exportation/download to the menu ([3287](https://github.com/jupyter/notebook/pull/3287))
|
||||
- Add any extra installed nbconvert exporters to the "Download as"
|
||||
menu ([3323](https://github.com/jupyter/notebook/pull/3323))
|
||||
menu ([3323](https://github.com/jupyter/notebook/pull/3323))
|
||||
- Editor: warning when overwriting a file that is modified on disk ([2783](https://github.com/jupyter/notebook/pull/2783))
|
||||
- Display a warning message if cookies are not enabled ([3511](https://github.com/jupyter/notebook/pull/3511))
|
||||
- Basic `__version__` reporting for extensions ([3541](https://github.com/jupyter/notebook/pull/3541))
|
||||
- Add `NotebookApp.terminals_enabled` config option ([3478](https://github.com/jupyter/notebook/pull/3478))
|
||||
- Make buffer time between last modified on disk and last modified on
|
||||
last save configurable ([3273](https://github.com/jupyter/notebook/pull/3273))
|
||||
last save configurable ([3273](https://github.com/jupyter/notebook/pull/3273))
|
||||
- Allow binding custom shortcuts for 'close and halt' ([3314](https://github.com/jupyter/notebook/pull/3314))
|
||||
- Add description for 'Trusted' notification ([3386](https://github.com/jupyter/notebook/pull/3386))
|
||||
- Add `settings['activity_sources']` ([3401](https://github.com/jupyter/notebook/pull/3401))
|
||||
@ -933,7 +933,7 @@ Fixing problems:
|
||||
- Prevent default on pageup/pagedown when completer is active ([3500](https://github.com/jupyter/notebook/pull/3500))
|
||||
- Prevent default event handling on new terminal ([3497](https://github.com/jupyter/notebook/pull/3497))
|
||||
- ConfigManager should not write out default values found in the .d
|
||||
directory ([3485](https://github.com/jupyter/notebook/pull/3485))
|
||||
directory ([3485](https://github.com/jupyter/notebook/pull/3485))
|
||||
- Fix leak of iopub object in activity monitoring ([3424](https://github.com/jupyter/notebook/pull/3424))
|
||||
- Javascript lint in notebooklist.js ([3409](https://github.com/jupyter/notebook/pull/3409))
|
||||
- Some Javascript syntax fixes ([3294](https://github.com/jupyter/notebook/pull/3294))
|
||||
@ -945,10 +945,10 @@ Fixing problems:
|
||||
- API spec improvements, API handler improvements ([3368](https://github.com/jupyter/notebook/pull/3368))
|
||||
- Set notebook to dirty state after change to kernel metadata ([3350](https://github.com/jupyter/notebook/pull/3350))
|
||||
- Use CSP header to treat served files as belonging to a separate
|
||||
origin ([3341](https://github.com/jupyter/notebook/pull/3341))
|
||||
origin ([3341](https://github.com/jupyter/notebook/pull/3341))
|
||||
- Don't install gettext into builtins ([3330](https://github.com/jupyter/notebook/pull/3330))
|
||||
- Add missing `import _` ([3316](https://github.com/jupyter/notebook/pull/3316),
|
||||
[3326](https://github.com/jupyter/notebook/pull/3326))
|
||||
[3326](https://github.com/jupyter/notebook/pull/3326))
|
||||
- Write `notebook.json` file atomically ([3305](https://github.com/jupyter/notebook/pull/3305))
|
||||
- Fix clicking with modifiers, page title updates ([3282](https://github.com/jupyter/notebook/pull/3282))
|
||||
- Upgrade jQuery to version 2.2 ([3428](https://github.com/jupyter/notebook/pull/3428))
|
||||
@ -964,12 +964,12 @@ Documentation:
|
||||
- Add explanation on how to change the type of a cell to Markdown ([3377](https://github.com/jupyter/notebook/pull/3377))
|
||||
- Update docs with confd implementation details ([3520](https://github.com/jupyter/notebook/pull/3520))
|
||||
- Add more information for where `jupyter_notebook_config.py` is
|
||||
located ([3346](https://github.com/jupyter/notebook/pull/3346))
|
||||
located ([3346](https://github.com/jupyter/notebook/pull/3346))
|
||||
- Document options to enable nbextensions in specific sections ([3525](https://github.com/jupyter/notebook/pull/3525))
|
||||
- jQuery attribute selector value MUST be surrounded by quotes ([3527](https://github.com/jupyter/notebook/pull/3527))
|
||||
- Do not execute special notebooks with nbsphinx ([3360](https://github.com/jupyter/notebook/pull/3360))
|
||||
- Other minor fixes in [3288](https://github.com/jupyter/notebook/pull/3288),
|
||||
[3528](https://github.com/jupyter/notebook/pull/3528), [3293](https://github.com/jupyter/notebook/pull/3293), [3367](https://github.com/jupyter/notebook/pull/3367)
|
||||
[3528](https://github.com/jupyter/notebook/pull/3528), [3293](https://github.com/jupyter/notebook/pull/3293), [3367](https://github.com/jupyter/notebook/pull/3367)
|
||||
|
||||
Testing:
|
||||
|
||||
@ -1040,16 +1040,16 @@ it and bringing it to our attention.
|
||||
## 5.4.0
|
||||
|
||||
- Fix creating files and folders after navigating directories in the
|
||||
dashboard ([3264](https://github.com/jupyter/notebook/pull/3264)).
|
||||
dashboard ([3264](https://github.com/jupyter/notebook/pull/3264)).
|
||||
- Enable printing notebooks in colour, removing the CSS that made
|
||||
everything black and white ([3212](https://github.com/jupyter/notebook/pull/3212)).
|
||||
everything black and white ([3212](https://github.com/jupyter/notebook/pull/3212)).
|
||||
- Limit the completion options displayed in the notebook to 1000, to
|
||||
avoid performance issues with very long lists ([3195](https://github.com/jupyter/notebook/pull/3195)).
|
||||
avoid performance issues with very long lists ([3195](https://github.com/jupyter/notebook/pull/3195)).
|
||||
- Accessibility improvements in `tree.html` ([3271](https://github.com/jupyter/notebook/pull/3271)).
|
||||
- Added alt-text to the kernel logo image in the notebook UI ([3228](https://github.com/jupyter/notebook/pull/3228)).
|
||||
- Added a test on Travis CI to flag if symlinks are accidentally
|
||||
introduced in the future. This should prevent the issue that
|
||||
necessitated `release-5.3.1`{.interpreted-text role="ref"} ([3227](https://github.com/jupyter/notebook/pull/3227)).
|
||||
introduced in the future. This should prevent the issue that
|
||||
necessitated `release-5.3.1`{.interpreted-text role="ref"} ([3227](https://github.com/jupyter/notebook/pull/3227)).
|
||||
- Use lowercase letters for random IDs generated in our Javascript ([3264](https://github.com/jupyter/notebook/pull/3264)).
|
||||
- Removed duplicate code setting `TextCell.notebook` ([3256](https://github.com/jupyter/notebook/pull/3256)).
|
||||
|
||||
@ -1082,7 +1082,7 @@ notebook dashboard are moved to the OS trash vs. deleted permanently).
|
||||
- Send files to os trash mechanism on delete ([1968](https://github.com/jupyter/notebook/pull/1968)).
|
||||
- Allow programmatic copy to clipboard ([3088](https://github.com/jupyter/notebook/pull/3088)).
|
||||
- Use DOM History API for navigating between directories in the file
|
||||
browser ([3115](https://github.com/jupyter/notebook/pull/3115)).
|
||||
browser ([3115](https://github.com/jupyter/notebook/pull/3115)).
|
||||
- Add translated files to folder(docs-translations) ([3065](https://github.com/jupyter/notebook/pull/3065)).
|
||||
- Allow non empty dirs to be deleted ([3108](https://github.com/jupyter/notebook/pull/3108)).
|
||||
- Set cookie on base_url ([2959](https://github.com/jupyter/notebook/pull/2959)).
|
||||
@ -1091,7 +1091,7 @@ notebook dashboard are moved to the OS trash vs. deleted permanently).
|
||||
- Config option to shut down server after n seconds with no kernels ([2963](https://github.com/jupyter/notebook/pull/2963)).
|
||||
- Display a "close" button on load notebook error ([3176](https://github.com/jupyter/notebook/pull/3176)).
|
||||
- Add action to command pallette to run CodeMirror's "indentAuto"
|
||||
on selection ([3175](https://github.com/jupyter/notebook/pull/3175)).
|
||||
on selection ([3175](https://github.com/jupyter/notebook/pull/3175)).
|
||||
- Add option to specify extra services ([3158](https://github.com/jupyter/notebook/pull/3158)).
|
||||
- Warn_bad_name should not use global name ([3160](https://github.com/jupyter/notebook/pull/3160)).
|
||||
- Avoid overflow of hidden form ([3148](https://github.com/jupyter/notebook/pull/3148)).
|
||||
@ -1099,11 +1099,11 @@ notebook dashboard are moved to the OS trash vs. deleted permanently).
|
||||
- Find available kernelspecs more efficiently ([3136](https://github.com/jupyter/notebook/pull/3136)).
|
||||
- Don't try to translate missing help strings ([3122](https://github.com/jupyter/notebook/pull/3122)).
|
||||
- Frontend/extension-config: allow default json files in a .d
|
||||
directory ([3116](https://github.com/jupyter/notebook/pull/3116)).
|
||||
directory ([3116](https://github.com/jupyter/notebook/pull/3116)).
|
||||
- Use [requirejs]{.title-ref} vs. [require]{.title-ref} ([3097](https://github.com/jupyter/notebook/pull/3097)).
|
||||
- Fixes some ui bugs in firefox \#3044 ([3058](https://github.com/jupyter/notebook/pull/3058)).
|
||||
- Compare non-specific language code when choosing to use arabic
|
||||
numerals ([3055](https://github.com/jupyter/notebook/pull/3055)).
|
||||
numerals ([3055](https://github.com/jupyter/notebook/pull/3055)).
|
||||
- Fix save-script deprecation ([3053](https://github.com/jupyter/notebook/pull/3053)).
|
||||
- Include moment locales in package_data ([3051](https://github.com/jupyter/notebook/pull/3051)).
|
||||
- Fix moment locale loading in bidi support ([3048](https://github.com/jupyter/notebook/pull/3048)).
|
||||
@ -1194,7 +1194,7 @@ involved in this release.
|
||||
- Avoid base64-literals in image tests ([2851](https://github.com/jupyter/notebook/pull/2851)).
|
||||
- Upgrade xterm.js to 2.9.2 ([2849](https://github.com/jupyter/notebook/pull/2849)).
|
||||
- Changed all python variables named file to file_name to not override
|
||||
built_in file ([2830](https://github.com/jupyter/notebook/pull/2830)).
|
||||
built_in file ([2830](https://github.com/jupyter/notebook/pull/2830)).
|
||||
- Add more doc tests ([2823](https://github.com/jupyter/notebook/pull/2823)).
|
||||
- Typos fix ([2815](https://github.com/jupyter/notebook/pull/2815)).
|
||||
- Rename and update license \[ci skip\] ([2810](https://github.com/jupyter/notebook/pull/2810)).
|
||||
@ -1203,7 +1203,7 @@ involved in this release.
|
||||
- Factor out output_prompt_function, as is done with input prompt ([2774](https://github.com/jupyter/notebook/pull/2774)).
|
||||
- Use rfc5987 encoding for filenames ([2767](https://github.com/jupyter/notebook/pull/2767)).
|
||||
- Added path to the resources metadata, the same as in
|
||||
from_filename(...) in nbconvert.exporters.py ([2753](https://github.com/jupyter/notebook/pull/2753)).
|
||||
from_filename(...) in nbconvert.exporters.py ([2753](https://github.com/jupyter/notebook/pull/2753)).
|
||||
- Make "extrakeys" consistent for notebook and editor ([2745](https://github.com/jupyter/notebook/pull/2745)).
|
||||
- Bidi support ([2357](https://github.com/jupyter/notebook/pull/2357)).
|
||||
|
||||
@ -1233,7 +1233,7 @@ involved in this release.
|
||||
- Stop notebook server from command line ([2388](https://github.com/jupyter/notebook/pull/2388)).
|
||||
- Improve "View" and "Edit" file handling in dashboard ([2449](https://github.com/jupyter/notebook/pull/2449)) and ([2402](https://github.com/jupyter/notebook/pull/2402)).
|
||||
- Provide a promise to replace use of the
|
||||
`app_initialized.NotebookApp` event ([2710](https://github.com/jupyter/notebook/pull/2710)).
|
||||
`app_initialized.NotebookApp` event ([2710](https://github.com/jupyter/notebook/pull/2710)).
|
||||
- Fix disabled collapse/expand output button ([2681](https://github.com/jupyter/notebook/pull/2681)).
|
||||
- Cull idle kernels using `--MappingKernelManager.cull_idle_timeout` ([2215](https://github.com/jupyter/notebook/pull/2215)).
|
||||
- Allow read-only notebooks to be trusted ([2718](https://github.com/jupyter/notebook/pull/2718)).
|
||||
@ -1264,7 +1264,7 @@ Files in the dashboard may now be sorted by last modified date or name
|
||||
|
||||
### Cell tags
|
||||
|
||||
There is a new cell toolbar for adding *cell tags*
|
||||
There is a new cell toolbar for adding _cell tags_
|
||||
([2048](https://github.com/jupyter/notebook/pull/2048)):
|
||||
|
||||

|
||||
@ -1293,7 +1293,7 @@ After:
|
||||
|
||||
### Customise keyboard shortcuts
|
||||
|
||||
You can now edit keyboard shortcuts for *Command Mode* within the UI
|
||||
You can now edit keyboard shortcuts for _Command Mode_ within the UI
|
||||
([1347](https://github.com/jupyter/notebook/pull/1347)):
|
||||
|
||||

|
||||
@ -1304,41 +1304,41 @@ instructions.
|
||||
### Other additions
|
||||
|
||||
- You can copy and paste cells between notebooks, using
|
||||
`Ctrl-C`{.interpreted-text role="kbd"} and
|
||||
`Ctrl-V`{.interpreted-text role="kbd"} (`Cmd-C`{.interpreted-text
|
||||
role="kbd"} and `Cmd-V`{.interpreted-text role="kbd"} on Mac).
|
||||
`Ctrl-C`{.interpreted-text role="kbd"} and
|
||||
`Ctrl-V`{.interpreted-text role="kbd"} (`Cmd-C`{.interpreted-text
|
||||
role="kbd"} and `Cmd-V`{.interpreted-text role="kbd"} on Mac).
|
||||
- It's easier to configure a password for the notebook with the new
|
||||
`jupyter notebook password` command ([2007](https://github.com/jupyter/notebook/pull/2007)).
|
||||
- The file list can now be ordered by *last modified* or by *name* ([943](https://github.com/jupyter/notebook/pull/943)).
|
||||
`jupyter notebook password` command ([2007](https://github.com/jupyter/notebook/pull/2007)).
|
||||
- The file list can now be ordered by _last modified_ or by _name_ ([943](https://github.com/jupyter/notebook/pull/943)).
|
||||
- Markdown cells now support attachments. Simply drag and drop an
|
||||
image from your desktop to a markdown cell to add it. Unlike
|
||||
relative links that you enter manually, attachments are embedded in
|
||||
the notebook itself. An unreferenced attachment will be
|
||||
automatically scrubbed from the notebook on save ([621](https://github.com/jupyter/notebook/pull/621)).
|
||||
image from your desktop to a markdown cell to add it. Unlike
|
||||
relative links that you enter manually, attachments are embedded in
|
||||
the notebook itself. An unreferenced attachment will be
|
||||
automatically scrubbed from the notebook on save ([621](https://github.com/jupyter/notebook/pull/621)).
|
||||
- Undoing cell deletion now supports undeleting multiple cells. Cells
|
||||
may not be in the same order as before their deletion, depending on
|
||||
the actions you did on the meantime, but this should should help
|
||||
reduce the impact of accidentally deleting code.
|
||||
- The file browser now has *Edit* and *View* buttons.
|
||||
may not be in the same order as before their deletion, depending on
|
||||
the actions you did on the meantime, but this should should help
|
||||
reduce the impact of accidentally deleting code.
|
||||
- The file browser now has _Edit_ and _View_ buttons.
|
||||
- The file browser now supports moving multiple files at once ([1088](https://github.com/jupyter/notebook/pull/1088)).
|
||||
- The Notebook will refuse to run as root unless the `--allow-root`
|
||||
flag is given ([1115](https://github.com/jupyter/notebook/pull/1115)).
|
||||
flag is given ([1115](https://github.com/jupyter/notebook/pull/1115)).
|
||||
- Keyboard shortcuts are now declarative ([1234](https://github.com/jupyter/notebook/pull/1234)).
|
||||
- Toggling line numbers can now affect all cells ([1312](https://github.com/jupyter/notebook/pull/1312)).
|
||||
- Add more visible *Trusted* and *Untrusted* notifications ([1658](https://github.com/jupyter/notebook/pull/1658)).
|
||||
- Add more visible _Trusted_ and _Untrusted_ notifications ([1658](https://github.com/jupyter/notebook/pull/1658)).
|
||||
- The favicon (browser shortcut icon) now changes to indicate when the
|
||||
kernel is busy ([1837](https://github.com/jupyter/notebook/pull/1837)).
|
||||
kernel is busy ([1837](https://github.com/jupyter/notebook/pull/1837)).
|
||||
- Header and toolbar visibility is now persisted in nbconfig and
|
||||
across sessions ([1769](https://github.com/jupyter/notebook/pull/1769)).
|
||||
across sessions ([1769](https://github.com/jupyter/notebook/pull/1769)).
|
||||
- Load server extensions with ConfigManager so that merge happens
|
||||
recursively, unlike normal config values, to make it load more
|
||||
consistently with frontend extensions([2108](https://github.com/jupyter/notebook/pull/2108)).
|
||||
recursively, unlike normal config values, to make it load more
|
||||
consistently with frontend extensions([2108](https://github.com/jupyter/notebook/pull/2108)).
|
||||
- The notebook server now supports the [bundler
|
||||
API](https://jupyter-notebook.readthedocs.io/en/latest/extending/bundler_extensions.html)
|
||||
from the [jupyter_cms incubator
|
||||
project](https://github.com/jupyter-incubator/contentmanagement) ([1579](https://github.com/jupyter/notebook/pull/1579)).
|
||||
API](https://jupyter-notebook.readthedocs.io/en/latest/extending/bundler_extensions.html)
|
||||
from the [jupyter_cms incubator
|
||||
project](https://github.com/jupyter-incubator/contentmanagement) ([1579](https://github.com/jupyter/notebook/pull/1579)).
|
||||
- The notebook server now provides information about kernel activity
|
||||
in its kernel resource API ([1827](https://github.com/jupyter/notebook/pull/1827)).
|
||||
in its kernel resource API ([1827](https://github.com/jupyter/notebook/pull/1827)).
|
||||
|
||||
Remember that upgrading `notebook` only affects the user interface.
|
||||
Upgrading kernels and libraries may also provide new features, better
|
||||
@ -1347,10 +1347,10 @@ stability and integration with the notebook interface.
|
||||
## 4.4.0
|
||||
|
||||
- Allow override of output callbacks to redirect output messages. This
|
||||
is used to implement the ipywidgets Output widget, for example.
|
||||
is used to implement the ipywidgets Output widget, for example.
|
||||
- Fix an async bug in message handling by allowing comm message
|
||||
handlers to return a promise which halts message processing until
|
||||
the promise resolves.
|
||||
handlers to return a promise which halts message processing until
|
||||
the promise resolves.
|
||||
|
||||
See the 4.4 milestone on GitHub for a complete list of
|
||||
[issues](https://github.com/jupyter/notebook/issues?utf8=%E2%9C%93&q=is%3Aissue%20milestone%3A4.4)
|
||||
@ -1364,10 +1364,10 @@ involved in this release.
|
||||
handling of the "editable" cell metadata field.
|
||||
|
||||
- Monkey-patch for CodeMirror that resolves
|
||||
[\#2037](https://github.com/jupyter/notebook/issues/2037) without
|
||||
breaking [\#1967](https://github.com/jupyter/notebook/issues/1967)
|
||||
[\#2037](https://github.com/jupyter/notebook/issues/2037) without
|
||||
breaking [\#1967](https://github.com/jupyter/notebook/issues/1967)
|
||||
- Read-only (`"editable": false`) cells can be executed but cannot be
|
||||
split, merged, or deleted
|
||||
split, merged, or deleted
|
||||
|
||||
See the 4.3.2 milestone on GitHub for a complete list of
|
||||
[issues](https://github.com/jupyter/notebook/issues?utf8=%E2%9C%93&q=is%3Aissue%20milestone%3A4.3.2)
|
||||
@ -1383,9 +1383,9 @@ improvements to the newly-released token authentication.
|
||||
**Security fix**:
|
||||
|
||||
- CVE-2016-9971. Fix CSRF vulnerability, where malicious forms could
|
||||
create untitled files and start kernels (no remote execution or
|
||||
modification of existing files) for users of certain browsers (Firefox, Internet Explorer / Edge). All previous notebook releases
|
||||
are affected.
|
||||
create untitled files and start kernels (no remote execution or
|
||||
modification of existing files) for users of certain browsers (Firefox, Internet Explorer / Edge). All previous notebook releases
|
||||
are affected.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
@ -1420,12 +1420,12 @@ you can paste into your browser.
|
||||
Highlights:
|
||||
|
||||
- API for creating mime-type based renderer extensions using
|
||||
`OutputArea.register_mime_type` and `Notebook.render_cell_output`
|
||||
methods. See
|
||||
[mimerender-cookiecutter](https://github.com/jupyterlab/mimerender-cookiecutter)
|
||||
for reference implementations and cookiecutter.
|
||||
`OutputArea.register_mime_type` and `Notebook.render_cell_output`
|
||||
methods. See
|
||||
[mimerender-cookiecutter](https://github.com/jupyterlab/mimerender-cookiecutter)
|
||||
for reference implementations and cookiecutter.
|
||||
- Enable token authentication by default. See
|
||||
`server_security`{.interpreted-text role="ref"} for more details.
|
||||
`server_security`{.interpreted-text role="ref"} for more details.
|
||||
- Update security docs to reflect new signature system
|
||||
- Switched from term.js to xterm.js
|
||||
|
||||
@ -1477,7 +1477,7 @@ involved in this release.
|
||||
> Highlights:
|
||||
|
||||
- Fix regression in 4.2.2 that delayed loading custom.js until after
|
||||
`notebook_loaded` and `app_initialized` events have fired.
|
||||
`notebook_loaded` and `app_initialized` events have fired.
|
||||
- Fix some outdated docs and links.
|
||||
|
||||
## 4.2.2
|
||||
@ -1488,13 +1488,13 @@ All users are strongly encouraged to upgrade to 4.2.2.
|
||||
> Highlights:
|
||||
|
||||
- **Security fix**: CVE-2016-6524, where untrusted latex output could
|
||||
be added to the page in a way that could execute javascript.
|
||||
be added to the page in a way that could execute javascript.
|
||||
- Fix missing POST in OPTIONS responses.
|
||||
- Fix for downloading non-ascii filenames.
|
||||
- Avoid clobbering ssl_options, so that users can specify more
|
||||
detailed SSL configuration.
|
||||
detailed SSL configuration.
|
||||
- Fix inverted load order in nbconfig, so user config has highest
|
||||
priority.
|
||||
priority.
|
||||
- Improved error messages here and there.
|
||||
|
||||
## 4.2.1
|
||||
@ -1515,14 +1515,14 @@ package, as well.
|
||||
Highlighted changes:
|
||||
|
||||
- Upgrade MathJax to 2.6 to fix vertical-bar appearing on some
|
||||
equations.
|
||||
equations.
|
||||
- Restore ability for notebook directory to be root (4.1 regression)
|
||||
- Large outputs are now throttled, reducing the ability of output
|
||||
floods to kill the browser.
|
||||
floods to kill the browser.
|
||||
- Fix the notebook ignoring cell executions while a kernel is starting
|
||||
by queueing the messages.
|
||||
by queueing the messages.
|
||||
- Fix handling of url prefixes (e.g. JupyterHub) in terminal and edit
|
||||
pages.
|
||||
pages.
|
||||
- Support nested SVGs in output.
|
||||
|
||||
And various other fixes and improvements.
|
||||
@ -1541,46 +1541,46 @@ Bug fixes:
|
||||
|
||||
UI changes:
|
||||
|
||||
- Moved the cell toolbar selector into the *View* menu. Added a button
|
||||
that triggers a "hint" animation to the main toolbar so users can
|
||||
find the new location. (Click here to see a
|
||||
[screencast](https://cloud.githubusercontent.com/assets/335567/10711889/59665a5a-7a3e-11e5-970f-86b89592880c.gif)
|
||||
)
|
||||
- Moved the cell toolbar selector into the _View_ menu. Added a button
|
||||
that triggers a "hint" animation to the main toolbar so users can
|
||||
find the new location. (Click here to see a
|
||||
[screencast](https://cloud.githubusercontent.com/assets/335567/10711889/59665a5a-7a3e-11e5-970f-86b89592880c.gif)
|
||||
)
|
||||
|
||||
> 
|
||||
> 
|
||||
|
||||
- Added *Restart & Run All* to the *Kernel* menu. Users can also bind
|
||||
it to a keyboard shortcut on action
|
||||
`restart-kernel-and-run-all-cells`.
|
||||
- Added _Restart & Run All_ to the _Kernel_ menu. Users can also bind
|
||||
it to a keyboard shortcut on action
|
||||
`restart-kernel-and-run-all-cells`.
|
||||
|
||||
- Added multiple-cell selection. Users press `Shift-Up/Down` or
|
||||
`Shift-K/J` to extend selection in command mode. Various actions
|
||||
such as cut/copy/paste, execute, and cell type conversions apply to
|
||||
all selected cells.
|
||||
`Shift-K/J` to extend selection in command mode. Various actions
|
||||
such as cut/copy/paste, execute, and cell type conversions apply to
|
||||
all selected cells.
|
||||
|
||||

|
||||

|
||||
|
||||
- Added a command palette for executing Jupyter actions by name. Users
|
||||
press `Cmd/Ctrl-Shift-P` or click the new command palette icon on
|
||||
the toolbar.
|
||||
press `Cmd/Ctrl-Shift-P` or click the new command palette icon on
|
||||
the toolbar.
|
||||
|
||||

|
||||

|
||||
|
||||
- Added a *Find and Replace* dialog to the *Edit* menu. Users can also
|
||||
press `F` in command mode to show the dialog.
|
||||
- Added a _Find and Replace_ dialog to the _Edit_ menu. Users can also
|
||||
press `F` in command mode to show the dialog.
|
||||
|
||||

|
||||

|
||||
|
||||
Other improvements:
|
||||
|
||||
- Custom KernelManager methods can be Tornado coroutines, allowing
|
||||
async operations.
|
||||
async operations.
|
||||
- Make clearing output optional when rewriting input with
|
||||
`set_next_input(replace=True)`.
|
||||
`set_next_input(replace=True)`.
|
||||
- Added support for TLS client authentication via
|
||||
`--NotebookApp.client-ca`.
|
||||
`--NotebookApp.client-ca`.
|
||||
- Added tags to `jupyter/notebook` releases on DockerHub. `latest`
|
||||
continues to track the master branch.
|
||||
continues to track the master branch.
|
||||
|
||||
See the 4.1 milestone on GitHub for a complete list of
|
||||
[issues](https://github.com/jupyter/notebook/issues?page=3&q=milestone%3A4.1+is%3Aclosed+is%3Aissue&utf8=%E2%9C%93)
|
||||
@ -1601,9 +1601,9 @@ handled.
|
||||
Security fixes for maliciously crafted files.
|
||||
|
||||
- [CVE-2015-6938](http://www.openwall.com/lists/oss-security/2015/09/02/3):
|
||||
malicious filenames
|
||||
malicious filenames
|
||||
- [CVE-2015-7337](http://www.openwall.com/lists/oss-security/2015/09/16/3):
|
||||
malicious binary files in text editor.
|
||||
malicious binary files in text editor.
|
||||
|
||||
Thanks to Jonathan Kamens at Quantopian and Juan Broullón for the
|
||||
reports.
|
||||
|
95
CONTRIBUTING.md
Normal file
@ -0,0 +1,95 @@
|
||||
# Contributing to Jupyter Notebook
|
||||
|
||||
Thanks for contributing to Jupyter Notebook!
|
||||
|
||||
Make sure to follow [Project Jupyter's Code of Conduct](https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md)
|
||||
for a friendly and welcoming collaborative environment.
|
||||
|
||||
## Setting up a development environment
|
||||
|
||||
Note: You will need NodeJS to build the extension package.
|
||||
|
||||
The `jlpm` command is JupyterLab's pinned version of [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
|
||||
`yarn` or `npm` in lieu of `jlpm` below.
|
||||
|
||||
**Note**: we recomment using `mamba` to speed the creating of the environment.
|
||||
|
||||
```bash
|
||||
# create a new environment
|
||||
mamba create -n notebook -c conda-forge python nodejs -y
|
||||
|
||||
# activate the environment
|
||||
mamba activate notebook
|
||||
|
||||
# Install package in development mode
|
||||
pip install -e .
|
||||
|
||||
# Link the notebook extension and @jupyter-notebook schemas
|
||||
jlpm develop
|
||||
|
||||
# Enable the server extension
|
||||
jupyter server extension enable notebook
|
||||
```
|
||||
|
||||
`notebook` follows a monorepo structure. To build all the packages at once:
|
||||
|
||||
```bash
|
||||
jlpm build
|
||||
```
|
||||
|
||||
There is also a `watch` script to watch for changes and rebuild the app automatically:
|
||||
|
||||
```bash
|
||||
jlpm watch
|
||||
```
|
||||
|
||||
To make sure the `notebook` server extension is installed:
|
||||
|
||||
```bash
|
||||
$ jupyter server extension list
|
||||
Config dir: /home/username/.jupyter
|
||||
|
||||
Config dir: /home/username/miniforge3/envs/notebook/etc/jupyter
|
||||
jupyterlab enabled
|
||||
- Validating jupyterlab...
|
||||
jupyterlab 3.0.0 OK
|
||||
notebook enabled
|
||||
- Validating notebook...
|
||||
notebook 7.0.0a0 OK
|
||||
|
||||
Config dir: /usr/local/etc/jupyter
|
||||
```
|
||||
|
||||
Then start Jupyter Notebook with:
|
||||
|
||||
```bash
|
||||
jupyter notebook
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run the tests:
|
||||
|
||||
```bash
|
||||
jlpm run build:test
|
||||
jlpm run test
|
||||
```
|
||||
|
||||
There are also end to end tests to cover higher level user interactions, located in the [`ui-tests`](./ui-tests) folder. To run these tests:
|
||||
|
||||
```bash
|
||||
cd ui-tests
|
||||
# start a new Jupyter server in a terminal
|
||||
jlpm start
|
||||
|
||||
# in a new terminal, run the tests
|
||||
jlpm test
|
||||
```
|
||||
|
||||
The `test` script calls the Playwright test runner. You can pass additional arguments to `playwright` by appending parameters to the command. For example to run the test in headed mode, `jlpm test --headed`.
|
||||
|
||||
Checkout the [Playwright Command Line Reference](https://playwright.dev/docs/test-cli/) for more information about the available command line options.
|
||||
|
||||
Running the end to end tests in headful mode will trigger something like the following:
|
||||
|
||||

|
197
CONTRIBUTING.rst
@ -1,197 +0,0 @@
|
||||
Contributing to the Jupyter Notebook
|
||||
====================================
|
||||
|
||||
If you're reading this section, you're probably interested in contributing to
|
||||
Jupyter. Welcome and thanks for your interest in contributing!
|
||||
|
||||
Please take a look at the Contributor documentation, familiarize yourself with
|
||||
using the Jupyter Notebook, and introduce yourself on the mailing list and
|
||||
share what area of the project you are interested in working on.
|
||||
|
||||
General Guidelines
|
||||
------------------
|
||||
|
||||
For general documentation about contributing to Jupyter projects, see the
|
||||
`Project Jupyter Contributor Documentation`__.
|
||||
|
||||
__ https://jupyter.readthedocs.io/en/latest/contributing/content-contributor.html
|
||||
|
||||
|
||||
Setting Up a Development Environment
|
||||
------------------------------------
|
||||
|
||||
Installing Node.js and npm
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Building the Notebook from its GitHub source code requires some tools to
|
||||
create and minify JavaScript components and the CSS,
|
||||
specifically Node.js and Node's package manager, ``npm``.
|
||||
It should be node version ≥ 6.0.
|
||||
|
||||
If you use ``conda``, you can get them with::
|
||||
|
||||
conda install -c conda-forge nodejs
|
||||
|
||||
If you use `Homebrew <https://brew.sh/>`_ on Mac OS X::
|
||||
|
||||
brew install node
|
||||
|
||||
Installation on Linux may vary, but be aware that the `nodejs` or `npm` packages
|
||||
included in the system package repository may be too old to work properly.
|
||||
|
||||
You can also use the installer from the `Node.js website <https://nodejs.org>`_.
|
||||
|
||||
|
||||
Installing the Jupyter Notebook
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once you have installed the dependencies mentioned above, use the following
|
||||
steps::
|
||||
|
||||
pip install --upgrade setuptools pip
|
||||
git clone https://github.com/jupyter/notebook
|
||||
cd notebook
|
||||
pip install -e .
|
||||
|
||||
If you are using a system-wide Python installation and you only want to install the notebook for you,
|
||||
you can add ``--user`` to the install commands.
|
||||
|
||||
Once you have done this, you can launch the master branch of Jupyter notebook
|
||||
from any directory in your system with::
|
||||
|
||||
jupyter notebook
|
||||
|
||||
Verification
|
||||
^^^^^^^^^^^^
|
||||
|
||||
While running the notebook, select one of your notebook files (the file will have the extension ``.ipynb``).
|
||||
In the top tab you will click on "Help" and then click on "About". In the pop window you will see information about the version of Jupyter that you are running. You will see "The version of the notebook server is:".
|
||||
If you are working in development mode, you will see that your version of Jupyter notebook will include the word "dev". If it does not include the word "dev", you are currently not working in development mode and should follow the steps below to uninstall and reinstall Jupyter.
|
||||
|
||||
Troubleshooting the Installation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you do not see that your Jupyter Notebook is not running on dev mode, it's possible that you are
|
||||
running other instances of Jupyter Notebook. You can try the following steps:
|
||||
|
||||
1. Uninstall all instances of the notebook package. These include any installations you made using
|
||||
pip or conda.
|
||||
2. Run ``python3 -m pip install -e .`` in the notebook repository to install the notebook from there.
|
||||
3. Run ``npm run build`` to make sure the Javascript and CSS are updated and compiled.
|
||||
4. Launch with ``python3 -m notebook --port 8989``, and check that the browser is pointing to ``localhost:8989``
|
||||
(rather than the default 8888). You don't necessarily have to launch with port 8989, as long as you use
|
||||
a port that is neither the default nor in use, then it should be fine.
|
||||
5. Verify the installation with the steps in the previous section.
|
||||
|
||||
|
||||
Rebuilding JavaScript and CSS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is a build step for the JavaScript and CSS in the notebook.
|
||||
To make sure that you are working with up-to-date code, you will need to run
|
||||
this command whenever there are changes to JavaScript or LESS sources::
|
||||
|
||||
npm run build
|
||||
|
||||
**IMPORTANT:** Don't forget to run ``npm run build`` after switching branches.
|
||||
When switching between branches of different versions (e.g. ``4.x`` and
|
||||
``master``), run ``pip install -e .``. If you have tried the above and still
|
||||
find that the notebook is not reflecting the current source code, try cleaning
|
||||
the repo with ``git clean -xfd`` and reinstalling with ``pip install -e .``.
|
||||
|
||||
Development Tip
|
||||
"""""""""""""""
|
||||
|
||||
When doing development, you can use this command to automatically rebuild
|
||||
JavaScript and LESS sources as they are modified::
|
||||
|
||||
npm run build:watch
|
||||
|
||||
Git Hooks
|
||||
"""""""""
|
||||
|
||||
If you want to automatically update dependencies and recompile JavaScript and
|
||||
CSS after checking out a new commit, you can install post-checkout and
|
||||
post-merge hooks which will do it for you::
|
||||
|
||||
git-hooks/install-hooks.sh
|
||||
|
||||
See ``git-hooks/README.md`` for more details.
|
||||
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
Python Tests
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Install dependencies::
|
||||
|
||||
pip install -e '.[test]'
|
||||
|
||||
To run the Python tests, use::
|
||||
|
||||
pytest
|
||||
|
||||
If you want coverage statistics as well, you can run::
|
||||
|
||||
py.test --cov notebook -v --pyargs notebook
|
||||
|
||||
JavaScript Tests
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
To run the JavaScript tests, you will need to have PhantomJS and CasperJS
|
||||
installed::
|
||||
|
||||
npm install -g casperjs phantomjs-prebuilt
|
||||
|
||||
Then, to run the JavaScript tests::
|
||||
|
||||
python -m notebook.jstest [group]
|
||||
|
||||
where ``[group]`` is an optional argument that is a path relative to
|
||||
``notebook/tests/``.
|
||||
For example, to run all tests in ``notebook/tests/notebook``::
|
||||
|
||||
python -m notebook.jstest notebook
|
||||
|
||||
or to run just ``notebook/tests/notebook/deletecell.js``::
|
||||
|
||||
python -m notebook.jstest notebook/deletecell.js
|
||||
|
||||
|
||||
Building the Documentation
|
||||
--------------------------
|
||||
|
||||
To build the documentation you'll need `Sphinx <http://www.sphinx-doc.org/>`_,
|
||||
`pandoc <http://pandoc.org/>`_ and a few other packages.
|
||||
|
||||
To install (and activate) a conda environment named ``notebook_docs``
|
||||
containing all the necessary packages (except pandoc), use::
|
||||
|
||||
conda create -n notebook_docs pip
|
||||
conda activate notebook_docs # Linux and OS X
|
||||
activate notebook_docs # Windows
|
||||
pip install .[docs]
|
||||
|
||||
If you want to install the necessary packages with ``pip``, use the following instead::
|
||||
|
||||
pip install .[docs]
|
||||
|
||||
Once you have installed the required packages, you can build the docs with::
|
||||
|
||||
cd docs
|
||||
make html
|
||||
|
||||
After that, the generated HTML files will be available at
|
||||
``build/html/index.html``. You may view the docs in your browser.
|
||||
|
||||
You can automatically check if all hyperlinks are still valid::
|
||||
|
||||
make linkcheck
|
||||
|
||||
Windows users can find ``make.bat`` in the ``docs`` folder.
|
||||
|
||||
You should also have a look at the `Project Jupyter Documentation Guide`__.
|
||||
|
||||
__ https://jupyter.readthedocs.io/en/latest/contributing/docs-contributions/index.html
|
36
MANIFEST.in
@ -1,32 +1,22 @@
|
||||
include LICENSE
|
||||
include CONTRIBUTING.rst
|
||||
include README.md
|
||||
include CHANGELOG.md
|
||||
include package.json
|
||||
include bower.json
|
||||
include .bowerrc
|
||||
include *.md
|
||||
include pyproject.toml
|
||||
include setup.py
|
||||
include setupbase.py
|
||||
include Dockerfile
|
||||
include *.js
|
||||
graft tools
|
||||
graft notebook/tests
|
||||
include jupyter-config/notebook.json
|
||||
|
||||
# Translations
|
||||
graft notebook/i18n
|
||||
include package.json
|
||||
include install.json
|
||||
include ts*.json
|
||||
|
||||
# Documentation
|
||||
graft docs
|
||||
exclude docs/\#*
|
||||
graft notebook/labextension
|
||||
graft notebook/static
|
||||
graft notebook/templates
|
||||
|
||||
# Examples
|
||||
graft examples
|
||||
|
||||
# docs subdirs we want to skip
|
||||
prune docs/build
|
||||
prune docs/gh-pages
|
||||
prune docs/dist
|
||||
# Javascript files
|
||||
graft src
|
||||
graft style
|
||||
prune **/node_modules
|
||||
prune lib
|
||||
|
||||
# Patterns to exclude from any directory
|
||||
global-exclude *~
|
||||
|
66
README.md
@ -1,41 +1,57 @@
|
||||
# Jupyter Notebook
|
||||
|
||||
[](https://groups.google.com/forum/#!forum/jupyter)
|
||||
[](https://travis-ci.org/jupyter/notebook)
|
||||

|
||||
[](https://jupyter-notebook.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://mybinder.org/v2/gh/jupyter/notebook/main?urlpath=tree)
|
||||
[](https://codecov.io/gh/jupyter/notebook)
|
||||
|
||||
The Jupyter notebook is a web-based notebook environment for interactive
|
||||
computing.
|
||||
|
||||

|
||||

|
||||
|
||||
### Notice
|
||||
Please note that this repository is currently maintained by a skeleton crew of maintainers from the Jupyter community. We encourage users to transition to JupyterLab, where more immediate support can occur. Our approach moving forward will be:
|
||||
|
||||
1. To maintain the security of the Jupyter Notebook. That means security-related issues and pull requests are our highest priority.
|
||||
2. To address JupyterLab [feature parity issues](https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aopen+is%3Aissue+label%3A%22tag%3AFeature+Parity%22). As part of this effort, we are also working on a better [notebook-only experience](https://github.com/jupyterlab/jupyterlab/issues/8450) in JupyterLab for users who prefer the UI of the classic Jupyter Notebook.
|
||||
3. To be responsive to the hard work of community members who have opened pull requests. We are triaging these PRs. We cannot support or maintain new features at this time, but we welcome security and other sustainability fixes.
|
||||
The Jupyter Notebook project is currently undertaking a transition to a more modern code base built from the ground-up using JupyterLab components and extensions.
|
||||
|
||||
If you have an open pull request with a new feature or if you were planning to open one, please consider shipping it as a [notebook extension](https://jupyter-notebook.readthedocs.io/en/stable/extending/) instead.
|
||||
There is new stream of work which was submitted and then accepted as a Jupyter Enhancement Proposal (JEP): https://jupyter.org/enhancement-proposals/79-notebook-v7/notebook-v7.html
|
||||
|
||||
##### Alternatives to contributing to `notebook`
|
||||
Additionally, please consider whether your contribution would be appropriate for either the underlying server for Jupyter front-ends, [jupyter_server](https://github.com/jupyter/jupyter_server) or in the [JupyterLab front-end](https://github.com/jupyterlab/jupyterlab).
|
||||
#### Notebook v7
|
||||
|
||||
The next major version of Notebook will be based on:
|
||||
|
||||
- JupyterLab components for the frontend
|
||||
- Jupyter Server for the Python server
|
||||
|
||||
This results in a rather change to the `jupyter/notebook` code base.
|
||||
|
||||
To learn more about Notebook v7: https://jupyter.org/enhancement-proposals/79-notebook-v7/notebook-v7.html
|
||||
|
||||
#### Classic Notebook v6
|
||||
|
||||
Maintainance and security-related issues are now being addressed in the [`6.4.x`](https://github.com/jupyter/notebook/tree/6.4.x) branch.
|
||||
|
||||
New features and continuous improvement is now focused on Notebook v7 (see section above).
|
||||
|
||||
If you have an open pull request with a new feature or if you were planning to open one, we encourage switching over to the Jupyter Server and JupyterLab architecture, and distribute it as a server extension and / or JupyterLab prebuilt extension. That way your new feature will also be compatible with the new Notebook v7.
|
||||
|
||||
### Jupyter notebook, the language-agnostic evolution of IPython notebo
|
||||
|
||||
### Jupyter notebook, the language-agnostic evolution of IPython notebook
|
||||
Jupyter notebook is a language-agnostic HTML notebook application for
|
||||
Project Jupyter. In 2015, Jupyter notebook was released as a part of
|
||||
The Big Split™ of the IPython codebase. IPython 3 was the last major monolithic
|
||||
release containing both language-agnostic code, such as the *IPython notebook*,
|
||||
and language specific code, such as the *IPython kernel for Python*. As
|
||||
release containing both language-agnostic code, such as the _IPython notebook_,
|
||||
and language specific code, such as the _IPython kernel for Python_. As
|
||||
computing spans across many languages, Project Jupyter will continue to develop the
|
||||
language-agnostic **Jupyter notebook** in this repo and with the help of the
|
||||
community develop language specific kernels which are found in their own
|
||||
discrete repos.
|
||||
[[The Big Split™ announcement](https://blog.jupyter.org/the-big-split-9d7b88a031a7)]
|
||||
[[Jupyter Ascending blog post](https://blog.jupyter.org/jupyter-ascending-1bf5b362d97e)]
|
||||
|
||||
- [The Big Split™ announcement](https://blog.jupyter.org/the-big-split-9d7b88a031a7)
|
||||
- [Jupyter Ascending blog post](https://blog.jupyter.org/jupyter-ascending-1bf5b362d97e)
|
||||
|
||||
## Installation
|
||||
|
||||
You can find the installation documentation for the
|
||||
[Jupyter platform, on ReadTheDocs](https://jupyter.readthedocs.io/en/latest/install.html).
|
||||
The documentation for advanced usage of Jupyter notebook can be found
|
||||
@ -44,7 +60,9 @@ The documentation for advanced usage of Jupyter notebook can be found
|
||||
For a local installation, make sure you have
|
||||
[pip installed](https://pip.readthedocs.io/en/stable/installing/) and run:
|
||||
|
||||
$ pip install notebook
|
||||
```bash
|
||||
pip install notebook
|
||||
```
|
||||
|
||||
## Usage - Running Jupyter notebook
|
||||
|
||||
@ -52,7 +70,9 @@ For a local installation, make sure you have
|
||||
|
||||
Launch with:
|
||||
|
||||
$ jupyter notebook
|
||||
```bash
|
||||
jupyter notebook
|
||||
```
|
||||
|
||||
### Running in a remote installation
|
||||
|
||||
@ -60,17 +80,23 @@ You need some configuration before starting Jupyter notebook remotely. See [Runn
|
||||
|
||||
## Development Installation
|
||||
|
||||
See [`CONTRIBUTING.rst`](CONTRIBUTING.rst) for how to set up a local development installation.
|
||||
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for how to set up a local development installation.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are interested in contributing to the project, see [`CONTRIBUTING.rst`](CONTRIBUTING.rst).
|
||||
If you are interested in contributing to the project, see [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
||||
|
||||
## Community Guidelines and Code of Conduct
|
||||
|
||||
This repository is a Jupyter project and follows the Jupyter
|
||||
[Community Guides and Code of Conduct](https://jupyter.readthedocs.io/en/latest/community/content-community.html).
|
||||
|
||||
## Resources
|
||||
|
||||
- [Project Jupyter website](https://jupyter.org)
|
||||
- [Online Demo at jupyter.org/try](https://jupyter.org/try)
|
||||
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
|
||||
- [Korean Version of Installation](https://github.com/ChungJooHo/Jupyter_Kor_doc/)
|
||||
- [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)]
|
||||
- [Issues](https://github.com/jupyter/notebook/issues)
|
||||
- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter)
|
||||
- [Technical support - Jupyter Google Group](https://discourse.jupyter.org/)
|
||||
|
79
RELEASE.md
@ -1,80 +1,9 @@
|
||||
# Making a Release of Notebook
|
||||
# Releasing Jupyter Notebook
|
||||
|
||||
## Using `jupyter_releaser`
|
||||
## Automated releases
|
||||
|
||||
The recommended way to make a release is to use [`jupyter_releaser`](https://github.com/jupyter-server/jupyter_releaser#checklist-for-adoption).
|
||||
|
||||
## Manual Release Process
|
||||
We follow a similar bump strategy as in JupyterLab: https://github.com/jupyterlab/jupyterlab/blob/master/RELEASE.md#bump-version
|
||||
|
||||
### Start from a fresh git checkout and conda environment
|
||||
|
||||
#### Set the release branch
|
||||
|
||||
```bash
|
||||
export release_branch=master
|
||||
```
|
||||
|
||||
#### Create the git checkout
|
||||
|
||||
```bash
|
||||
git clone git@github.com:jupyter/notebook.git
|
||||
cd notebook
|
||||
git checkout ${release_banch}
|
||||
```
|
||||
|
||||
#### Create and activate the conda environment
|
||||
|
||||
```bash
|
||||
conda create -n notebook-release -c conda-forge jupyter
|
||||
conda activate notebook-release
|
||||
```
|
||||
|
||||
### Perform a local dev install
|
||||
|
||||
```bash
|
||||
pip install -ve .
|
||||
```
|
||||
|
||||
### Install release dependencies
|
||||
|
||||
```bash
|
||||
conda install -c conda-forge nodejs babel
|
||||
npm install -g po2json
|
||||
pip install jupyter_releaser # used for build dependencies (build, twine, tbump)
|
||||
```
|
||||
|
||||
### Update the version
|
||||
|
||||
```bash
|
||||
tbump --only-patch <new_version> # set the new version
|
||||
python setup.py jsversion
|
||||
git commit -am "Release $(python setup.py --version)"
|
||||
git tag $(python setup.py --version)
|
||||
```
|
||||
|
||||
### Create the artifacts
|
||||
|
||||
```bash
|
||||
rm -rf dist
|
||||
python -m build .
|
||||
```
|
||||
|
||||
### Upload the artifacts
|
||||
|
||||
```bash
|
||||
twine check dist/* && twine upload dist/*
|
||||
```
|
||||
|
||||
### Change back to dev version
|
||||
|
||||
```bash
|
||||
tbump --only-patch <dev_version> # Add the .dev suffix
|
||||
python setup.py jsversion
|
||||
git commit -am "Back to dev version"
|
||||
```
|
||||
|
||||
### Push the commits and tags
|
||||
|
||||
```bash
|
||||
git push origin ${release_branch} --tags
|
||||
```
|
||||
If you would still like to do the release manually instead, read below.
|
||||
|
338
app/index.js
Normal file
@ -0,0 +1,338 @@
|
||||
// Copyright (c) Jupyter Development Team.
|
||||
// Distributed under the terms of the Modified BSD License.
|
||||
|
||||
// Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/index.js
|
||||
|
||||
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
|
||||
|
||||
require('./style.js');
|
||||
require('./extraStyle.js');
|
||||
|
||||
function loadScript(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const newScript = document.createElement('script');
|
||||
newScript.onerror = reject;
|
||||
newScript.onload = resolve;
|
||||
newScript.async = true;
|
||||
document.head.appendChild(newScript);
|
||||
newScript.src = url;
|
||||
});
|
||||
}
|
||||
async function loadComponent(url, scope) {
|
||||
await loadScript(url);
|
||||
|
||||
// From MIT-licensed https://github.com/module-federation/module-federation-examples/blob/af043acd6be1718ee195b2511adf6011fba4233c/advanced-api/dynamic-remotes/app1/src/App.js#L6-L12
|
||||
// eslint-disable-next-line no-undef
|
||||
await __webpack_init_sharing__('default');
|
||||
const container = window._JUPYTERLAB[scope];
|
||||
// Initialize the container, it may provide shared modules and may need ours
|
||||
// eslint-disable-next-line no-undef
|
||||
await container.init(__webpack_share_scopes__.default);
|
||||
}
|
||||
|
||||
async function createModule(scope, module) {
|
||||
try {
|
||||
const factory = await window._JUPYTERLAB[scope].get(module);
|
||||
return factory();
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
`Failed to create module: package: ${scope}; module: ${module}`
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function
|
||||
*/
|
||||
async function main() {
|
||||
// load extra packages
|
||||
require('@jupyterlab/celltags');
|
||||
|
||||
const mimeExtensionsMods = [
|
||||
require('@jupyterlab/javascript-extension'),
|
||||
require('@jupyterlab/json-extension'),
|
||||
require('@jupyterlab/pdf-extension'),
|
||||
require('@jupyterlab/vega5-extension')
|
||||
];
|
||||
const mimeExtensions = await Promise.all(mimeExtensionsMods);
|
||||
|
||||
const disabled = [];
|
||||
// TODO: formalize the way the set of initial extensions and plugins are specified
|
||||
let baseMods = [
|
||||
// @jupyter-notebook plugins
|
||||
require('@jupyter-notebook/application-extension'),
|
||||
require('@jupyter-notebook/console-extension'),
|
||||
require('@jupyter-notebook/docmanager-extension'),
|
||||
require('@jupyter-notebook/documentsearch-extension'),
|
||||
require('@jupyter-notebook/help-extension'),
|
||||
require('@jupyter-notebook/notebook-extension'),
|
||||
// to handle opening new tabs after creating a new terminal
|
||||
require('@jupyter-notebook/terminal-extension'),
|
||||
|
||||
// @jupyterlab plugins
|
||||
require('@jupyterlab/application-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/application-extension:commands',
|
||||
'@jupyterlab/application-extension:context-menu',
|
||||
'@jupyterlab/application-extension:faviconbusy'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/apputils-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/apputils-extension:palette',
|
||||
'@jupyterlab/apputils-extension:settings',
|
||||
'@jupyterlab/apputils-extension:state',
|
||||
'@jupyterlab/apputils-extension:themes',
|
||||
'@jupyterlab/apputils-extension:themes-palette-menu',
|
||||
'@jupyterlab/apputils-extension:toolbar-registry'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/codemirror-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/codemirror-extension:services',
|
||||
'@jupyterlab/codemirror-extension:codemirror'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/completer-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/completer-extension:manager'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/console-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/console-extension:completer',
|
||||
'@jupyterlab/console-extension:cursor-position',
|
||||
'@jupyterlab/console-extension:factory',
|
||||
'@jupyterlab/console-extension:foreign',
|
||||
'@jupyterlab/console-extension:tracker'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/docmanager-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/docmanager-extension:plugin',
|
||||
'@jupyterlab/docmanager-extension:download'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/docprovider-extension'),
|
||||
require('@jupyterlab/documentsearch-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/documentsearch:plugin'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/filebrowser-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/filebrowser-extension:factory'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/fileeditor-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/fileeditor-extension:plugin'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/mainmenu-extension'),
|
||||
require('@jupyterlab/mathjax2-extension'),
|
||||
require('@jupyterlab/notebook-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/notebook-extension:code-console',
|
||||
'@jupyterlab/notebook-extension:export',
|
||||
'@jupyterlab/notebook-extension:factory',
|
||||
'@jupyterlab/notebook-extension:tracker',
|
||||
'@jupyterlab/notebook-extension:widget-factory'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyterlab/rendermime-extension'),
|
||||
require('@jupyterlab/shortcuts-extension'),
|
||||
// so new terminals can be create from the menu
|
||||
require('@jupyterlab/terminal-extension'),
|
||||
require('@jupyterlab/theme-light-extension'),
|
||||
require('@jupyterlab/theme-dark-extension'),
|
||||
require('@jupyterlab/translation-extension'),
|
||||
// Add the "Hub Control Panel" menu option when running in JupyterHub
|
||||
require('@jupyterlab/user-extension'),
|
||||
require('@jupyterlab/hub-extension')
|
||||
];
|
||||
|
||||
// The motivation here is to only load a specific set of plugins dependending on
|
||||
// the current page
|
||||
const page = PageConfig.getOption('notebookPage');
|
||||
switch (page) {
|
||||
case 'tree': {
|
||||
baseMods = baseMods.concat([
|
||||
require('@jupyterlab/filebrowser-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/filebrowser-extension:browser',
|
||||
'@jupyterlab/filebrowser-extension:download',
|
||||
'@jupyterlab/filebrowser-extension:file-upload-status',
|
||||
'@jupyterlab/filebrowser-extension:open-with',
|
||||
'@jupyterlab/filebrowser-extension:share-file'
|
||||
].includes(id)
|
||||
),
|
||||
require('@jupyter-notebook/tree-extension'),
|
||||
require('@jupyterlab/running-extension')
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case 'notebooks': {
|
||||
baseMods = baseMods.concat([
|
||||
require('@jupyterlab/completer-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/completer-extension:notebooks'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/tooltip-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/tooltip-extension:manager',
|
||||
'@jupyterlab/tooltip-extension:notebooks'
|
||||
].includes(id)
|
||||
)
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case 'consoles': {
|
||||
baseMods = baseMods.concat([
|
||||
require('@jupyterlab/completer-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/completer-extension:consoles'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/tooltip-extension').default.filter(({ id }) =>
|
||||
[
|
||||
'@jupyterlab/tooltip-extension:manager',
|
||||
'@jupyterlab/tooltip-extension:consoles'
|
||||
].includes(id)
|
||||
)
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
baseMods = baseMods.concat([
|
||||
require('@jupyterlab/completer-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/completer-extension:files'].includes(id)
|
||||
),
|
||||
require('@jupyterlab/filebrowser-extension').default.filter(({ id }) =>
|
||||
['@jupyterlab/filebrowser-extension:browser'].includes(id)
|
||||
)
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over active plugins in an extension.
|
||||
*
|
||||
* #### Notes
|
||||
* This also populates the disabled
|
||||
*/
|
||||
function* activePlugins(extension) {
|
||||
// Handle commonjs or es2015 modules
|
||||
let exports;
|
||||
if (Object.prototype.hasOwnProperty.call(extension, '__esModule')) {
|
||||
exports = extension.default;
|
||||
} else {
|
||||
// CommonJS exports.
|
||||
exports = extension;
|
||||
}
|
||||
|
||||
let plugins = Array.isArray(exports) ? exports : [exports];
|
||||
for (let plugin of plugins) {
|
||||
if (PageConfig.Extension.isDisabled(plugin.id)) {
|
||||
disabled.push(plugin.id);
|
||||
continue;
|
||||
}
|
||||
yield plugin;
|
||||
}
|
||||
}
|
||||
|
||||
const extension_data = JSON.parse(
|
||||
PageConfig.getOption('federated_extensions')
|
||||
);
|
||||
|
||||
const mods = [];
|
||||
const federatedExtensionPromises = [];
|
||||
const federatedMimeExtensionPromises = [];
|
||||
const federatedStylePromises = [];
|
||||
|
||||
const extensions = await Promise.allSettled(
|
||||
extension_data.map(async data => {
|
||||
await loadComponent(
|
||||
`${URLExt.join(
|
||||
PageConfig.getOption('fullLabextensionsUrl'),
|
||||
data.name,
|
||||
data.load
|
||||
)}`,
|
||||
data.name
|
||||
);
|
||||
return data;
|
||||
})
|
||||
);
|
||||
|
||||
extensions.forEach(p => {
|
||||
if (p.status === 'rejected') {
|
||||
// There was an error loading the component
|
||||
console.error(p.reason);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = p.value;
|
||||
if (data.extension) {
|
||||
federatedExtensionPromises.push(createModule(data.name, data.extension));
|
||||
}
|
||||
if (data.mimeExtension) {
|
||||
federatedMimeExtensionPromises.push(
|
||||
createModule(data.name, data.mimeExtension)
|
||||
);
|
||||
}
|
||||
if (data.style) {
|
||||
federatedStylePromises.push(createModule(data.name, data.style));
|
||||
}
|
||||
});
|
||||
|
||||
// Add the base frontend extensions
|
||||
const baseFrontendMods = await Promise.all(baseMods);
|
||||
baseFrontendMods.forEach(p => {
|
||||
for (let plugin of activePlugins(p)) {
|
||||
mods.push(plugin);
|
||||
}
|
||||
});
|
||||
|
||||
// Add the federated extensions.
|
||||
const federatedExtensions = await Promise.allSettled(
|
||||
federatedExtensionPromises
|
||||
);
|
||||
federatedExtensions.forEach(p => {
|
||||
if (p.status === 'fulfilled') {
|
||||
for (let plugin of activePlugins(p.value)) {
|
||||
mods.push(plugin);
|
||||
}
|
||||
} else {
|
||||
console.error(p.reason);
|
||||
}
|
||||
});
|
||||
|
||||
// Add the federated mime extensions.
|
||||
const federatedMimeExtensions = await Promise.allSettled(
|
||||
federatedMimeExtensionPromises
|
||||
);
|
||||
federatedMimeExtensions.forEach(p => {
|
||||
if (p.status === 'fulfilled') {
|
||||
for (let plugin of activePlugins(p.value)) {
|
||||
mimeExtensions.push(plugin);
|
||||
}
|
||||
} else {
|
||||
console.error(p.reason);
|
||||
}
|
||||
});
|
||||
|
||||
// Load all federated component styles and log errors for any that do not
|
||||
(await Promise.allSettled(federatedStylePromises))
|
||||
.filter(({ status }) => status === 'rejected')
|
||||
.forEach(({ reason }) => {
|
||||
console.error(reason);
|
||||
});
|
||||
|
||||
const NotebookApp = require('@jupyter-notebook/application').NotebookApp;
|
||||
const app = new NotebookApp({ mimeExtensions });
|
||||
|
||||
app.registerPluginModules(mods);
|
||||
|
||||
// Expose global app instance when in dev mode or when toggled explicitly.
|
||||
const exposeAppInBrowser =
|
||||
(PageConfig.getOption('exposeAppInBrowser') || '').toLowerCase() === 'true';
|
||||
|
||||
if (exposeAppInBrowser) {
|
||||
window.jupyterapp = app;
|
||||
}
|
||||
|
||||
await app.start();
|
||||
}
|
||||
|
||||
window.addEventListener('load', main);
|
240
app/package.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"name": "@jupyter-notebook/app",
|
||||
"version": "7.0.0-alpha.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"build:prod": "webpack --mode=production",
|
||||
"clean": "rimraf build && jlpm run clean:static",
|
||||
"clean:static": "rimraf -g \"../notebook/static/!(favicons)\"",
|
||||
"prepublishOnly": "yarn run build",
|
||||
"watch": "webpack --config ./webpack.config.watch.js"
|
||||
},
|
||||
"resolutions": {
|
||||
"@jupyter-notebook/application": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/application-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/console-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/docmanager-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/documentsearch-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/help-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/notebook-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/terminal-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/tree-extension": "~7.0.0-alpha.0",
|
||||
"@jupyter-notebook/ui-components": "~7.0.0-alpha.0",
|
||||
"@jupyterlab/application": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/application-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/apputils": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/apputils-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/celltags": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/codeeditor": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/codemirror-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/completer": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/completer-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/console": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/console-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/coreutils": "~6.0.0-alpha.5",
|
||||
"@jupyterlab/docmanager": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/docmanager-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/docprovider": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/docprovider-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/documentsearch": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/documentsearch-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/filebrowser": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/filebrowser-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/fileeditor": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/fileeditor-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/hub-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/javascript-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/json-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/mainmenu": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/mainmenu-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/mathjax2-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/notebook": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/notebook-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/observables": "~5.0.0-alpha.5",
|
||||
"@jupyterlab/outputarea": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/pdf-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/rendermime": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/rendermime-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/rendermime-interfaces": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/running-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/services": "~7.0.0-alpha.5",
|
||||
"@jupyterlab/settingregistry": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/shared-models": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/shortcuts-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/statedb": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/statusbar": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/terminal": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/terminal-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/theme-dark-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/theme-light-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/tooltip": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/tooltip-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/translation": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/translation-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/ui-components": "~4.0.0-alpha.20",
|
||||
"@jupyterlab/user": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/user-extension": "~4.0.0-alpha.5",
|
||||
"@jupyterlab/vega5-extension": "~4.0.0-alpha.5",
|
||||
"@lumino/algorithm": "~1.9.1",
|
||||
"@lumino/application": "~1.28.1",
|
||||
"@lumino/commands": "~1.20.0",
|
||||
"@lumino/coreutils": "~1.12.0",
|
||||
"@lumino/disposable": "~1.10.1",
|
||||
"@lumino/domutils": "~1.8.1",
|
||||
"@lumino/dragdrop": "~1.14.0",
|
||||
"@lumino/messaging": "~1.10.1",
|
||||
"@lumino/properties": "~1.8.1",
|
||||
"@lumino/signaling": "~1.10.1",
|
||||
"@lumino/virtualdom": "~1.14.1",
|
||||
"@lumino/widgets": "~1.31.1",
|
||||
"react": "~17.0.2",
|
||||
"react-dom": "~17.0.2",
|
||||
"yjs": "~13.5.27"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyter-notebook/application": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/application-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/console-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/docmanager-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/documentsearch-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/help-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/notebook-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/terminal-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/tree-extension": "^7.0.0-alpha.0",
|
||||
"@jupyter-notebook/ui-components": "^7.0.0-alpha.0",
|
||||
"@jupyterlab/application-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/apputils-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/celltags": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/codemirror-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/completer-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/console-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/coreutils": "~6.0.0-alpha.5",
|
||||
"@jupyterlab/docmanager-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/docprovider-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/documentsearch-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/filebrowser-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/fileeditor-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/hub-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/javascript-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/json-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/mainmenu-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/mathjax2-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/notebook-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/pdf-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/rendermime-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/running-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/shortcuts-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/terminal-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/theme-dark-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/theme-light-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/tooltip-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/translation-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/user-extension": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/vega5-extension": "^4.0.0-alpha.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jupyterlab/builder": "^4.0.0-alpha.5",
|
||||
"@jupyterlab/buildutils": "^4.0.0-alpha.5",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"css-loader": "~5.0.1",
|
||||
"file-loader": "~5.0.2",
|
||||
"fs-extra": "^8.1.0",
|
||||
"glob": "~7.1.6",
|
||||
"mini-css-extract-plugin": "~0.9.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"raw-loader": "~4.0.0",
|
||||
"rimraf": "~3.0.2",
|
||||
"style-loader": "~1.0.1",
|
||||
"svg-url-loader": "~6.0.0",
|
||||
"url-loader": "~4.1.1",
|
||||
"watch": "~1.0.2",
|
||||
"webpack": "^5.7.0",
|
||||
"webpack-bundle-analyzer": "^4.1.0",
|
||||
"webpack-cli": "^4.2.0",
|
||||
"webpack-merge": "^5.1.2",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
},
|
||||
"jupyterlab": {
|
||||
"name": "Jupyter Notebook",
|
||||
"extensions": [
|
||||
"@jupyter-notebook/application-extension",
|
||||
"@jupyter-notebook/console-extension",
|
||||
"@jupyter-notebook/docmanager-extension",
|
||||
"@jupyter-notebook/documentsearch-extension",
|
||||
"@jupyter-notebook/help-extension",
|
||||
"@jupyter-notebook/notebook-extension",
|
||||
"@jupyter-notebook/terminal-extension",
|
||||
"@jupyter-notebook/tree-extension",
|
||||
"@jupyterlab/application-extension",
|
||||
"@jupyterlab/apputils-extension",
|
||||
"@jupyterlab/codemirror-extension",
|
||||
"@jupyterlab/completer-extension",
|
||||
"@jupyterlab/console-extension",
|
||||
"@jupyterlab/docmanager-extension",
|
||||
"@jupyterlab/documentsearch-extension",
|
||||
"@jupyterlab/filebrowser-extension",
|
||||
"@jupyterlab/fileeditor-extension",
|
||||
"@jupyterlab/hub-extension",
|
||||
"@jupyterlab/mainmenu-extension",
|
||||
"@jupyterlab/mathjax2-extension",
|
||||
"@jupyterlab/notebook-extension",
|
||||
"@jupyterlab/rendermime-extension",
|
||||
"@jupyterlab/running-extension",
|
||||
"@jupyterlab/shortcuts-extension",
|
||||
"@jupyterlab/terminal-extension",
|
||||
"@jupyterlab/theme-dark-extension",
|
||||
"@jupyterlab/theme-light-extension",
|
||||
"@jupyterlab/tooltip-extension",
|
||||
"@jupyterlab/translation-extension",
|
||||
"@jupyterlab/user-extension"
|
||||
],
|
||||
"singletonPackages": [
|
||||
"@jupyterlab/application",
|
||||
"@jupyterlab/apputils",
|
||||
"@jupyterlab/celltags",
|
||||
"@jupyterlab/codeeditor",
|
||||
"@jupyterlab/completer",
|
||||
"@jupyterlab/console",
|
||||
"@jupyterlab/coreutils",
|
||||
"@jupyterlab/docmanager",
|
||||
"@jupyterlab/docprovider",
|
||||
"@jupyterlab/documentsearch",
|
||||
"@jupyterlab/filebrowser",
|
||||
"@jupyterlab/fileeditor",
|
||||
"@jupyterlab/mainmenu",
|
||||
"@jupyterlab/notebook",
|
||||
"@jupyterlab/observables",
|
||||
"@jupyterlab/outputarea",
|
||||
"@jupyterlab/rendermime",
|
||||
"@jupyterlab/rendermime-interfaces",
|
||||
"@jupyterlab/services",
|
||||
"@jupyterlab/settingregistry",
|
||||
"@jupyterlab/shared-models",
|
||||
"@jupyterlab/statedb",
|
||||
"@jupyterlab/statusbar",
|
||||
"@jupyterlab/terminal",
|
||||
"@jupyterlab/tooltip",
|
||||
"@jupyterlab/translation",
|
||||
"@jupyterlab/user",
|
||||
"@jupyterlab/ui-components",
|
||||
"@lumino/algorithm",
|
||||
"@lumino/application",
|
||||
"@lumino/commands",
|
||||
"@lumino/coreutils",
|
||||
"@lumino/disposable",
|
||||
"@lumino/domutils",
|
||||
"@lumino/dragdrop",
|
||||
"@lumino/messaging",
|
||||
"@lumino/properties",
|
||||
"@lumino/signaling",
|
||||
"@lumino/virtualdom",
|
||||
"@lumino/widgets",
|
||||
"react",
|
||||
"react-dom",
|
||||
"yjs"
|
||||
],
|
||||
"mimeExtensions": {},
|
||||
"linkedPackages": {}
|
||||
}
|
||||
}
|
37
app/publicpath.js
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) Jupyter Development Team.
|
||||
// Distributed under the terms of the Modified BSD License.
|
||||
|
||||
// We dynamically set the webpack public path based on the page config
|
||||
// settings from the JupyterLab app. We copy some of the pageconfig parsing
|
||||
// logic in @jupyterlab/coreutils below, since this must run before any other
|
||||
// files are loaded (including @jupyterlab/coreutils).
|
||||
|
||||
/**
|
||||
* Get global configuration data for the Jupyter application.
|
||||
*
|
||||
* @param name - The name of the configuration option.
|
||||
*
|
||||
* @returns The config value or an empty string if not found.
|
||||
*
|
||||
* #### Notes
|
||||
* All values are treated as strings.
|
||||
* For browser based applications, it is assumed that the page HTML
|
||||
* includes a script tag with the id `jupyter-config-data` containing the
|
||||
* configuration as valid JSON. In order to support the classic Notebook,
|
||||
* we fall back on checking for `body` data of the given `name`.
|
||||
*/
|
||||
function getOption(name) {
|
||||
let configData = Object.create(null);
|
||||
// Use script tag if available.
|
||||
if (typeof document !== 'undefined' && document) {
|
||||
const el = document.getElementById('jupyter-config-data');
|
||||
|
||||
if (el) {
|
||||
configData = JSON.parse(el.textContent || '{}');
|
||||
}
|
||||
}
|
||||
return configData[name] || '';
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
__webpack_public_path__ = getOption('fullStaticUrl') + '/';
|
1
app/style.js
Normal file
@ -0,0 +1 @@
|
||||
import '@jupyterlab/celltags/style/index.js';
|
180
app/webpack.config.js
Normal file
@ -0,0 +1,180 @@
|
||||
// Copyright (c) Jupyter Development Team.
|
||||
// Distributed under the terms of the Modified BSD License.
|
||||
|
||||
// Heavily inspired (and slightly tweaked) from:
|
||||
// https://github.com/jupyterlab/jupyterlab/blob/master/examples/federated/core_package/webpack.config.js
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge').default;
|
||||
const { ModuleFederationPlugin } = webpack.container;
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
|
||||
.BundleAnalyzerPlugin;
|
||||
|
||||
const Build = require('@jupyterlab/builder').Build;
|
||||
const baseConfig = require('@jupyterlab/builder/lib/webpack.config.base');
|
||||
|
||||
const data = require('./package.json');
|
||||
|
||||
const names = Object.keys(data.dependencies).filter(name => {
|
||||
const packageData = require(path.join(name, 'package.json'));
|
||||
return packageData.jupyterlab !== undefined;
|
||||
});
|
||||
|
||||
// Ensure a clear build directory.
|
||||
const buildDir = path.resolve(__dirname, 'build');
|
||||
if (fs.existsSync(buildDir)) {
|
||||
fs.removeSync(buildDir);
|
||||
}
|
||||
fs.ensureDirSync(buildDir);
|
||||
|
||||
// Copy extra files
|
||||
const index = path.resolve(__dirname, 'index.js');
|
||||
const cssImports = path.resolve(__dirname, 'style.js');
|
||||
fs.copySync(index, path.resolve(buildDir, 'index.js'));
|
||||
fs.copySync(cssImports, path.resolve(buildDir, 'extraStyle.js'));
|
||||
|
||||
const extras = Build.ensureAssets({
|
||||
packageNames: names,
|
||||
output: buildDir,
|
||||
schemaOutput: path.resolve(__dirname, '..', 'notebook')
|
||||
});
|
||||
|
||||
/**
|
||||
* Create the webpack ``shared`` configuration
|
||||
*/
|
||||
function createShared(packageData) {
|
||||
// Set up module federation sharing config
|
||||
const shared = {};
|
||||
const extensionPackages = packageData.jupyterlab.extensions;
|
||||
|
||||
// Make sure any resolutions are shared
|
||||
for (let [pkg, requiredVersion] of Object.entries(packageData.resolutions)) {
|
||||
shared[pkg] = { requiredVersion };
|
||||
}
|
||||
|
||||
// Add any extension packages that are not in resolutions (i.e., installed from npm)
|
||||
for (let pkg of extensionPackages) {
|
||||
if (!shared[pkg]) {
|
||||
shared[pkg] = {
|
||||
requiredVersion: require(`${pkg}/package.json`).version
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Add dependencies and sharedPackage config from extension packages if they
|
||||
// are not already in the shared config. This means that if there is a
|
||||
// conflict, the resolutions package version is the one that is shared.
|
||||
const extraShared = [];
|
||||
for (let pkg of extensionPackages) {
|
||||
let pkgShared = {};
|
||||
let {
|
||||
dependencies = {},
|
||||
jupyterlab: { sharedPackages = {} } = {}
|
||||
} = require(`${pkg}/package.json`);
|
||||
for (let [dep, requiredVersion] of Object.entries(dependencies)) {
|
||||
if (!shared[dep]) {
|
||||
pkgShared[dep] = { requiredVersion };
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrite automatic dependency sharing with custom sharing config
|
||||
for (let [dep, config] of Object.entries(sharedPackages)) {
|
||||
if (config === false) {
|
||||
delete pkgShared[dep];
|
||||
} else {
|
||||
if ('bundled' in config) {
|
||||
config.import = config.bundled;
|
||||
delete config.bundled;
|
||||
}
|
||||
pkgShared[dep] = config;
|
||||
}
|
||||
}
|
||||
extraShared.push(pkgShared);
|
||||
}
|
||||
|
||||
// Now merge the extra shared config
|
||||
const mergedShare = {};
|
||||
for (let sharedConfig of extraShared) {
|
||||
for (let [pkg, config] of Object.entries(sharedConfig)) {
|
||||
// Do not override the basic share config from resolutions
|
||||
if (shared[pkg]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add if we haven't seen the config before
|
||||
if (!mergedShare[pkg]) {
|
||||
mergedShare[pkg] = config;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Choose between the existing config and this new config. We do not try
|
||||
// to merge configs, which may yield a config no one wants
|
||||
let oldConfig = mergedShare[pkg];
|
||||
|
||||
// if the old one has import: false, use the new one
|
||||
if (oldConfig.import === false) {
|
||||
mergedShare[pkg] = config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(shared, mergedShare);
|
||||
|
||||
// Transform any file:// requiredVersion to the version number from the
|
||||
// imported package. This assumes (for simplicity) that the version we get
|
||||
// importing was installed from the file.
|
||||
for (let [pkg, { requiredVersion }] of Object.entries(shared)) {
|
||||
if (requiredVersion && requiredVersion.startsWith('file:')) {
|
||||
shared[pkg].requiredVersion = require(`${pkg}/package.json`).version;
|
||||
}
|
||||
}
|
||||
|
||||
// Add singleton package information
|
||||
for (let pkg of packageData.jupyterlab.singletonPackages) {
|
||||
if (shared[pkg]) {
|
||||
shared[pkg].singleton = true;
|
||||
}
|
||||
}
|
||||
|
||||
return shared;
|
||||
}
|
||||
|
||||
// Make a bootstrap entrypoint
|
||||
const entryPoint = path.join(buildDir, 'bootstrap.js');
|
||||
const bootstrap = 'import("./index.js");';
|
||||
fs.writeFileSync(entryPoint, bootstrap);
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
baseConfig.mode = 'production';
|
||||
}
|
||||
|
||||
if (process.argv.includes('--analyze')) {
|
||||
extras.push(new BundleAnalyzerPlugin());
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
merge(baseConfig, {
|
||||
mode: 'development',
|
||||
entry: ['./publicpath.js', './' + path.relative(__dirname, entryPoint)],
|
||||
output: {
|
||||
path: path.resolve(__dirname, '..', 'notebook/static/'),
|
||||
library: {
|
||||
type: 'var',
|
||||
name: ['_JUPYTERLAB', 'CORE_OUTPUT']
|
||||
},
|
||||
filename: 'bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
new ModuleFederationPlugin({
|
||||
library: {
|
||||
type: 'var',
|
||||
name: ['_JUPYTERLAB', 'CORE_LIBRARY_FEDERATION']
|
||||
},
|
||||
name: 'CORE_FEDERATION',
|
||||
shared: createShared(data)
|
||||
})
|
||||
]
|
||||
})
|
||||
].concat(extras);
|
17
app/webpack.config.watch.js
Normal file
@ -0,0 +1,17 @@
|
||||
const base = require('./webpack.config');
|
||||
const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
...base[0],
|
||||
bail: false,
|
||||
watch: true,
|
||||
plugins: [
|
||||
...base[0].plugins,
|
||||
new ExtraWatchWebpackPlugin({
|
||||
files: ['../packages/_metapackage/tsconfig.tsbuildinfo']
|
||||
})
|
||||
]
|
||||
},
|
||||
...base.slice(1)
|
||||
];
|
13
binder/environment.yml
Normal file
@ -0,0 +1,13 @@
|
||||
name: notebook
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- ipywidgets=7.6
|
||||
- jupyterlab=3
|
||||
- jupyterlab-language-pack-fr-FR
|
||||
- jupyterlab-link-share>=0.2
|
||||
- matplotlib
|
||||
- numpy
|
||||
- nodejs
|
||||
- python >=3.9,<3.10
|
||||
- xeus-python
|
339
binder/example.ipynb
Normal file
6
binder/postBuild
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
python -m pip install -e .
|
||||
jlpm && jlpm run build
|
||||
jlpm run develop
|
29
bower.json
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "jupyter-notebook-deps",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"backbone": "components/backbone#~1.2",
|
||||
"bootstrap": "bootstrap#~3.4",
|
||||
"bootstrap-tour": "0.9.0",
|
||||
"codemirror": "components/codemirror#5.56.0+components1",
|
||||
"create-react-class": "https://cdn.jsdelivr.net/npm/create-react-class@15.6.3/create-react-class.min.js",
|
||||
"es6-promise": "~1.0",
|
||||
"font-awesome": "components/font-awesome#~4.7.0",
|
||||
"jed": "~1.1.1",
|
||||
"jquery": "components/jquery#~3.5.0",
|
||||
"jquery-typeahead": "~2.10.6",
|
||||
"jquery-ui": "components/jqueryui#~1.12",
|
||||
"marked": "~0.7",
|
||||
"MathJax": "^2.7.4",
|
||||
"moment": "~2.19.3",
|
||||
"react": "~16.0.0",
|
||||
"requirejs": "~2.2",
|
||||
"requirejs-text": "~2.0.15",
|
||||
"requirejs-plugins": "~1.0.3",
|
||||
"text-encoding": "~0.1",
|
||||
"underscore": "components/underscore#~1.8.3",
|
||||
"xterm.js": "https://unpkg.com/xterm@~3.1.0/dist/xterm.js",
|
||||
"xterm.js-css": "https://unpkg.com/xterm@~3.1.0/dist/xterm.css",
|
||||
"xterm.js-fit": "https://unpkg.com/xterm@~3.1.0/dist/addons/fit/fit.js"
|
||||
}
|
||||
}
|
43
buildutils/package.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "@jupyter-notebook/buildutils",
|
||||
"version": "7.0.0-alpha.0",
|
||||
"private": true,
|
||||
"description": "Jupyter Notebook - Build Utilities",
|
||||
"homepage": "https://github.com/jupyter/notebook",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jupyter/notebook/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jupyter/notebook.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"author": "Project Jupyter",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib/"
|
||||
},
|
||||
"files": [
|
||||
"lib/*.d.ts",
|
||||
"lib/*.js.map",
|
||||
"lib/*.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
|
||||
"prepublishOnly": "npm run build",
|
||||
"watch": "tsc -w --listEmittedFiles"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyterlab/buildutils": "^4.0.0-alpha.5",
|
||||
"commander": "^6.2.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"typescript": "~4.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.10",
|
||||
"@types/node": "^14.6.1",
|
||||
"rimraf": "~3.0.0"
|
||||
}
|
||||
}
|
56
buildutils/src/develop.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
| Copyright (c) Jupyter Development Team.
|
||||
| Distributed under the terms of the Modified BSD License.
|
||||
|----------------------------------------------------------------------------*/
|
||||
|
||||
import commander from 'commander';
|
||||
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import process from 'process';
|
||||
|
||||
import { run } from '@jupyterlab/buildutils';
|
||||
|
||||
commander
|
||||
.description('Setup the repository for develop mode')
|
||||
.option('--overwrite', 'Force linking the notebook schemas')
|
||||
.option('--source', 'The path to the notebook package')
|
||||
.action((options: any) => {
|
||||
const { overwrite } = options;
|
||||
const prefix = run(
|
||||
'python -c "import sys; print(sys.prefix)"',
|
||||
{
|
||||
stdio: 'pipe'
|
||||
},
|
||||
true
|
||||
);
|
||||
const source = path.resolve(options.source ?? process.cwd());
|
||||
const sourceDir = path.join(
|
||||
source,
|
||||
'notebook',
|
||||
'schemas',
|
||||
'@jupyter-notebook'
|
||||
);
|
||||
const destDir = path.join(
|
||||
prefix,
|
||||
'share',
|
||||
'jupyter',
|
||||
'lab',
|
||||
'schemas',
|
||||
'@jupyter-notebook'
|
||||
);
|
||||
if (overwrite) {
|
||||
try {
|
||||
fs.unlinkSync(destDir);
|
||||
console.log('Removed previous symlink:', destDir);
|
||||
} catch (e) {
|
||||
console.info('Skip unlinkink', destDir);
|
||||
}
|
||||
}
|
||||
console.log('Symlinking:', sourceDir, destDir);
|
||||
fs.symlinkSync(sourceDir, destDir, 'dir');
|
||||
});
|
||||
|
||||
commander.parse(process.argv);
|
38
buildutils/src/ensure-repo.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import * as fs from 'fs-extra';
|
||||
|
||||
import { writePackageData } from '@jupyterlab/buildutils';
|
||||
|
||||
/**
|
||||
* Ensure the application package resolutions.
|
||||
*/
|
||||
function ensureResolutions(): string[] {
|
||||
const basePath = path.resolve('.');
|
||||
const corePath = path.join(basePath, 'app', 'package.json');
|
||||
const corePackage = fs.readJSONSync(corePath);
|
||||
|
||||
corePackage.jupyterlab.mimeExtensions = {};
|
||||
corePackage.jupyterlab.linkedPackages = {};
|
||||
corePackage.resolutions = {};
|
||||
|
||||
const packages = Object.keys(corePackage.dependencies).concat(
|
||||
corePackage.jupyterlab.singletonPackages
|
||||
);
|
||||
|
||||
packages.forEach(name => {
|
||||
const data = require(`${name}/package.json`);
|
||||
// Insist on a restricted version in the yarn resolution.
|
||||
corePackage.resolutions[name] = `~${data.version}`;
|
||||
});
|
||||
|
||||
// Write the package.json back to disk.
|
||||
if (writePackageData(corePath, corePackage)) {
|
||||
return ['Updated dev mode'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
void ensureResolutions();
|
||||
}
|
122
buildutils/src/release-bump.ts
Normal file
@ -0,0 +1,122 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
| Copyright (c) Jupyter Development Team.
|
||||
| Distributed under the terms of the Modified BSD License.
|
||||
|----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/buildutils/src/bumpversion.ts
|
||||
*/
|
||||
|
||||
import * as utils from '@jupyterlab/buildutils';
|
||||
|
||||
import commander from 'commander';
|
||||
|
||||
import { getPythonVersion, postbump } from './utils';
|
||||
|
||||
// Specify the program signature.
|
||||
commander
|
||||
.description('Update the version')
|
||||
.option('--dry-run', 'Dry run')
|
||||
.option('--force', 'Force the upgrade')
|
||||
.option('--skip-commit', 'Whether to skip commit changes')
|
||||
.arguments('<spec>')
|
||||
.action((spec: any, opts: any) => {
|
||||
// Get the previous version.
|
||||
const prev = getPythonVersion();
|
||||
const isFinal = /\d+\.\d+\.\d+$/.test(prev);
|
||||
|
||||
// Whether to commit after bumping
|
||||
const commit = opts.skipCommit !== true;
|
||||
|
||||
// for "next", determine whether to use "patch" or "build"
|
||||
if (spec === 'next') {
|
||||
spec = isFinal ? 'patch' : 'build';
|
||||
}
|
||||
|
||||
// For patch, defer to `patch:release` command
|
||||
if (spec === 'patch') {
|
||||
let cmd = 'jlpm run release:patch';
|
||||
if (opts.force) {
|
||||
cmd += ' --force';
|
||||
}
|
||||
if (!commit) {
|
||||
cmd += ' --skip-commit';
|
||||
}
|
||||
utils.run(cmd);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Make sure we have a valid version spec.
|
||||
const options = ['major', 'minor', 'release', 'build'];
|
||||
if (options.indexOf(spec) === -1) {
|
||||
throw new Error(`Version spec must be one of: ${options}`);
|
||||
}
|
||||
if (isFinal && spec === 'release') {
|
||||
throw new Error('Use "major" or "minor" to switch back to alpha release');
|
||||
}
|
||||
if (isFinal && spec === 'build') {
|
||||
throw new Error('Cannot increment a build on a final release');
|
||||
}
|
||||
|
||||
// Run pre-bump script.
|
||||
utils.prebump();
|
||||
|
||||
// Handle dry runs.
|
||||
if (opts.dryRun) {
|
||||
utils.run(`bumpversion --dry-run --verbose ${spec}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a major release during the alpha cycle, bump
|
||||
// just the Python version.
|
||||
if (prev.indexOf('a') !== -1 && spec === 'major') {
|
||||
// Bump the version.
|
||||
utils.run(`bumpversion ${spec}`);
|
||||
|
||||
// Run the post-bump script.
|
||||
postbump(commit);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the version spec to use for lerna.
|
||||
let lernaVersion = 'preminor';
|
||||
if (spec === 'build') {
|
||||
lernaVersion = 'prerelease';
|
||||
// a -> b
|
||||
} else if (spec === 'release' && prev.indexOf('a') !== -1) {
|
||||
lernaVersion = 'prerelease --preid=beta';
|
||||
// b -> rc
|
||||
} else if (spec === 'release' && prev.indexOf('b') !== -1) {
|
||||
lernaVersion = 'prerelease --preid=rc';
|
||||
// rc -> final
|
||||
} else if (spec === 'release' && prev.indexOf('rc') !== -1) {
|
||||
lernaVersion = 'patch';
|
||||
}
|
||||
if (lernaVersion === 'preminor') {
|
||||
lernaVersion += ' --preid=alpha';
|
||||
}
|
||||
|
||||
let cmd = `jlpm run lerna version --force-publish --no-push --no-git-tag-version ${lernaVersion}`;
|
||||
if (opts.force) {
|
||||
cmd += ' --yes';
|
||||
}
|
||||
// For a preminor release, we bump 10 minor versions so that we do
|
||||
// not conflict with versions during minor releases of the top
|
||||
// level package.
|
||||
if (lernaVersion === 'preminor') {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
utils.run(cmd);
|
||||
}
|
||||
} else {
|
||||
utils.run(cmd);
|
||||
}
|
||||
|
||||
// Bump the version.
|
||||
utils.run(`bumpversion ${spec} --allow-dirty`);
|
||||
|
||||
// Run the post-bump script.
|
||||
postbump(commit);
|
||||
});
|
||||
|
||||
commander.parse(process.argv);
|
54
buildutils/src/release-patch.ts
Normal file
@ -0,0 +1,54 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
| Copyright (c) Jupyter Development Team.
|
||||
| Distributed under the terms of the Modified BSD License.
|
||||
|----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/buildutils/src/patch-release.ts
|
||||
*/
|
||||
|
||||
import * as utils from '@jupyterlab/buildutils';
|
||||
|
||||
import commander from 'commander';
|
||||
|
||||
import { getPythonVersion, postbump } from './utils';
|
||||
|
||||
// Specify the program signature.
|
||||
commander
|
||||
.description('Create a patch release')
|
||||
.option('--force', 'Force the upgrade')
|
||||
.option('--skip-commit', 'Whether to skip commit changes')
|
||||
.action((options: any) => {
|
||||
// Make sure we can patch release.
|
||||
const pyVersion = getPythonVersion();
|
||||
if (
|
||||
pyVersion.includes('a') ||
|
||||
pyVersion.includes('b') ||
|
||||
pyVersion.includes('rc')
|
||||
) {
|
||||
throw new Error('Can only make a patch release from a final version');
|
||||
}
|
||||
|
||||
// Run pre-bump actions.
|
||||
utils.prebump();
|
||||
|
||||
// Patch the python version
|
||||
utils.run('bumpversion patch'); // switches to alpha
|
||||
utils.run('bumpversion release --allow-dirty'); // switches to beta
|
||||
utils.run('bumpversion release --allow-dirty'); // switches to rc.
|
||||
utils.run('bumpversion release --allow-dirty'); // switches to final.
|
||||
|
||||
// Version the changed
|
||||
let cmd =
|
||||
'jlpm run lerna version patch --no-push --force-publish --no-git-tag-version';
|
||||
if (options.force) {
|
||||
cmd += ' --yes';
|
||||
}
|
||||
utils.run(cmd);
|
||||
|
||||
// Whether to commit after bumping
|
||||
const commit = options.skipCommit !== true;
|
||||
postbump(commit);
|
||||
});
|
||||
|
||||
commander.parse(process.argv);
|
23
buildutils/src/utils.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { run } from '@jupyterlab/buildutils';
|
||||
|
||||
/**
|
||||
* Get the current version of notebook
|
||||
*/
|
||||
export function getPythonVersion(): string {
|
||||
const cmd = 'python setup.py --version';
|
||||
const lines = run(cmd, { stdio: 'pipe' }, true).split('\n');
|
||||
return lines[lines.length - 1];
|
||||
}
|
||||
|
||||
export function postbump(commit = true): void {
|
||||
// run the integrity
|
||||
run('jlpm integrity');
|
||||
|
||||
const newPyVersion = getPythonVersion();
|
||||
|
||||
// Commit changes.
|
||||
if (commit) {
|
||||
run(`git commit -am "Release ${newPyVersion}"`);
|
||||
run(`git tag ${newPyVersion}`);
|
||||
}
|
||||
}
|
10
buildutils/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../tsconfigbase",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"rootDir": "src",
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["src/*"],
|
||||
"references": []
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
# Jupyter Notebook
|
||||
|
||||
[](https://groups.google.com/forum/#!forum/jupyter)
|
||||
[](https://travis-ci.org/jupyter/notebook)
|
||||
[](https://jupyter-notebook.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
|
||||
|
||||
Jupyter नोटबुक इंटरैक्टिव के लिए एक वेब-आधारित नोटबुक वातावरण है
|
||||
कंप्यूटिंग।
|
||||
|
||||

|
||||
|
||||
### नोटिस
|
||||
कृपया ध्यान दें कि इस भंडार का रखरखाव वर्तमान में जुपिटर समुदाय के एक कंकाल के दल द्वारा किया जाता है। हम उपयोगकर्ताओं को जुपिटरलैब में संक्रमण के लिए प्रोत्साहित करते हैं, जहां अधिक तत्काल समर्थन हो सकता है। हमारा दृष्टिकोण आगे बढ़ेगा:
|
||||
|
||||
1. जुपिटर नोटबुक की सुरक्षा बनाए रखने के लिए। इसका मतलब है कि सुरक्षा से संबंधित मुद्दे और पुल अनुरोध हमारी सर्वोच्च प्राथमिकता है।
|
||||
2. JupyterLab को संबोधित करने के लिए [समता मुद्दों की सुविधा](https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aopen+is%3Aissue+label%3A%22tag%3AFeature+Parity%22)| इस प्रयास के हिस्से के रूप में, हम एक बेहतर [नोटबुक-ओनली एक्सपीरियंस](https://github.com/jupyterlab/jupyterlab/issues/8450)JupyterLab में उन उपयोगकर्ताओं के लिए जो क्लासिक Jupyter नोटबुक के UI को पसंद करते हैं।
|
||||
3. समुदाय के सदस्यों की कड़ी मेहनत के प्रति उत्तरदायी होना जिन्होंने पुल अनुरोधों को खोला है। हम इन पीआर को ट्राई कर रहे हैं। हम इस समय नई सुविधाओं का समर्थन या रखरखाव नहीं कर सकते हैं, लेकिन हम सुरक्षा और अन्य स्थिरता सुधारों का स्वागत करते हैं।
|
||||
|
||||
यदि आपके पास एक नई सुविधा के साथ एक खुला पुल अनुरोध है या यदि आप एक खोलने की योजना बना रहे हैं, तो कृपया इसे [नोटबुक एक्सटेंशन](https://jupyter-notebook.readthedocs.io/en/stable/extending/) के रूप में शिपिंग करने पर विचार करें। बजाय।
|
||||
|
||||
##### `नोटबुक` में योगदान करने के लिए विकल्प
|
||||
इसके अतिरिक्त, कृपया विचार करें कि क्या आपका योगदान Jupyter फ्रंट-एंड के लिए अंतर्निहित सर्वर के लिए उपयुक्त होगा, [jupyter server](https://github.com/jupyter/jupyter_server) या में [JupyterLab फ़्रंट एंड](https://github.com/jupyterlab/jupyterlab).
|
||||
|
||||
### जुपिटर नोटबुक, आइपीथॉन नोटबुक की भाषा-अज्ञेय विकास
|
||||
Jupyter नोटबुक एक भाषा-अज्ञेय HTML नोटबुक अनुप्रयोग है
|
||||
प्रोजेक्ट जुपिटर। 2015 में, जुपिटर नोटबुक के एक भाग के रूप में जारी किया गया था
|
||||
IPython कोडबेस का बिग स्प्लिट ™। IPython 3 अंतिम प्रमुख अखंड था
|
||||
दोनों भाषा-अज्ञेयवादी कोड, जैसे *IPython नोटबुक*,
|
||||
और भाषा विशिष्ट कोड, जैसे कि *अजगर के लिए आईपीथॉन कर्नेल*। जैसा
|
||||
कई भाषाओं में कंप्यूटिंग स्पैन, प्रोजेक्ट जुपिटर विकसित करना जारी रखेगा
|
||||
भाषा-अज्ञेय **जुपिटर नोटबुक** इस रेपो में और की मदद से
|
||||
समुदाय भाषा विशिष्ट गुठली विकसित करते हैं जो अपने आप में पाए जाते हैं
|
||||
असतत रेपो।
|
||||
[[Big Split™ घोषणा](https://blog.jupyter.org/the-big-split-9d7b88a031a7)]
|
||||
[[Jupyter आरोही ब्लॉग पोस्ट](https://blog.jupyter.org/jupyter-ascending-1bf5b362d97e)]
|
||||
|
||||
## स्थापना
|
||||
आप के लिए स्थापना प्रलेखन पा सकते हैं
|
||||
[बृहस्पति मंच, ReadTheDocs पर](https://jupyter.readthedocs.io/en/latest/install.html).
|
||||
जुपिटर नोटबुक के उन्नत उपयोग के लिए दस्तावेज पाया जा सकता है
|
||||
[यहाँ](https://jupyter-notebook.readthedocs.io/en/latest/).
|
||||
|
||||
स्थानीय स्थापना के लिए, सुनिश्चित करें कि आपके पास है
|
||||
[pip स्थापित](https://pip.readthedocs.io/en/stable/installing/) और भाग खड़ा हुआ:
|
||||
|
||||
$ pip install notebook
|
||||
|
||||
## उपयोग - जुपिटर नोटबुक चल रहा है
|
||||
|
||||
### स्थानीय स्थापना में चल रहा है
|
||||
|
||||
इसके साथ लॉन्च करें:
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
### एक दूरस्थ स्थापना में चल रहा है
|
||||
|
||||
आपको बृहस्पति नोटबुक को दूरस्थ रूप से शुरू करने से पहले कुछ कॉन्फ़िगरेशन की आवश्यकता है। देखें [नोटबुक सर्वर चला रहा है](https://jupyter-notebook.readthedocs.io/en/stable/public_server.html).
|
||||
|
||||
## विकास स्थापना
|
||||
|
||||
स्थानीय विकास की स्थापना कैसे करें, इसके लिए [`CONTRIBUTING.rst`](CONTRIBUTING.rst) देखें।
|
||||
|
||||
## योगदान
|
||||
|
||||
यदि आप इस परियोजना में योगदान देने में रुचि रखते हैं, तो [`CONTRIBUTING.rst`](CONTRIBUTING.rst) देखें।
|
||||
|
||||
## साधन
|
||||
- [Project Jupyter website](https://jupyter.org)
|
||||
- [Online Demo at jupyter.org/try](https://jupyter.org/try)
|
||||
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
|
||||
- [Korean Version of Installation](https://github.com/ChungJooHo/Jupyter_Kor_doc/)
|
||||
- [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)]
|
||||
- [Issues](https://github.com/jupyter/notebook/issues)
|
||||
- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter)
|
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 331 KiB |
@ -1,57 +0,0 @@
|
||||
# Jupyter Notebook
|
||||
|
||||
[](https://groups.google.com/forum/#!forum/jupyter)
|
||||
[](https://travis-ci.org/jupyter/notebook)
|
||||
[](https://jupyter-notebook.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
英語版のリンク : [[English Version](http://github.com/jupyter/notebook/)]
|
||||
|
||||
Jupyter Notebookは、インタラクティブなWebベースのノートブック形式の環境です。
|
||||
|
||||

|
||||
|
||||
### Jupyter Notebook, 言語に依存しないIPython Notebookの進化
|
||||
|
||||
Jupyter Notebookは、Project Jupyter用の言語に依存しないHTMLノートブックアプリケーションです。
|
||||
2015年、Jupyter NotebookはIPythonコードベースのThe Big Split™の一部としてリリースされました。IPython3はIPython Notebookなどのユーザーの言語に依存しないコードとIPython kernel for Pythonのような特定の言語ベースのコードの機能を持ってリリースしました。
|
||||
コンピューティングは多くの言語にまたがるため、Project Jupyterはこのリポジトリで言語に依存しない**Jupyter Notebook**を継続的に開発します。そして、コミュニティの助けを借りて、独自のリポジトリにある言語固有のカーネルを開発します。
|
||||
[[The Big Split™ announcement](https://blog.jupyter.org/the-big-split-9d7b88a031a7)]
|
||||
[[Jupyter Ascending blog post](https://blog.jupyter.org/jupyter-ascending-1bf5b362d97e)]
|
||||
|
||||
## インストール
|
||||
|
||||
[Jupyter platform, on ReadTheDocs](https://jupyter.readthedocs.io/en/latest/install.html)から、インストールドキュメントをご覧になれます。
|
||||
Jupyter Notebookの発展的な使用方法に関するドキュメントは、[こちら](https://jupyter-notebook.readthedocs.io/en/latest/)をご覧ください。
|
||||
|
||||
ローカルへのインストールの場合、[pip](https://pip.readthedocs.io/en/stable/installing/)をインストールしていることを確認し、以下のコマンドを実行してください。
|
||||
|
||||
$ pip install notebook
|
||||
|
||||
## 使用方法 - Jupyter Notebookの実行
|
||||
|
||||
### ローカルへのインストールにおける実行
|
||||
|
||||
以下のコマンドをを実行してください:
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
### リモートへのインストールにおける実行
|
||||
|
||||
Jupyter Notebookをリモートで起動する前に、いくつかの構成が必要です。 [Notebookサーバーの実行](https://jupyter-notebook.readthedocs.io/en/stable/public_server.html)を参照してください。
|
||||
|
||||
## 開発用インストール
|
||||
|
||||
開発用インストールのセットアップ方法については、[`CONTRIBUTING.rst`](https://github.com/jupyter/notebook/blob/master/CONTRIBUTING.rst)を参照してください。
|
||||
|
||||
## 貢献
|
||||
|
||||
プロジェクトへの貢献に興味がある場合は、[`CONTRIBUTING.rst`](https://github.com/jupyter/notebook/blob/master/CONTRIBUTING.rst)をご覧ください。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Project Jupyter website](https://jupyter.org)
|
||||
- [Online Demo at try.jupyter.org](https://try.jupyter.org)
|
||||
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
|
||||
- [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)]
|
||||
- [Issues](https://github.com/jupyter/notebook/issues)
|
||||
- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter)
|
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 331 KiB |
@ -1,57 +0,0 @@
|
||||
# Notebook 실행하기
|
||||
|
||||
## 첫 걸음
|
||||
1. 다음 명령어를 통해 Notebook 서버를 시작하세요 :
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
2. 브라우저에 Notebook이 실행된 것을 확인할 수 있습니다.
|
||||
|
||||
|
||||
# Notebook 서버 시작하기
|
||||
|
||||
Notebook을 컴퓨터에 설치하였으면 Notebook 서버를 시작할 수 있습니다. 다음 명령어를 이용하여 Notebook서버를 시작할 수 있습니다.
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
이 명령어를 실행하면, 터미널에 웹 응용프로그램의 주소와 서버에 대한 정보가 출력됩니다.
|
||||
|
||||
$ jupyter notebook
|
||||
$ [I 08:58:24.417 NotebookApp] Serving notebooks from local directory: /Users/catherline
|
||||
$ [I 08:58:24.417 NotebookApp] 0 active kernels
|
||||
$ [I 08:58:24.417 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
|
||||
$ [I 08:58:24.417 NotebookApp] Use Control-C to stop this server and shut down all kernels
|
||||
|
||||
기본 브라우저를 통해 이 주소가 열립니다.
|
||||
|
||||
Notebook이 브라우저에 열리면, Notebook의 목록을 보여주는 Notebook Dashboard를 볼 수 있습니다. 대체로 가장 상위의 디렉토리를 열어줄 것입니다.
|
||||
|
||||
**Notebook Dashboard**
|
||||
|
||||

|
||||
|
||||
# Notebook 서버의 명령어 소개
|
||||
|
||||
## 커스텀 IP 나 포트를 이용하여 시작하려면 어떻게 해야할까?
|
||||
|
||||
기본값으로, Notebook 서버는 포트 8888로 시작됩니다. 만약 포트8888이 사용할 수 없다면, Notebook 서버는 다른 가능한 포트를 찾습니다. 또한 임의로 포트를 설정해주는 것도 가능합니다. 예를 들어 포트 9999로 실행하면 :
|
||||
|
||||
$ jupyter notebook --port 9999
|
||||
|
||||
|
||||
## 브라우저를 열지않고 Notebook를 열기
|
||||
|
||||
브라우저를 열지 않고 Notebook 서버를 시작하려면 :
|
||||
|
||||
$ jupyter notebook --no-browser
|
||||
|
||||
|
||||
## Notebook 서버 옵션 도움말 보기
|
||||
|
||||
Notebook 서버는 --help 옵션을 통해 도움말 메시지를 제공합니다 :
|
||||
|
||||
$ jupyter notebook --help
|
||||
|
||||
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
# Jupyter Notebook 설치하기
|
||||
|
||||
## 필요한 것 : Python
|
||||
|
||||
Jupyter Notebook 을 설치하기 위해선 Jupyter가 많은 프로그래밍 언어들로 동작되기 때문에, Python이 필요합니다. (Python 3.3이상, Python 2.7)
|
||||
|
||||
Python과 Jupyter를 설치할 때 Anaconda를 이용하는 것을 추천합니다. 밑에서 이를 이용하여 설치할 것입니다.
|
||||
|
||||
## Anaconda 와 conda 를 이용하여 Jupyter 설치하기
|
||||
|
||||
새로운 이용자들은 Anaconda를 설치하는 것을 강력하게 추천합니다. Anaconda는 Python과 Jupyter를 쉽게 설치하게 해주고, 과학적인 계산과 데이터를 위한 자주 사용되는 패키지들의 설치에도 유용합니다.
|
||||
|
||||
설치 순서 :
|
||||
|
||||
1. Anaconda를 다운받으세요. Anaconda의 가장 최신의 Python 3버전을 다운 받는 것을 추천합니다.
|
||||
2. 다운 받은 Anaconda 의 다운로드 페이지에 있는 설명을 읽고 설치해주세요.
|
||||
3. 축하합니다. Jupyter Notebook 을 설치하셨습니다. Jupyter Notebook을 실행하려면 :
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
## 숙련된 Python 이용자 : pip을 통해 설치하기
|
||||
|
||||
Python 이용자라면, Anaconda 대신에 Python의 패키지 매니저 pip을 이용하여 설치하세요.
|
||||
|
||||
첫째로, 가장 최신의 pip인지를 확인하세요; 구 버전은 독립성에 문제가 있을 수 있습니다.
|
||||
|
||||
$ pip install --upgrade pip
|
||||
|
||||
이제 다음을 이용하여 Jupyter Notebook를 설치하세요 :
|
||||
|
||||
$ pip install jupyter
|
||||
|
||||
(축하합니다. Jupyter Notebook를 설치하셨습니다.)
|
@ -1,55 +0,0 @@
|
||||
# Jupyter Notebook
|
||||
|
||||
[](https://groups.google.com/forum/#!forum/jupyter)
|
||||
[](https://travis-ci.org/jupyter/notebook)
|
||||
[](http://jupyter-notebook.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
English 버전 링크 : [[English Version](http://github.com/jupyter/notebook/)]
|
||||
|
||||
Jupyter notebook 은 상호 교환을 위한 웹 기반 환경입니다.
|
||||
|
||||

|
||||
|
||||
### Jupyter notebook, 사용자의 언어에 독립적인 IPython notebook의 진화
|
||||
Jupyter notebook은 Jupyter 프로젝트를 위한 사용자 언어에 독립적인 HTML 응용 프로그램입니다.
|
||||
2015년에 Jupyter notebook은 IPython 코드 기반의 The Big Split™ 의 일부분으로 시작되었습니다.
|
||||
IPython 3는 *IPython notebook* 과 같은 사용자 언어에 독립적인 코드와 *IPython kernel for Python* 과 같은 특정 언어 기반의 코드의 기능을 가지고 출시되었습니다.
|
||||
컴퓨터에는 많은 언어가 사용되기 때문에, Jupyter 프로젝트는 사용자 언어에 독립적인 **Jupyter notebook** 을 이 저장소와 개인의 독립적인 저장소에 있는 특정 언어 중심의 커널의 도움으로 지속적으로 개발할 것입니다.
|
||||
[[The Big Split™ announcement](https://blog.jupyter.org/2015/04/15/the-big-split/)]
|
||||
[[Jupyter Ascending blog post](http://blog.jupyter.org/2015/08/12/first-release-of-jupyter/)]
|
||||
|
||||
## 설치
|
||||
설치법 문서는 다음 주소에서 찾을 수 있습니다.
|
||||
You can find the installation documentation for the
|
||||
[Jupyter platform, on ReadTheDocs](https://jupyter.readthedocs.io/en/latest/install.html).
|
||||
조금 더 심화된 Jupyter notebook의 사용은 다음 주소에서 볼 수 있습니다.
|
||||
[here](https://jupyter-notebook.readthedocs.io/en/latest/).
|
||||
|
||||
설치를 위해서는
|
||||
[pip installed](https://pip.readthedocs.io/en/stable/installing/) 가 있는지 확인한 후 다음을 실행해주세요:
|
||||
|
||||
$ pip install notebook
|
||||
|
||||
## 활용 - Jupyter notebook 실행하기
|
||||
|
||||
### 로컬에서 실행할 때
|
||||
|
||||
이와 같이 실행하세요:
|
||||
|
||||
$ jupyter notebook
|
||||
|
||||
## 개발 설치
|
||||
|
||||
[`CONTRIBUTING.rst`](CONTRIBUTING.rst) 을 통해 설치법을 확인하세요.
|
||||
|
||||
## 기여하기
|
||||
|
||||
이 프로젝트에 기여를 하고 싶다면, [`CONTRIBUTING.rst`](CONTRIBUTING.rst) 을 참고해주세요.
|
||||
|
||||
## 자료
|
||||
- [Project Jupyter website](https://jupyter.org)
|
||||
- [Online Demo at try.jupyter.org](https://try.jupyter.org)
|
||||
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
|
||||
- [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)]
|
||||
- [Issues](https://github.com/jupyter/notebook/issues)
|
||||
- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter)
|
@ -1,38 +0,0 @@
|
||||
# UI 기능
|
||||
|
||||
버그 리포트나 Jupyter Mailing list에 메일을 보내려고 할 때, 개발자나 사용자들이 버그를 진단하거나 해결해줄 경우 다른 UI를 사용하면 시간이 단축된다.
|
||||
이번 장에서는 Notebook과 Notebook의 다른 모드의 UI 요소를 알려줄 것이다.
|
||||
|
||||
## Notebook Dashboard
|
||||
|
||||
jupyter notebook 명령어를 실행하면 가장 먼저 Notebook Dashboard가 나타난다.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Notebook 편집기
|
||||
|
||||
편집을 위해 Notebook을 선택했다면, Notebook은 Notebook편집기를 열어준다.
|
||||
|
||||

|
||||
## Notebook 의 사용자 도움 인터페이스
|
||||
|
||||
만약 Notebook 편집기의 특정 요소를 더 배우고 싶다면, 도움 메뉴 - 사용자 인터페이스 를 선택함으로써 사용사 인터페이스 도움말을 볼 수 있습니다.
|
||||
|
||||
## 편집 모드와 Notebook편집기
|
||||
|
||||
셀이 편집모드에 있다면, 셀 모드 지시자는 셀의 상태를 반영합니다. 이 상태는 오른쪽 위의 작은 연필모양으로 선택가능합니다. 셀이 명령 모드에 있다면, 그 위치에 아이콘이 없습니다.
|
||||
|
||||

|
||||
|
||||
## 파일 편집기
|
||||
|
||||
이제 Notebook Dashboard 안의 Notebook 파일이 아닌 표시된 파일을 선택하여 열어야한다고 한다면, 파일은 파일 편집기로 열립니다.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 331 KiB |
@ -1,77 +0,0 @@
|
||||
# Jupyter Notebook
|
||||
|
||||
[](https://groups.google.com/forum/#!forum/jupyter)
|
||||
[](https://travis-ci.org/jupyter/notebook)
|
||||
[](https://jupyter-notebook.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
|
||||
|
||||
Jupyter Notebook是用于交互的基于Web的笔记本环境
|
||||
计算。
|
||||
|
||||

|
||||
|
||||
### 注意
|
||||
请注意,这家商店目前由木星社区的骨干团队维护。我们鼓励用户过渡到 JupyterLab,那里可能会立即提供更多支持。我们的方法将向前发展:
|
||||
|
||||
1.维护Jupiter笔记本电脑的安全性。这意味着与安全相关的问题和请求是我们的首要任务。
|
||||
2.解决JupyterLab [促进平等问题](https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aopen+is%3Aissue+label%3A%22tag%3AFeature+Parity%22)|作为这项工作的一部分,我们有更好的[仅限笔记本电脑的体验](https://github.com/jupyterlab/jupyterlab/issues/8450)在JupyterLab中,适合喜欢经典Jupyter笔记本UI的用户。
|
||||
3.负责提出请求请求的社区成员的辛勤工作。我们正在尝试这些PR。我们目前无法支持或维护新设施,但是我们欢迎安全性和其他稳定性方面的改进。
|
||||
|
||||
如果您有一个具有新功能的打开请求请求,或者您打算打开一个请求,请将该请求命名为[notebook extension](https://jupyter-notebook.readthedocs.io/en/stable/extending/) 考虑运送为。代替。
|
||||
|
||||
##### 选择贡献“笔记本”
|
||||
此外,请考虑您的贡献是否适合Jupyter前端的基础服务器, [jupyter server](https://github.com/jupyter/jupyter_server) 或在 [JupyterLab 前端](https://github.com/jupyterlab/jupyterlab).
|
||||
|
||||
### Jupyter笔记本,与IPython笔记本无关的语言开发
|
||||
Jupyter Notebook是与语言无关的HTML Notebook应用程序
|
||||
木星计划。 2015年,木星作为笔记本的一部分发布
|
||||
IPython代码库的Big Split™。 IPython 3是最后一个主要的整体
|
||||
两种与语言无关的代码,例如 *IPython notebook*,
|
||||
以及特定语言的代码,例如 *用于Python的IPython内核* 。如
|
||||
通过多种语言计算SPAN,Jupyter项目将继续发展
|
||||
与语言无关 **Jupyter Notebook** 在此仓库中更多帮助下
|
||||
社区开发自己发现的特定于语言的内核
|
||||
离散回购。
|
||||
[[Big Split™ 宣言](https://blog.jupyter.org/the-big-split-9d7b88a031a7)]
|
||||
[[Jupyter 升序博客文章](https://blog.jupyter.org/jupyter-ascending-1bf5b362d97e)]
|
||||
|
||||
## 成立
|
||||
您可以找到以下安装文件
|
||||
[Jupiter论坛,在ReadTheDocs上](https://jupyter.readthedocs.io/en/latest/install.html).
|
||||
可以找到有关Jupiter笔记本的高级使用的文档
|
||||
[这里](https://jupyter-notebook.readthedocs.io/en/latest/).
|
||||
|
||||
对于本地安装,请确保您已经
|
||||
[pip 成立时间](https://pip.readthedocs.io/en/stable/installing/) 并运行:
|
||||
|
||||
$ pip install notebook
|
||||
|
||||
## 用法-运行木星笔记本
|
||||
|
||||
### 在本地安装中运行
|
||||
|
||||
与启动
|
||||
|
||||
$ jupyter笔记本
|
||||
|
||||
### 在远程安装中运行
|
||||
|
||||
在远程启动Jupiter笔记本电脑之前,需要进行一些配置。请参阅 [运行笔记本服务器](https://jupyter-notebook.readthedocs.io/en/stable/public_server.html).
|
||||
|
||||
## 开发设置
|
||||
|
||||
有关如何建立本地发展 [`CONTRIBUTING.rst`](CONTRIBUTING.rst) 看到。
|
||||
|
||||
## 贡献
|
||||
|
||||
如果您有兴趣为这个项目做贡献,请参阅 [`CONTRIBUTING.rst`](CONTRIBUTING.rst).
|
||||
|
||||
## 资源
|
||||
- [Project Jupyter website](https://jupyter.org)
|
||||
- [Online Demo at jupyter.org/try](https://jupyter.org/try)
|
||||
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
|
||||
- [Korean Version of Installation](https://github.com/ChungJooHo/Jupyter_Kor_doc/)
|
||||
- [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)]
|
||||
- [Issues](https://github.com/jupyter/notebook/issues)
|
||||
- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter)
|
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 331 KiB |
@ -53,15 +53,11 @@ clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
rm -rf source/config.rst
|
||||
|
||||
html: source/config.rst
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
source/config.rst:
|
||||
python3 autogen_config.py
|
||||
@echo "Created docs for config options"
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@ -176,7 +172,7 @@ linkcheck:
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
|
||||
spelling:
|
||||
$(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling
|
||||
@echo "Spell check complete; look for any errors in the above output " \
|
||||
|
@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from notebook.notebookapp import NotebookApp
|
||||
|
||||
header = """\
|
||||
.. _config:
|
||||
|
||||
|
||||
Config file and command line options
|
||||
====================================
|
||||
|
||||
The notebook server can be run with a variety of command line arguments.
|
||||
A list of available options can be found below in the :ref:`options section
|
||||
<options>`.
|
||||
|
||||
Defaults for these options can also be set by creating a file named
|
||||
``jupyter_notebook_config.py`` in your Jupyter folder. The Jupyter
|
||||
folder is in your home directory, ``~/.jupyter``.
|
||||
|
||||
To create a ``jupyter_notebook_config.py`` file, with all the defaults
|
||||
commented out, you can use the following command line::
|
||||
|
||||
$ jupyter notebook --generate-config
|
||||
|
||||
|
||||
.. _options:
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
This list of options can be generated by running the following and hitting
|
||||
enter::
|
||||
|
||||
$ jupyter notebook --help
|
||||
|
||||
"""
|
||||
try:
|
||||
destination = os.path.join(os.path.dirname(__file__), 'source/config.rst')
|
||||
except:
|
||||
destination = os.path.join(os.getcwd(), 'config.rst')
|
||||
|
||||
with open(destination, 'w') as f:
|
||||
f.write(header)
|
||||
f.write(NotebookApp().document_config_options())
|
@ -1,5 +1,5 @@
|
||||
sphinx>=1.3.6
|
||||
sphinx-rtd-theme
|
||||
pydata-sphinx-theme
|
||||
nbsphinx
|
||||
sphinxcontrib_github_alt
|
||||
myst_parser
|
||||
|
@ -3,7 +3,7 @@ channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- python=3.8
|
||||
- sphinx_rtd_theme
|
||||
- pydata-sphinx-theme
|
||||
- jinja2
|
||||
- tornado
|
||||
- nbformat
|
||||
|
@ -1,21 +1,16 @@
|
||||
{
|
||||
"markdown": {
|
||||
"parser": "gfm"
|
||||
},
|
||||
"plugins": [
|
||||
"plugins/markdown" ,
|
||||
"jsdoc_plugin.js"
|
||||
],
|
||||
"source": {
|
||||
"include": [
|
||||
"../notebook/static/notebook/js/notebook.js"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
},
|
||||
"templates": {
|
||||
"cleverLinks": false,
|
||||
"monospaceLinks": false
|
||||
}
|
||||
"markdown": {
|
||||
"parser": "gfm"
|
||||
},
|
||||
"plugins": ["plugins/markdown", "jsdoc_plugin.js"],
|
||||
"source": {
|
||||
"include": ["../notebook/static/notebook/js/notebook.js"]
|
||||
},
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
},
|
||||
"templates": {
|
||||
"cleverLinks": false,
|
||||
"monospaceLinks": false
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
exports.handlers = {
|
||||
newDoclet: function(e) {
|
||||
// e.doclet will refer to the newly created doclet
|
||||
// you can read and modify properties of that doclet if you wish
|
||||
if (typeof e.doclet.name === 'string') {
|
||||
if (e.doclet.name[0] == '_') {
|
||||
console.log('Private method "' + e.doclet.longname + '" not documented.');
|
||||
e.doclet.memberof = '<anonymous>';
|
||||
}
|
||||
}
|
||||
newDoclet: function(e) {
|
||||
// e.doclet will refer to the newly created doclet
|
||||
// you can read and modify properties of that doclet if you wish
|
||||
if (typeof e.doclet.name === 'string') {
|
||||
if (e.doclet.name[0] == '_') {
|
||||
console.log(
|
||||
'Private method "' + e.doclet.longname + '" not documented.'
|
||||
);
|
||||
e.doclet.memberof = '<anonymous>';
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
Before Width: | Height: | Size: 566 KiB |
Before Width: | Height: | Size: 614 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 940 KiB |
BIN
docs/source/_static/images/notebook-running-code.png
Normal file
After Width: | Height: | Size: 940 KiB |
1622
docs/source/changelog.md
Normal file
@ -1,98 +0,0 @@
|
||||
Comms
|
||||
=====
|
||||
|
||||
*Comms* allow custom messages between the frontend and the kernel. They are used,
|
||||
for instance, in `ipywidgets <https://ipywidgets.readthedocs.io/en/latest/>`__ to
|
||||
update widget state.
|
||||
|
||||
A comm consists of a pair of objects, in the kernel and the frontend, with an
|
||||
automatically assigned unique ID. When one side sends a message, a callback on
|
||||
the other side is triggered with that message data. Either side, the frontend
|
||||
or kernel, can open or close the comm.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Custom Messages <https://jupyter-client.readthedocs.io/en/latest/messaging.html#custom-messages>`__
|
||||
The messaging specification section on comms
|
||||
|
||||
Opening a comm from the kernel
|
||||
------------------------------
|
||||
|
||||
First, the function to accept the comm must be available on the frontend. This
|
||||
can either be specified in a `requirejs` module, or registered in a registry, for
|
||||
example when an :doc:`extension <extending/frontend_extensions>` is loaded.
|
||||
This example shows a frontend comm target registered in a registry:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
Jupyter.notebook.kernel.comm_manager.register_target('my_comm_target',
|
||||
function(comm, msg) {
|
||||
// comm is the frontend comm instance
|
||||
// msg is the comm_open message, which can carry data
|
||||
|
||||
// Register handlers for later messages:
|
||||
comm.on_msg(function(msg) {...});
|
||||
comm.on_close(function(msg) {...});
|
||||
comm.send({'foo': 0});
|
||||
});
|
||||
|
||||
Now that the frontend comm is registered, you can open the comm from the kernel:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from ipykernel.comm import Comm
|
||||
|
||||
# Use comm to send a message from the kernel
|
||||
my_comm = Comm(target_name='my_comm_target', data={'foo': 1})
|
||||
my_comm.send({'foo': 2})
|
||||
|
||||
# Add a callback for received messages.
|
||||
@my_comm.on_msg
|
||||
def _recv(msg):
|
||||
# Use msg['content']['data'] for the data in the message
|
||||
|
||||
|
||||
This example uses the IPython kernel; it's up to each language kernel what API,
|
||||
if any, it offers for using comms.
|
||||
|
||||
Opening a comm from the frontend
|
||||
--------------------------------
|
||||
|
||||
This is very similar to above, but in reverse. First, a comm target must be
|
||||
registered in the kernel. For instance, this may be done by code displaying
|
||||
output: it will register a target in the kernel, and then display output
|
||||
containing Javascript to connect to it.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def target_func(comm, open_msg):
|
||||
# comm is the kernel Comm instance
|
||||
# msg is the comm_open message
|
||||
|
||||
# Register handler for later messages
|
||||
@comm.on_msg
|
||||
def _recv(msg):
|
||||
# Use msg['content']['data'] for the data in the message
|
||||
comm.send({'echo': msg['content']['data']})
|
||||
|
||||
# Send data to the frontend on creation
|
||||
comm.send({'foo': 5})
|
||||
|
||||
get_ipython().kernel.comm_manager.register_target('my_comm_target', target_func)
|
||||
|
||||
This example uses the IPython kernel again; this example will be different in
|
||||
other kernels that support comms. Refer to the specific language kernel's
|
||||
documentation for comms support.
|
||||
|
||||
And then open the comm from the frontend:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const comm = Jupyter.notebook.kernel.comm_manager.new_comm('my_comm_target', {'foo': 6})
|
||||
// Send data
|
||||
comm.send({'foo': 7})
|
||||
|
||||
// Register a handler
|
||||
comm.on_msg(function(msg) {
|
||||
console.log(msg.content.data.foo);
|
||||
});
|
@ -14,7 +14,6 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
@ -46,16 +45,6 @@ print("===============================")
|
||||
for item in sys.path:
|
||||
print(item)
|
||||
|
||||
# Check if docs are being built by ReadTheDocs
|
||||
# If so, generate a config.rst file and populate it with documentation about
|
||||
# configuration options
|
||||
|
||||
if os.environ.get('READTHEDOCS', ''):
|
||||
# Readthedocs doesn't run our Makefile, so we do this to force it to generate
|
||||
# the config docs.
|
||||
with open('../autogen_config.py') as f:
|
||||
exec(compile(f.read(), '../autogen_config.py', 'exec'), {})
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
@ -161,7 +150,7 @@ todo_include_todos = False
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme = "pydata_sphinx_theme"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@ -180,7 +169,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
html_logo = "examples/images/jupyter_logo.png"
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
@ -355,6 +344,3 @@ intersphinx_mapping = {
|
||||
|
||||
spelling_lang='en_US'
|
||||
spelling_word_list_filename='spelling_wordlist.txt'
|
||||
|
||||
# import before any doc is built, so _ is guaranteed to be injected
|
||||
import notebook.transutils
|
||||
|
@ -8,8 +8,7 @@ options to suit your workflow. Here are areas that are commonly configured
|
||||
when using Jupyter Notebook:
|
||||
|
||||
- :ref:`Jupyter's common configuration system <configure_common>`
|
||||
- :ref:`Notebook server <configure_nbserver>`
|
||||
- :ref:`Notebook front-end client <configure_nbclient>`
|
||||
- :ref:`Jupyter Server <configure_jupyter_server>`
|
||||
- :ref:`Notebook extensions <configure_nbextensions>`
|
||||
|
||||
Let's look at highlights of each area.
|
||||
@ -28,48 +27,37 @@ and editing settings is similar for all the Jupyter applications.
|
||||
- `traitlets <https://traitlets.readthedocs.io/en/latest/config.html#module-traitlets.config>`_
|
||||
provide a low-level architecture for configuration.
|
||||
|
||||
.. _configure_nbserver:
|
||||
.. _configure_jupyter_server:
|
||||
|
||||
Notebook server
|
||||
Jupyter server
|
||||
---------------
|
||||
The Notebook server runs the language kernel and communicates with the
|
||||
|
||||
The Jupyter Server runs the language kernel and communicates with the
|
||||
front-end Notebook client (i.e. the familiar notebook interface).
|
||||
|
||||
- Configuring the Notebook server
|
||||
- Configuring the Jupyter Server
|
||||
|
||||
To create a ``jupyter_notebook_config.py`` file in the ``.jupyter``
|
||||
To create a ``jupyter_server_config.py`` file in the ``.jupyter``
|
||||
directory, with all the defaults commented out, use the following
|
||||
command::
|
||||
|
||||
$ jupyter notebook --generate-config
|
||||
$ jupyter server --generate-config
|
||||
|
||||
:ref:`Command line arguments for configuration <config>` settings are
|
||||
documented in the configuration file and the user documentation.
|
||||
|
||||
- :ref:`Running a Notebook server <working_remotely>`
|
||||
- `Running a Jupyter Server <https://jupyter-server.readthedocs.io/en/stable/operators/public-server.html>`_
|
||||
- Related: `Configuring a language kernel <https://ipython.readthedocs.io/en/latest/install/kernel_install.html>`_
|
||||
to run in the Notebook server enables your server to run other languages, like R or Julia.
|
||||
|
||||
.. _configure_nbclient:
|
||||
|
||||
Notebook front-end client
|
||||
-------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
frontend_config
|
||||
to run in the Jupyter Server enables your server to run other languages, like R or Julia.
|
||||
|
||||
.. _configure_nbextensions:
|
||||
|
||||
Notebook extensions
|
||||
-------------------
|
||||
- `Distributing Jupyter Extensions as Python Packages <https://jupyter-notebook.readthedocs.io/en/latest/examples/Notebook/Distributing%20Jupyter%20Extensions%20as%20Python%20Packages.html#Distributing-Jupyter-Extensions-as-Python-Packages>`_
|
||||
- `Extending the Notebook <https://jupyter-notebook.readthedocs.io/en/latest/extending/index.html>`_
|
||||
|
||||
The Notebook frontend can be extending with JupyterLab extensions.
|
||||
|
||||
:ref:`Security in Jupyter notebooks: <notebook_security>` Since security
|
||||
policies vary from organization to organization, we encourage you to
|
||||
See the :ref:`Frontend Extension Guide <frontend_extensions>` for more information.
|
||||
|
||||
`Security in Jupyter notebooks: <https://jupyter-server.readthedocs.io/en/stable/operators/security.html>`_
|
||||
Since security policies vary from organization to organization, we encourage you to
|
||||
consult with your security team on settings that would be best for your use
|
||||
cases. Our documentation offers some responsible security practices, and we
|
||||
recommend becoming familiar with the practices.
|
||||
|
12
docs/source/configuration.rst
Normal file
@ -0,0 +1,12 @@
|
||||
=============
|
||||
Configuration
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Configuration
|
||||
|
||||
config_overview
|
||||
config
|
||||
Security <https://jupyter-server.readthedocs.io/en/stable/operators/security.html>
|
||||
extending/index.rst
|
10
docs/source/contributor.rst
Normal file
@ -0,0 +1,10 @@
|
||||
=========================
|
||||
Contributor Documentation
|
||||
=========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Contributor Documentation
|
||||
|
||||
contributing
|
||||
development_faq
|
@ -11,129 +11,17 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Starting with Jupyter Notebook 5.0, you can customize the `command` mode shortcuts from within the Notebook Application itself. \n",
|
||||
"You can customize the `command` mode shortcuts from within the Notebook Application itself. \n",
|
||||
"\n",
|
||||
"Head to the **`Help`** menu and select the **`Edit keyboard Shortcuts`** item.\n",
|
||||
"Head to the **Settings** menu and select the **Settings Editor** item.\n",
|
||||
"A dialog will guide you through the process of adding custom keyboard shortcuts.\n",
|
||||
"\n",
|
||||
"Keyboard shortcut set from within the Notebook Application will be persisted to your configuration file. \n",
|
||||
"A single action may have several shortcuts attached to it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Keyboard Shortcut Customization (Pre Notebook 5.0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Starting with IPython 2.0 keyboard shortcuts in command and edit mode are fully customizable. These customizations are made using the Jupyter JavaScript API. Here is an example that makes the `r` key available for running a cell:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"\n",
|
||||
"Jupyter.keyboard_manager.command_shortcuts.add_shortcut('r', {\n",
|
||||
" help : 'run cell',\n",
|
||||
" help_index : 'zz',\n",
|
||||
" handler : function (event) {\n",
|
||||
" IPython.notebook.execute_cell();\n",
|
||||
" return false;\n",
|
||||
" }}\n",
|
||||
");"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\"By default the keypress `r`, while in command mode, changes the type of the selected cell to `raw`. This shortcut is overridden by the code in the previous cell, and thus the action no longer be available via the keypress `r`.\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"There are a couple of points to mention about this API:\n",
|
||||
"\n",
|
||||
"* The `help_index` field is used to sort the shortcuts in the Keyboard Shortcuts help dialog. It defaults to `zz`.\n",
|
||||
"* When a handler returns `false` it indicates that the event should stop propagating and the default action should not be performed. For further details about the `event` object or event handling, see the jQuery docs.\n",
|
||||
"* If you don't need a `help` or `help_index` field, you can simply pass a function as the second argument to `add_shortcut`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"\n",
|
||||
"Jupyter.keyboard_manager.command_shortcuts.add_shortcut('r', function (event) {\n",
|
||||
" IPython.notebook.execute_cell();\n",
|
||||
" return false;\n",
|
||||
"});"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Likewise, to remove a shortcut, use `remove_shortcut`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"\n",
|
||||
"Jupyter.keyboard_manager.command_shortcuts.remove_shortcut('r');"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you want your keyboard shortcuts to be active for all of your notebooks, put the above API calls into your `custom.js` file."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"source": [
|
||||
"Of course we provide name for majority of existing action so that you do not have to re-write everything, here is for example how to bind `r` back to it's initial behavior:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"\n",
|
||||
"Jupyter.keyboard_manager.command_shortcuts.add_shortcut('r', 'jupyter-notebook:change-cell-to-raw');"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"nbsphinx": {
|
||||
"execute": "never"
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
@ -150,6 +38,9 @@
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.2"
|
||||
},
|
||||
"nbsphinx": {
|
||||
"execute": "never"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -1,603 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Embracing web standards"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"One of the main reasons why we developed the current notebook web application \n",
|
||||
"was to embrace the web technology. \n",
|
||||
"\n",
|
||||
"By being a pure web application using HTML, JavaScript, and CSS, the Notebook can get \n",
|
||||
"all the web technology improvement for free. Thus, as browser support for different \n",
|
||||
"media extend, the notebook web app should be able to be compatible without modification. \n",
|
||||
"\n",
|
||||
"This is also true with performance of the User Interface as the speed of JavaScript VM increases. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The other advantage of using only web technology is that the code of the interface is fully accessible to the end user and is modifiable live.\n",
|
||||
"Even if this task is not always easy, we strive to keep our code as accessible and reusable as possible.\n",
|
||||
"This should allow us - with minimum effort - development of small extensions that customize the behavior of the web interface. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Tampering with the Notebook application"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The first tool that is available to you and that you should be aware of are browser \"developers tool\". The exact naming can change across browser and might require the installation of extensions. But basically they can allow you to inspect/modify the DOM, and interact with the JavaScript code that runs the frontend.\n",
|
||||
"\n",
|
||||
" - In Chrome and Safari, Developer tools are in the menu `View > Developer > JavaScript Console` \n",
|
||||
" - In Firefox you might need to install [Firebug](http://getfirebug.com/)\n",
|
||||
" \n",
|
||||
"Those will be your best friends to debug and try different approaches for your extensions."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Injecting JS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Using magics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The above tools can be tedious for editing edit long JavaScript files. Therefore we provide the `%%javascript` magic. This allows you to quickly inject JavaScript into the notebook. Still the JavaScript injected this way will not survive reloading. Hence, it is a good tool for testing and refining a script.\n",
|
||||
"\n",
|
||||
"You might see here and there people modifying css and injecting js into the notebook by reading file(s) and publishing them into the notebook.\n",
|
||||
"Not only does this often break the flow of the notebook and make the re-execution of the notebook broken, but it also means that you need to execute those cells in the entire notebook every time you need to update the code.\n",
|
||||
"\n",
|
||||
"This can still be useful in some cases, like the `%autosave` magic that allows you to control the time between each save. But this can be replaced by a JavaScript dropdown menu to select the save interval."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## you can inspect the autosave code to see what it does.\n",
|
||||
"%autosave??"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### custom.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To inject JavaScript we provide an entry point: `custom.js` that allows the user to execute and load other resources into the notebook.\n",
|
||||
"JavaScript code in `custom.js` will be executed when the notebook app starts and can then be used to customize almost anything in the UI and in the behavior of the notebook.\n",
|
||||
"\n",
|
||||
"`custom.js` can be found in the `~/.jupyter/custom/custom.js`. You can share your custom.js with others."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"##### Back to theory"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from jupyter_core.paths import jupyter_config_dir\n",
|
||||
"jupyter_dir = jupyter_config_dir()\n",
|
||||
"jupyter_dir"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and custom js is in "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os.path\n",
|
||||
"custom_js_path = os.path.join(jupyter_dir, 'custom', 'custom.js')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# my custom js\n",
|
||||
"if os.path.isfile(custom_js_path):\n",
|
||||
" with open(custom_js_path) as f:\n",
|
||||
" print(f.read())\n",
|
||||
"else:\n",
|
||||
" print(\"You don't have a custom.js file\") "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that `custom.js` is meant to be modified by user. When writing a script, you can define it in a separate file and add a line of configuration into `custom.js` that will fetch and execute the file."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Warning** : even if modification of `custom.js` takes effect immediately after browser refresh (except if browser cache is aggressive), *creating* a file in `static/` directory needs a **server restart**."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Exercise :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
" - Create a `custom.js` in the right location with the following content:\n",
|
||||
"```javascript\n",
|
||||
"alert(\"hello world from custom.js\")\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
" - Restart your server and open any notebook.\n",
|
||||
" - Be greeted by custom.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Have a look at [default custom.js](https://github.com/jupyter/notebook/blob/4.0.x/notebook/static/custom/custom.js), to see it's content and for more explanation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### For the quick ones : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We've seen above that you can change the autosave rate by using a magic. This is typically something I don't want to type every time, and that I don't like to embed into my workflow and documents. (readers don't care what my autosave time is). Let's build an extension that allows us to do it. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"foo": true
|
||||
},
|
||||
"source": [
|
||||
"Create a dropdown element in the toolbar (DOM `Jupyter.toolbar.element`), you will need \n",
|
||||
"\n",
|
||||
"- `Jupyter.notebook.set_autosave_interval(milliseconds)`\n",
|
||||
"- know that 1 min = 60 sec, and 1 sec = 1000 ms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```javascript\n",
|
||||
"\n",
|
||||
"var label = jQuery('<label/>').text('AutoScroll Limit:');\n",
|
||||
"var select = jQuery('<select/>')\n",
|
||||
" //.append(jQuery('<option/>').attr('value', '2').text('2min (default)'))\n",
|
||||
" .append(jQuery('<option/>').attr('value', undefined).text('disabled'))\n",
|
||||
"\n",
|
||||
" // TODO:\n",
|
||||
" //the_toolbar_element.append(label)\n",
|
||||
" //the_toolbar_element.append(select);\n",
|
||||
" \n",
|
||||
"select.change(function() {\n",
|
||||
" var val = jQuery(this).val() // val will be the value in [2]\n",
|
||||
" // TODO\n",
|
||||
" // this will be called when dropdown changes\n",
|
||||
"\n",
|
||||
"});\n",
|
||||
"\n",
|
||||
"var time_m = [1,5,10,15,30];\n",
|
||||
"for (var i=0; i < time_m.length; i++) {\n",
|
||||
" var ts = time_m[i];\n",
|
||||
" //[2] ____ this will be `val` on [1] \n",
|
||||
" // | \n",
|
||||
" // v \n",
|
||||
" select.append($('<option/>').attr('value', ts).text(thr+'min'));\n",
|
||||
" // this will fill up the dropdown `select` with\n",
|
||||
" // 1 min\n",
|
||||
" // 5 min\n",
|
||||
" // 10 min\n",
|
||||
" // 10 min\n",
|
||||
" // ...\n",
|
||||
"}\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### A non-interactive example first"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"I like my cython to be nicely highlighted\n",
|
||||
"\n",
|
||||
"```javascript\n",
|
||||
"Jupyter.config.cell_magic_highlight['magic_text/x-cython'] = {}\n",
|
||||
"Jupyter.config.cell_magic_highlight['magic_text/x-cython'].reg = [/^%%cython/]\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"`text/x-cython` is the name of CodeMirror mode name, `magic_` prefix will just patch the mode so that the first line that contains a magic does not screw up the highlighting. `reg`is a list or regular expression that will trigger the change of mode."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Get more documentation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Sadly, you will have to read the js source file (but there are lots of comments) and/or build the JavaScript documentation using yuidoc.\n",
|
||||
"If you have `node` and `yui-doc` installed:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```bash\n",
|
||||
"$ cd ~/jupyter/notebook/notebook/static/notebook/js/\n",
|
||||
"$ yuidoc . --server\n",
|
||||
"warn: (yuidoc): Failed to extract port, setting to the default :3000\n",
|
||||
"info: (yuidoc): Starting YUIDoc@0.3.45 using YUI@3.9.1 with NodeJS@0.10.15\n",
|
||||
"info: (yuidoc): Scanning for yuidoc.json file.\n",
|
||||
"info: (yuidoc): Starting YUIDoc with the following options:\n",
|
||||
"info: (yuidoc):\n",
|
||||
"{ port: 3000,\n",
|
||||
" nocode: false,\n",
|
||||
" paths: [ '.' ],\n",
|
||||
" server: true,\n",
|
||||
" outdir: './out' }\n",
|
||||
"info: (yuidoc): Scanning for yuidoc.json file.\n",
|
||||
"info: (server): Starting server: http://127.0.0.1:3000\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"and browse http://127.0.0.1:3000 to get documentation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"foo": true
|
||||
},
|
||||
"source": [
|
||||
"#### Some convenience methods"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"By browsing the documentation you will see that we have some convenience methods that allows us to avoid re-inventing the UI every time :\n",
|
||||
"```javascript\n",
|
||||
"Jupyter.toolbar.add_buttons_group([\n",
|
||||
" {\n",
|
||||
" 'label' : 'run qtconsole',\n",
|
||||
" 'icon' : 'fa-terminal', // select your icon from \n",
|
||||
" // http://fontawesome.io/icons/\n",
|
||||
" 'callback': function(){Jupyter.notebook.kernel.execute('%qtconsole')}\n",
|
||||
" }\n",
|
||||
" // add more button here if needed.\n",
|
||||
" ]);\n",
|
||||
"```\n",
|
||||
"with a [lot of icons] you can select from. \n",
|
||||
"\n",
|
||||
"[lot of icons]: http://fontawesome.io/icons/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"foo": true
|
||||
},
|
||||
"source": [
|
||||
"## Cell Metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"foo": true
|
||||
},
|
||||
"source": [
|
||||
"The most requested feature is generally to be able to distinguish an individual cell in the notebook, or run a specific action with them.\n",
|
||||
"To do so, you can either use `Jupyter.notebook.get_selected_cell()`, or rely on `CellToolbar`. This allows you to register a set of actions and graphical elements that will be attached to individual cells."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Cell Toolbar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can see some example of what can be done by toggling the `Cell Toolbar` selector in the toolbar on top of the notebook. It provides two default `presets` that are `Default` and `slideshow`. Default allows the user to edit the metadata attached to each cell manually."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First we define a function that takes at first parameter an element on the DOM in which to inject UI element. The second element is the cell this element wis registered with. Then we will need to register that function and give it a name.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Register a callback"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"var CellToolbar = Jupyter.CellToolbar\n",
|
||||
"var toggle = function(div, cell) {\n",
|
||||
" var button_container = $(div)\n",
|
||||
"\n",
|
||||
" // let's create a button that shows the current value of the metadata\n",
|
||||
" var button = $('<button/>').addClass('btn btn-mini').text(String(cell.metadata.foo));\n",
|
||||
"\n",
|
||||
" // On click, change the metadata value and update the button label\n",
|
||||
" button.click(function(){\n",
|
||||
" var v = cell.metadata.foo;\n",
|
||||
" cell.metadata.foo = !v;\n",
|
||||
" button.text(String(!v));\n",
|
||||
" })\n",
|
||||
"\n",
|
||||
" // add the button to the DOM div.\n",
|
||||
" button_container.append(button);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
" // now we register the callback under the name foo to give the\n",
|
||||
" // user the ability to use it later\n",
|
||||
" CellToolbar.register_callback('tuto.foo', toggle);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Registering a preset"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This function can now be part of many `preset` of the CellToolBar."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"foo": true,
|
||||
"slideshow": {
|
||||
"slide_type": "subslide"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%javascript\n",
|
||||
"Jupyter.CellToolbar.register_preset('Tutorial 1',['tuto.foo','default.rawedit'])\n",
|
||||
"Jupyter.CellToolbar.register_preset('Tutorial 2',['slideshow.select','tuto.foo'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You should now have access to two presets :\n",
|
||||
"\n",
|
||||
" - Tutorial 1\n",
|
||||
" - Tutorial 2\n",
|
||||
" \n",
|
||||
"And check that the buttons you defined share state when you toggle preset. \n",
|
||||
"Also check that the metadata of the cell is modified when you click the button, and that when saved on reloaded the metadata is still available."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Exercise:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Try to wrap the all code in a file, put this file in `{jupyter_dir}/custom/<a-name>.js`, and add \n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"require(['custom/<a-name>']);\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"in `custom.js` to have this script automatically loaded in all your notebooks.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"`require` is provided by a [JavaScript library](http://requirejs.org/) that allow you to express dependency. For simple extension like the previous one we directly mute the global namespace, but for more complex extension you could pass a callback to `require([...], <callback>)` call, to allow the user to pass configuration information to your plugin.\n",
|
||||
"\n",
|
||||
"In Python language, \n",
|
||||
"\n",
|
||||
"```javascript\n",
|
||||
"require(['a/b', 'c/d'], function( e, f){\n",
|
||||
" e.something()\n",
|
||||
" f.something()\n",
|
||||
"})\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"could be read as\n",
|
||||
"```python\n",
|
||||
"import a.b as e\n",
|
||||
"import c.d as f\n",
|
||||
"e.something()\n",
|
||||
"f.something()\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"See for example @damianavila [\"ZenMode\" plugin](https://github.com/ipython-contrib/jupyter_contrib_nbextensions/blob/b29c698394239a6931fa4911440550df214812cb/src/jupyter_contrib_nbextensions/nbextensions/zenmode/main.js#L32) :\n",
|
||||
"\n",
|
||||
"```javascript\n",
|
||||
"\n",
|
||||
"// read that as\n",
|
||||
"// import custom.zenmode.main as zenmode\n",
|
||||
"require(['custom/zenmode/main'],function(zenmode){\n",
|
||||
" zenmode.background('images/back12.jpg');\n",
|
||||
"})\n",
|
||||
"```\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### For the quickest"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Try to use [the following](https://github.com/ipython/ipython/blob/1.x/IPython/html/static/notebook/js/celltoolbar.js#L367) to bind a dropdown list to `cell.metadata.difficulty.select`. \n",
|
||||
"\n",
|
||||
"It should be able to take the 4 following values :\n",
|
||||
"\n",
|
||||
" - `<None>`\n",
|
||||
" - `Easy`\n",
|
||||
" - `Medium`\n",
|
||||
" - `Hard`\n",
|
||||
" \n",
|
||||
"We will use it to customize the output of the converted notebook depending on the tag on each cell"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# %load soln/celldiff.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"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.5.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
@ -30,9 +30,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -41,9 +44,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -84,9 +90,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -106,7 +115,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -174,7 +186,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -193,7 +208,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -227,7 +245,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -270,7 +291,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -346,7 +370,10 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@ -864,7 +891,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@ -878,9 +905,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
|
@ -1,183 +0,0 @@
|
||||
Custom bundler extensions
|
||||
=========================
|
||||
|
||||
The notebook server supports the writing of *bundler extensions* that
|
||||
transform, package, and download/deploy notebook files. As a developer, you
|
||||
need only write a single Python function to implement a bundler. The notebook
|
||||
server automatically generates a *File -> Download as* or *File -> Deploy as*
|
||||
menu item in the notebook front-end to trigger your bundler.
|
||||
|
||||
Here are some examples of what you can implement using bundler extensions:
|
||||
|
||||
* Convert a notebook file to a HTML document and publish it as a post on a
|
||||
blog site
|
||||
* Create a snapshot of the current notebook environment and bundle that
|
||||
definition plus notebook into a zip download
|
||||
* Deploy a notebook as a standalone, interactive `dashboard <https://github.com/jupyter-incubator/dashboards_bundlers>`_
|
||||
|
||||
To implement a bundler extension, you must do all of the following:
|
||||
|
||||
* Declare bundler extension metadata in your Python package
|
||||
* Write a `bundle` function that responds to bundle requests
|
||||
* Instruct your users on how to enable/disable your bundler extension
|
||||
|
||||
The following sections describe these steps in detail.
|
||||
|
||||
Declaring bundler metadata
|
||||
--------------------------
|
||||
|
||||
You must provide information about the bundler extension(s) your package
|
||||
provides by implementing a `_jupyter_bundlerextensions_paths` function. This
|
||||
function can reside anywhere in your package so long as it can be imported
|
||||
when enabling the bundler extension. (See :ref:`enabling-bundlers`.)
|
||||
|
||||
.. code:: python
|
||||
|
||||
# in mypackage.hello_bundler
|
||||
|
||||
def _jupyter_bundlerextension_paths():
|
||||
"""Example "hello world" bundler extension"""
|
||||
return [{
|
||||
'name': 'hello_bundler', # unique bundler name
|
||||
'label': 'Hello Bundler', # human-readable menu item label
|
||||
'module_name': 'mypackage.hello_bundler', # module containing bundle()
|
||||
'group': 'deploy' # group under 'deploy' or 'download' menu
|
||||
}]
|
||||
|
||||
Note that the return value is a list. By returning multiple dictionaries in
|
||||
the list, you allow users to enable/disable sets of bundlers all at once.
|
||||
|
||||
Writing the `bundle` function
|
||||
-----------------------------
|
||||
|
||||
At runtime, a menu item with the given label appears either in the
|
||||
*File -> Deploy as* or *File -> Download as* menu depending on the `group`
|
||||
value in your metadata. When a user clicks the menu item, a new browser tab
|
||||
opens and notebook server invokes a `bundle` function in the `module_name`
|
||||
specified in the metadata.
|
||||
|
||||
You must implement a `bundle` function that matches the signature of the
|
||||
following example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# in mypackage.hello_bundler
|
||||
|
||||
def bundle(handler, model):
|
||||
"""Transform, convert, bundle, etc. the notebook referenced by the given
|
||||
model.
|
||||
|
||||
Then issue a Tornado web response using the `handler` to redirect
|
||||
the user's browser, download a file, show a HTML page, etc. This function
|
||||
must finish the handler response before returning either explicitly or by
|
||||
raising an exception.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
handler : tornado.web.RequestHandler
|
||||
Handler that serviced the bundle request
|
||||
model : dict
|
||||
Notebook model from the configured ContentManager
|
||||
"""
|
||||
handler.finish('I bundled {}!'.format(model['path']))
|
||||
|
||||
Your `bundle` function is free to do whatever it wants with the request and
|
||||
respond in any manner. For example, it may read additional query parameters
|
||||
from the request, issue a redirect to another site, run a local process (e.g.,
|
||||
`nbconvert`), make a HTTP request to another service, etc.
|
||||
|
||||
The caller of the `bundle` function is `@tornado.gen.coroutine` decorated and
|
||||
wraps its call with `torando.gen.maybe_future`. This behavior means you may
|
||||
handle the web request synchronously, as in the example above, or
|
||||
asynchronously using `@tornado.gen.coroutine` and `yield`, as in the example
|
||||
below.
|
||||
|
||||
.. code:: python
|
||||
|
||||
from tornado import gen
|
||||
|
||||
@gen.coroutine
|
||||
def bundle(handler, model):
|
||||
# simulate a long running IO op (e.g., deploying to a remote host)
|
||||
yield gen.sleep(10)
|
||||
|
||||
# now respond
|
||||
handler.finish('I spent 10 seconds bundling {}!'.format(model['path']))
|
||||
|
||||
You should prefer the second, asynchronous approach when your bundle operation
|
||||
is long-running and would otherwise block the notebook server main loop if
|
||||
handled synchronously.
|
||||
|
||||
For more details about the data flow from menu item click to bundle function
|
||||
invocation, see :ref:`bundler-details`.
|
||||
|
||||
.. _enabling-bundlers:
|
||||
|
||||
Enabling/disabling bundler extensions
|
||||
-------------------------------------
|
||||
|
||||
The notebook server includes a command line interface (CLI) for enabling and
|
||||
disabling bundler extensions.
|
||||
|
||||
You should document the basic commands for enabling and disabling your
|
||||
bundler. One possible command for enabling the `hello_bundler` example is the
|
||||
following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
jupyter bundlerextension enable --py mypackage.hello_bundler --sys-prefix
|
||||
|
||||
The above updates the notebook configuration file in the current
|
||||
conda/virtualenv environment (`--sys-prefix`) with the metadata returned by
|
||||
the `mypackage.hellow_bundler._jupyter_bundlerextension_paths` function.
|
||||
|
||||
The corresponding command to later disable the bundler extension is the
|
||||
following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
jupyter bundlerextension disable --py mypackage.hello_bundler --sys-prefix
|
||||
|
||||
For more help using the `bundlerextension` subcommand, run the following.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
jupyter bundlerextension --help
|
||||
|
||||
The output describes options for listing enabled bundlers, configuring
|
||||
bundlers for single users, configuring bundlers system-wide, etc.
|
||||
|
||||
Example: IPython Notebook bundle (.zip)
|
||||
---------------------------------------
|
||||
|
||||
The `hello_bundler` example in this documentation is simplistic in the name
|
||||
of brevity. For more meaningful examples, see
|
||||
`notebook/bundler/zip_bundler.py` and `notebook/bundler/tarball_bundler.py`.
|
||||
You can enable them to try them like so:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
jupyter bundlerextension enable --py notebook.bundler.zip_bundler --sys-prefix
|
||||
jupyter bundlerextension enable --py notebook.bundler.tarball_bundler --sys-prefix
|
||||
|
||||
.. _bundler-details:
|
||||
|
||||
Bundler invocation details
|
||||
--------------------------
|
||||
|
||||
Support for bundler extensions comes from Python modules in `notebook/bundler`
|
||||
and JavaScript in `notebook/static/notebook/js/menubar.js`. The flow of data
|
||||
between the various components proceeds roughly as follows:
|
||||
|
||||
1. User opens a notebook document
|
||||
2. Notebook front-end JavaScript loads notebook configuration
|
||||
3. Bundler front-end JS creates menu items for all bundler extensions in the
|
||||
config
|
||||
4. User clicks a bundler menu item
|
||||
5. JS click handler opens a new browser window/tab to
|
||||
`<notebook base_url>/bundle/<path/to/notebook>?bundler=<name>` (i.e., a
|
||||
HTTP GET request)
|
||||
6. Bundle handler validates the notebook path and bundler `name`
|
||||
7. Bundle handler delegates the request to the `bundle` function in the
|
||||
bundler's `module_name`
|
||||
8. `bundle` function finishes the HTTP request
|
@ -1,293 +0,0 @@
|
||||
.. _contents_api:
|
||||
|
||||
Contents API
|
||||
============
|
||||
|
||||
.. currentmodule:: notebook.services.contents
|
||||
|
||||
The Jupyter Notebook web application provides a graphical interface for
|
||||
creating, opening, renaming, and deleting files in a virtual filesystem.
|
||||
|
||||
The :class:`~manager.ContentsManager` class defines an abstract
|
||||
API for translating these interactions into operations on a particular storage
|
||||
medium. The default implementation,
|
||||
:class:`~filemanager.FileContentsManager`, uses the local
|
||||
filesystem of the server for storage and straightforwardly serializes notebooks
|
||||
into JSON. Users can override these behaviors by supplying custom subclasses
|
||||
of ContentsManager.
|
||||
|
||||
This section describes the interface implemented by ContentsManager subclasses.
|
||||
We refer to this interface as the **Contents API**.
|
||||
|
||||
Data Model
|
||||
----------
|
||||
|
||||
.. currentmodule:: notebook.services.contents.manager
|
||||
|
||||
Filesystem Entities
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
.. _notebook models:
|
||||
|
||||
ContentsManager methods represent virtual filesystem entities as dictionaries,
|
||||
which we refer to as **models**.
|
||||
|
||||
Models may contain the following entries:
|
||||
|
||||
+--------------------+-----------+------------------------------+
|
||||
| Key | Type |Info |
|
||||
+====================+===========+==============================+
|
||||
|**name** |unicode |Basename of the entity. |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**path** |unicode |Full |
|
||||
| | |(:ref:`API-style<apipaths>`) |
|
||||
| | |path to the entity. |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**type** |unicode |The entity type. One of |
|
||||
| | |``"notebook"``, ``"file"`` or |
|
||||
| | |``"directory"``. |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**created** |datetime |Creation date of the entity. |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**last_modified** |datetime |Last modified date of the |
|
||||
| | |entity. |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**content** |variable |The "content" of the entity. |
|
||||
| | |(:ref:`See |
|
||||
| | |Below<modelcontent>`) |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**mimetype** |unicode or |The mimetype of ``content``, |
|
||||
| |``None`` |if any. (:ref:`See |
|
||||
| | |Below<modelcontent>`) |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|**format** |unicode or |The format of ``content``, |
|
||||
| |``None`` |if any. (:ref:`See |
|
||||
| | |Below<modelcontent>`) |
|
||||
+--------------------+-----------+------------------------------+
|
||||
|
||||
.. _modelcontent:
|
||||
|
||||
Certain model fields vary in structure depending on the ``type`` field of the
|
||||
model. There are three model types: **notebook**, **file**, and **directory**.
|
||||
|
||||
- ``notebook`` models
|
||||
- The ``format`` field is always ``"json"``.
|
||||
- The ``mimetype`` field is always ``None``.
|
||||
- The ``content`` field contains a
|
||||
:class:`nbformat.notebooknode.NotebookNode` representing the .ipynb file
|
||||
represented by the model. See the `NBFormat`_ documentation for a full
|
||||
description.
|
||||
|
||||
- ``file`` models
|
||||
- The ``format`` field is either ``"text"`` or ``"base64"``.
|
||||
- The ``mimetype`` field can be any mimetype string, but defaults to
|
||||
``text/plain`` for text-format models and
|
||||
``application/octet-stream`` for base64-format models. For files with
|
||||
unknown mime types (e.g. unknown file extensions), this field may be
|
||||
`None`.
|
||||
- The ``content`` field is always of type ``unicode``. For text-format
|
||||
file models, ``content`` simply contains the file's bytes after decoding
|
||||
as UTF-8. Non-text (``base64``) files are read as bytes, base64 encoded,
|
||||
and then decoded as UTF-8.
|
||||
|
||||
- ``directory`` models
|
||||
- The ``format`` field is always ``"json"``.
|
||||
- The ``mimetype`` field is always ``None``.
|
||||
- The ``content`` field contains a list of :ref:`content-free<contentfree>`
|
||||
models representing the entities in the directory.
|
||||
|
||||
.. note::
|
||||
|
||||
.. _contentfree:
|
||||
|
||||
In certain circumstances, we don't need the full content of an entity to
|
||||
complete a Contents API request. In such cases, we omit the ``content``, and
|
||||
``format`` keys from the model. The default values for the ``mimetype``
|
||||
field will might also not be evaluated, in which case it will be set as `None`.
|
||||
This reduced reply most commonly occurs when listing a directory, in
|
||||
which circumstance we represent files within the directory as content-less
|
||||
models to avoid having to recursively traverse and serialize the entire
|
||||
filesystem.
|
||||
|
||||
**Sample Models**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Notebook Model with Content
|
||||
{
|
||||
'content': {
|
||||
'metadata': {},
|
||||
'nbformat': 4,
|
||||
'nbformat_minor': 0,
|
||||
'cells': [
|
||||
{
|
||||
'cell_type': 'markdown',
|
||||
'metadata': {},
|
||||
'source': 'Some **Markdown**',
|
||||
},
|
||||
],
|
||||
},
|
||||
'created': datetime(2015, 7, 25, 19, 50, 19, 19865),
|
||||
'format': 'json',
|
||||
'last_modified': datetime(2015, 7, 25, 19, 50, 19, 19865),
|
||||
'mimetype': None,
|
||||
'name': 'a.ipynb',
|
||||
'path': 'foo/a.ipynb',
|
||||
'type': 'notebook',
|
||||
'writable': True,
|
||||
}
|
||||
|
||||
# Notebook Model without Content
|
||||
{
|
||||
'content': None,
|
||||
'created': datetime.datetime(2015, 7, 25, 20, 17, 33, 271931),
|
||||
'format': None,
|
||||
'last_modified': datetime.datetime(2015, 7, 25, 20, 17, 33, 271931),
|
||||
'mimetype': None,
|
||||
'name': 'a.ipynb',
|
||||
'path': 'foo/a.ipynb',
|
||||
'type': 'notebook',
|
||||
'writable': True
|
||||
}
|
||||
|
||||
|
||||
API Paths
|
||||
~~~~~~~~~
|
||||
.. _apipaths:
|
||||
|
||||
ContentsManager methods represent the locations of filesystem resources as
|
||||
**API-style paths**. Such paths are interpreted as relative to the root
|
||||
directory of the notebook server. For compatibility across systems, the
|
||||
following guarantees are made:
|
||||
|
||||
* Paths are always ``unicode``, not ``bytes``.
|
||||
* Paths are not URL-escaped.
|
||||
* Paths are always forward-slash (/) delimited, even on Windows.
|
||||
* Leading and trailing slashes are stripped. For example, ``/foo/bar/buzz/``
|
||||
becomes ``foo/bar/buzz``.
|
||||
* The empty string (``""``) represents the root directory.
|
||||
|
||||
|
||||
Writing a Custom ContentsManager
|
||||
--------------------------------
|
||||
|
||||
The default ContentsManager is designed for users running the notebook as an
|
||||
application on a personal computer. It stores notebooks as .ipynb files on the
|
||||
local filesystem, and it maps files and directories in the Notebook UI to files
|
||||
and directories on disk. It is possible to override how notebooks are stored
|
||||
by implementing your own custom subclass of ``ContentsManager``. For example,
|
||||
if you deploy the notebook in a context where you don't trust or don't have
|
||||
access to the filesystem of the notebook server, it's possible to write your
|
||||
own ContentsManager that stores notebooks and files in a database.
|
||||
|
||||
|
||||
Required Methods
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
A minimal complete implementation of a custom
|
||||
:class:`~manager.ContentsManager` must implement the following
|
||||
methods:
|
||||
|
||||
.. autosummary::
|
||||
ContentsManager.get
|
||||
ContentsManager.save
|
||||
ContentsManager.delete_file
|
||||
ContentsManager.rename_file
|
||||
ContentsManager.file_exists
|
||||
ContentsManager.dir_exists
|
||||
ContentsManager.is_hidden
|
||||
|
||||
You may be required to specify a Checkpoints object, as the default one,
|
||||
``FileCheckpoints``, could be incompatible with your custom
|
||||
ContentsManager.
|
||||
|
||||
|
||||
Chunked Saving
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The contents API allows for "chunked" saving of files, i.e.
|
||||
saving/transmitting in partial pieces:
|
||||
|
||||
* This can only be used when the ``type`` of the model is ``file``.
|
||||
* The model should be as otherwise expected for
|
||||
:meth:`~manager.ContentsManager.save`, with an added field ``chunk``.
|
||||
* The value of ``chunk`` should be an integer starting at ``1``, and incrementing
|
||||
for each subsequent chunk, except for the final chunk, which should be
|
||||
indicated with a value of ``-1``.
|
||||
* The model returned from using :meth:`~manager.ContentsManager.save` with
|
||||
``chunk`` should be treated as unreliable for all chunks except the final one.
|
||||
* Any interaction with a file being saved in a chunked manner is unreliable
|
||||
until the final chunk has been saved. This includes directory listings.
|
||||
|
||||
|
||||
Customizing Checkpoints
|
||||
-----------------------
|
||||
.. currentmodule:: notebook.services.contents.checkpoints
|
||||
|
||||
Customized Checkpoint definitions allows behavior to be
|
||||
altered and extended.
|
||||
|
||||
The ``Checkpoints`` and ``GenericCheckpointsMixin`` classes
|
||||
(from :mod:`notebook.services.contents.checkpoints`)
|
||||
have reusable code and are intended to be used together,
|
||||
but require the following methods to be implemented.
|
||||
|
||||
.. autosummary::
|
||||
Checkpoints.rename_checkpoint
|
||||
Checkpoints.list_checkpoints
|
||||
Checkpoints.delete_checkpoint
|
||||
GenericCheckpointsMixin.create_file_checkpoint
|
||||
GenericCheckpointsMixin.create_notebook_checkpoint
|
||||
GenericCheckpointsMixin.get_file_checkpoint
|
||||
GenericCheckpointsMixin.get_notebook_checkpoint
|
||||
|
||||
No-op example
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Here is an example of a no-op checkpoints object - note the mixin
|
||||
comes first. The docstrings indicate what each method should do or
|
||||
return for a more complete implementation.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class NoOpCheckpoints(GenericCheckpointsMixin, Checkpoints):
|
||||
"""requires the following methods:"""
|
||||
def create_file_checkpoint(self, content, format, path):
|
||||
""" -> checkpoint model"""
|
||||
def create_notebook_checkpoint(self, nb, path):
|
||||
""" -> checkpoint model"""
|
||||
def get_file_checkpoint(self, checkpoint_id, path):
|
||||
""" -> {'type': 'file', 'content': <str>, 'format': {'text', 'base64'}}"""
|
||||
def get_notebook_checkpoint(self, checkpoint_id, path):
|
||||
""" -> {'type': 'notebook', 'content': <output of nbformat.read>}"""
|
||||
def delete_checkpoint(self, checkpoint_id, path):
|
||||
"""deletes a checkpoint for a file"""
|
||||
def list_checkpoints(self, path):
|
||||
"""returns a list of checkpoint models for a given file,
|
||||
default just does one per file
|
||||
"""
|
||||
return []
|
||||
def rename_checkpoint(self, checkpoint_id, old_path, new_path):
|
||||
"""renames checkpoint from old path to new path"""
|
||||
|
||||
See ``GenericFileCheckpoints`` in :mod:`notebook.services.contents.filecheckpoints`
|
||||
for a more complete example.
|
||||
|
||||
Testing
|
||||
-------
|
||||
.. currentmodule:: notebook.services.contents.tests
|
||||
|
||||
:mod:`notebook.services.contents.tests` includes several test suites written
|
||||
against the abstract Contents API. This means that an excellent way to test a
|
||||
new ContentsManager subclass is to subclass our tests to make them use your
|
||||
ContentsManager.
|
||||
|
||||
.. note::
|
||||
|
||||
PGContents_ is an example of a complete implementation of a custom
|
||||
``ContentsManager``. It stores notebooks and files in PostgreSQL_ and encodes
|
||||
directories as SQL relations. PGContents also provides an example of how to
|
||||
re-use the notebook's tests.
|
||||
|
||||
.. _NBFormat: https://nbformat.readthedocs.io/en/latest/index.html
|
||||
.. _PGContents: https://github.com/quantopian/pgcontents
|
||||
.. _PostgreSQL: https://www.postgresql.org/
|
@ -1,280 +1,19 @@
|
||||
.. _frontend_extensions:
|
||||
|
||||
===========================
|
||||
Custom front-end extensions
|
||||
===========================
|
||||
|
||||
This describes the basic steps to write a JavaScript extension for the Jupyter
|
||||
This describes the basic steps to write a TypeScript extension for the Jupyter
|
||||
notebook front-end. This allows you to customize the behaviour of the various
|
||||
pages like the dashboard, the notebook, or the text editor.
|
||||
|
||||
The structure of a front-end extension
|
||||
--------------------------------------
|
||||
Starting with Notebook v7, front-end extensions for the notebook can be developed
|
||||
as prebuilt JupyterLab extensions.
|
||||
|
||||
.. note::
|
||||
This means Notebook v7 is able to reuse many of the existing extensions from the JupyterLab ecosystem as is.
|
||||
|
||||
The notebook front-end and Javascript API are not stable, and are subject
|
||||
to a lot of changes. Any extension written for the current notebook is
|
||||
almost guaranteed to break in the next release.
|
||||
If you would like to develop a prebuilt extension for Notebook v7, check out:
|
||||
|
||||
.. _AMD module: https://en.wikipedia.org/wiki/Asynchronous_module_definition
|
||||
|
||||
A front-end extension is a JavaScript file that defines an `AMD module`_
|
||||
which exposes at least a function called ``load_ipython_extension``, which
|
||||
takes no arguments. We will not get into the details of what each of these
|
||||
terms consists of yet, but here is the minimal code needed for a working
|
||||
extension:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file my_extension/main.js
|
||||
|
||||
define(function(){
|
||||
|
||||
function load_ipython_extension(){
|
||||
console.info('this is my first extension');
|
||||
}
|
||||
|
||||
return {
|
||||
load_ipython_extension: load_ipython_extension
|
||||
};
|
||||
});
|
||||
|
||||
.. note::
|
||||
|
||||
Although for historical reasons the function is called
|
||||
``load_ipython_extension``, it does apply to the Jupyter notebook in
|
||||
general, and will work regardless of the kernel in use.
|
||||
|
||||
If you are familiar with JavaScript, you can use this template to require any
|
||||
Jupyter module and modify its configuration, or do anything else in client-side
|
||||
Javascript. Your extension will be loaded at the right time during the notebook
|
||||
page initialisation for you to set up a listener for the various events that
|
||||
the page can trigger.
|
||||
|
||||
You might want access to the current instances of the various Jupyter notebook
|
||||
components on the page, as opposed to the classes defined in the modules. The
|
||||
current instances are exposed by a module named ``base/js/namespace``. If you
|
||||
plan on accessing instances on the page, you should ``require`` this module
|
||||
rather than accessing the global variable ``Jupyter``, which will be removed in
|
||||
future. The following example demonstrates how to access the current notebook
|
||||
instance:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file my_extension/main.js
|
||||
|
||||
define([
|
||||
'base/js/namespace'
|
||||
], function(
|
||||
Jupyter
|
||||
) {
|
||||
function load_ipython_extension() {
|
||||
console.log(
|
||||
'This is the current notebook application instance:',
|
||||
Jupyter.notebook
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
load_ipython_extension: load_ipython_extension
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Modifying key bindings
|
||||
----------------------
|
||||
|
||||
One of the abilities of extensions is to modify key bindings, although once
|
||||
again this is an API which is not guaranteed to be stable. However, custom key
|
||||
bindings are frequently requested, and are helpful to increase accessibility,
|
||||
so in the following we show how to access them.
|
||||
|
||||
Here is an example of an extension that will unbind the shortcut ``0,0`` in
|
||||
command mode, which normally restarts the kernel, and bind ``0,0,0`` in its
|
||||
place:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file my_extension/main.js
|
||||
|
||||
define([
|
||||
'base/js/namespace'
|
||||
], function(
|
||||
Jupyter
|
||||
) {
|
||||
|
||||
function load_ipython_extension() {
|
||||
Jupyter.keyboard_manager.command_shortcuts.remove_shortcut('0,0');
|
||||
Jupyter.keyboard_manager.command_shortcuts.add_shortcut('0,0,0', 'jupyter-notebook:restart-kernel');
|
||||
}
|
||||
|
||||
return {
|
||||
load_ipython_extension: load_ipython_extension
|
||||
};
|
||||
});
|
||||
|
||||
.. note::
|
||||
|
||||
The standard keybindings might not work correctly on non-US keyboards.
|
||||
Unfortunately, this is a limitation of browser implementations and the
|
||||
status of keyboard event handling on the web in general. We appreciate your
|
||||
feedback if you have issues binding keys, or have any ideas to help improve
|
||||
the situation.
|
||||
|
||||
You can see that I have used the **action name**
|
||||
``jupyter-notebook:restart-kernel`` to bind the new shortcut. There is no API
|
||||
yet to access the list of all available *actions*, though the following in the
|
||||
JavaScript console of your browser on a notebook page should give you an idea
|
||||
of what is available:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
Object.keys(require('base/js/namespace').actions._actions);
|
||||
|
||||
In this example, we changed a keyboard shortcut in **command mode**; you
|
||||
can also customize keyboard shortcuts in **edit mode**.
|
||||
However, most of the keyboard shortcuts in edit mode are handled by CodeMirror,
|
||||
which supports custom key bindings via a completely different API.
|
||||
|
||||
|
||||
Defining and registering your own actions
|
||||
-----------------------------------------
|
||||
|
||||
As part of your front-end extension, you may wish to define actions, which can
|
||||
be attached to toolbar buttons, or called from the command palette. Here is an
|
||||
example of an extension that defines an (not very useful!) action to show an
|
||||
alert, and adds a toolbar button using the full action name:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file my_extension/main.js
|
||||
|
||||
define([
|
||||
'base/js/namespace'
|
||||
], function(
|
||||
Jupyter
|
||||
) {
|
||||
function load_ipython_extension() {
|
||||
|
||||
var handler = function () {
|
||||
alert('this is an alert from my_extension!');
|
||||
};
|
||||
|
||||
var action = {
|
||||
icon: 'fa-comment-o', // a font-awesome class used on buttons, etc
|
||||
help : 'Show an alert',
|
||||
help_index : 'zz',
|
||||
handler : handler
|
||||
};
|
||||
var prefix = 'my_extension';
|
||||
var action_name = 'show-alert';
|
||||
|
||||
var full_action_name = Jupyter.actions.register(action, action_name, prefix); // returns 'my_extension:show-alert'
|
||||
Jupyter.toolbar.add_buttons_group([full_action_name]);
|
||||
}
|
||||
|
||||
return {
|
||||
load_ipython_extension: load_ipython_extension
|
||||
};
|
||||
});
|
||||
|
||||
Every action needs a name, which, when joined with its prefix to make the full
|
||||
action name, should be unique. Built-in actions, like the
|
||||
``jupyter-notebook:restart-kernel`` we bound in the earlier
|
||||
`Modifying key bindings`_ example, use the prefix ``jupyter-notebook``. For
|
||||
actions defined in an extension, it makes sense to use the extension name as
|
||||
the prefix. For the action name, the following guidelines should be considered:
|
||||
|
||||
.. adapted from notebook/static/notebook/js/actions.js
|
||||
|
||||
* First pick a noun and a verb for the action. For example, if the action is
|
||||
"restart kernel," the verb is "restart" and the noun is "kernel".
|
||||
* Omit terms like "selected" and "active" by default, so "delete-cell", rather
|
||||
than "delete-selected-cell". Only provide a scope like "-all-" if it is other
|
||||
than the default "selected" or "active" scope.
|
||||
* If an action has a secondary action, separate the secondary action with
|
||||
"-and-", so "restart-kernel-and-clear-output".
|
||||
* Use above/below or previous/next to indicate spatial and sequential
|
||||
relationships.
|
||||
* Don't ever use before/after as they have a temporal connotation that is
|
||||
confusing when used in a spatial context.
|
||||
* For dialogs, use a verb that indicates what the dialog will accomplish, such
|
||||
as "confirm-restart-kernel".
|
||||
|
||||
|
||||
Installing and enabling extensions
|
||||
----------------------------------
|
||||
|
||||
You can install your nbextension with the command::
|
||||
|
||||
jupyter nbextension install path/to/my_extension/ [--user|--sys-prefix]
|
||||
|
||||
The default installation is system-wide. You can use ``--user`` to do a
|
||||
per-user installation, or ``--sys-prefix`` to install to Python's prefix (e.g.
|
||||
in a virtual or conda environment). Where my_extension is the directory
|
||||
containing the Javascript files. This will copy it to a Jupyter data directory
|
||||
(the exact location is platform dependent - see :ref:`jupyter_path`).
|
||||
|
||||
For development, you can use the ``--symlink`` flag to symlink your extension
|
||||
rather than copying it, so there's no need to reinstall after changes.
|
||||
|
||||
To use your extension, you'll also need to **enable** it, which tells the
|
||||
notebook interface to load it. You can do that with another command::
|
||||
|
||||
jupyter nbextension enable my_extension/main [--sys-prefix][--section='common']
|
||||
|
||||
The argument refers to the Javascript module containing your
|
||||
``load_ipython_extension`` function, which is ``my_extension/main.js`` in this
|
||||
example. The ``--section='common'`` argument will affect all pages, by default
|
||||
it will be loaded on the notebook view only.
|
||||
There is a corresponding ``disable`` command to stop using an
|
||||
extension without uninstalling it.
|
||||
|
||||
.. versionchanged:: 4.2
|
||||
|
||||
Added ``--sys-prefix`` argument
|
||||
|
||||
|
||||
Kernel Specific extensions
|
||||
--------------------------
|
||||
|
||||
.. warning::
|
||||
|
||||
This feature serves as a stopgap for kernel developers who need specific
|
||||
JavaScript injected onto the page. The availability and API are subject to
|
||||
change at anytime.
|
||||
|
||||
|
||||
It is possible to load some JavaScript on the page on a per kernel basis. Be
|
||||
aware that doing so will make the browser page reload without warning as
|
||||
soon as the user switches the kernel without notice.
|
||||
|
||||
If you, a kernel developer, need a particular piece of JavaScript to be loaded
|
||||
on a "per kernel" basis, such as:
|
||||
|
||||
* if you are developing a CodeMirror mode for your language
|
||||
* if you need to enable some specific debugging options
|
||||
|
||||
your ``kernelspecs`` are allowed to contain a ``kernel.js`` file that defines
|
||||
an AMD module. The AMD module should define an `onload` function that will be
|
||||
called when the kernelspec loads, such as:
|
||||
|
||||
* when you load a notebook that uses your kernelspec
|
||||
* change the active kernelspec of a notebook to your kernelspec.
|
||||
|
||||
Note that adding a `kernel.js` to your kernelspec will add an unexpected side
|
||||
effect to changing a kernel in the notebook. As it is impossible to "unload"
|
||||
JavaScript, any attempt to change the kernelspec again will save the current
|
||||
notebook and reload the page without confirmations.
|
||||
|
||||
Here is an example of ``kernel.js``:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
define(function(){
|
||||
return {onload: function(){
|
||||
console.info('Kernel specific javascript loaded');
|
||||
|
||||
// do more things here, like define a codemirror mode
|
||||
|
||||
}}
|
||||
|
||||
});
|
||||
- `JupyterLab Extension Tutorial <https://jupyterlab.readthedocs.io/en/latest/extension/extension_tutorial.html>`_: A tutorial to learn how to make a simple JupyterLab extension.
|
||||
- The `JupyterLab Extension Examples Repository <https://github.com/jupyterlab/extension-examples>`_: A short tutorial series to learn how to develop extensions for JupyterLab by example.
|
@ -1,174 +0,0 @@
|
||||
Custom request handlers
|
||||
=======================
|
||||
|
||||
The notebook webserver can be interacted with using a well `defined
|
||||
RESTful
|
||||
API <http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml>`__.
|
||||
You can define custom RESTful API handlers in addition to the ones
|
||||
provided by the notebook. As described below, to define a custom handler
|
||||
you need to first write a notebook server extension. Then, in the
|
||||
extension, you can register the custom handler.
|
||||
|
||||
Writing a notebook server extension
|
||||
-----------------------------------
|
||||
|
||||
The notebook webserver is written in Python, hence your server extension
|
||||
should be written in Python too. Server extensions, like IPython
|
||||
extensions, are Python modules that define a specially named load
|
||||
function, ``load_jupyter_server_extension``. This function is called
|
||||
when the extension is loaded.
|
||||
|
||||
.. code:: python
|
||||
|
||||
def load_jupyter_server_extension(nb_server_app):
|
||||
"""
|
||||
Called when the extension is loaded.
|
||||
|
||||
Args:
|
||||
nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance.
|
||||
"""
|
||||
pass
|
||||
|
||||
To get the notebook server to load your custom extension, you'll need to
|
||||
add it to the list of extensions to be loaded. You can do this using the
|
||||
config system. ``NotebookApp.nbserver_extensions`` is a config variable
|
||||
which is a dictionary of strings, each a Python module to be imported, mapping
|
||||
to ``True`` to enable or ``False`` to disable each extension.
|
||||
Because this variable is notebook config, you can set it two different
|
||||
ways, using config files or via the command line.
|
||||
|
||||
For example, to get your extension to load via the command line add a
|
||||
double dash before the variable name, and put the Python dictionary in
|
||||
double quotes. If your package is "mypackage" and module is
|
||||
"mymodule", this would look like
|
||||
``jupyter notebook --NotebookApp.nbserver_extensions="{'mypackage.mymodule':True}"``
|
||||
.
|
||||
Basically the string should be Python importable.
|
||||
|
||||
Alternatively, you can have your extension loaded regardless of the
|
||||
command line args by setting the variable in the Jupyter config file.
|
||||
The default location of the Jupyter config file is
|
||||
``~/.jupyter/jupyter_notebook_config.py`` (see :doc:`/config_overview`). Inside
|
||||
the config file, you can use Python to set the variable. For example,
|
||||
the following config does the same as the previous command line example.
|
||||
|
||||
.. code:: python
|
||||
|
||||
c = get_config()
|
||||
c.NotebookApp.nbserver_extensions = {
|
||||
'mypackage.mymodule': True,
|
||||
}
|
||||
|
||||
Before continuing, it's a good idea to verify that your extension is
|
||||
being loaded. Use a print statement to print something unique. Launch
|
||||
the notebook server and you should see your statement printed to the
|
||||
console.
|
||||
|
||||
Registering custom handlers
|
||||
---------------------------
|
||||
|
||||
Once you've defined a server extension, you can register custom handlers
|
||||
because you have a handle to the Notebook server app instance
|
||||
(``nb_server_app`` above). However, you first need to define your custom
|
||||
handler. To declare a custom handler, inherit from
|
||||
``notebook.base.handlers.IPythonHandler``. The example below[1] is a
|
||||
Hello World handler:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from notebook.base.handlers import IPythonHandler
|
||||
|
||||
class HelloWorldHandler(IPythonHandler):
|
||||
def get(self):
|
||||
self.finish('Hello, world!')
|
||||
|
||||
The Jupyter Notebook server use
|
||||
`Tornado <http://www.tornadoweb.org/en/stable/>`__ as its web framework.
|
||||
For more information on how to implement request handlers, refer to the
|
||||
`Tornado documentation on the
|
||||
matter <http://www.tornadoweb.org/en/stable/web.html#request-handlers>`__.
|
||||
|
||||
After defining the handler, you need to register the handler with the
|
||||
Notebook server. See the following example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
web_app = nb_server_app.web_app
|
||||
host_pattern = '.*$'
|
||||
route_pattern = url_path_join(web_app.settings['base_url'], '/hello')
|
||||
web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)])
|
||||
|
||||
Putting this together with the extension code, the example looks like the
|
||||
following:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from notebook.utils import url_path_join
|
||||
from notebook.base.handlers import IPythonHandler
|
||||
|
||||
class HelloWorldHandler(IPythonHandler):
|
||||
def get(self):
|
||||
self.finish('Hello, world!')
|
||||
|
||||
def load_jupyter_server_extension(nb_server_app):
|
||||
"""
|
||||
Called when the extension is loaded.
|
||||
|
||||
Args:
|
||||
nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance.
|
||||
"""
|
||||
web_app = nb_server_app.web_app
|
||||
host_pattern = '.*$'
|
||||
route_pattern = url_path_join(web_app.settings['base_url'], '/hello')
|
||||
web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)])
|
||||
|
||||
|
||||
Extra Parameters and authentication
|
||||
===================================
|
||||
|
||||
Here is a quick rundown of what you need to know to pass extra parameters to the handler and enable authentication:
|
||||
|
||||
- extra arguments to the ``__init__`` constructor are given in a dictionary after the handler class in ``add_handlers``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
|
||||
class HelloWorldHandler(IPythonHandler):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.extra = kwargs.pop('extra')
|
||||
...
|
||||
|
||||
def load_jupyter_server_extension(nb_server_app):
|
||||
|
||||
...
|
||||
|
||||
web_app.add_handlers(host_pattern,
|
||||
[
|
||||
(route_pattern, HelloWorldHandler, {"extra": nb_server_app.extra})
|
||||
])
|
||||
|
||||
|
||||
All handler methods that require authentication _MUST_ be decorated with ``@tornado.web.authenticated``:
|
||||
|
||||
|
||||
.. code:: python
|
||||
|
||||
from tornado import web
|
||||
|
||||
class HelloWorldHandler(IPythonHandler):
|
||||
|
||||
...
|
||||
|
||||
@web.authenticated
|
||||
def get(self, *args, **kwargs):
|
||||
...
|
||||
|
||||
@web.authenticated
|
||||
def post(self, *args, **kwargs):
|
||||
...
|
||||
|
||||
|
||||
References:
|
||||
|
||||
1. `Peter Parente's Mindtrove <https://mindtrove.info/4-ways-to-extend-jupyter-notebook/#nb-server-exts>`__
|
@ -9,9 +9,5 @@ override the notebook's defaults with your own custom behavior.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
contents
|
||||
savehooks
|
||||
handlers
|
||||
Extending the Jupyter Server <https://jupyter-server.readthedocs.io/en/stable/developers/index.html>
|
||||
frontend_extensions
|
||||
keymaps
|
||||
bundler_extensions
|
||||
|
@ -1,91 +0,0 @@
|
||||
Customize keymaps
|
||||
=================
|
||||
|
||||
.. note::
|
||||
|
||||
Declarative Custom Keymaps is a provisional feature with unstable API
|
||||
which is not guaranteed to be kept in future versions of the notebook,
|
||||
and can be removed or changed without warnings.
|
||||
|
||||
The notebook shortcuts that are defined by jupyter both in edit mode and
|
||||
command mode are configurable in the frontend configuration file
|
||||
``~/.jupyter/nbconfig/notebook.json``. The modification of keyboard
|
||||
shortcuts suffers from several limitations, mainly that your Browser and OS
|
||||
might prevent certain shortcuts from working correctly. If this is the case,
|
||||
there is unfortunately not much that can be done. The second issue can arise
|
||||
with keyboards that have a layout different than US English. Again, even if
|
||||
we are aware of the issue, there is not much that can be done.
|
||||
|
||||
Shortcuts are also limited by the underlying library that handles code and
|
||||
text editing: CodeMirror. If some keyboard shortcuts are conflicting, the
|
||||
method described below might not work to create new keyboard shortcuts,
|
||||
especially in the ``edit`` mode of the notebook.
|
||||
|
||||
|
||||
The 4 sections of interest in ``~/.jupyter/nbconfig/notebook.json`` are the
|
||||
following:
|
||||
|
||||
- ``keys.command.unbind``
|
||||
- ``keys.edit.unbind``
|
||||
- ``keys.command.bind``
|
||||
- ``keys.edit.bind``
|
||||
|
||||
The first two sections describe which default keyboard shortcuts not to
|
||||
register at notebook startup time. These are mostly useful if you need to
|
||||
``unbind`` a default keyboard shortcut before binding it to a new
|
||||
``command``.
|
||||
|
||||
The first two sections apply respectively to the ``command`` and ``edit``
|
||||
mode of the notebook. They take a list of shortcuts to ``unbind``.
|
||||
|
||||
For example, to unbind the shortcut to split a cell at the position of the
|
||||
cursor (``Ctrl-Shift-Minus``) use the following:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file ~/.jupyter/nbconfig/notebook.json
|
||||
|
||||
{
|
||||
"keys": {
|
||||
"edit": {
|
||||
"unbind": [
|
||||
"Ctrl-Shift-Minus"
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
The last two sections describe which new keyboard shortcuts to register
|
||||
at notebook startup time and which actions they trigger.
|
||||
|
||||
The last two sections apply respectively to the ``command`` and ``edit``
|
||||
mode of the notebook. They take a dictionary with shortcuts as ``keys`` and
|
||||
``commands`` name as value.
|
||||
|
||||
For example, to bind the shortcut ``G,G,G`` (Press G three time in a row) in
|
||||
command mode to the command that restarts the kernel and runs all cells, use
|
||||
the following:
|
||||
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// file ~/.jupyter/nbconfig/notebook.json
|
||||
|
||||
{
|
||||
"keys": {
|
||||
"command": {
|
||||
"bind": {
|
||||
"G,G,G":"jupyter-notebook:restart-kernel-and-run-all-cells"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
The name of the available ``commands`` can be find by hovering over the
|
||||
right end of a row in the command palette.
|
@ -1,87 +0,0 @@
|
||||
File save hooks
|
||||
===============
|
||||
|
||||
You can configure functions that are run whenever a file is saved. There are
|
||||
two hooks available:
|
||||
|
||||
* ``ContentsManager.pre_save_hook`` runs on the API path and model with
|
||||
content. This can be used for things like stripping output that people don't
|
||||
like adding to VCS noise.
|
||||
* ``FileContentsManager.post_save_hook`` runs on the filesystem path and model
|
||||
without content. This could be used to commit changes after every save, for
|
||||
instance.
|
||||
|
||||
They are both called with keyword arguments:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pre_save_hook(model=model, path=path, contents_manager=cm)
|
||||
post_save_hook(model=model, os_path=os_path, contents_manager=cm)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
These can both be added to :file:`jupyter_notebook_config.py`.
|
||||
|
||||
A pre-save hook for stripping output:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def scrub_output_pre_save(model, **kwargs):
|
||||
"""scrub output before saving notebooks"""
|
||||
# only run on notebooks
|
||||
if model['type'] != 'notebook':
|
||||
return
|
||||
# only run on nbformat v4
|
||||
if model['content']['nbformat'] != 4:
|
||||
return
|
||||
|
||||
for cell in model['content']['cells']:
|
||||
if cell['cell_type'] != 'code':
|
||||
continue
|
||||
cell['outputs'] = []
|
||||
cell['execution_count'] = None
|
||||
|
||||
c.FileContentsManager.pre_save_hook = scrub_output_pre_save
|
||||
|
||||
A post-save hook to make a script equivalent whenever the notebook is saved
|
||||
(replacing the ``--script`` option in older versions of the notebook):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import io
|
||||
import os
|
||||
from notebook.utils import to_api_path
|
||||
|
||||
_script_exporter = None
|
||||
|
||||
def script_post_save(model, os_path, contents_manager, **kwargs):
|
||||
"""convert notebooks to Python script after save with nbconvert
|
||||
|
||||
replaces `jupyter notebook --script`
|
||||
"""
|
||||
from nbconvert.exporters.script import ScriptExporter
|
||||
|
||||
if model['type'] != 'notebook':
|
||||
return
|
||||
|
||||
global _script_exporter
|
||||
|
||||
if _script_exporter is None:
|
||||
_script_exporter = ScriptExporter(parent=contents_manager)
|
||||
|
||||
log = contents_manager.log
|
||||
|
||||
base, ext = os.path.splitext(os_path)
|
||||
script, resources = _script_exporter.from_filename(os_path)
|
||||
script_fname = base + resources.get('output_extension', '.txt')
|
||||
log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir))
|
||||
|
||||
with io.open(script_fname, 'w', encoding='utf-8') as f:
|
||||
f.write(script)
|
||||
|
||||
c.FileContentsManager.post_save_hook = script_post_save
|
||||
|
||||
|
||||
This could be a simple call to ``jupyter nbconvert --to script``, but spawning
|
||||
the subprocess every time is quite slow.
|
@ -1,91 +0,0 @@
|
||||
.. _frontend_config:
|
||||
|
||||
Configuring the notebook frontend
|
||||
=================================
|
||||
|
||||
.. note::
|
||||
|
||||
The ability to configure the notebook frontend UI and preferences is
|
||||
still a work in progress.
|
||||
|
||||
This document is a rough explanation on how you can persist some configuration
|
||||
options for the notebook JavaScript.
|
||||
|
||||
There is no exhaustive list of all the configuration options as most options
|
||||
are passed down to other libraries, which means that non valid
|
||||
configuration can be ignored without any error messages.
|
||||
|
||||
|
||||
How front end configuration works
|
||||
---------------------------------
|
||||
The frontend configuration system works as follows:
|
||||
|
||||
- get a handle of a configurable JavaScript object.
|
||||
- access its configuration attribute.
|
||||
- update its configuration attribute with a JSON patch.
|
||||
|
||||
|
||||
Example - Changing the notebook's default indentation
|
||||
-----------------------------------------------------
|
||||
This example explains how to change the default setting ``indentUnit``
|
||||
for CodeMirror Code Cells::
|
||||
|
||||
var cell = Jupyter.notebook.get_selected_cell();
|
||||
var config = cell.config;
|
||||
var patch = {
|
||||
CodeCell:{
|
||||
cm_config:{indentUnit:2}
|
||||
}
|
||||
}
|
||||
config.update(patch)
|
||||
|
||||
You can enter the previous snippet in your browser's JavaScript console once.
|
||||
Then reload the notebook page in your browser. Now, the preferred indent unit
|
||||
should be equal to two spaces. The custom setting persists and you do not need
|
||||
to reissue the patch on new notebooks.
|
||||
|
||||
``indentUnit``, used in this example, is one of the many `CodeMirror options
|
||||
<https://codemirror.net/doc/manual.html#option_indentUnit>`_ which are available
|
||||
for configuration.
|
||||
|
||||
You can similarly change the options of the file editor by entering the following
|
||||
snippet in the browser's Javascript console once (from a file editing page).::
|
||||
|
||||
var config = Jupyter.editor.config
|
||||
var patch = {
|
||||
Editor: {
|
||||
codemirror_options: {
|
||||
indentUnit: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
config.update(patch)
|
||||
|
||||
Example - Restoring the notebook's default indentation
|
||||
------------------------------------------------------
|
||||
If you want to restore a notebook frontend preference to its default value,
|
||||
you will enter a JSON patch with a ``null`` value for the preference setting.
|
||||
|
||||
For example, let's restore the indent setting ``indentUnit`` to its default of
|
||||
four spaces. Enter the following code snippet in your JavaScript console::
|
||||
|
||||
var cell = Jupyter.notebook.get_selected_cell();
|
||||
var config = cell.config;
|
||||
var patch = {
|
||||
CodeCell:{
|
||||
cm_config:{indentUnit: null} // only change here.
|
||||
}
|
||||
}
|
||||
config.update(patch)
|
||||
|
||||
Reload the notebook in your browser and the default indent should again be two
|
||||
spaces.
|
||||
|
||||
Persisting configuration settings
|
||||
---------------------------------
|
||||
Under the hood, Jupyter will persist the preferred configuration settings in
|
||||
``~/.jupyter/nbconfig/<section>.json``, with ``<section>``
|
||||
taking various value depending on the page where the configuration is issued.
|
||||
``<section>`` can take various values like ``notebook``, ``tree``, and
|
||||
``editor``. A ``common`` section contains configuration settings shared by all
|
||||
pages.
|
@ -2,41 +2,15 @@
|
||||
The Jupyter Notebook
|
||||
====================
|
||||
|
||||
|
||||
.. image:: ./_static/images/notebook-running-code.png
|
||||
|
||||
* `Installation <https://jupyter.readthedocs.io/en/latest/install.html>`_
|
||||
* `Starting the Notebook <https://jupyter.readthedocs.io/en/latest/running.html>`_
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: User Documentation
|
||||
:maxdepth: 2
|
||||
|
||||
notebook
|
||||
ui_components
|
||||
examples/Notebook/examples_index.rst
|
||||
troubleshooting
|
||||
changelog
|
||||
comms
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Configuration
|
||||
|
||||
config_overview
|
||||
config
|
||||
public_server
|
||||
security
|
||||
frontend_config
|
||||
examples/Notebook/Distributing Jupyter Extensions as Python Packages
|
||||
extending/index.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Contributor Documentation
|
||||
|
||||
contributing
|
||||
development_faq
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
examples/Notebook/nbpackage/mynotebook.ipynb
|
||||
examples/Notebook/nbpackage/nbs/other.ipynb
|
||||
user-documentation
|
||||
configuration
|
||||
contributor
|
||||
|
@ -171,7 +171,7 @@ Other clients may connect to the same kernel.
|
||||
When each kernel is started, the notebook server prints to the terminal a
|
||||
message like this::
|
||||
|
||||
[NotebookApp] Kernel started: 87f7d2c0-13e3-43df-8bb8-1bd37aaf3373
|
||||
[JupyterNotebookApp] Kernel started: 87f7d2c0-13e3-43df-8bb8-1bd37aaf3373
|
||||
|
||||
This long string is the kernel's ID which is sufficient for getting the
|
||||
information necessary to connect to the kernel. If the notebook uses the IPython
|
||||
|