A JupyterLab plugin to facilitate invocation of code formatters.
Documentation: Hosted on GitHub Pages
I recommend you going to the documentation site, but this should work too.
Install the package
bash
pip install jupyterlab-code-formatter
Install some supported formatters (isort+black are default for Python) ```bash
pip install black isort ```
This plugin includes a server plugin, restart JupyterLab if you have followed the above steps while it's running.
To configure which/how formatters are invoked, see configuration.
I could really use your support in giving me a star on GitHub, recommending features, fixing bugs or maybe even providing monetary support!
Massive thanks to the below list of people who made past contributions to the project!
This project is licensed under the terms of the MIT license.
Fixes https://github.com/ryantam626/jupyterlab_code_formatter/issues/293
Switches to importlib.util.find_spec
which is slightly faster than reloading packages.
Exposes a new user setting allowing to cache the formatter information:
Ruff is a linter for python that also has the ability to fix the lints automatically. I'm using it as an alternative to isort.
I think it would be good to add it as a supported option in this package.
Here is the code I used to add it as a custom formatter:
```python from jupyterlab_code_formatter.formatters import ( SERVER_FORMATTERS, CommandLineFormatter, )
class RuffFixFormatter(CommandLineFormatter): def init(self): try: from ruff.main import find_ruff_bin
ruff_command = find_ruff_bin()
except (ImportError, FileNotFoundError):
ruff_command = "ruff"
self.command = [ruff_command, "check", "--fix-only", "-", "--select=COM,I"]
SERVER_FORMATTERS["ruff_isort"] = RuffFixFormatter() ```
I'm not sure how to pass args to a custom function via the normal jupyter lab config, so I hardcoded my rule selection argument --select=COM,I
.
I'm trying to run Jupyterlab_code_formatter in a regular python file in Jupyter Lab. It is not formatted on save. I Can add a shortcut to manually run it:
{
"args": {},
"command": "jupyterlab_code_formatter:black",
"keys": [
"Ctrl K",
"Ctrl M"
],
"selector": ".jp-CodeMirrorEditor"
},
Can I add a shortcut to run both Isort and Black formatter? The following setting doesn't work:
{
"shortcuts": [
{
"command": "apputils:run-all-enabled",
"args": {
"commands": ["jupyterlab_code_formatter:black", "jupyterlab_code_formatter:isort"],
},
"keys": [
"Ctrl K",
"Ctrl M"
],
"selector": ".jp-CodeMirrorEditor"
}
]
}
Is there a functionality to remove unused imports and variables, autoflake? I couldn't see it in the configuration page:
https://ryantam626.github.io/jupyterlab_code_formatter/configuration.html
Checklist prior to opening an issue - [X] I have followed fully the installation steps laid out in the documentation site. - [X] I have restarted jupyterlab. - [X] I have read the FAQ section in the documentation site.
Describe the bug Using this plugin adds ~1.5-2s of pageload time for my setup.
Additional context
I narrowed this down by looking at the network tab. This stems from loading the my-jupyterlab.foo.com/jupyterlab_code_formatter/formatters
route which in Jupyter both blocks pageload and (I think) blocks the server as it is single threaded. This network call leads to this code being called.
Below is a reproducer of the longest part of the call, which on my setup takes ~1.6s: ``` %%time
from jupyterlab_code_formatter.formatters import SERVER_FORMATTERS
json.dumps( { "formatters": { name: { "enabled": formatter.importable, "label": formatter.label, } for name, formatter in SERVER_FORMATTERS.items() } } ) ```
Digging deeper, the problem is formatter.importable
does not act like property, but function which often calls this expensive function. Each call in my setup takes ~300ms.
I believe if importib.reload
is called at most once per get call, that would save 4/5 of the cost. In my setup, I'm ok with this not detecting new instances installed/uninstalled after lab is started.
Would you be open to a PR that:
1. Reduced the times importib is called per get
2. Allowed users to opt for a cached version for this getter
Checklist prior to opening an issue - [x] I have followed fully the installation steps laid out in the documentation site. - [x] I have restarted jupyterlab. - [x] I have read the FAQ section in the documentation site.
Describe the bug Given the following python code in a jupyter cell, it formats it correctly the first time, but fails the second time:
python
print("Foo: %s" % (len(df.loc[(df["Cloudfront-Is-Android-Viewer"] == "true") & (df["OS_TYPE"] != "ANDROID_OS_TYPE")])))
Formats to
python
print(
"Foo: %s"
% (
len(
df.loc[
(df["Cloudfront-Is-Android-Viewer"] == "true")
& (df["OS_TYPE"] != "ANDROID_OS_TYPE")
]
)
)
)
But if I click the button again, I get:
Jupyterlab Code Formatter Error
Cannot parse: 4:8: len(
Diagnostic commands
Please attach the output of the following commands (please format them properly)
pip freeze
$ pip freeze
aiofiles==22.1.0
aiosqlite==0.18.0
anyio==3.6.2
appnope==0.1.3
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
arrow==1.2.3
asttokens==2.2.1
attrs==22.2.0
Babel==2.11.0
backcall==0.2.0
beautifulsoup4==4.11.2
black==23.1.0
bleach==6.0.0
certifi==2022.12.7
cffi==1.15.1
charset-normalizer==3.0.1
click==8.1.3
colorama==0.4.6
comm==0.1.2
debugpy==1.6.6
decorator==5.1.1
defusedxml==0.7.1
executing==1.2.0
fastjsonschema==2.16.2
fqdn==1.5.1
gitdb==4.0.10
GitPython==3.1.30
idna==3.4
ipykernel==6.21.2
ipython==8.10.0
ipython-genutils==0.2.0
isoduration==20.11.0
isort==5.12.0
jedi==0.18.2
Jinja2==3.1.2
json5==0.9.11
jsonpointer==2.3
jsonschema==4.17.3
jupyter-events==0.5.0
jupyter-server-mathjax==0.2.6
jupyter-ydoc==0.2.2
jupyter_client==8.0.2
jupyter_core==5.2.0
jupyter_server==2.2.1
jupyter_server_fileid==0.6.0
jupyter_server_terminals==0.4.4
jupyter_server_ydoc==0.6.1
jupyterlab==3.6.1
jupyterlab-code-formatter==1.5.3
jupyterlab-git==0.41.0
jupyterlab-pygments==0.2.2
jupyterlab_server==2.19.0
MarkupSafe==2.1.2
matplotlib-inline==0.1.6
mistune==2.0.5
mypy-extensions==1.0.0
nbclassic==0.5.1
nbclient==0.7.2
nbconvert==7.2.9
nbdime==3.1.1
nbformat==5.7.3
nest-asyncio==1.5.6
notebook==6.5.2
notebook_shim==0.2.2
numpy==1.24.2
packaging==23.0
pandas==1.5.3
pandocfilters==1.5.0
parso==0.8.3
pathspec==0.11.0
pexpect==4.8.0
pickleshare==0.7.5
platformdirs==3.0.0
prometheus-client==0.16.0
prompt-toolkit==3.0.36
psutil==5.9.4
ptyprocess==0.7.0
pure-eval==0.2.2
pycparser==2.21
Pygments==2.14.0
pyrsistent==0.19.3
python-dateutil==2.8.2
python-json-logger==2.0.5
pytz==2022.7.1
PyYAML==6.0
pyzmq==25.0.0
requests==2.28.2
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
Send2Trash==1.8.0
six==1.16.0
smmap==5.0.0
sniffio==1.3.0
soupsieve==2.3.2.post1
stack-data==0.6.2
terminado==0.17.1
tinycss2==1.2.1
tornado==6.2
traitlets==5.9.0
uri-template==1.2.0
urllib3==1.26.14
wcwidth==0.2.6
webcolors==1.12
webencodings==0.5.1
websocket-client==1.5.1
y-py==0.5.5
ypy-websocket==0.8.2
jupyter labextension list
```
$ jupyter labextension list
JupyterLab v3.6.1
/Users/mikemi/src/cloudfront-header-analysis/.venv/share/jupyter/labextensions
jupyterlab_pygments v0.2.2 enabled OK (python, jupyterlab_pygments)
nbdime-jupyterlab v2.1.1 enabled OK
@ryantam626/jupyterlab_code_formatter v1.5.3 enabled OK (python, jupyterlab-code-formatter)
@jupyterlab/git v0.41.0 enabled OK (python, jupyterlab-git)
/usr/local/share/jupyter/labextensions jupyterlab-theme-solarized-dark v2.0.0-dev.1 enabled OK (python, jupyterlab_theme_solarized_dark)
Other labextensions (built into JupyterLab) app dir: /Users/mikemi/src/cloudfront-header-analysis/.venv/share/jupyter/lab
- `jupyter serverextension list`
$ jupyter serverextension list
config dir: /Users/mikemi/src/cloudfront-header-analysis/.venv/etc/jupyter
jupyter_server_ydoc enabled
- Validating...
X is jupyter_server_ydoc importable?
jupyterlab enabled
- Validating...
jupyterlab 3.6.1 OK
jupyterlab_code_formatter enabled
- Validating...
jupyterlab_code_formatter 1.5.3 OK
jupyterlab_git enabled
- Validating...
jupyterlab_git 0.41.0 OK
nbdime enabled
- Validating...
nbdime 3.1.1 OK
config dir: /usr/local/etc/jupyter
jupyterlab enabled
- Validating...
jupyterlab 3.6.1 OK
jupyterlab_code_formatter enabled
- Validating...
jupyterlab_code_formatter 1.5.3 OK
jupyterlab_git enabled
- Validating...
jupyterlab_git 0.41.0 OK
nbdime enabled
- Validating...
nbdime 3.1.1 OK
```
Screenshots
n/a
Additional context
n/a
Software Engineer at @huq-industries :metal: :cat: :hong_kong: :gb:
GitHub Repository Homepagejupyterlab-extension jupyterlab-extensions yapf black code-formatter autopep8 python r