Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
* transform() and transform_umap() now require some parameters to be keyword-only

### Added
* CI: Enable notebook validation in GitHub Actions to ensure documentation notebooks remain executable
* CI: Enable notebook validation by default in docs builds (set VALIDATE_NOTEBOOK_EXECUTION=0 to disable)
* CI: Run notebook validation after doc generation for faster error detection

### Fixed
* Fix Sphinx documentation build errors in docstrings for kusto and spanner methods
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Sphinx in strict mode:

CI runs `html.sh` and checks for warnings and errors. If there are any, it will fail the build.

Notebook validation is enabled by default. To disable: `VALIDATE_NOTEBOOK_EXECUTION=0 ./ci.sh`

## Develop

- Edit the `demo/` notebooks, `graphistry/` Python code, and `docs/source` .rst files
Expand Down
3 changes: 2 additions & 1 deletion docs/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
set -ex

DOCS_FORMAT=${DOCS_FORMAT:-all} # Default to building all formats if not specified
VALIDATE_NOTEBOOK_EXECUTION=${VALIDATE_NOTEBOOK_EXECUTION:-1} # Default to validating notebooks

(
cd docker \
&& docker compose build \
&& docker compose run --rm \
-e DOCS_FORMAT=$DOCS_FORMAT \
-e VALIDATE_NOTEBOOK_EXECUTION=${VALIDATE_NOTEBOOK_EXECUTION:-0} \
-e VALIDATE_NOTEBOOK_EXECUTION=$VALIDATE_NOTEBOOK_EXECUTION \
sphinx
)
11 changes: 6 additions & 5 deletions docs/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ RUN --mount=type=cache,target=/var/cache/apt \
# Step 2: Copy project files needed for pip install (setup.py, setup.cfg, versioneer.py, README.md)
COPY ../../setup.py ../../setup.cfg ../../versioneer.py ../../README.md ./

# Step 3: Install the project dependencies with pip, including docs extras and register kernel
# Step 3: Copy the graphistry source files into the container BEFORE pip install
COPY ../../graphistry /docs/graphistry

# Step 4: Install the project dependencies with pip, including docs extras and register kernel
# Install graphistry in editable mode so it's available for notebook execution
RUN --mount=type=cache,target=/root/.cache/pip \
python3 -m pip install -e .[docs] && \
python3 -m ipykernel install --sys-prefix --name python3

# Step 4: Copy the graphistry source files into the container
COPY ../../graphistry /graphistry
ENV PYTHONPATH="/graphistry:${PYTHONPATH}"

# Step 5: Copy the build script into the container
COPY docs/docker/build-docs.sh /build-docs.sh
COPY docs/source /docs/source
COPY demos /docs/source/demos
COPY docs/test_notebooks /docs/test_notebooks
COPY README.md /docs/source/README.md
COPY ARCHITECTURE.md /docs/source/ARCHITECTURE.md
COPY CONTRIBUTING.md /docs/source/CONTRIBUTING.md
Expand Down
84 changes: 44 additions & 40 deletions docs/docker/build-docs.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,50 @@
#!/bin/bash
set -ex

# Validate notebooks before building docs
# Debug: Check if graphistry is importable
python3 -c "import sys; print('Python path:', sys.path); import graphistry; print('Graphistry imported successfully from:', graphistry.__file__)" || echo "WARNING: Cannot import graphistry"

build_html() {
sphinx-build -b html -d /docs/doctrees . /docs/_build/html
}

build_epub() {
sphinx-build -b epub -d /docs/doctrees . /docs/_build/epub
}

build_pdf() {
sphinx-build -b latex -d /docs/doctrees . /docs/_build/latexpdf
cd /docs/_build/latexpdf
# Run pdflatex twice to resolve cross-references, using batchmode for non-interactive build
pdflatex -file-line-error -interaction=nonstopmode PyGraphistry.tex
pdflatex -file-line-error -interaction=nonstopmode PyGraphistry.tex
}

# Build docs first
case "$DOCS_FORMAT" in
html)
build_html
;;
epub)
build_epub
;;
pdf)
build_pdf
;;
all)
build_html
build_epub
build_pdf
;;
*)
echo "Invalid DOCS_FORMAT value: $DOCS_FORMAT"
exit 1
;;
esac

# Validate notebooks after building docs
NOTEBOOKS_TO_VALIDATE=(
"/docs/source/demos/more_examples/graphistry_features/layout_tree.ipynb"
"/docs/test_notebooks/test_graphistry_import.ipynb"
)

for notebook in "${NOTEBOOKS_TO_VALIDATE[@]}"; do
Expand Down Expand Up @@ -43,41 +84,4 @@ else:
echo "$(basename $notebook) execution completed successfully"
fi
fi
done

build_html() {
sphinx-build -b html -d /docs/doctrees . /docs/_build/html
}

build_epub() {
sphinx-build -b epub -d /docs/doctrees . /docs/_build/epub
}

build_pdf() {
sphinx-build -b latex -d /docs/doctrees . /docs/_build/latexpdf
cd /docs/_build/latexpdf
# Run pdflatex twice to resolve cross-references, using batchmode for non-interactive build
pdflatex -file-line-error -interaction=nonstopmode PyGraphistry.tex
pdflatex -file-line-error -interaction=nonstopmode PyGraphistry.tex
}

case "$DOCS_FORMAT" in
html)
build_html
;;
epub)
build_epub
;;
pdf)
build_pdf
;;
all)
build_html
build_epub
build_pdf
;;
*)
echo "Invalid DOCS_FORMAT value: $DOCS_FORMAT"
exit 1
;;
esac
done
69 changes: 69 additions & 0 deletions docs/test_notebooks/test_graphistry_import.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test Graphistry Import\n",
"\n",
"This is a minimal notebook used for CI validation to ensure graphistry can be imported in the docs build environment."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# Basic import test\n",
"import graphistry"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# Test version is accessible\n",
"assert hasattr(graphistry, '__version__')\n",
"print(f\"Graphistry version: {graphistry.__version__}\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Test basic functionality without external deps\n",
"import pandas as pd\n",
"df = pd.DataFrame({'src': [0, 1, 2], 'dst': [1, 2, 0]})\n",
"g = graphistry.edges(df, 'src', 'dst')\n",
"assert g is not None\n",
"print(\"Basic graph creation successful\")"
]
}
],
"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.8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading