Metadata-Version: 2.4
Name: flowbook-python
Version: 0.1.0
Summary: Reproducibility enforcement for Jupyter notebooks: a JupyterLab extension that enforces rerun consistency by tracking variable- and column-level dependencies between cells.
Project-URL: Homepage, https://github.com/stephenfreund/FlowBook
Project-URL: Bug Tracker, https://github.com/stephenfreund/FlowBook/issues
Project-URL: Repository, https://github.com/stephenfreund/FlowBook.git
Author-email: Stephen Freund <sfreund@williams.edu>
License: BSD 3-Clause License
        
        Copyright (c) 2025, Stephen Freund
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        1. Redistributions of source code must retain the above copyright notice, this
           list of conditions and the following disclaimer.
        
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
        
        3. Neither the name of the copyright holder nor the names of its
           contributors may be used to endorse or promote products derived from
           this software without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License-File: LICENSE
Keywords: data-science,dependency-tracking,jupyter,jupyterlab,jupyterlab-extension,notebook,pandas,reproducibility,rerun-consistency
Classifier: Framework :: Jupyter
Classifier: Framework :: Jupyter :: JupyterLab
Classifier: Framework :: Jupyter :: JupyterLab :: 4
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: attrs
Requires-Dist: dill
Requires-Dist: filelock>=3.0
Requires-Dist: hypothesis
Requires-Dist: jupyter
Requires-Dist: jupyter-client>=7.0
Requires-Dist: jupyter-server<3,>=2.4.0
Requires-Dist: jupyterlab<5,>=4.0.0
Requires-Dist: jupytext
Requires-Dist: libcst>=1.0.0
Requires-Dist: markdown
Requires-Dist: matplotlib
Requires-Dist: nbconvert
Requires-Dist: nbformat>=5.0.0
Requires-Dist: numpy
Requires-Dist: pandas>=2.2.3
Requires-Dist: psutil
Requires-Dist: pyarrow>=10.0.1
Requires-Dist: pydantic>=2.0
Requires-Dist: pympler
Requires-Dist: pytest
Requires-Dist: pytest-asyncio
Requires-Dist: pyyaml
Requires-Dist: scikit-learn
Requires-Dist: scipy
Requires-Dist: seaborn
Requires-Dist: termcolor
Requires-Dist: tornado
Provides-Extra: mcp
Requires-Dist: jupyter-collaboration; extra == 'mcp'
Requires-Dist: mcp; extra == 'mcp'
Provides-Extra: nbi
Requires-Dist: notebook-intelligence; extra == 'nbi'
Description-Content-Type: text/markdown

