Skip to content

Commit 262a20f

Browse files
committed
First commit
0 parents  commit 262a20f

18 files changed

+1487
-0
lines changed

.github/workflows/build.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
branches: master
6+
pull_request:
7+
branches: '*'
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v1
15+
- name: Install node
16+
uses: actions/setup-node@v1
17+
with:
18+
node-version: '10.x'
19+
- name: Install Python
20+
uses: actions/setup-python@v1
21+
with:
22+
python-version: '3.7'
23+
architecture: 'x64'
24+
- name: Install dependencies
25+
run: python -m pip install jupyterlab
26+
- name: Build the extension
27+
run: |
28+
pip install .
29+
jupyter lab build
30+
jupyter serverextension list
31+
jupyter labextension list
32+
python -m jupyterlab.browser_check

.gitignore

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
*.bundle.*
2+
lib/
3+
node_modules/
4+
.ipynb_checkpoints
5+
*.tsbuildinfo
6+
7+
# Created by https://www.gitignore.io/api/python
8+
# Edit at https://www.gitignore.io/?templates=python
9+
10+
### Python ###
11+
# Byte-compiled / optimized / DLL files
12+
__pycache__/
13+
*.py[cod]
14+
*$py.class
15+
16+
# C extensions
17+
*.so
18+
19+
# Distribution / packaging
20+
.Python
21+
build/
22+
develop-eggs/
23+
dist/
24+
downloads/
25+
eggs/
26+
.eggs/
27+
lib/
28+
lib64/
29+
parts/
30+
sdist/
31+
var/
32+
wheels/
33+
pip-wheel-metadata/
34+
share/python-wheels/
35+
*.egg-info/
36+
.installed.cfg
37+
*.egg
38+
MANIFEST
39+
40+
# PyInstaller
41+
# Usually these files are written by a python script from a template
42+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
43+
*.manifest
44+
*.spec
45+
46+
# Installer logs
47+
pip-log.txt
48+
pip-delete-this-directory.txt
49+
50+
# Unit test / coverage reports
51+
htmlcov/
52+
.tox/
53+
.nox/
54+
.coverage
55+
.coverage.*
56+
.cache
57+
nosetests.xml
58+
coverage.xml
59+
*.cover
60+
.hypothesis/
61+
.pytest_cache/
62+
63+
# Translations
64+
*.mo
65+
*.pot
66+
67+
# Scrapy stuff:
68+
.scrapy
69+
70+
# Sphinx documentation
71+
docs/_build/
72+
73+
# PyBuilder
74+
target/
75+
76+
# pyenv
77+
.python-version
78+
79+
# celery beat schedule file
80+
celerybeat-schedule
81+
82+
# SageMath parsed files
83+
*.sage.py
84+
85+
# Spyder project settings
86+
.spyderproject
87+
.spyproject
88+
89+
# Rope project settings
90+
.ropeproject
91+
92+
# Mr Developer
93+
.mr.developer.cfg
94+
.project
95+
.pydevproject
96+
97+
# mkdocs documentation
98+
/site
99+
100+
# mypy
101+
.mypy_cache/
102+
.dmypy.json
103+
dmypy.json
104+
105+
# Pyre type checker
106+
.pyre/
107+
108+
# End of https://www.gitignore.io/api/python
109+
110+
yarn.lock
111+
.vscode

LICENSE

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2020, QuantStack
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
* Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

MANIFEST.in

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include LICENSE
2+
include README.md
3+
4+
include setupbase.py
5+
include jupyter-config/jupyterlab-code-snippets.json
6+
7+
include package.json
8+
include ts*.json
9+
include jupyterlab-code-snippets/labextension/*.tgz
10+
11+
# Javascript files
12+
graft src
13+
graft style
14+
prune **/node_modules
15+
prune lib
16+
17+
# Patterns to exclude from any directory
18+
global-exclude *~
19+
global-exclude *.pyc
20+
global-exclude *.pyo
21+
global-exclude .git
22+
global-exclude .ipynb_checkpoints

