Skip to content

Commit

Permalink
Pydanticdocs2 (#362)
Browse files Browse the repository at this point in the history
* tweak psi envs after v1.6 rel

* envs

* emv

* noncontrived?

* autodoc pydantic

* docs

* rest of ci
  • Loading branch information
loriab authored Jun 11, 2022
1 parent 1f8e26d commit 7b3e843
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 39 deletions.
7 changes: 4 additions & 3 deletions devtools/conda-envs/docs-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ dependencies:

# docs
- python-graphviz
- sphinx >=3.5
- sphinx
- sphinx-autodoc-typehints
- sphinx-automodapi
- sphinx_rtd_theme
- autodoc-pydantic

# testing
- pytest>=4.0.0
- pytest-cov
- codecov

- pip:
- git+https://github.com/MolSSI/qcarchive-sphinx-theme#egg=qcarchive_sphinx_theme
#- pip:
# - git+https://github.com/MolSSI/qcarchive-sphinx-theme#egg=qcarchive_sphinx_theme
2 changes: 0 additions & 2 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ QCEngine API

.. automodapi:: qcengine

.. automodapi:: qcengine.compute

.. automodapi:: qcengine.config

.. automodapi:: qcengine.util
Expand Down
39 changes: 23 additions & 16 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,31 @@
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx.ext.intersphinx',
'sphinx.ext.extlinks',
'sphinx.ext.graphviz',
'sphinx.ext.autosummary',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi',
'sphinx_automodapi.automodsumm',
'sphinx_automodapi.smart_resolver',
"sphinx_autodoc_typehints",
"sphinxcontrib.autodoc_pydantic",
]

napoleon_google_docstring = False
napoleon_use_param = False
napoleon_use_ivar = True
autosummary_generate = True
automodapi_toctreedirnm = 'api'
autodoc_typehints = "description"
napoleon_use_param = True
napoleon_use_rtype = True
autodoc_pydantic_model_hide_paramlist = True
autodoc_pydantic_model_show_config_summary = False
autodoc_pydantic_field_swap_name_and_alias = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down Expand Up @@ -97,11 +106,7 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
try:
import qcarchive_sphinx_theme
html_theme = 'qcarchive_sphinx_theme'
except ModuleNotFoundError:
html_theme = 'sphinx_rtd_theme'
html_theme = 'sphinx_rtd_theme'

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
Expand Down Expand Up @@ -192,11 +197,13 @@
# -- Options for intersphinx extension ---------------------------------------

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.7', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None),
'matplotlib': ('https://matplotlib.org/', None),
'qcelemental': ('https://qcelemental.readthedocs.io/en/latest/', None)
intersphinx_mapping = {'python': ('https://docs.python.org/3.10', None),
"numpy": ("https://numpy.org/doc/stable/", None),
'scipy': ('https://docs.scipy.org/doc/scipy/', None),
'matplotlib': ('https://matplotlib.org/stable/', None),
"qcelemental": ("http://docs.qcarchive.molssi.org/projects/QCElemental/en/latest/", None),
"qcportal": ("http://docs.qcarchive.molssi.org/projects/QCPortal/en/latest/", None),
"qcfractal": ("http://docs.qcarchive.molssi.org/projects/QCFractal/en/latest/", None),
}

# -- Options for todo extension ----------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion docs/source/environment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ The keys in the YAML file are human-friendly names for the configurations.
The values are dictionaries that define configurations for different nodes,
following the ``NodeDescription`` schema:

.. autoclass:: qcengine.config.NodeDescriptor
.. autopydantic_model:: qcengine.config.NodeDescriptor
:noindex:

When running QCEngine, the proper configuration for a node is determined based on the hostname of the node
and matching the ``hostname_pattern`` to each of the configurations defined in ``qcengine.yaml``.
Expand Down
10 changes: 6 additions & 4 deletions docs/source/single_compute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,22 @@ The results contain a complete record of the computation:
Input Fields
-------------

.. autoclass:: qcelemental.models.AtomicInput
.. autopydantic_model:: qcelemental.models.AtomicInput
:noindex:

Returned Fields
---------------

.. autoclass:: qcelemental.models.AtomicResult
.. autopydantic_model:: qcelemental.models.AtomicResult
:noindex:

FAQ
---

#. Where is scratch so I can access the CMS code's files?

The QCArchive philosophy is that you shouldn't go looking in scratch for CMS-code-written files since the scratch directory is deleted automatically by QCEngine and even if preserved may be subject to autodeletion if run from a cluster. Instead, QCEngine brings back the primary input and output and any ancillary files from which it can harvest results. Whether these are returned to the user in ``AtomicResult`` can be controlled through protocols in the input like ``atomicinput.protocols.stdout = True`` and eventually (https://github.com/MolSSI/QCElemental/pull/275) ``atomicinput.protocols.native_files = "all"``.

Nevertheless, you can, of course, access the scratch directory and CMS-code-written files. Pass an existing directory to the compute command (this directory will be parent) and tell it to not delete after the run: ``qcng.compute(..., local_options={"scratch_directory": "/existing/parent/dir", "scratch_messy": True})``.

#. sdfs
5 changes: 3 additions & 2 deletions qcengine/procedures/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
from .nwchem_opt import NWChemDriverProcedure
from .optking import OptKingProcedure
from .torsiondrive import TorsionDriveProcedure
from .model import ProcedureHarness

__all__ = ["register_procedure", "get_procedure", "list_all_procedures", "list_available_procedures"]

procedures = {}


def register_procedure(entry_point: "ProcedureHarness") -> None:
def register_procedure(entry_point: ProcedureHarness) -> None:
"""
Register a new ProcedureHarness with QCEngine
"""
Expand All @@ -28,7 +29,7 @@ def register_procedure(entry_point: "ProcedureHarness") -> None:
procedures[name.lower()] = entry_point


def get_procedure(name: str) -> "ProcedureHarness":
def get_procedure(name: str) -> ProcedureHarness:
"""
Returns a procedures executor class
"""
Expand Down
5 changes: 3 additions & 2 deletions qcengine/programs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Set

from ..exceptions import InputError, ResourceError
from .model import ProgramHarness
from .adcc import AdccHarness
from .cfour import CFOURHarness
from .dftd3 import DFTD3Harness
Expand Down Expand Up @@ -32,7 +33,7 @@
programs = {}


def register_program(entry_point: "ProgramHarness") -> None:
def register_program(entry_point: ProgramHarness) -> None:
"""
Register a new ProgramHarness with QCEngine.
"""
Expand All @@ -54,7 +55,7 @@ def unregister_program(name: str) -> None:
raise KeyError(f"Program {name} is not registered with QCEngine")


def get_program(name: str, check: bool = True) -> "ProgramHarness":
def get_program(name: str, check: bool = True) -> ProgramHarness:
"""
Returns a program's executor class
Expand Down
9 changes: 5 additions & 4 deletions qcengine/programs/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from qcelemental.models import AtomicInput, AtomicResult

from qcengine.exceptions import KnownErrorException
from qcengine.config import TaskConfig

logger = logging.getLogger(__name__)

Expand All @@ -29,7 +30,7 @@ def __init__(self, **kwargs):
super().__init__(**{**self._defaults, **kwargs})

@abc.abstractmethod
def compute(self, input_data: "AtomicInput", config: "TaskConfig") -> "AtomicResult":
def compute(self, input_data: AtomicInput, config: TaskConfig) -> AtomicResult:
pass

@staticmethod
Expand Down Expand Up @@ -63,7 +64,7 @@ def get_version(self) -> str:
## Computers

def build_input(
self, input_model: "AtomicInput", config: "TaskConfig", template: Optional[str] = None
self, input_model: AtomicInput, config: TaskConfig, template: Optional[str] = None
) -> Dict[str, Any]:
raise ValueError("build_input is not implemented for {}.", self.__class__)

Expand Down Expand Up @@ -99,10 +100,10 @@ class ErrorCorrectionProgramHarness(ProgramHarness, abc.ABC):
``ErrorCorrectionProgramHarness`` and used to determine if/how to re-run the computation.
"""

def _compute(self, input_data: AtomicInput, config: "TaskConfig") -> AtomicResult:
def _compute(self, input_data: AtomicInput, config: TaskConfig) -> AtomicResult:
raise NotImplementedError()

def compute(self, input_data: AtomicInput, config: "TaskConfig") -> AtomicResult:
def compute(self, input_data: AtomicInput, config: TaskConfig) -> AtomicResult:
# Get the error correction configuration
error_policy = input_data.protocols.error_correction

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/psi4.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def _handle_errors(self, output_data):
error_message = output_data["error"]["error_message"]
error_type = output_data["error"].get("error_type", "unknown_error")
else:
error_message = "Unknown error, error message is not found"
error_message = "Unknown error, error message is not found, possibly segfaulted"
error_type = "internal_error"

return error_message, error_type
Expand Down
8 changes: 4 additions & 4 deletions qcengine/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from threading import Thread
from typing import Any, BinaryIO, Dict, List, Optional, TextIO, Tuple, Union

from pydantic import ValidationError
from pydantic import BaseModel, ValidationError
from qcelemental.models import FailedOperation

from qcengine.config import TaskConfig
Expand Down Expand Up @@ -54,7 +54,7 @@ def create_mpi_invocation(executable: str, task_config: TaskConfig) -> List[str]
return command


def model_wrapper(input_data: Dict[str, Any], model: "BaseModel") -> "BaseModel":
def model_wrapper(input_data: Dict[str, Any], model: BaseModel) -> BaseModel:
"""
Wrap input data in the given model, or return a controlled error
"""
Expand Down Expand Up @@ -142,11 +142,11 @@ def compute_wrapper(capture_output: bool = True, raise_error: bool = False) -> D


def handle_output_metadata(
output_data: Union[Dict[str, Any], "BaseModel"],
output_data: Union[Dict[str, Any], BaseModel],
metadata: Dict[str, Any],
raise_error: bool = False,
return_dict: bool = True,
) -> Union[Dict[str, Any], "BaseModel"]:
) -> Union[Dict[str, Any], BaseModel]:
"""
Fuses general metadata and output together.
Expand Down

0 comments on commit 7b3e843

Please sign in to comment.