Skip to content

Commit be49781

Browse files
committed
fix: Refactor once more with overload
1 parent 3ca91c6 commit be49781

File tree

2 files changed

+89
-32
lines changed

2 files changed

+89
-32
lines changed

src/c2pa/c2pa.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -597,13 +597,10 @@ def sign_file(
597597
source_path: Union[str, Path],
598598
dest_path: Union[str, Path],
599599
manifest: str,
600-
signer_info: C2paSignerInfo
601-
) -> str:
600+
signer_info: C2paSignerInfo,
601+
return_manifest_as_bytes: bool = False
602+
) -> Union[str, bytes]:
602603
"""Sign a file with a C2PA manifest using signer info.
603-
604-
.. deprecated:: 0.10.0
605-
This function is deprecated and will be removed in a future version.
606-
Please use the Builder class for signing and the Reader class for reading signed data instead.
607604
"""
608605
...
609606

@@ -612,22 +609,20 @@ def sign_file(
612609
source_path: Union[str, Path],
613610
dest_path: Union[str, Path],
614611
manifest: str,
615-
signer: 'Signer'
616-
) -> str:
612+
signer: 'Signer',
613+
return_manifest_as_bytes: bool = False
614+
) -> Union[str, bytes]:
617615
"""Sign a file with a C2PA manifest using a signer.
618-
619-
.. deprecated:: 0.10.0
620-
This function is deprecated and will be removed in a future version.
621-
Please use the Builder class for signing and the Reader class for reading signed data instead.
622616
"""
623617
...
624618

