Skip to content

Commit ab195fa

Browse files
committed
Use MkDocs to build the documentation
The documentation is generated using MkDocs, using the Material theme plus mkdocstrings (and a few minor supporting extensions) to build the API documentation extracted from code comments. For now the home page is a place holder, and the supporting script `docs/mkdocstrings-autoapi.py` should eventually be moved to a common repository. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent ba1ea56 commit ab195fa

File tree

11 files changed

+263
-8
lines changed

11 files changed

+263
-8
lines changed

.github/labeler.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
"part:docs":
1010
- "**/*.md"
11+
- "docs/**"
1112
- LICENSE
1213

1314
"part:tests":
@@ -16,11 +17,13 @@
1617
"part:tooling":
1718
- "**/*.ini"
1819
- "**/*.toml"
20+
- "**/*.yaml"
1921
- "*requirements*.txt"
2022
- ".git*"
2123
- ".git*/**"
2224
- CODEOWNERS
2325
- MANIFEST.in
26+
- docs/mkdocstrings_autoapi.py
2427
- noxfile.py
2528
- setup.py
2629

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,7 @@ dmypy.json
127127

128128
# Pyre type checker
129129
.pyre/
130+
131+
# Automatically generated documentation
132+
docs/reference/
133+
site/

CONTRIBUTING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ python -m pip install nox
2929
nox
3030
```
3131

32+
To build the documentation, first install the dependencies:
33+
34+
```sh
35+
python -m pip install -e .[docs]
36+
```
37+
38+
Then you can build the documentation (it will be written in the `site/`
39+
directory):
40+
41+
```sh
42+
mkdocs build
43+
```
44+
45+
Or you can just serve the documentation without building it using:
46+
47+
```sh
48+
mkdocs serve
49+
```
50+
3251
Releasing
3352
=========
3453

docs/css/mkdocstrings.css

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* Recommended style from:
2+
* https://mkdocstrings.github.io/python/customization/#recommended-style-material
3+
* With some additions from:
4+
* https://github.com/mkdocstrings/mkdocstrings/blob/master/docs/css/mkdocstrings.css
5+
*/
6+
7+
/* Indentation. */
8+
div.doc-contents:not(.first) {
9+
padding-left: 25px;
10+
border-left: .05rem solid var(--md-typeset-table-color);
11+
}
12+
13+
/* Indentation. */
14+
div.doc-contents:not(.first) {
15+
padding-left: 25px;
16+
border-left: 4px solid rgba(230, 230, 230);
17+
margin-bottom: 80px;
18+
}
19+
20+
/* Avoid breaking parameters name, etc. in table cells. */
21+
td code {
22+
word-break: normal !important;
23+
}
24+
25+
/* Mark external links as such. */
26+
a.autorefs-external::after {
27+
/* https://primer.style/octicons/arrow-up-right-24 */
28+
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="rgb(0, 0, 0)" d="M18.25 15.5a.75.75 0 00.75-.75v-9a.75.75 0 00-.75-.75h-9a.75.75 0 000 1.5h7.19L6.22 16.72a.75.75 0 101.06 1.06L17.5 7.56v7.19c0 .414.336.75.75.75z"></path></svg>');
29+
content: ' ';
30+
31+
display: inline-block;
32+
position: relative;
33+
top: 0.1em;
34+
margin-left: 0.2em;
35+
margin-right: 0.1em;
36+
37+
height: 1em;
38+
width: 1em;
39+
border-radius: 100%;
40+
background-color: var(--md-typeset-a-color);
41+
}
42+
a.autorefs-external:hover::after {
43+
background-color: var(--md-accent-fg-color);
44+
}

docs/css/style.css

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* Based on:
2+
* https://github.com/mkdocstrings/mkdocstrings/blob/master/docs/css/style.css
3+
*/
4+
5+
/* Increase logo size */
6+
.md-header__button.md-logo {
7+
padding-bottom: 0.2rem;
8+
padding-right: 0;
9+
}
10+
.md-header__button.md-logo img {
11+
height: 1.5rem;
12+
}
13+
14+
/* Mark external links as such (also in nav) */
15+
a.external:hover::after, a.md-nav__link[href^="https:"]:hover::after {
16+
/* https://primer.style/octicons/link-external-16 */
17+
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="rgb(233, 235, 252)" d="M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z"></path></svg>');
18+
height: 0.8em;
19+
width: 0.8em;
20+
margin-left: 0.2em;
21+
content: ' ';
22+
display: inline-block;
23+
}
24+
25+
/* More space at the bottom of the page */
26+
.md-main__inner {
27+
margin-bottom: 1.5rem;
28+
}

docs/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Home
2+
3+
Welcome to Frequenz's channels implementation for Python.
4+
5+
This website is still under heavy construction. Most information can be found in the [Reference](reference/frequenz/channels) section.

docs/logo.png

55.9 KB
Loading

docs/mkdocstrings_autoapi.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# License: MIT
2+
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3+
4+
"""Generate the code reference pages.
5+
6+
Based on the recipe at:
7+
https://mkdocstrings.github.io/recipes/#automatic-code-reference-pages
8+
"""
9+
10+
from pathlib import Path
11+
12+
import mkdocs_gen_files
13+
14+
SRC_PATH = "src"
15+
DST_PATH = "reference"
16+
17+
# noqa because mkdocs_gen_files uses a very weird module-level
18+
# __getattr__() which messes up the type system
19+
nav = mkdocs_gen_files.Nav() # noqa
20+
21+
for path in sorted(Path(SRC_PATH).rglob("*.py")):
22+
module_path = path.relative_to(SRC_PATH).with_suffix("")
23+
24+
doc_path = path.relative_to(SRC_PATH).with_suffix(".md")
25+
full_doc_path = Path(DST_PATH, doc_path)
26+
parts = tuple(module_path.parts)
27+
if parts[-1] == "__init__":
28+
doc_path = doc_path.with_name("index.md")
29+
full_doc_path = full_doc_path.with_name("index.md")
30+
parts = parts[:-1]
31+
32+
nav[parts] = doc_path.as_posix()
33+
34+
with mkdocs_gen_files.open(full_doc_path, "w") as fd:
35+
fd.write(f"::: {'.'.join(parts)}\n")
36+
37+
mkdocs_gen_files.set_edit_path(full_doc_path, Path("..") / path)
38+
39+
with mkdocs_gen_files.open(Path(DST_PATH) / "SUMMARY.md", "w") as nav_file:
40+
nav_file.writelines(nav.build_literate_nav())

mkdocs.yml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# MkDocs configuration
2+
# For details see: https://www.mkdocs.org/user-guide/configuration/
3+
4+
# Project information
5+
site_name: Frequenz's channels for Python
6+
site_description: Frequenz's channels implementation for Python.
7+
site_author: Frequenz Energy-as-a-Service GmbH
8+
copyright: Frequenz Energy-as-a-Service GmbH
9+
repo_name: "frequenz-channels-python"
10+
repo_url: "https://github.com/frequenz-floss/frequenz-channels-python"
11+
edit_uri: "edit/v0.x.x/docs/"
12+
13+
# Build directories
14+
theme:
15+
name: "material"
16+
logo: logo.png
17+
favicon: logo.png
18+
language: en
19+
icon:
20+
edit: material/file-edit-outline
21+
repo: fontawesome/brands/github
22+
features:
23+
- navigation.instant
24+
- navigation.tabs
25+
- navigation.top
26+
- navigation.tracking
27+
- toc.follow
28+
palette:
29+
- media: "(prefers-color-scheme: light)"
30+
scheme: default
31+
primary: indigo
32+
accent: deep purple
33+
toggle:
34+
icon: material/weather-sunny
35+
name: Switch to dark mode
36+
- media: "(prefers-color-scheme: dark)"
37+
scheme: slate
38+
primary: black
39+
accent: teal
40+
toggle:
41+
icon: material/weather-night
42+
name: Switch to light mode
43+
44+
extra:
45+
social:
46+
- icon: fontawesome/brands/github
47+
link: https://github.com/frequenz-floss
48+
- icon: fontawesome/brands/linkedin
49+
link: https://www.linkedin.com/company/frequenz-com
50+
51+
extra_css:
52+
- css/style.css
53+
- css/mkdocstrings.css
54+
55+
# Formatting options
56+
markdown_extensions:
57+
- admonition
58+
- attr_list
59+
- pymdownx.details
60+
- pymdownx.superfences
61+
- pymdownx.tasklist
62+
- pymdownx.tabbed
63+
- pymdownx.snippets:
64+
check_paths: true
65+
- pymdownx.superfences:
66+
custom_fences:
67+
- name: mermaid
68+
class: mermaid
69+
format: "!!python/name:pymdownx.superfences.fence_code_format"
70+
- toc:
71+
permalink: "¤"
72+
73+
plugins:
74+
- gen-files:
75+
scripts:
76+
- docs/mkdocstrings_autoapi.py
77+
- literate-nav:
78+
nav_file: SUMMARY.md
79+
- mkdocstrings:
80+
custom_templates: templates
81+
default_handler: python
82+
handlers:
83+
python:
84+
options:
85+
paths: [src]
86+
docstring_section_style: spacy
87+
merge_init_into_class: false
88+
show_category_heading: true
89+
show_root_heading: true
90+
show_root_members_full_path: true
91+
show_source: true
92+
import:
93+
- https://docs.python.org/3/objects.inv
94+
- search
95+
- section-index
96+
97+
# Preview controls
98+
watch:
99+
- src

noxfile.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,24 @@
99

1010
import nox
1111

12+
check_dirs = [
13+
"benchmarks",
14+
"docs",
15+
"src",
16+
"tests",
17+
]
1218

1319
@nox.session
1420
def formatting(session: nox.Session) -> None:
1521
session.install("black", "isort")
16-
session.run("black", "--check", "src", "tests", "benchmarks")
17-
session.run("isort", "--check", "src", "tests", "benchmarks")
22+
session.run("black", "--check", *check_dirs)
23+
session.run("isort", "--check", *check_dirs)
1824

1925

2026
@nox.session
2127
def pylint(session: nox.Session) -> None:
22-
session.install(".", "pylint", "pytest")
23-
session.run("pylint", "src", "tests", "benchmarks")
28+
session.install(".[docs]", "pylint", "pytest")
29+
session.run("pylint", *check_dirs)
2430

2531

2632
@nox.session
@@ -35,9 +41,7 @@ def mypy(session: nox.Session) -> None:
3541
"--explicit-package-bases",
3642
"--follow-imports=silent",
3743
"--strict",
38-
"src",
39-
"tests",
40-
"benchmarks",
44+
*check_dirs,
4145
)
4246

4347

@@ -46,7 +50,7 @@ def docstrings(session: nox.Session) -> None:
4650
"""Check docstring tone with pydocstyle and param descriptions with darglint."""
4751
session.install("pydocstyle", "darglint", "toml")
4852

49-
session.run("pydocstyle", "src", "tests", "benchmarks")
53+
session.run("pydocstyle", *check_dirs)
5054

5155
# Darglint checks that function argument and return values are documented.
5256
# This is needed only for the `src` dir, so we exclude the other top level

0 commit comments

Comments
 (0)