Skip to content

Commit

Permalink
api: Add Metadata.from_bytes()
Browse files Browse the repository at this point in the history
This is essentially short-hand for
    JSONDeserializer().deserialize(data)
but seems much easier for the API user so may be worth it.

Metadata.from_file() now uses Metadata.from_bytes() internally.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
  • Loading branch information
Jussi Kukkonen committed Apr 21, 2021
1 parent ed3d00e commit 4e8738f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
9 changes: 5 additions & 4 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ def test_generic_read(self):
path = os.path.join(self.repo_dir, 'metadata', metadata + '.json')
metadata_obj = Metadata.from_file(path)
with open(path, 'rb') as f:
metadata_str = f.read()
metadata_obj2 = JSONDeserializer().deserialize(metadata_str)
metadata_obj2 = Metadata.from_bytes(f.read())

# Assert that both methods instantiate the right inner class for
# each metadata type and ...
Expand All @@ -119,15 +118,17 @@ def test_generic_read(self):
self.assertDictEqual(
metadata_obj.to_dict(), metadata_obj2.to_dict())


# Assert that it chokes correctly on an unknown metadata type
bad_metadata_path = 'bad-metadata.json'
bad_metadata = {'signed': {'_type': 'bad-metadata'}}
bad_string = json.dumps(bad_metadata).encode('utf-8')
with open(bad_metadata_path, 'wb') as f:
f.write(json.dumps(bad_metadata).encode('utf-8'))
f.write(bad_string)

with self.assertRaises(DeserializationError):
Metadata.from_file(bad_metadata_path)
with self.assertRaises(DeserializationError):
Metadata.from_bytes(bad_string)

os.remove(bad_metadata_path)

Expand Down
34 changes: 27 additions & 7 deletions tuf/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,40 @@ def from_file(
A TUF Metadata object.
"""
if storage_backend is None:
storage_backend = FilesystemBackend()

with storage_backend.get(filename) as file_obj:
return cls.from_bytes(file_obj.read(), deserializer)

@staticmethod
def from_bytes(
data: bytes,
deserializer: Optional[MetadataDeserializer] = None,
) -> "Metadata":
"""Loads TUF metadata from raw data.
Arguments:
data: metadata content as bytes.
deserializer: Optional; A MetadataDeserializer instance that
implements deserialization. Default is JSONDeserializer.
Raises:
tuf.api.serialization.DeserializationError:
The file cannot be deserialized.
Returns:
A TUF Metadata object.
"""

if deserializer is None:
# Use local scope import to avoid circular import errors
# pylint: disable=import-outside-toplevel
from tuf.api.serialization.json import JSONDeserializer

deserializer = JSONDeserializer()

if storage_backend is None:
storage_backend = FilesystemBackend()

with storage_backend.get(filename) as file_obj:
raw_data = file_obj.read()

return deserializer.deserialize(raw_data)
return deserializer.deserialize(data)

def to_dict(self) -> Dict[str, Any]:
"""Returns the dict representation of self. """
Expand Down

0 comments on commit 4e8738f

Please sign in to comment.