nbqa: Run Code Quality Tools on Jupyter Notebooks
nbqa is a command-line tool that allows you to run any standard Python code quality tool on Jupyter Notebooks. It robustly handles IPython magics, respects your existing configuration files (like `pyproject.toml`), and can lint both code and markdown cells. The current version is 1.9.1, with frequent minor point releases.
Warnings
- gotcha nbqa converts code cells to temporary Python files for linting. This conversion process can cause certain tool-specific flags, such as `flake8`'s `--per-file-ignores`, to behave unexpectedly or not work perfectly.
- gotcha By default, nbqa skips cells with invalid syntax. While this can be overridden with the `--nbqa-dont-skip-bad-cells` flag, cells containing multi-line IPython magics or automagics (e.g., `%timeit`) will still not be processed.
- gotcha When configuring `nbqa` via both `pyproject.toml` and command-line arguments, command-line arguments take precedence for `nbqa`'s own flags. For flags passed through to the underlying code quality tools, both sets of flags might be used, with `pyproject.toml` flags applied first. This can lead to tool-dependent or unexpected behavior.
- gotcha nbqa is designed primarily for command-line execution or integration into pre-commit hooks and CI/CD pipelines. It is not intended for real-time, interactive code quality checks directly within a running Jupyter Notebook or JupyterLab interface.
- gotcha When using `nbqa` as a `pre-commit` hook, particularly with `additional_dependencies`, running `pre-commit autoupdate` will update the `nbqa` hook itself, but *not* the versions of the code quality tools (e.g., `black`, `isort`) specified in `additional_dependencies`. These must be updated manually for reproducibility.
Install
-
pip install nbqa -
pip install -U "nbqa[toolchain]"
Quickstart
# Install nbqa and a code quality tool (e.g., black)
pip install -U nbqa black
# Create a dummy notebook (e.g., my_notebook.ipynb)
echo '{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["import os\n\nx = 1 + 2"]
}
],
"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.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}' > my_notebook.ipynb
# Run black on the notebook using nbqa
nbqa black my_notebook.ipynb
# Expected output will show reformatting, e.g.:
# reformatted my_notebook.ipynb
# All done! ✨ 🍰 ✨ 1 file reformatted.
# To verify changes (if you open the notebook, it should be formatted)
# cat my_notebook.ipynb