README.md

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# jupyterlab-code-snippets
2+
3+
![Github Actions Status](https://github.com/QuantStack/jupyterlab-code-snippets/workflows/Build/badge.svg)
4+
5+
Code Snippets Extension for JupyterLab.
6+
7+
This extension is composed of a Python package named `jupyterlab-code-snippets`
8+
for the server extension and a NPM package named `jupyterlab-code-snippets`
9+
for the frontend extension.
10+
11+
## Requirements
12+
13+
- JupyterLab >= 2.0
14+
- Node.js
15+
16+
## Install
17+
18+
```bash
19+
pip install jupyterlab-code-snippets
20+
jupyter lab build
21+
```
22+
23+
## Usage
24+
25+
In `jupyter_notebook_config.py`:
26+
27+
```python
28+
c.JupyterLabCodeSnippets.snippet_dir = "/path/to/snippets"
29+
```
30+
31+
In JupyterLab, use the "Code Snippets" menu to select the snippet:
32+
33+
![screenshot](./screenshot.png)
34+
35+
36+
## Troubleshoot
37+
38+
If you are seeing the frontend extension but it is not working, check
39+
that the server extension is enabled:
40+
41+
```bash
42+
jupyter serverextension list
43+
```
44+
45+
If the server extension is installed and enabled but you are not seeing
46+
the frontend, check the frontend extension is installed and enabled:
47+
48+
```bash
49+
jupyter labextension list
50+
```
51+
52+
If it is installed, try:
53+
54+
```bash
55+
jupyter lab clean
56+
jupyter lab build
57+
```
58+
59+
## Contributing
60+
61+
### Development Install
62+
63+
The `jlpm` command is JupyterLab's pinned version of
64+
[yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
65+
`yarn` or `npm` in lieu of `jlpm` below.
66+
67+
```bash
68+
# Clone the repo to your local environment
69+
# Move to jupyterlab-code-snippets directory
70+
# Install the server extension
71+
pip install -e .
72+
73+
# Register the server extension
74+
jupyter serverextension enable --py jupyterlab-code-snippets
75+
76+
# Install the dependencies
77+
jlpm
78+
79+
# Build the TypeScript source
80+
jlpm build
81+
82+
# Link your development version of the extension with JupyterLab
83+
jupyter labextension link .
84+
85+
# Rebuild the TypeScript source after making changes
86+
jlpm build
87+
88+
# Rebuild JupyterLab after making any changes
89+
jupyter lab build
90+
```
91+
92+
You can watch the source directory and run JupyterLab in watch mode to watch for changes in the extension's source and automatically rebuild the extension and application.
93+
94+
```bash
95+
# Watch the source directory in another terminal tab
96+
jlpm watch
97+
98+
# Run jupyterlab in watch mode in one terminal tab
99+
jupyter lab --watch
100+
```
101+
102+
### Uninstall
103+
104+
```bash
105+
pip uninstall jupyterlab-code-snippets
106+
jupyter labextension uninstall jupyterlab-code-snippets
107+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"NotebookApp": {
3+
"nbserver_extensions": {
4+
"jupyterlab-code-snippets": true
5+
}
6+
}
7+
}

jupyterlab-code-snippets/__init__.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from ._version import __version__
2+
from .handlers import setup_handlers
3+
from .loader import SnippetsLoader
4+
5+
6+
def _jupyter_server_extension_paths():
7+
return [{
8+
'module': 'jupyterlab-code-snippets'
9+
}]
10+
11+
12+
def load_jupyter_server_extension(nb_app):
13+
"""Registers the API handler to receive HTTP requests from the frontend extension.
14+
Parameters
15+
----------
16+
nb_app: notebook.notebookapp.NotebookApp
17+
Notebook application instance
18+
"""
19+
snippet_dir = nb_app.config.get('JupyterLabCodeSnippets', {}).get('snippet_dir', '')
20+
# TODO: add snippets from jupyter paths?
21+
22+
loader = SnippetsLoader(snippet_dir)
23+
setup_handlers(nb_app.web_app, loader)

jupyterlab-code-snippets/_version.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version_info = (0, 1, 0)
2+
__version__ = ".".join(map(str, version_info))

jupyterlab-code-snippets/handlers.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import json
2+
3+
import tornado
4+
5+
from notebook.base.handlers import APIHandler
6+
from notebook.utils import url_path_join
7+
8+
9+
class ListSnippets(APIHandler):
10+
def initialize(self, loader):
11+
self.loader = loader
12+
13+
@tornado.web.authenticated
14+
@tornado.gen.coroutine
15+
def get(self):
16+
snippets = self.loader.collect_snippets()
17+
self.finish(json.dumps(snippets))
18+
19+
20+
class GetSnippet(APIHandler):
21+
def initialize(self, loader):
22+
self.loader = loader
23+
24+
@tornado.web.authenticated
25+
@tornado.gen.coroutine
26+
def post(self):
27+
data = self.get_json_body()
28+
snippet = data['snippet']
29+
content = self.loader.get_snippet_content(snippet)
30+
self.finish(json.dumps({
31+
"content": content
32+
}))
33+
34+
35+
def setup_handlers(web_app, loader):
36+
base_url = web_app.settings['base_url']
37+
handlers = [
38+
(url_path_join(base_url, 'snippets', 'list'), ListSnippets, {'loader': loader}),
39+
(url_path_join(base_url, 'snippets', 'get'), GetSnippet, {'loader': loader})
40+
]
41+
web_app.add_handlers('.*$', handlers)

0 commit comments

Comments
 (0)