From 72b5d4b5fb97c97e7f14e39bf6a40ad777c40145 Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Fri, 18 Aug 2023 10:33:21 +0200 Subject: [PATCH 1/3] docs: add sphinx and rtd boilerplate - add basic docs landing page (index.rst) - copy and adapt docs config from python-tuf (docs/conf.py) - add sphinx make files generated with sphinx-quickstart - add docs- and include in dev- reqirements.txt - gitignore sphinx build directory - add rtd config file Signed-off-by: Lukas Puehringer --- .gitignore | 3 ++ .readthedocs.yaml | 21 ++++++++++++++ docs/Makefile | 20 +++++++++++++ docs/conf.py | 65 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 6 ++++ docs/make.bat | 35 +++++++++++++++++++++++ requirements-dev.txt | 1 + requirements-docs.txt | 5 ++++ 8 files changed, 156 insertions(+) create mode 100644 .readthedocs.yaml create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100644 requirements-docs.txt diff --git a/.gitignore b/.gitignore index 974c41f6..9ff67194 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ env/* tests/htmlcov/* .DS_Store .python-version + +# Sphinx documentation +docs/_build/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..28d3e0fb --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,21 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 +build: + os: ubuntu-22.04 + apt_packages: + - swig + - softhsm2 + tools: + python: "3.11" + +sphinx: + builder: html + configuration: docs/conf.py + fail_on_warning: true + +python: + install: + - requirements: requirements-docs.txt diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d4bb2cbb --- /dev/null +++ b/docs/Makefile @@ -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) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..919f7fe3 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,65 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +sys.path.insert(0, os.path.abspath(os.path.join(".."))) + +import securesystemslib + +# -- Project information ----------------------------------------------------- + +project = "securesystemslib" +copyright = "2023, New York University and the securesystemslib contributors" +author = "New York University and the securesystemslib contributors" + + +# -- General configuration --------------------------------------------------- + +master_doc = "index" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.napoleon", + "sphinx.ext.autosummary", + "sphinx.ext.autosectionlabel", +] + +autosectionlabel_prefix_document = True + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "sphinx_rtd_theme" + +# -- Autodoc configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html + +# Shorten paths +add_module_names = False +python_use_unqualified_type_names = True + +# Show typehints in argument doc lines, but not in signatures +autodoc_typehints = "description" + +autodoc_default_options = { + "members": True, + "inherited-members": "Exception", # excl. members inherited from 'Exception' +} + +# Version +version = securesystemslib.__version__ diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..5aa8e083 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,6 @@ +Welcome to ``securesystemslib`` +=============================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..32bb2452 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/requirements-dev.txt b/requirements-dev.txt index e1c12e9a..af095433 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,4 +5,5 @@ tox -r requirements.txt -r requirements-test.txt -r requirements-lint.txt +-r requirements-docs.txt -e . diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 00000000..7dc741f1 --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,5 @@ +-r requirements-pinned.txt + +# install sphinx and its extensions +sphinx +sphinx-rtd-theme From fff0a81814b800cdae84639947d2927483566dcc Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Fri, 18 Aug 2023 13:37:51 +0200 Subject: [PATCH 2/3] doc: make Signer docstrings sphinx-friendly - re-format Signer and Key docstrings - add autodoc docstrings for public dispatch tables - add args docstrings for Signature Signed-off-by: Lukas Puehringer --- securesystemslib/signer/_key.py | 10 ++++++++-- securesystemslib/signer/_signature.py | 6 ++++++ securesystemslib/signer/_signer.py | 26 ++++++++++++++++---------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/securesystemslib/signer/_key.py b/securesystemslib/signer/_key.py index 9d6ddcb7..64af3352 100644 --- a/securesystemslib/signer/_key.py +++ b/securesystemslib/signer/_key.py @@ -56,6 +56,11 @@ # NOTE Key dispatch table is defined here so it's usable by Key, # but is populated in __init__.py (and can be appended by users). KEY_FOR_TYPE_AND_SCHEME: Dict[Tuple[str, str], Type] = {} +"""Key dispatch table for ``Key.from_dict()`` + +See ``securesystemslib.signer.KEY_FOR_TYPE_AND_SCHEME`` for default key types +and schemes, and how to register custom implementations. +""" class Key(metaclass=ABCMeta): @@ -121,8 +126,9 @@ def from_dict(cls, keyid: str, key_dict: Dict[str, Any]) -> "Key": Key implementations must override this factory constructor that is used as a deserialization helper. - Users should call Key.from_dict(): it dispatches to the actual subclass - implementation based on supported keys in KEY_FOR_TYPE_AND_SCHEME. + Users should call ``Key.from_dict()``: it dispatches to the actual + subclass implementation based on supported keys in + ``KEY_FOR_TYPE_AND_SCHEME``. Raises: KeyError, TypeError: Invalid arguments. diff --git a/securesystemslib/signer/_signature.py b/securesystemslib/signer/_signature.py index 1869125d..ee696f2c 100644 --- a/securesystemslib/signer/_signature.py +++ b/securesystemslib/signer/_signature.py @@ -15,6 +15,12 @@ class Signature: Provides utility methods to easily create an object from a dictionary and return the dictionary representation of the object. + Args: + keyid: HEX string used as a unique identifier of the key. + sig: HEX string representing the signature. + unrecognized_fields: Dictionary of all attributes that are not managed + by securesystemslib. + Attributes: keyid: HEX string used as a unique identifier of the key. signature: HEX string representing the signature. diff --git a/securesystemslib/signer/_signer.py b/securesystemslib/signer/_signer.py index 67fa53f4..cc7b5913 100644 --- a/securesystemslib/signer/_signer.py +++ b/securesystemslib/signer/_signer.py @@ -12,7 +12,11 @@ # NOTE Signer dispatch table is defined here so it's usable by Signer, # but is populated in __init__.py (and can be appended by users). SIGNER_FOR_URI_SCHEME: Dict[str, Type] = {} +"""Signer dispatch table for ``Signer.from_priv_key()`` +See ``securesystemslib.signer.SIGNER_FOR_URI_SCHEME`` for default URI schemes, +and how to register custom implementations. +""" # SecretsHandler is a function the calling code can provide to Signer: # SecretsHandler will be called if Signer needs additional secrets. @@ -24,23 +28,25 @@ class Signer(metaclass=ABCMeta): """Signer interface that supports multiple signing implementations. - Usage example: + Usage example:: signer = Signer.from_priv_key_uri("envvar:MYPRIVKEY", pub_key) sig = signer.sign(b"data") Note that signer implementations may raise errors (during both - Signer.from_priv_key_uri() and Signer.sign()) that are not documented here: - examples could include network errors or file read errors. Applications - should use generic try-except here if unexpected raises are not an option. + ``Signer.from_priv_key_uri()`` and ``Signer.sign()``) that are not + documented here: examples could include network errors or file read errors. + Applications should use generic try-except here if unexpected raises are + not an option. - See SIGNER_FOR_URI_SCHEME for supported private key URI schemes. The + See ``SIGNER_FOR_URI_SCHEME`` for supported private key URI schemes. The currently supported default schemes are: - * envvar: see SSlibSigner for details - * file: see SSlibSigner for details + + * envvar: see ``SSlibSigner`` for details + * file: see ``SSlibSigner`` for details Interactive applications may also define a secrets handler that allows - asking for user secrets if they are needed: + asking for user secrets if they are needed:: from getpass import getpass @@ -55,7 +61,7 @@ def sec_handler(secret_name:str) -> str: uri2 = "file:keys/myenckey?encrypted=true" signer2 = Signer.from_priv_key_uri(uri2, pub_key2, sec_handler) - Applications can provide their own Signer and Key implementations: + Applications can provide their own Signer and Key implementations:: from securesystemslib.signer import Signer, SIGNER_FOR_URI_SCHEME from mylib import MySigner @@ -90,7 +96,7 @@ def from_priv_key_uri( """Factory constructor for a given private key URI Returns a specific Signer instance based on the private key URI and the - supported uri schemes listed in SIGNER_FOR_URI_SCHEME. + supported uri schemes listed in ``SIGNER_FOR_URI_SCHEME``. Args: priv_key_uri: URI that identifies the private key From 0989edde0c84caeeffa1743fa920518531785165 Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Fri, 18 Aug 2023 13:39:53 +0200 Subject: [PATCH 3/3] doc: add basic Signer API overview to RTD docs Signed-off-by: Lukas Puehringer --- docs/index.rst | 11 +++++++++++ docs/signer.rst | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 docs/signer.rst diff --git a/docs/index.rst b/docs/index.rst index 5aa8e083..651a5c68 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,17 @@ Welcome to ``securesystemslib`` =============================== +A cryptography interface to sign and verify `TUF +`_ and `in-toto `_ metadata. + +.. note:: + This documentation is built for + `securesystemslib (Python) `_, used by + `python-tuf `_ and + `in-toto (Python) `_ reference implementations. + .. toctree:: :maxdepth: 2 :caption: Contents + + signer diff --git a/docs/signer.rst b/docs/signer.rst new file mode 100644 index 00000000..316b880a --- /dev/null +++ b/docs/signer.rst @@ -0,0 +1,21 @@ +Signer API +========== + +.. currentmodule:: securesystemslib.signer + +.. warning:: + The API is experimental and may change without warning in versions ``<1.0.0``. + + See `'New Signer API' `_ blog post + for background infos. + + +.. Autodoc cannot resolve docs for imported globals (sphinx-doc/sphinx#6495) +.. As workaround we reference their original internal definition. +.. autodata:: securesystemslib.signer._signer.SIGNER_FOR_URI_SCHEME + :no-value: +.. autodata:: securesystemslib.signer._key.KEY_FOR_TYPE_AND_SCHEME + :no-value: +.. autoclass:: securesystemslib.signer.Signer +.. autoclass:: securesystemslib.signer.Key +.. autoclass:: securesystemslib.signer.Signature