diff --git a/docs/api/tuf.api.metadata.metadata.rst b/docs/api/tuf.api.metadata.metadata.rst new file mode 100644 index 00000000..bac11a31 --- /dev/null +++ b/docs/api/tuf.api.metadata.metadata.rst @@ -0,0 +1,4 @@ +Metadata class +--------------------------------- + +.. autoclass:: tuf.api.metadata.Metadata diff --git a/docs/api/tuf.api.metadata.root.rst b/docs/api/tuf.api.metadata.root.rst new file mode 100644 index 00000000..ab6194bc --- /dev/null +++ b/docs/api/tuf.api.metadata.root.rst @@ -0,0 +1,4 @@ +Root class +--------------------------------- + +.. autoclass:: tuf.api.metadata.Root diff --git a/docs/api/tuf.api.metadata.rst b/docs/api/tuf.api.metadata.rst deleted file mode 100644 index c4a58bb4..00000000 --- a/docs/api/tuf.api.metadata.rst +++ /dev/null @@ -1,7 +0,0 @@ -Metadata ---------------------------------- - -.. automodule:: tuf.api.metadata - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/tuf.api.metadata.snapshot.rst b/docs/api/tuf.api.metadata.snapshot.rst new file mode 100644 index 00000000..1d1c2025 --- /dev/null +++ b/docs/api/tuf.api.metadata.snapshot.rst @@ -0,0 +1,4 @@ +Snapshot class +--------------------------------- + +.. autoclass:: tuf.api.metadata.Snapshot diff --git a/docs/api/tuf.api.metadata.supporting.rst b/docs/api/tuf.api.metadata.supporting.rst new file mode 100644 index 00000000..906e70e9 --- /dev/null +++ b/docs/api/tuf.api.metadata.supporting.rst @@ -0,0 +1,27 @@ +Supporting classes +--------------------------------- + +The Metadata API includes multiple classes that are used by the top-level +ones (Root, Timestamp, Snapshot, Targets): + +.. autosummary:: + :nosignatures: + + tuf.api.metadata.DelegatedRole + tuf.api.metadata.Delegations + tuf.api.metadata.Key + tuf.api.metadata.MetaFile + tuf.api.metadata.Role + tuf.api.metadata.TargetFile + +.. autoclass:: tuf.api.metadata.DelegatedRole + +.. autoclass:: tuf.api.metadata.Delegations + +.. autoclass:: tuf.api.metadata.Key + +.. autoclass:: tuf.api.metadata.MetaFile + +.. autoclass:: tuf.api.metadata.Role + +.. autoclass:: tuf.api.metadata.TargetFile diff --git a/docs/api/tuf.api.metadata.targets.rst b/docs/api/tuf.api.metadata.targets.rst new file mode 100644 index 00000000..a8af3ab3 --- /dev/null +++ b/docs/api/tuf.api.metadata.targets.rst @@ -0,0 +1,4 @@ +Targets class +--------------------------------- + +.. autoclass:: tuf.api.metadata.Targets diff --git a/docs/api/tuf.api.metadata.timestamp.rst b/docs/api/tuf.api.metadata.timestamp.rst new file mode 100644 index 00000000..2d29d37d --- /dev/null +++ b/docs/api/tuf.api.metadata.timestamp.rst @@ -0,0 +1,4 @@ +Timestamp class +--------------------------------- + +.. autoclass:: tuf.api.metadata.Timestamp diff --git a/docs/api/tuf.api.rst b/docs/api/tuf.api.rst index b93902c6..d4309b84 100644 --- a/docs/api/tuf.api.rst +++ b/docs/api/tuf.api.rst @@ -1,18 +1,19 @@ Metadata API =============== -The low-level Metadata API contains two modules: +.. toctree:: -* :doc:`tuf.api.metadata` contains the actual Metadata abstraction - that higher level libraries and application code should use to interact - with TUF metadata. This abstraction provides safe reading and writing to - supported file formats and helper functions for accessing and modifying - the metadata contents. -* :doc:`tuf.api.serialization` covers serializing the metadata into - specific wire formats (like json). + tuf.api.metadata.metadata + tuf.api.metadata.root + tuf.api.metadata.timestamp + tuf.api.metadata.snapshot + tuf.api.metadata.targets .. toctree:: :hidden: - tuf.api.metadata + tuf.api.metadata.supporting tuf.api.serialization + +.. automodule:: tuf.api.metadata + :no-members: \ No newline at end of file diff --git a/docs/api/tuf.api.serialization.rst b/docs/api/tuf.api.serialization.rst index 1603148d..610ab910 100644 --- a/docs/api/tuf.api.serialization.rst +++ b/docs/api/tuf.api.serialization.rst @@ -1,10 +1,10 @@ Serialization ============================= +.. automodule:: tuf.api.serialization + JSON serialization ----------------------------- .. automodule:: tuf.api.serialization.json - :members: - :undoc-members: :show-inheritance: diff --git a/docs/api/tuf.ngclient.config.rst b/docs/api/tuf.ngclient.config.rst index 150df082..b69d7cf4 100644 --- a/docs/api/tuf.ngclient.config.rst +++ b/docs/api/tuf.ngclient.config.rst @@ -2,6 +2,4 @@ Configuration ============= .. automodule:: tuf.ngclient.config - :members: :undoc-members: - :show-inheritance: diff --git a/docs/api/tuf.ngclient.fetcher.rst b/docs/api/tuf.ngclient.fetcher.rst index 1f689d4f..f37ea14f 100644 --- a/docs/api/tuf.ngclient.fetcher.rst +++ b/docs/api/tuf.ngclient.fetcher.rst @@ -2,6 +2,4 @@ Fetcher ============ .. automodule:: tuf.ngclient.fetcher - :members: :undoc-members: - :show-inheritance: diff --git a/docs/api/tuf.ngclient.updater.rst b/docs/api/tuf.ngclient.updater.rst index 0fc46757..3f032c6b 100644 --- a/docs/api/tuf.ngclient.updater.rst +++ b/docs/api/tuf.ngclient.updater.rst @@ -2,5 +2,3 @@ Updater ========= .. automodule:: tuf.ngclient.updater - :members: - :special-members: __init__ diff --git a/docs/conf.py b/docs/conf.py index 2b087620..cb146ed9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ # 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'] +extensions = ['sphinx.ext.napoleon', 'sphinx.ext.autosummary'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -52,5 +52,19 @@ # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] +# -- Autodoc configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html + autodoc_mock_imports = ['securesystemslib'] +# Tone down the "tuf.api.metadata." repetition +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, + 'exclude-members': 'to_dict, from_dict' +} \ No newline at end of file diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index 4e3f5a5b..0b88f4c0 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -1,38 +1,28 @@ # Copyright New York University and the TUF contributors # SPDX-License-Identifier: MIT OR Apache-2.0 -"""TUF role metadata model. - -This module contains low-level API through container classes for TUF role -metadata. The API aims to provide: +""" +The low-level Metadata API in ``tuf.api.metadata`` module contains: * Safe de/serialization of metadata to and from files. * Access to and modification of signed metadata content. * Signing metadata and verifying signatures. -Each of the top level metadata roles is an instance of the Metadata[T] class -where the "signed" portion of each of the roles (or the "T") is an instance -of one of the classes Root, Timestamp, Snapshot or Targets. -For example, Metadata[Root] represents the TUF root role and that in practice -means that this is a Metadata object with a signed attribute of type Root. +Metadata API implements functionality at the metadata file level, it does +not provide TUF repository or client functionality on its own (but can be used +to implement them). -Additionally, there are helper classes providing abstractions over the complex -metadata fields inside the four top level classes - Root, Timestamp, Snapshot -and Targets. +The API design is based on the file format defined in the `TUF specification +`_ and the object +attributes generally follow the JSON format used in the specification. -Note: the metadata module provides a low-level API and as such it doesn't use -concepts like "repository" or "trusted collection of metadata". -In this file there is no implementation of the repository-side logic or client -update workflows, but instead it provides solid base for other components to do -so. - -The metadata model supports any custom serialization format, defaulting to JSON -as wireline format and Canonical JSON for reproducible signature creation and -verification. -Custom serializers must implement the abstract serialization interface defined -in 'tuf.api.serialization', and may use the [to|from]_dict convenience methods -available in the class model. +The above principle means that a ``Metadata`` object represents a single +metadata file, and has a ``signed`` attribute that is an instance of one of the +four top level signed classes (Root, Timestamp, Snapshot and Targets). To make +Python type annotations useful Metadata can be type constrained: e.g. the +signed attribute of ``Metadata[Root]`` is known to be ``Root``. +Currently Metadata API supports JSON as the file format. """ import abc import fnmatch @@ -104,9 +94,12 @@ class Metadata(Generic[T]): "[Root]" is not validated at runtime (as pure annotations are not available then). - Attributes: - signed: A subclass of Signed, which has the actual metadata payload, - i.e. one of Targets, Snapshot, Timestamp or Root. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + signed: The actual metadata payload, i.e. one of Targets, Snapshot, + Timestamp or Root. signatures: An ordered dictionary of keyids to Signature objects, each signing the canonical serialized representation of 'signed'. """ @@ -205,9 +198,9 @@ def from_bytes( """Loads TUF metadata from raw data. Arguments: - data: metadata content as bytes. - deserializer: Optional; A MetadataDeserializer instance that - implements deserialization. Default is JSONDeserializer. + data: metadata content. + deserializer: MetadataDeserializer implementation to use. Default + is JSONDeserializer. Raises: tuf.api.serialization.DeserializationError: @@ -340,7 +333,7 @@ def verify_delegate( Args: delegated_role: Name of the delegated role to verify delegated_metadata: The Metadata object for the delegated role - signed_serializer: Optional; serializer used for delegate + signed_serializer: serializer used for delegate serialization. Default is CanonicalJSONSerializer. Raises: @@ -390,12 +383,13 @@ class Signed(metaclass=abc.ABCMeta): on the signed attribute. This class provides attributes and methods that are common for all TUF metadata types (roles). - Attributes: - _type: The metadata type string. Also available without underscore. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: version: The metadata version number. - spec_version: The TUF specification version number (semver) the - metadata format adheres to. - expires: The metadata expiration datetime object. + spec_version: The supported TUF specification version number. + expires: The metadata expiry date. unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -409,6 +403,7 @@ def _type(self) -> str: @property def type(self) -> str: + """Metadata type as string.""" return self._signed_type # NOTE: Signed is a stupid name, because this might not be signed yet, but @@ -420,7 +415,7 @@ def __init__( spec_version: str, expires: datetime, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): spec_list = spec_version.split(".") if ( len(spec_list) != 3 @@ -492,9 +487,8 @@ def is_expired(self, reference_time: Optional[datetime] = None) -> bool: """Checks metadata expiration against a reference time. Args: - reference_time: Optional; The time to check expiration date against. - A naive datetime in UTC expected. - If not provided, checks against the current UTC date and time. + reference_time: The time to check expiration date against. A naive + datetime in UTC expected. Default is current UTC date and time. Returns: True if expiration time is less than the reference time. @@ -517,18 +511,20 @@ def bump_version(self) -> None: class Key: """A container class representing the public portion of a Key. - Please note that "Key" instances are not semanticly validated during - initialization: this only happens at signature verification time. + Supported key content (type, scheme and keyval) is defined in + Securesystemslib. - Attributes: - keyid: An identifier string that must uniquely identify a key within - the metadata it is used in. This implementation does not verify - that keyid is the hash of a specific representation of the key. - keytype: A string denoting a public key signature system, - such as "rsa", "ed25519", "ecdsa" and "ecdsa-sha2-nistp256". - scheme: A string denoting a corresponding signature scheme. For example: + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + keyid: Key identifier that is unique within the metadata it is used in. + Keyid is not verified to be the hash of a specific representation + of the key. + keytype: key type, e.g. "rsa", "ed25519" or "ecdsa-sha2-nistp256". + scheme: signature scheme. For example: "rsassa-pss-sha256", "ed25519", and "ecdsa-sha2-nistp256". - keyval: A dictionary containing the public portion of the key. + keyval: Opaque key content unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -539,7 +535,7 @@ def __init__( scheme: str, keyval: Dict[str, str], unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): if not all( isinstance(at, str) for at in [keyid, keytype, scheme] ) or not isinstance(keyval, Dict): @@ -605,7 +601,7 @@ def verify_signature( Arguments: metadata: Metadata to verify - signed_serializer: Optional; SignedSerializer to serialize + signed_serializer: SignedSerializer to serialize 'metadata.signed' with. Default is CanonicalJSONSerializer. Raises: @@ -653,8 +649,11 @@ class Role: Role defines how many keys are required to successfully sign the roles metadata, and which keys are accepted. - Attributes: - keyids: A set of strings representing signing keys for this role. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + keyids: The roles signing key identifiers. threshold: Number of keys required to sign this role's metadata. unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -664,7 +663,7 @@ def __init__( keyids: List[str], threshold: int, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): keyids_set = set(keyids) if len(keyids_set) != len(keyids): raise ValueError( @@ -697,12 +696,17 @@ def to_dict(self) -> Dict[str, Any]: class Root(Signed): """A container for the signed part of root metadata. - Attributes: - consistent_snapshot: An optional boolean indicating whether the - repository supports consistent snapshots. + Parameters listed below are also instance attributes. + + Args: + version: The metadata version number. + spec_version: The supported TUF specification version number. + expires: The metadata expiry date. keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'. roles: Dictionary of role names to Roles. Defines which keys are required to sign the metadata for a specific role. + consistent_snapshot: Does repository support consistent snapshots. + unrecognized_fields: Dictionary of all unrecognized fields. """ _signed_type = "root" @@ -718,7 +722,7 @@ def __init__( roles: Dict[str, Role], consistent_snapshot: Optional[bool] = None, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): super().__init__(version, spec_version, expires, unrecognized_fields) self.consistent_snapshot = consistent_snapshot self.keys = keys @@ -859,10 +863,13 @@ def _validate_length(length: int) -> None: class MetaFile(BaseFile): """A container with information about a particular metadata file. - Attributes: - version: An integer indicating the version of the metadata file. - length: An optional integer indicating the length of the metadata file. - hashes: An optional dictionary of hash algorithm names to hash values. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + version: Version of the metadata file. + length: Length of the metadata file. + hashes: Dictionary of hash algorithm names to hash values. unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -872,7 +879,7 @@ def __init__( length: Optional[int] = None, hashes: Optional[Dict[str, str]] = None, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): if version <= 0: raise ValueError(f"Metafile version must be > 0, got {version}") @@ -934,8 +941,15 @@ class Timestamp(Signed): TUF file format uses a dictionary to contain the snapshot information: this is not the case with Timestamp.snapshot_meta which is a MetaFile. - Attributes: - snapshot_meta: MetaFile instance with the snapshot meta information. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + version: The metadata version number. + spec_version: The supported TUF specification version number. + expires: The metadata expiry date. + unrecognized_fields: Dictionary of all unrecognized fields. + snapshot_meta: Meta information for snapshot metadata. """ _signed_type = "timestamp" @@ -947,7 +961,7 @@ def __init__( expires: datetime, snapshot_meta: MetaFile, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): super().__init__(version, spec_version, expires, unrecognized_fields) self.snapshot_meta = snapshot_meta @@ -977,7 +991,14 @@ class Snapshot(Signed): Snapshot contains information about all target Metadata files. - Attributes: + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + version: The metadata version number. + spec_version: The supported TUF specification version number. + expires: The metadata expiry date. + unrecognized_fields: Dictionary of all unrecognized fields. meta: A dictionary of target metadata filenames to MetaFile objects. """ @@ -990,7 +1011,7 @@ def __init__( expires: datetime, meta: Dict[str, MetaFile], unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): super().__init__(version, spec_version, expires, unrecognized_fields) self.meta = meta @@ -1034,13 +1055,17 @@ class DelegatedRole(Role): paths and path_hash_prefixes are mutually exclusive: both cannot be set, at least one of them must be set. - Attributes: - name: A string giving the name of the delegated role. - terminating: A boolean indicating whether subsequent delegations - should be considered during a target lookup. - paths: An optional list of path pattern strings. See note above. - path_hash_prefixes: An optional list of hash prefixes. See note above. - unrecognized_fields: Dictionary of all unrecognized fields. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + name: Delegated role name. + keyids: Delegated role signing key identifiers. + threshold: Number of keys required to sign this role's metadata. + terminating: Does this delegation terminate a target lookup. + paths: Path patterns. See note above. + path_hash_prefixes: Hash prefixes. See note above. + unrecognized_fields: Attributes not managed by TUF Metadata API. """ def __init__( @@ -1052,7 +1077,7 @@ def __init__( paths: Optional[List[str]] = None, path_hash_prefixes: Optional[List[str]] = None, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): super().__init__(keyids, threshold, unrecognized_fields) self.name = name self.terminating = terminating @@ -1152,12 +1177,15 @@ def is_delegated_path(self, target_filepath: str) -> bool: class Delegations: """A container object storing information about all delegations. - Attributes: + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'. roles: Ordered dictionary of role names to DelegatedRoles instances. It defines which keys are required to sign the metadata for a specific role. The roles order also defines the order that role delegations - are considered in. + are considered during target searches. unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -1166,7 +1194,7 @@ def __init__( keys: Dict[str, Key], roles: "OrderedDict[str, DelegatedRole]", unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): self.keys = keys self.roles = roles self.unrecognized_fields = unrecognized_fields or {} @@ -1202,11 +1230,13 @@ def to_dict(self) -> Dict[str, Any]: class TargetFile(BaseFile): """A container with information about a particular target file. - Attributes: - length: An integer indicating the length of the target file. + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + length: Length in bytes. hashes: A dictionary of hash algorithm names to hash values. - path: A string denoting the path to a target file relative to a base - URL of targets. + path: URL path to a target file, relative to a base targets URL. unrecognized_fields: Dictionary of all unrecognized fields. """ @@ -1216,7 +1246,7 @@ def __init__( hashes: Dict[str, str], path: str, unrecognized_fields: Optional[Mapping[str, Any]] = None, - ) -> None: + ): self._validate_length(length) self._validate_hashes(hashes) @@ -1255,12 +1285,13 @@ def from_file( hash_algorithms: Optional[List[str]] = None, ) -> "TargetFile": """Creates TargetFile object from a file. + Arguments: - target_file_path: The TargetFile path. - local_path: The local path to the file to create TargetFile from. - hash_algorithms: An optional list of hash algorithms to create - the hashes with. If not specified the securesystemslib default - hash algorithm is used. + target_file_path: URL path to a target file, relative to a base + targets URL. + local_path: The local path to target file content. + hash_algorithms: hash algorithms to calculate hashes with. If not + specified the securesystemslib default hash algorithm is used. Raises: FileNotFoundError: The file doesn't exist. UnsupportedAlgorithmError: The hash algorithms list @@ -1277,12 +1308,14 @@ def from_data( hash_algorithms: Optional[List[str]] = None, ) -> "TargetFile": """Creates TargetFile object from bytes. + Arguments: - target_file_path: The TargetFile path. - data: The data to create TargetFile from. - hash_algorithms: An optional list of hash algorithms to create - the hashes with. If not specified the securesystemslib default - hash algorithm is used. + target_file_path: URL path to a target file, relative to a base + targets URL. + data: The target file content. + hash_algorithms: Hash algorithms to create the hashes with. If not + specified the securesystemslib default hash algorithm is used. + Raises: UnsupportedAlgorithmError: The hash algorithms list contains an unsupported algorithm. @@ -1339,10 +1372,17 @@ class Targets(Signed): Targets contains verifying information about target files and also delegates responsibility to other Targets roles. - Attributes: + *All parameters named below are not just constructor arguments but also + instance attributes.* + + Args: + version: The metadata version number. + spec_version: The supported TUF specification version number. + expires: The metadata expiry date. targets: A dictionary of target filenames to TargetFiles - delegations: An optional Delegations that defines how this Targets - further delegates responsibility to other Targets Metadata files. + delegations: Defines how this Targets delegates responsibility to other + Targets Metadata files. + unrecognized_fields: Dictionary of all unrecognized fields. """ _signed_type = "targets" diff --git a/tuf/api/serialization/__init__.py b/tuf/api/serialization/__init__.py index 4ec0a4ae..36fa5d76 100644 --- a/tuf/api/serialization/__init__.py +++ b/tuf/api/serialization/__init__.py @@ -1,19 +1,19 @@ # Copyright New York University and the TUF contributors # SPDX-License-Identifier: MIT OR Apache-2.0 -"""TUF role metadata de/serialization. - -This sub-package provides abstract base classes and concrete implementations to -serialize and deserialize TUF role metadata and metadata parts. +"""``tuf.api.serialization`` module provides abstract base classes and concrete +implementations to serialize and deserialize TUF metadata. Any custom de/serialization implementations should inherit from the abstract -base classes defined in this __init__.py module. +base classes defined in this module. The implementations can use the +``to_dict()``/``from_dict()`` implementations available in the Metadata +API objects. - Metadata de/serializers are used to convert to and from wireline formats. - Signed serializers are used to canonicalize data for cryptographic signatures generation and verification. - """ + import abc from typing import TYPE_CHECKING @@ -36,7 +36,7 @@ class MetadataDeserializer(metaclass=abc.ABCMeta): @abc.abstractmethod def deserialize(self, raw_data: bytes) -> "Metadata": - """Deserialize passed bytes to Metadata object.""" + """Deserialize bytes to Metadata object.""" raise NotImplementedError @@ -45,7 +45,7 @@ class MetadataSerializer(metaclass=abc.ABCMeta): @abc.abstractmethod def serialize(self, metadata_obj: "Metadata") -> bytes: - """Serialize passed Metadata object to bytes.""" + """Serialize Metadata object to bytes.""" raise NotImplementedError @@ -54,5 +54,5 @@ class SignedSerializer(metaclass=abc.ABCMeta): @abc.abstractmethod def serialize(self, signed_obj: "Signed") -> bytes: - """Serialize passed Signed object to bytes.""" + """Serialize Signed object to bytes.""" raise NotImplementedError diff --git a/tuf/api/serialization/json.py b/tuf/api/serialization/json.py index 43814993..b043310f 100644 --- a/tuf/api/serialization/json.py +++ b/tuf/api/serialization/json.py @@ -1,14 +1,13 @@ # Copyright New York University and the TUF contributors # SPDX-License-Identifier: MIT OR Apache-2.0 -"""TUF role metadata JSON serialization and deserialization. - -This module provides concrete implementations to serialize and deserialize TUF -role metadata to and from the JSON wireline format for transportation, and -to serialize the 'signed' part of TUF role metadata to the OLPC Canonical JSON -format for signature generation and verification. - +"""``tuf.api.serialization.json`` module provides concrete implementations to +serialize and deserialize TUF role metadata to and from the JSON wireline +format for transportation, and to serialize the 'signed' part of TUF role +metadata to the OLPC Canonical JSON format for signature generation and +verification. """ + import json from securesystemslib.formats import encode_canonical @@ -51,7 +50,7 @@ class JSONSerializer(MetadataSerializer): """ - def __init__(self, compact: bool = False) -> None: + def __init__(self, compact: bool = False): self.compact = compact def serialize(self, metadata_obj: Metadata) -> bytes: diff --git a/tuf/ngclient/config.py b/tuf/ngclient/config.py index 177594bf..6182c70d 100644 --- a/tuf/ngclient/config.py +++ b/tuf/ngclient/config.py @@ -18,11 +18,11 @@ class UpdaterConfig: timestamp_max_length: The maximum length of a timestamp metadata file. snapshot_max_length: The maximum length of a snapshot metadata file. targets_max_length: The maximum length of a targets metadata file. - prefix_targets_with_hash: When consistent snapshots are used - (see https://theupdateframework.github.io/specification/latest/#consistent-snapshots), #pylint: disable=line-too-long - target download URLs are formed by prefixing the filename with a - hash digest of file content by default. This can be overridden by - setting prefix_targets_with_hash to False. + prefix_targets_with_hash: When `consistent snapshots + `_ + are used, target download URLs are formed by prefixing the filename + with a hash digest of file content by default. This can be + overridden by setting prefix_targets_with_hash to False. """ diff --git a/tuf/ngclient/updater.py b/tuf/ngclient/updater.py index 3e8667ba..20fda0e4 100644 --- a/tuf/ngclient/updater.py +++ b/tuf/ngclient/updater.py @@ -78,7 +78,21 @@ class Updater: - """Implementation of the TUF client workflow.""" + """Creates a new Updater instance and loads trusted root metadata. + + Args: + repository_dir: Local metadata directory. Directory must be + writable and it must contain a trusted root.json file. + metadata_base_url: Base URL for all remote metadata downloads + target_base_url: Optional; Default base URL for all remote target + downloads. Can be individually set in download_target() + fetcher: Optional; FetcherInterface implementation used to download + both metadata and targets. Default is RequestsFetcher + + Raises: + OSError: Local root.json cannot be read + RepositoryError: Local root.json is invalid + """ def __init__( self, @@ -88,21 +102,6 @@ def __init__( fetcher: Optional[FetcherInterface] = None, config: Optional[UpdaterConfig] = None, ): - """Creates a new Updater instance and loads trusted root metadata. - - Args: - repository_dir: Local metadata directory. Directory must be - writable and it must contain a trusted root.json file. - metadata_base_url: Base URL for all remote metadata downloads - target_base_url: Optional; Default base URL for all remote target - downloads. Can be individually set in download_target() - fetcher: Optional; FetcherInterface implementation used to download - both metadata and targets. Default is RequestsFetcher - - Raises: - OSError: Local root.json cannot be read - RepositoryError: Local root.json is invalid - """ self._dir = repository_dir self._metadata_base_url = _ensure_trailing_slash(metadata_base_url) if target_base_url is None: