Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds documentation site #141

Merged
merged 24 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1ca8d4f
Add Initial Sphinx Docs
BradyPlanden Oct 27, 2023
82c7849
Merge branch 'develop' into 15-create-documentation-for-pybop
BradyPlanden Dec 6, 2023
7f887af
doc dependancies
BradyPlanden Dec 8, 2023
3134b3d
Adds User Guide, Installation, and Quick Start
BradyPlanden Dec 8, 2023
ddae288
Add nox session for docs, add pip install option for docs
BradyPlanden Dec 8, 2023
f98355a
Updt cost, dataset structure, improve docstrings, iterate on docs site
BradyPlanden Dec 10, 2023
d0499f3
Merge branch 'develop' into 15-create-documentation-for-pybop
BradyPlanden Dec 10, 2023
dafa750
Updts docstrings across package, remove redundant base naming convent…
BradyPlanden Dec 10, 2023
8743034
Add deploy docs workflow
BradyPlanden Dec 11, 2023
17e60ca
Add workflow dispatch to deploy workflow
BradyPlanden Dec 11, 2023
6909d30
updt permissions for deployment action
BradyPlanden Dec 11, 2023
5dfec0b
Finish docstring update, add pypi icon, update links & frontpage
BradyPlanden Dec 11, 2023
cec7d64
Updts. changelog and contributing, reverts deployment workflow trigge…
BradyPlanden Dec 11, 2023
32d6766
Updt deployment to use nox session
BradyPlanden Dec 11, 2023
33ca4d0
restores on push deployment for testing
BradyPlanden Dec 11, 2023
32f5a27
Remove duplicate docstrings, updt broken links in contributing.md
BradyPlanden Dec 11, 2023
c34a9ea
Remove treat warnings as errors
BradyPlanden Dec 11, 2023
3a0b2b4
relocate _build directory for deployable access
BradyPlanden Dec 11, 2023
a807a56
Tidy conf.py
BradyPlanden Dec 12, 2023
7aaa4a8
Updt noxfile for notebooks, optimisation.py change to _optimisation.p…
BradyPlanden Dec 13, 2023
6ac1880
Automate version linking
BradyPlanden Dec 14, 2023
af10b31
Updt. landing page grid and header names, docstring typos, contributi…
BradyPlanden Dec 14, 2023
a51d720
Add readthedocs configuration
BradyPlanden Dec 14, 2023
a0d44e5
Add version switcher, updt header location, link rtd versions
BradyPlanden Dec 14, 2023
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
39 changes: 39 additions & 0 deletions .github/workflows/deploy-docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Deploy Documentation

on:
release:
types: [created]
workflow_dispatch:

permissions:
contents: write # allow write access for docs deployment

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Check out PyBOP repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod

- name: Set up Python 3.11
id: setup-python
uses: actions/setup-python@v4
with:
python-version: 3.11
cache: 'pip'
cache-dependency-path: setup.py

- name: Install dependencies
run: |
python -m pip install --upgrade pip nox
- name: Using Python 3.11, build the docs
run: nox -s docs

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/_build/html
publish_branch: gh-pages
2 changes: 1 addition & 1 deletion .github/workflows/scheduled_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
python -m nox -s unit
python -m nox -s notebooks

#M-series Mac Mini
#M-series Mac Mini
build-apple-mseries:
runs-on: [self-hosted, macOS, ARM64]
env:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,4 @@ $RECYCLE.BIN/
.vscode/*

# Output JSON files
*fit_ecm_parameters.json
**/fit_ecm_parameters.json
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features

