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

Auto-generate API reference in docs and an overhaul #430

Merged
merged 35 commits into from Jul 31, 2020
Merged

Conversation

CasperWA
Copy link
Member

@CasperWA CasperWA commented Jul 24, 2020

New invoke task to create "API Reference".

This new task will go through the optimade folder and all subfolders, excluding data folders. A markdown file will be created for every python file and the folder tree will be kept.
.pages files will also be created and __init__.py files will be foregone, since the mkdocstrings plugin does not respect what can be imported from the root of a module and what can not, it will simply add everything with a docstring under the module ...

Due to the __init__.py file being foregone, the adapters that were defined in said files have been moved to an adapter.py file. No other __init__.py files define classes and functions that need to be moved to separate files, so all good.

The new task has a flag --pre-clean, which will completely remove the api_reference docs sub-folder and recreate all the files anew.
Otherwise the task will check the content of existing files to determine whether it needs to rewrite them or skip writing. This will of course not remove "old" files, for this the --pre-clean flag should be added.

This task also goes for the philosophy to write the table of contents of the "API Reference" using the proper folder and file names, i.e., lower case and including _ if present.

Larger overhaul

INSTALL.md has been renamed to install.md and moved to /docs. The link to it mentioned in README.md has been changed to link to the install.md's file in the online documentation.

All links (which created build warnings) have been fixed, either by creating symlinks in the /docs folder or writing the correct link name.

Fancy new logo and icon.
Here, I'm just using the new OPTIMADE logo (svg), converting it to a png matching the size of the existing files.

Use black/red for prime/accent color.

Update various plugins and markdown extensions to the newest recommended editions (codehilite -> pymdown.highlight).
Also added other pymdown extensions.

Doc string standard (example)

I have updated a file with the recommended format of doc strings; a very specific kind of Google doc string.
This is done like this to make mkdocstrings as happy as possible.
Example file: entries.py

EDIT: Excluding __json_encoder__

Added filter to exclude __json_encoder__ from the documention builds.
This fixes #365.
Note, the first filter added is the default filter used. It excludes all entities starting with _, i.e., private stuff, while including everything starting with two underscores; __. This is done do include __init__, but then also finds __json_encoder__.
Another way of doing this would be to first exclude all entities starting with an underscore (_) and then add a filter including specifically __init__.

Edit: I'm excluding also __all__ and __config__. Since there are other "special" methods we would like to include, like __default__ and overriding __getattr__, it seems it doesn't matter anymore whether we're adding a new explicit exclude or include (concerning the discussion immediately above here).

@CasperWA CasperWA added the docs Issues pertaining to documentation. label Jul 24, 2020
@CasperWA CasperWA requested review from ml-evs and shyamd July 24, 2020 23:28
@codecov
Copy link

codecov bot commented Jul 24, 2020

Codecov Report

Merging #430 into master will increase coverage by 0.14%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #430      +/-   ##
==========================================
+ Coverage   91.31%   91.45%   +0.14%     
==========================================
  Files          58       60       +2     
  Lines        2705     2751      +46     
==========================================
+ Hits         2470     2516      +46     
  Misses        235      235              
Flag Coverage Δ
#unittests 91.45% <100.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
optimade/adapters/structures/cif.py 100.00% <ø> (ø)
optimade/adapters/structures/proteindatabank.py 100.00% <ø> (ø)
optimade/models/entries.py 97.43% <ø> (ø)
optimade/server/entry_collections/mongo.py 96.77% <ø> (-0.11%) ⬇️
optimade/server/query_params.py 100.00% <ø> (ø)
optimade/validator/validator.py 77.10% <ø> (ø)
optimade/adapters/base.py 100.00% <100.00%> (ø)
optimade/adapters/references/__init__.py 100.00% <100.00%> (ø)
optimade/adapters/references/adapter.py 100.00% <100.00%> (ø)
optimade/adapters/structures/adapter.py 100.00% <100.00%> (ø)
... and 9 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 27ea22c...8bc9b61. Read the comment docs.

@CasperWA CasperWA changed the title Update docs Auto-generate API reference in docs Jul 25, 2020
@CasperWA CasperWA changed the title Auto-generate API reference in docs Auto-generate API reference in docs and an overhaul Jul 29, 2020
CONTRIBUTING.md Show resolved Hide resolved
docs/.pages Show resolved Hide resolved
docs/install.md Show resolved Hide resolved
docs/install.md Outdated Show resolved Hide resolved
mkdocs.yml Outdated Show resolved Hide resolved
optimade/server/mappers/entries.py Outdated Show resolved Hide resolved
optimade/server/mappers/entries.py Outdated Show resolved Hide resolved
optimade/server/mappers/entries.py Outdated Show resolved Hide resolved
optimade/validator/validator.py Show resolved Hide resolved
for filename in filenames:
if re.match(r".*\.py$", filename) is None or filename == "__init__.py":
# Not a Python file: We don't care about it!
# Or filename is `__init__.py`: We don't want it!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want to capture e.g. module-level docstrings (that would be in the __init__.py)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that it doesn't come off nicely in the API Reference section, since it will "break" the system a little. One will have to have a __init__ entry in the ToC to work this in. I have tried here to avoid that, but it may be that it's still better than nothing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I get you, not sure the best way of fixing it really with the current tree structure we have in the docs. Unless it could be renamed to "contents" and include the submodule docstrings... probably more trouble than its worth.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but not a bad idea. I'll give it a go.
And then make sure to also name the ToC header something non-API-like, e.g., "Contents" as you suggest (the capitalization being important here).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So mostly this presents the issue that mkdocstrings cannot handle the __all__ "imports". I.e., it errors when trying to build the docs due to a "NameError":

    __all__ = exceptions.__all__ + references.__all__ + structures.__all__  # noqa: F405
NameError: name 'exceptions' is not defined

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also why I gave up and moved the resource-specific adapters I had written in the __init__.py files to new adapters.py files, so they could be included.

Copy link
Member Author

@CasperWA CasperWA Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I could instead try to create a custom markdown file that already exists at the top of each module that can parse in the doc string from the __init__.py file? Unfortunately, it won't get anything else from there. Like, e.g., the validate() function in optimade.validator.__init__

Copy link
Member Author

@CasperWA CasperWA Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if you want to include this, I suggest instead to move it to a new file, e.g., cli.py and keep __init__.py only to create an __all__ if needed?

@CasperWA
Copy link
Member Author

Okay, I may have gone a little overboard now (for this PR). But I have now updated all doc strings relevant for the optimade.adapters module (and all sub-modules) ...

optimade/adapters/base.py Outdated Show resolved Hide resolved
optimade/server/query_params.py Outdated Show resolved Hide resolved
optimade/adapters/structures/aiida.py Show resolved Hide resolved
optimade/adapters/structures/utils.py Outdated Show resolved Hide resolved
optimade/adapters/structures/utils.py Outdated Show resolved Hide resolved
optimade/adapters/structures/utils.py Outdated Show resolved Hide resolved
optimade/adapters/structures/utils.py Outdated Show resolved Hide resolved
optimade/adapters/structures/utils.py Outdated Show resolved Hide resolved
@CasperWA
Copy link
Member Author

It seems the only "issue" is the type annotation for the pymatgen conversion function, since it extrapolates the complete type path, which is wrong for the customly created types Structure and Molecule.
I don't consider it a huge issue.
What do you think @ml-evs?

@shyamd
Copy link
Contributor

shyamd commented Jul 31, 2020

Wow... I walk away for a few weeks and you rewrite all the docs. :P
This looks great. I wouldn't worry about minor type annotations. While useful, most people will figure it out in-use rather than from the docs.

shyamd
shyamd previously approved these changes Jul 31, 2020
@CasperWA
Copy link
Member Author

I'll just wait for a response from @ml-evs before merging, since he has reviewed this a couple of times already :)

ml-evs
ml-evs previously approved these changes Jul 31, 2020
Copy link
Member

@ml-evs ml-evs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the only "issue" is the type annotation for the pymatgen conversion function, since it extrapolates the complete type path, which is wrong for the customly created types Structure and Molecule.
I don't consider it a huge issue.
What do you think @ml-evs?

I think it's fine, and already a big improvement on "None".

This PR is really great, thanks for all your hard work @CasperWA, it has been fun vicariously learning mkdocs through you... I think my only slight niggle is that lack of a top-level module list (with the module docstrings giving an overview), but that's something we can work on in the future if we get time!

@CasperWA
Copy link
Member Author

(...) it has been fun vicariously learning mkdocs through you... I think my only slight niggle is that lack of a top-level module list (with the module docstrings giving an overview), but that's something we can work on in the future if we get time!

I have never used mkdocs before either 😅 So yeah, collected learning experience.

Concerning your last point here. You could make an issue for it (low priority) and we can get back to it later/you can try stuff out locally to see if you get a nice thing going? 😃

Update icons and logo.
Use new color scheme.
Rename INSTALL.md -> install.md
Added GitHub social in site footer pointing to Materials-Consortia.
Fix existing links by creating symlinks.
Add PyMdown Snippets:
https://facelessuser.github.io/pymdown-extensions/extensions/snippets/
This is an example update of how the doc strings should be written to
show up nicely in the new API reference documentation.
CasperWA and others added 19 commits July 31, 2020 17:09
This is done to have easy access to any configurations should we want
it.
It also helps to show what the default is right away, instead of having
to check the mkdocstrings documentation.

Extend filters to exclude `__all__` and `__config__`.

Add to the invoke task that for `models` only, it should set
`rendering.show_if_no_docstring` to True.
This ensures we get _all_ models into the documentation, no matter if
the have doc strings or not.
It correctly added `optimade.server.warnings`. Prior to which `mkdocs
build` emitted warnings about missing cross-references (to
`OptimadeWarning`). Afterwards all was beautiful and quiet :)
Update malformed cross-references after rebasing.

Move the attributes `provider_prefix` and `provider_fields` from
`MongoCollection` to the parent abstract class `EntryCollection`.
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
Also add doc string for `EntryResource`.
The class doc string is not parsed correctly by `mkdocstrings` if a line
break is not included straight after the first `"""`.
For all other doc strings there does not seem to be a similar issue.
Hence they have been reverted to keep their original form where
possible.

Furthermore, all `Returns` has had their "type"-annotation removed,
since this is retrieved from the Python type annotation by
`mkdocstrings` instead.
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
The type annotation can be left out of Parameters lists, since they will
be taken from the Python type annotation.
The code is lifted from the `mkdocstrings` repository's own
documentation.
It indents the references according to subsections and creates a
vertical gray line left of the text in the indentation.
Also, it makes sure not to break code weirdly.

Furthermore, the starting heading level is reset to the default (2).
And the `optimade` folder (and all sub-folders) are added to the watch
list for mkdocstrings to request a rebuild when using `mkdocs serve`
locally, whenever a file in `optimade/` is updated.
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
If an adapter dependency is not installed, a new type will be created
with the same name.
This is done for the sake of the docs.

In order to still warn and return about the non-existent dependency,
when trying to convert an OPTIMADE entry resource, the string
"optimade.adapters" is searched for in the representation of the "new"
type created.
This is because the new type will show up as belonging to the file in
which is was created.
This depends on a dependency never coming from within
"optimade.adapters", which makes sense, since it will always be external
libraries and packages.
@ml-evs
Copy link
Member

ml-evs commented Jul 31, 2020

Other final comment is that default values of pydantic fields aren't documented at the moment with pytk, which isn't a big deal, except maybe for the docs of ServerConfig, looks like there's an open issue with pytk/mkdocstrings docs to set this up for simple pydantic attributes, but not sure about e.g. Field or Query objects.

We might consider updating the config docs to make it clearer what the defaults are, though we are showing the snippet of an example config, some fields are missing here (like the new log_dir, I'll make a quick PR adding this after we've merged this).

@ml-evs
Copy link
Member

ml-evs commented Jul 31, 2020

We might consider updating the config docs to make it clearer what the defaults are, though we are showing the snippet of an example config, some fields are missing here (like the new log_dir, I'll make a quick PR adding this after we've merged this).

Ah, I forgot you also had #426 open, let's do this there instead :)

@CasperWA CasperWA merged commit c4e6f3f into master Jul 31, 2020
@CasperWA CasperWA deleted the update_docs branch July 31, 2020 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Issues pertaining to documentation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Private/dunder methods incorrectly documented in mkdocs
3 participants