From 70ef43eb8bb4ee1d6b914cd18dba68e9410061ba Mon Sep 17 00:00:00 2001 From: Tania Mathern Date: Wed, 22 Oct 2025 14:35:25 -0700 Subject: [PATCH] fix: Add an API --- src/c2pa/c2pa.py | 32 ++++++++++++++++++++++++++++++++ tests/test_unit_tests.py | 13 +++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/c2pa/c2pa.py b/src/c2pa/c2pa.py index 390e015c..b0252279 100644 --- a/src/c2pa/c2pa.py +++ b/src/c2pa/c2pa.py @@ -41,6 +41,7 @@ 'c2pa_reader_from_manifest_data_and_stream', 'c2pa_reader_free', 'c2pa_reader_json', + 'c2pa_reader_detailed_json', 'c2pa_reader_resource_to_stream', 'c2pa_builder_from_json', 'c2pa_builder_from_archive', @@ -379,6 +380,9 @@ def _setup_function(func, argtypes, restype=None): _setup_function( _lib.c2pa_reader_json, [ ctypes.POINTER(C2paReader)], ctypes.c_void_p) +_setup_function( + _lib.c2pa_reader_detailed_json, [ + ctypes.POINTER(C2paReader)], ctypes.c_void_p) _setup_function(_lib.c2pa_reader_resource_to_stream, [ctypes.POINTER( C2paReader), ctypes.c_char_p, ctypes.POINTER(C2paStream)], ctypes.c_int64) _setup_function( @@ -1737,6 +1741,34 @@ def json(self) -> str: self._manifest_json_str_cache = _convert_to_py_string(result) return self._manifest_json_str_cache + def detailed_json(self) -> str: + """Get the detailed JSON representation of the C2PA manifest store. + + This method returns a more detailed JSON string than Reader.json(), + providing additional information about the manifest structure. + Note that the returned JSON by this method has a slightly different + structure than the one returned by Reader.json(). + + Returns: + A JSON string containing the detailed manifest store data. + + Raises: + C2paError: If there is an error reading the manifest data or if + the Reader has been closed. + """ + + self._ensure_valid_state() + + result = _lib.c2pa_reader_detailed_json(self._reader) + + if result is None: + error = _parse_operation_result_for_error(_lib.c2pa_error()) + if error: + raise C2paError(error) + raise C2paError("Error during detailed manifest parsing in Reader") + + return _convert_to_py_string(result) + def get_active_manifest(self) -> Optional[dict]: """Get the active manifest from the manifest store. diff --git a/tests/test_unit_tests.py b/tests/test_unit_tests.py index 7bdb8897..e7f2d778 100644 --- a/tests/test_unit_tests.py +++ b/tests/test_unit_tests.py @@ -64,6 +64,12 @@ def test_stream_read(self): json_data = reader.json() self.assertIn(DEFAULT_TEST_FILE_NAME, json_data) + def test_stream_read_detailed(self): + with open(self.testPath, "rb") as file: + reader = Reader("image/jpeg", file) + json_data = reader.detailed_json() + self.assertIn(DEFAULT_TEST_FILE_NAME, json_data) + def test_get_active_manifest(self): with open(self.testPath, "rb") as file: reader = Reader("image/jpeg", file) @@ -142,6 +148,13 @@ def test_stream_read_and_parse(self): title = manifest_store["manifests"][manifest_store["active_manifest"]]["title"] self.assertEqual(title, DEFAULT_TEST_FILE_NAME) + def test_stream_read_detailed_and_parse(self): + with open(self.testPath, "rb") as file: + reader = Reader("image/jpeg", file) + manifest_store = json.loads(reader.detailed_json()) + title = manifest_store["manifests"][manifest_store["active_manifest"]]["claim"]["dc:title"] + self.assertEqual(title, DEFAULT_TEST_FILE_NAME) + def test_stream_read_string_stream(self): with Reader(self.testPath) as reader: json_data = reader.json()