625619
def sign_file(
626620
source_path: Union[str, Path],
627621
dest_path: Union[str, Path],
628622
manifest: str,
629-
signer_or_info: Union[C2paSignerInfo, 'Signer']
630-
) -> str:
623+
signer_or_info: Union[C2paSignerInfo, 'Signer'],
624+
return_manifest_as_bytes: bool = False
625+
) -> Union[str, bytes]:
631626
"""Sign a file with a C2PA manifest.
632627
For now, this function is left here to provide a backwards-compatible API.
633628
@@ -636,9 +631,10 @@ def sign_file(
636631
dest_path: Path to write the signed file to
637632
manifest: The manifest JSON string
638633
signer_or_info: Either a signer configuration or a signer object
634+
return_manifest_as_bytes: If True, return manifest bytes instead of JSON string
639635
640636
Returns:
641-
The signed manifest as a JSON string
637+
The signed manifest as a JSON string or bytes, depending on return_manifest_as_bytes
642638
643639
Raises:
644640
C2paError: If there was an error signing the file
@@ -666,17 +662,28 @@ def sign_file(
666662
raise C2paError.NotSupported(
667663
f"Could not determine MIME type for file: {source_path}")
668664

669-
# Sign the file using the builder
670-
builder.sign(
671-
signer=signer,
672-
format=mime_type,
673-
source=source_file,
674-
dest=dest_file
675-
)
665+
if return_manifest_as_bytes:
666+
# Convert Python streams to Stream objects for internal signing
667+
source_stream = Stream(source_file)
668+
dest_stream = Stream(dest_file)
669+
670+
# Use the builder's internal signing logic to get manifest bytes
671+
result, manifest_bytes = builder._sign_internal(
672+
signer, mime_type, source_stream, dest_stream)
673+
674+
return manifest_bytes
675+
else:
676+
# Sign the file using the builder
677+
builder.sign(
678+
signer=signer,
679+
format=mime_type,
680+
source=source_file,
681+
dest=dest_file
682+
)
676683

677-
# Read the signed manifest from the destination file
678-
with Reader(dest_path) as reader:
679-
return reader.json()
684+
# Read the signed manifest from the destination file
685+
with Reader(dest_path) as reader:
686+
return reader.json()
680687

681688
except Exception as e:
682689
# Clean up destination file if it exists and there was an error

tests/test_unit_tests.py

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -936,12 +936,13 @@ def sign_callback(data: bytes) -> bytes:
936936
tsa_url="http://timestamp.digicert.com"
937937
)
938938

939-
# Use the overloaded sign_file function with a Signer object
939+
# Test with return_manifest_as_bytes=False (default) - should return JSON string
940940
result_json = sign_file(
941941
self.testPath,
942942
output_path,
943943
self.manifestDefinition,
944-
signer
944+
signer,
945+
False
945946
)
946947

947948
# Verify the output file was created
@@ -956,6 +957,23 @@ def sign_callback(data: bytes) -> bytes:
956957
self.assertIn("manifests", manifest_data)
957958
self.assertIn("active_manifest", manifest_data)
958959

960+
# Test with return_manifest_as_bytes=True - should return bytes
961+
output_path_bytes = os.path.join(temp_dir, "signed_output_callback_bytes.jpg")
962+
result_bytes = sign_file(
963+
self.testPath,
964+
output_path_bytes,
965+
self.manifestDefinition,
966+
signer,
967+
True
968+
)
969+
970+
# Verify the output file was created
971+
self.assertTrue(os.path.exists(output_path_bytes))
972+
973+
# Verify the result is bytes (not JSON string)
974+
self.assertIsInstance(result_bytes, bytes)
975+
self.assertGreater(len(result_bytes), 0)
976+
959977
# Read the signed file and verify the manifest contains expected content
960978
with open(output_path, "rb") as file:
961979
reader = Reader("image/jpeg", file)
@@ -989,35 +1007,63 @@ def test_sign_file_overloads(self):
9891007
ta_url=b"http://timestamp.digicert.com"
9901008
)
9911009

992-
# Test with C2paSignerInfo parameter
1010+
# Test with C2paSignerInfo parameter - JSON return
9931011
result_1 = sign_file(
9941012
self.testPath,
9951013
output_path_1,
9961014
self.manifestDefinition,
997-
signer_info
1015+
signer_info,
1016+
False
9981017
)
9991018

10001019
self.assertIsInstance(result_1, str)
10011020
self.assertTrue(os.path.exists(output_path_1))
10021021

1022+
# Test with C2paSignerInfo parameter - bytes return
1023+
output_path_1_bytes = os.path.join(temp_dir, "signed_output_1_bytes.jpg")
1024+
result_1_bytes = sign_file(
1025+
self.testPath,
1026+
output_path_1_bytes,
1027+
self.manifestDefinition,
1028+
signer_info,
1029+
True
1030+
)
1031+
1032+
self.assertIsInstance(result_1_bytes, bytes)
1033+
self.assertTrue(os.path.exists(output_path_1_bytes))
1034+
10031035
# Test with Signer object
10041036
output_path_2 = os.path.join(temp_dir, "signed_output_2.jpg")
10051037

10061038
# Create a signer from the signer info
10071039
signer = Signer.from_info(signer_info)
10081040

1009-
# Test with Signer parameter
1041+
# Test with Signer parameter - JSON return
10101042
result_2 = sign_file(
10111043
self.testPath,
10121044
output_path_2,
10131045
self.manifestDefinition,
1014-
signer
1046+
signer,
1047+
False
10151048
)
10161049

10171050
self.assertIsInstance(result_2, str)
10181051
self.assertTrue(os.path.exists(output_path_2))
1052+
1053+
# Test with Signer parameter - bytes return
1054+
output_path_2_bytes = os.path.join(temp_dir, "signed_output_2_bytes.jpg")
1055+
result_2_bytes = sign_file(
1056+
self.testPath,
1057+
output_path_2_bytes,
1058+
self.manifestDefinition,
1059+
signer,
1060+
True
1061+
)
10191062

1020-
# Both results should be similar (same manifest structure)
1063+
self.assertIsInstance(result_2_bytes, bytes)
1064+
self.assertTrue(os.path.exists(output_path_2_bytes))
1065+
1066+
# Both JSON results should be similar (same manifest structure)
10211067
manifest_1 = json.loads(result_1)
10221068
manifest_2 = json.loads(result_2)
10231069

@@ -1026,6 +1072,10 @@ def test_sign_file_overloads(self):
10261072
self.assertIn("active_manifest", manifest_1)
10271073
self.assertIn("active_manifest", manifest_2)
10281074

1075+
# Both bytes results should be non-empty
1076+
self.assertGreater(len(result_1_bytes), 0)
1077+
self.assertGreater(len(result_2_bytes), 0)
1078+
10291079
finally:
10301080
# Clean up the temporary directory
10311081
shutil.rmtree(temp_dir)

0 commit comments

Comments
 (0)