- [#141](https://github.com/pybop-team/PyBOP/pull/141) - Adds documentation with Sphinx and PyData Sphinx Theme. Updates docstrings across package, relocates `costs` and `dataset` to top-level of package. Adds noxfile session and deployment workflow for docs.
- [#131](https://github.com/pybop-team/PyBOP/issues/131) - Adds `SciPyDifferentialEvolution` optimiser, adds functionality for user-selectable maximum iteration limit to `SciPyMinimize`, `NLoptOptimize`, and `BaseOptimiser` classes.
- [#107](https://github.com/pybop-team/PyBOP/issues/107) - Adds Equivalent Circuit Model (ECM) with examples, Import/Export parameter methods `ParameterSet.import_parameter` and `ParameterSet.export_parameters`, updates default FittingProblem.signal definition to `"Voltage [V]"`, and testing infrastructure
- [#127](https://github.com/pybop-team/PyBOP/issues/127) - Adds Windows and macOS runners to the `test_on_push` action
Expand Down
16 changes: 13 additions & 3 deletions CONTRIBUTING.md
BradyPlanden marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

If you'd like to contribute to PyBOP, please have a look at the guidelines below.

## Installation
## Developer-Installation

To install PyBOP for development purposes, which includes the testing and plotting dependencies, use the `[all]` flag as demonstrated below:

Expand Down Expand Up @@ -30,7 +30,7 @@ pip install pre-commit
pre-commit install
```

This would run the checks every time a commit is created locally. The checks will only run on the files modified by that commit, but the checks can be triggered for all the files using -
This would run the checks every time a commit is created locally. The checks will only run on the files modified by that commit, but the checks can be triggered for all the files using,

```bash
pre-commit run --all-files
Expand All @@ -47,7 +47,7 @@ We use [GIT](https://en.wikipedia.org/wiki/Git) and [GitHub](https://en.wikipedi
1. Create an [issue](https://guides.github.com/features/issues/) where new proposals can be discussed before any coding is done.
2. Create a [branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/) of this repo (ideally on your own [fork](https://help.github.com/articles/fork-a-repo/)), where all changes will be made
3. Download the source code onto your local system, by [cloning](https://help.github.com/articles/cloning-a-repository/) the repository (or your fork of the repository).
4. [Install](Developer-Install) PyBOP with the developer options.
4. [Install](#developer-installation) PyBOP with the developer options.
5. [Test](#testing) if your installation worked: `$ pytest --unit -v`.

You now have everything you need to start making changes!
Expand Down Expand Up @@ -126,6 +126,16 @@ def plot_great_things(self, x, y, z):

This allows people to (1) use PyBOP without ever importing Matplotlib and (2) configure Matplotlib's back-end in their scripts, which _must_ be done before e.g. `pyplot` is first imported.

### Building documentation

We use [Sphinx](http://www.sphinx-doc.org/en/stable/) to build our documentation. A nox session has been created to reduce the overhead when building the documentation locally. To run this session, type

```bash
nox -s docs
```

This will build the docs using sphinx-autobuild and render them in your browser.

## Testing

All code requires testing. We use the [pytest](https://docs.pytest.org/en/) package for our tests. (These tests typically just check that the code runs without error, and so, are more _debugging_ than _testing_ in a strict sense. Nevertheless, they are very useful to have!)
Expand Down
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
145 changes: 145 additions & 0 deletions docs/_extension/gallery_directive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
"""A directive to generate a gallery of images from structured data.

Generating a gallery of images that are all the same size is a common
pattern in documentation, and this can be cumbersome if the gallery is
generated programmatically. This directive wraps this particular use-case
in a helper-directive to generate it with a single YAML configuration file.

It currently exists for maintainers of the pydata-sphinx-theme,
but might be abstracted into a standalone package if it proves useful.

Credit: PyData Sphinx Theme
"""
from pathlib import Path
from typing import Any, Dict, List

from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
from yaml import safe_load

logger = logging.getLogger(__name__)


TEMPLATE_GRID = """
`````{{grid}} {columns}
{options}

{content}

`````
"""

GRID_CARD = """
````{{grid-item-card}} {title}
{options}

{content}
````
"""


class GalleryGridDirective(SphinxDirective):
"""A directive to show a gallery of images and links in a Bootstrap grid.

The grid can be generated from a YAML file that contains a list of items, or
from the content of the directive (also formatted in YAML). Use the parameter
"class-card" to add an additional CSS class to all cards. When specifying the grid
items, you can use all parameters from "grid-item-card" directive to customize
individual cards + ["image", "header", "content", "title"].

Danger:
This directive can only be used in the context of a Myst documentation page as
the templates use Markdown flavored formatting.
"""

name = "gallery-grid"
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
option_spec = {
# A class to be added to the resulting container
"grid-columns": directives.unchanged,
"class-container": directives.unchanged,
"class-card": directives.unchanged,
}

def run(self) -> List[nodes.Node]:
"""Create the gallery grid."""
if self.arguments:
# If an argument is given, assume it's a path to a YAML file
# Parse it and load it into the directive content
path_data_rel = Path(self.arguments[0])
path_doc, _ = self.get_source_info()
path_doc = Path(path_doc).parent
path_data = (path_doc / path_data_rel).resolve()
if not path_data.exists():
logger.info(f"Could not find grid data at {path_data}.")
nodes.text("No grid data found at {path_data}.")
return
yaml_string = path_data.read_text()
else:
yaml_string = "\n".join(self.content)

# Use all the element with an img-bottom key as sites to show
# and generate a card item for each of them
grid_items = []
for item in safe_load(yaml_string):
# remove parameters that are not needed for the card options
title = item.pop("title", "")

# build the content of the card using some extra parameters
header = f"{item.pop('header')} \n^^^ \n" if "header" in item else ""
image = f"![image]({item.pop('image')}) \n" if "image" in item else ""
content = f"{item.pop('content')} \n" if "content" in item else ""

# optional parameter that influence all cards
if "class-card" in self.options:
item["class-card"] = self.options["class-card"]

loc_options_str = "\n".join(f":{k}: {v}" for k, v in item.items()) + " \n"

card = GRID_CARD.format(
options=loc_options_str, content=header + image + content, title=title
)
grid_items.append(card)

# Parse the template with Sphinx Design to create an output container
# Prep the options for the template grid
class_ = "gallery-directive" + f' {self.options.get("class-container", "")}'
options = {"gutter": 2, "class-container": class_}
options_str = "\n".join(f":{k}: {v}" for k, v in options.items())

# Create the directive string for the grid
grid_directive = TEMPLATE_GRID.format(
columns=self.options.get("grid-columns", "1 2 3 4"),
options=options_str,
content="\n".join(grid_items),
)

# Parse content as a directive so Sphinx Design processes it
container = nodes.container()
self.state.nested_parse([grid_directive], 0, container)

# Sphinx Design outputs a container too, so just use that
return [container.children[0]]


def setup(app: Sphinx) -> Dict[str, Any]:
"""Add custom configuration to sphinx app.

Args:
app: the Sphinx application

Returns:
the 2 parallel parameters set to ``True``.
"""
app.add_directive("gallery-grid", GalleryGridDirective)

return {
"parallel_read_safe": True,
"parallel_write_safe": True,
}
17 changes: 17 additions & 0 deletions docs/_static/custom-icon.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions docs/_templates/autoapi/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.. _api-reference:

API Reference
=============

This page contains auto-generated API reference documentation [#f1]_.

.. toctree::
:titlesonly:
:maxdepth: 2

{% for page in pages %}
{% if page.top_level_object and page.display %}
{{ page.include_path }}
{% endif %}
{% endfor %}

.. [#f1] Created with `sphinx-autoapi <https://github.com/readthedocs/sphinx-autoapi>`_
69 changes: 69 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Configuration file for the Sphinx documentation builder.


# -- Path setup --------------------------------------------------------------
import sys
from pathlib import Path

sys.path.append(str(Path(".").resolve()))

# -- Project information -----------------------------------------------------
project = "PyBOP"
copyright = "2023, The PyBOP Team"
author = "The PyBOP Team"
release = "v23.11"
BradyPlanden marked this conversation as resolved.
Show resolved Hide resolved

# -- General configuration ---------------------------------------------------
extensions = [
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.todo",
"sphinx.ext.viewcode",
"sphinx_design",
"sphinx_copybutton",
"autoapi.extension",
# custom extentions
"_extension.gallery_directive",
# For extension examples and demos
"myst_parser",
"sphinx_favicon",
]

templates_path = ["_templates"]
autoapi_template_dir = "_templates/autoapi"
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# -- Options for autoapi -------------------------------------------------------
autoapi_type = "python"
autoapi_dirs = ["../pybop"]
autoapi_keep_files = True
autoapi_root = "api"
autoapi_member_order = "groupwise"

# -- Options for HTML output -------------------------------------------------
html_theme = "pydata_sphinx_theme"
html_show_sourcelink = False
html_title = "PyBOP Documentation"

# html_theme options
html_theme_options = {
"header_links_before_dropdown": 4,
"icon_links": [
{
"name": "PyPI",
"url": "https://pypi.org/project/pybop/",
"icon": "fa-custom fa-pypi",
},
{
"name": "GitHub",
"url": "https://github.com/pybop-team/pybop",
"icon": "fab fa-github-square",
},
],
"search_bar_text": "Search the docs...",
"show_prev_next": False,
}

html_static_path = ["_static"]
html_js_files = ["custom-icon.js"]
4 changes: 4 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(contributing-guide) =
BradyPlanden marked this conversation as resolved.
Show resolved Hide resolved

```{include} ../CONTRIBUTING.md
```
Loading