![](https://github.com/stephenfreund/FlowBook/raw/main/media/flowbook-small.png)

---

[Emery Berger](https://emeryberger.com),
[Cormac Flanagan](https://users.soe.ucsc.edu/~cormac/),
[Stephen Freund](https://www.cs.williams.edu/~freund/),
[Eunice Jun](http://eunicemjun.com/)

**Reproducibility enforcement for Jupyter notebooks.**

FlowBook is a JupyterLab extension that enforces _rerun consistency_:
re-executing each cell from the current state would produce a result
consistent with a top-to-bottom execution of the notebook,
regardless of which cells have been run, modified, and rerun.
Cells whose inputs may have changed are marked _stale_,
and operations that would break rerun consistency (e.g., a later cell
overwriting a value read by an earlier one) disallowed.

When every cell is _clean_ — executed and rerun consistent —
the notebook is guaranteed reproducible: running it top-to-bottom from
an empty store yields exactly the outputs currently recorded.

## Quick Start

Install FlowBook using `pip`:

```bash
python3 -m pip install flowbook-python
```

Then launch jupyter lab

```bash
jupyter lab .
```

Once JupyterLab opens, create or open a notebook and select the
**FlowBook** kernel from the kernel picker.

To walk through FlowBook's features interactively, download the
[Getting Started demo notebook](https://github.com/stephenfreund/FlowBook/raw/main/examples/GettingStarted.ipynb),
open it in JupyterLab. Be sure to use the **FlowBook Kernel**.

For a longer, self-contained tutorial, download our
[FlowBook tutorial](https://github.com/stephenfreund/FlowBook/raw/main/examples/FlowBookTutorial.ipynb)

## Troubleshoot

If FlowBook does not appear to be working, work through these steps:

**1. Confirm the server extension is enabled.**

```bash
jupyter server extension list
```

Look for `flowbook` marked as `enabled`. If it is missing or disabled,
enable it:

```bash
jupyter server extension enable flowbook
```

**2. Confirm the frontend extension is installed.**

```bash
jupyter labextension list
```

Look for `flowbook` in the list of enabled extensions. If it is not
there, reinstall the package:

```bash
python3 -m pip install --force-reinstall flowbook-python
```

**3. Confirm the FlowBook kernel is registered.**

```bash
jupyter kernelspec list
```

You should see `flowbook_kernel` in the output. If it is missing,
reinstall the package (step 2) — the kernelspec is registered at
install time.

**4. Pick the FlowBook kernel in your notebook.**

FlowBook only tracks notebooks running under the **FlowBook Kernel**.
Use JupyterLab's kernel picker (top-right of the notebook) to switch
away from the default Python kernel if you are not seeing
staleness/violation markers.

**5. Hard-refresh the browser.**

After installing or upgrading, JupyterLab may cache older frontend
assets. Do a hard refresh (`Cmd+Shift+R` on macOS, `Ctrl+Shift+F5` on
Linux/Windows) and reopen the notebook.

**6. Check the browser console and the JupyterLab server log.**

Open the browser's developer tools (`Cmd+Option+I` / `Ctrl+Shift+I`)
and look for errors in the Console tab. Also look at the terminal
where you launched `jupyter lab` for server-side errors. These often
point directly at the underlying problem (missing dependency, version
mismatch, etc.).

**7. Still stuck?**

Please file an issue at
[github.com/stephenfreund/FlowBook/issues](https://github.com/stephenfreund/FlowBook/issues)
with the outputs of the commands above, your OS and Python version,
and a minimal notebook that reproduces the problem.

## Uninstall

To remove the extension, execute:

```bash
pip uninstall flowbook-python
```

## Source Installation

Clone this repository and then install it as an editable package

```bash
python3 -m pip install -e .
jupyter lab examples/
```

Once JupyterLab opens, create or open a notebook and select the
**FlowBook** kernel from the kernel picker. Start with
`GettingStarted.ipynb`, then explore the `demos/` and `litmus/`
directories.

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.

```bash
# Clone the repo to your local environment
# Change directory to the flowbook directory
# Install package in development mode
pip install -e "."
# Link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite
# Server extension must be manually installed in develop mode
jupyter server extension enable flowbook
# Rebuild extension Typescript source after making changes
jlpm build
```

You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.

```bash
# Watch the source directory in one terminal, automatically rebuilding when needed
jlpm watch
# Run JupyterLab in another terminal
jupyter lab
```

With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).

By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:

```bash
jupyter lab build --minimize=False
```

### Running tests

Run the full Python test suite with `pytest`:

```bash
pytest flowbook/
```

To run the tests for a specific subpackage, point `pytest` at its `tests/` directory, e.g.:

```bash
pytest flowbook/kernel/tests/
pytest flowbook/mcp/tests/
```

### Development uninstall

```bash
# Server extension must be manually disabled in develop mode
jupyter server extension disable flowbook
pip uninstall flowbook-python
```

In development mode, you will also need to remove the symlink created by `jupyter labextension develop`
command. To find its location, you can run `jupyter labextension list` to figure out where the `labextensions`
folder is located. Then you can remove the symlink named `flowbook` within that folder.
