c2pa-python 0.10.0__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. c2pa_python-0.11.0/PKG-INFO +67 -0
  2. c2pa_python-0.11.0/README.md +44 -0
  3. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/pyproject.toml +1 -1
  4. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/scripts/download_artifacts.py +13 -2
  5. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/setup.py +4 -0
  6. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa/lib.py +6 -1
  7. c2pa_python-0.11.0/src/c2pa_python.egg-info/PKG-INFO +67 -0
  8. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/tests/test_unit_tests.py +24 -0
  9. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/tests/test_unit_tests_threaded.py +72 -52
  10. c2pa_python-0.10.0/PKG-INFO +0 -156
  11. c2pa_python-0.10.0/README.md +0 -133
  12. c2pa_python-0.10.0/src/c2pa_python.egg-info/PKG-INFO +0 -156
  13. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/LICENSE-APACHE +0 -0
  14. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/LICENSE-MIT +0 -0
  15. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/MANIFEST.in +0 -0
  16. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/requirements.txt +0 -0
  17. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/setup.cfg +0 -0
  18. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa/__init__.py +0 -0
  19. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa/build.py +0 -0
  20. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa/c2pa.py +0 -0
  21. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa_python.egg-info/SOURCES.txt +0 -0
  22. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa_python.egg-info/dependency_links.txt +0 -0
  23. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa_python.egg-info/entry_points.txt +0 -0
  24. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa_python.egg-info/requires.txt +0 -0
  25. {c2pa_python-0.10.0 → c2pa_python-0.11.0}/src/c2pa_python.egg-info/top_level.txt +0 -0
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: c2pa-python
3
+ Version: 0.11.0
4
+ Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
5
+ Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
6
+ Maintainer-email: Gavin Peacock <gpeacock@adobe.com>
7
+ License: MIT OR Apache-2.0
8
+ Project-URL: homepage, https://contentauthenticity.org
9
+ Project-URL: repository, https://github.com/contentauth/c2pa-python
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: wheel>=0.41.2
17
+ Requires-Dist: setuptools>=68.0.0
18
+ Requires-Dist: toml>=0.10.2
19
+ Requires-Dist: pytest>=7.4.0
20
+ Requires-Dist: cryptography>=41.0.0
21
+ Requires-Dist: requests>=2.0.0
22
+ Dynamic: requires-python
23
+
24
+ # C2PA Python library
25
+
26
+ The [c2pa-python](https://github.com/contentauth/c2pa-python) repository provides a Python library that can:
27
+ - Read and validate C2PA manifest data from media files in supported formats.
28
+ - Create and sign manifest data, and attach it to media files in supported formats.
29
+
30
+ Features:
31
+
32
+ - Create and sign C2PA manifests using various signing algorithms.
33
+ - Verify C2PA manifests and extract metadata.
34
+ - Add assertions and ingredients to assets.
35
+ - Examples and unit tests to demonstrate usage.
36
+
37
+ ## Prerequisites
38
+
39
+ This library requires Python version 3.10+.
40
+
41
+ ## Package installation
42
+
43
+ Install the c2pa-python package from PyPI by running:
44
+
45
+ ```bash
46
+ pip install c2pa-python
47
+ ```
48
+
49
+ To use the module in Python code, import the module like this:
50
+
51
+ ```python
52
+ import c2pa
53
+ ```
54
+
55
+ ## Examples
56
+
57
+ See the [`examples` directory](https://github.com/contentauth/c2pa-python/tree/main/examples) for some helpful examples:
58
+ - `examples/sign.py` shows how to sign and verify an asset with a C2PA manifest.
59
+ - `examples/training.py` demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
60
+
61
+ ## Contributing
62
+
63
+ Contributions are welcome! For more information, see [Contributing to the project](https://github.com/contentauth/c2pa-python/blob/main/docs/project-contributions.md).
64
+
65
+ ## License
66
+
67
+ This project is licensed under the Apache License 2.0 and the MIT License. See the [LICENSE-MIT](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-MIT) and [LICENSE-APACHE](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-APACHE) files for details.
@@ -0,0 +1,44 @@
1
+ # C2PA Python library
2
+
3
+ The [c2pa-python](https://github.com/contentauth/c2pa-python) repository provides a Python library that can:
4
+ - Read and validate C2PA manifest data from media files in supported formats.
5
+ - Create and sign manifest data, and attach it to media files in supported formats.
6
+
7
+ Features:
8
+
9
+ - Create and sign C2PA manifests using various signing algorithms.
10
+ - Verify C2PA manifests and extract metadata.
11
+ - Add assertions and ingredients to assets.
12
+ - Examples and unit tests to demonstrate usage.
13
+
14
+ ## Prerequisites
15
+
16
+ This library requires Python version 3.10+.
17
+
18
+ ## Package installation
19
+
20
+ Install the c2pa-python package from PyPI by running:
21
+
22
+ ```bash
23
+ pip install c2pa-python
24
+ ```
25
+
26
+ To use the module in Python code, import the module like this:
27
+
28
+ ```python
29
+ import c2pa
30
+ ```
31
+
32
+ ## Examples
33
+
34
+ See the [`examples` directory](https://github.com/contentauth/c2pa-python/tree/main/examples) for some helpful examples:
35
+ - `examples/sign.py` shows how to sign and verify an asset with a C2PA manifest.
36
+ - `examples/training.py` demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
37
+
38
+ ## Contributing
39
+
40
+ Contributions are welcome! For more information, see [Contributing to the project](https://github.com/contentauth/c2pa-python/blob/main/docs/project-contributions.md).
41
+
42
+ ## License
43
+
44
+ This project is licensed under the Apache License 2.0 and the MIT License. See the [LICENSE-MIT](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-MIT) and [LICENSE-APACHE](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-APACHE) files for details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "c2pa-python"
7
- version = "0.10.0"
7
+ version = "0.11.0"
8
8
  requires-python = ">=3.10"
9
9
  description = "Python bindings for the C2PA Content Authenticity Initiative (CAI) library"
10
10
  readme = { file = "README.md", content-type = "text/markdown" }
@@ -46,16 +46,21 @@ def get_platform_identifier():
46
46
  Returns one of:
47
47
  - universal-apple-darwin (for Mac)
48
48
  - x86_64-pc-windows-msvc (for Windows 64-bit)
49
- - x86_64-unknown-linux-gnu (for Linux 64-bit)
49
+ - x86_64-unknown-linux-gnu (for Linux x86_64)
50
+ - aarch64-unknown-linux-gnu (for Linux ARM64)
50
51
  """
51
52
  system = platform.system().lower()
53
+ machine = platform.machine().lower()
52
54
 
53
55
  if system == "darwin":
54
56
  return "universal-apple-darwin"
55
57
  elif system == "windows":
56
58
  return "x86_64-pc-windows-msvc"
57
59
  elif system == "linux":
58
- return "x86_64-unknown-linux-gnu"
60
+ if machine in ["arm64", "aarch64"]:
61
+ return "aarch64-unknown-linux-gnu"
62
+ else:
63
+ return "x86_64-unknown-linux-gnu"
59
64
  else:
60
65
  raise ValueError(f"Unsupported operating system: {system}")
61
66
 
@@ -105,8 +110,12 @@ def copy_artifacts_to_root():
105
110
  print("Copying artifacts from scripts/artifacts to root...")
106
111
  if ROOT_ARTIFACTS_DIR.exists():
107
112
  shutil.rmtree(ROOT_ARTIFACTS_DIR)
113
+ print(f"Copying from {SCRIPTS_ARTIFACTS_DIR} to {ROOT_ARTIFACTS_DIR}")
108
114
  shutil.copytree(SCRIPTS_ARTIFACTS_DIR, ROOT_ARTIFACTS_DIR)
109
115
  print("Done copying artifacts")
116
+ print("\nFolder content of artifacts directory:")
117
+ for item in sorted(ROOT_ARTIFACTS_DIR.iterdir()):
118
+ print(f" {item.name}")
110
119
 
111
120
  def main():
112
121
  if len(sys.argv) < 2:
@@ -126,6 +135,8 @@ def main():
126
135
  if env_platform:
127
136
  print(f"Using platform from environment variable C2PA_LIBS_PLATFORM: {env_platform}")
128
137
  platform_id = env_platform or get_platform_identifier()
138
+ print("Looking up releases for platform id: ", platform_id)
139
+ print("Environment variable set for lookup: ", env_platform)
129
140
  platform_source = "environment variable" if env_platform else "auto-detection"
130
141
  print(f"Target platform: {platform_id} (set through{platform_source})")
131
142
 
@@ -30,6 +30,7 @@ PLATFORM_FOLDERS = {
30
30
  'x86_64-apple-darwin': 'dylib',
31
31
  'x86_64-pc-windows-msvc': 'dll',
32
32
  'x86_64-unknown-linux-gnu': 'so',
33
+ 'aarch64-unknown-linux-gnu': 'so', # Add ARM Linux support
33
34
  }
34
35
 
35
36
  # Directory structure
@@ -51,6 +52,7 @@ def get_platform_identifier(cpu_arch = None) -> str:
51
52
  - x86_64-apple-darwin (for Mac x86_64)
52
53
  - x86_64-pc-windows-msvc (for Windows 64-bit)
53
54
  - x86_64-unknown-linux-gnu (for Linux 64-bit)
55
+ - aarch64-unknown-linux-gnu (for Linux ARM64)
54
56
  """
55
57
  system = platform.system().lower()
56
58
 
@@ -66,6 +68,8 @@ def get_platform_identifier(cpu_arch = None) -> str:
66
68
  elif system == "windows":
67
69
  return "x86_64-pc-windows-msvc"
68
70
  elif system == "linux":
71
+ if platform.machine() == "aarch64":
72
+ return "aarch64-unknown-linux-gnu"
69
73
  return "x86_64-unknown-linux-gnu"
70
74
  else:
71
75
  raise ValueError(f"Unsupported operating system: {system}")
@@ -62,6 +62,8 @@ def get_platform_identifier(cpu_arch: Optional[CPUArchitecture] = None) -> str:
62
62
  elif system == "windows":
63
63
  return "x86_64-pc-windows-msvc"
64
64
  elif system == "linux":
65
+ if _get_architecture() in ['arm64', 'aarch64']:
66
+ return "aarch64-unknown-linux-gnu"
65
67
  return "x86_64-unknown-linux-gnu"
66
68
  else:
67
69
  raise ValueError(f"Unsupported operating system: {system}")
@@ -245,8 +247,11 @@ def dynamically_load_library(
245
247
  # If specific library name is provided, only load that one
246
248
  lib = _load_single_library(lib_name, possible_paths)
247
249
  if not lib:
250
+ platform_id = get_platform_identifier()
251
+ current_arch = _get_architecture()
248
252
  logger.error(f"Could not find {lib_name} in any of the search paths: {[str(p) for p in possible_paths]}")
249
- raise RuntimeError(f"Could not find {lib_name} in any of the search paths")
253
+ logger.error(f"Platform: {platform_id}, Architecture: {current_arch}")
254
+ raise RuntimeError(f"Could not find {lib_name} in any of the search paths (Platform: {platform_id}, Architecture: {current_arch})")
250
255
  return lib
251
256
 
252
257
  # Default path (no library name provided in the environment)
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: c2pa-python
3
+ Version: 0.11.0
4
+ Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
5
+ Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
6
+ Maintainer-email: Gavin Peacock <gpeacock@adobe.com>
7
+ License: MIT OR Apache-2.0
8
+ Project-URL: homepage, https://contentauthenticity.org
9
+ Project-URL: repository, https://github.com/contentauth/c2pa-python
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: wheel>=0.41.2
17
+ Requires-Dist: setuptools>=68.0.0
18
+ Requires-Dist: toml>=0.10.2
19
+ Requires-Dist: pytest>=7.4.0
20
+ Requires-Dist: cryptography>=41.0.0
21
+ Requires-Dist: requests>=2.0.0
22
+ Dynamic: requires-python
23
+
24
+ # C2PA Python library
25
+
26
+ The [c2pa-python](https://github.com/contentauth/c2pa-python) repository provides a Python library that can:
27
+ - Read and validate C2PA manifest data from media files in supported formats.
28
+ - Create and sign manifest data, and attach it to media files in supported formats.
29
+
30
+ Features:
31
+
32
+ - Create and sign C2PA manifests using various signing algorithms.
33
+ - Verify C2PA manifests and extract metadata.
34
+ - Add assertions and ingredients to assets.
35
+ - Examples and unit tests to demonstrate usage.
36
+
37
+ ## Prerequisites
38
+
39
+ This library requires Python version 3.10+.
40
+
41
+ ## Package installation
42
+
43
+ Install the c2pa-python package from PyPI by running:
44
+
45
+ ```bash
46
+ pip install c2pa-python
47
+ ```
48
+
49
+ To use the module in Python code, import the module like this:
50
+
51
+ ```python
52
+ import c2pa
53
+ ```
54
+
55
+ ## Examples
56
+
57
+ See the [`examples` directory](https://github.com/contentauth/c2pa-python/tree/main/examples) for some helpful examples:
58
+ - `examples/sign.py` shows how to sign and verify an asset with a C2PA manifest.
59
+ - `examples/training.py` demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
60
+
61
+ ## Contributing
62
+
63
+ Contributions are welcome! For more information, see [Contributing to the project](https://github.com/contentauth/c2pa-python/blob/main/docs/project-contributions.md).
64
+
65
+ ## License
66
+
67
+ This project is licensed under the Apache License 2.0 and the MIT License. See the [LICENSE-MIT](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-MIT) and [LICENSE-APACHE](https://github.com/contentauth/c2pa-python/blob/main/LICENSE-APACHE) files for details.
@@ -212,6 +212,30 @@ class TestReader(unittest.TestCase):
212
212
  except Exception as e:
213
213
  self.fail(f"Failed to read metadata from {filename}: {str(e)}")
214
214
 
215
+ def test_read_cawg_data_file(self):
216
+ """Test reading C2PA metadata from C_with_CAWG_data.jpg file."""
217
+ file_path = os.path.join(self.data_dir, "files-for-reading-tests", "C_with_CAWG_data.jpg")
218
+
219
+ with open(file_path, "rb") as file:
220
+ reader = Reader("image/jpeg", file)
221
+ json_data = reader.json()
222
+ self.assertIsInstance(json_data, str)
223
+
224
+ # Parse the JSON and verify specific fields
225
+ manifest_data = json.loads(json_data)
226
+
227
+ # Verify basic manifest structure
228
+ self.assertIn("manifests", manifest_data)
229
+ self.assertIn("active_manifest", manifest_data)
230
+
231
+ # Get the active manifest
232
+ active_manifest_id = manifest_data["active_manifest"]
233
+ active_manifest = manifest_data["manifests"][active_manifest_id]
234
+
235
+ # Verify manifest is not null or empty
236
+ assert active_manifest is not None, "Active manifest should not be null"
237
+ assert len(active_manifest) > 0, "Active manifest should not be empty"
238
+
215
239
 
216
240
  class TestBuilder(unittest.TestCase):
217
241
  def setUp(self):
@@ -2096,32 +2096,22 @@ class TestBuilderWithThreads(unittest.TestCase):
2096
2096
  builder.close()
2097
2097
 
2098
2098
  def test_builder_sign_with_multiple_ingredient_random_many_threads(self):
2099
- """Test Builder class operations with 10 threads, each adding 3 random ingredients and signing a random file."""
2099
+ """Test Builder class operations with 12 threads, each adding 3 specific ingredients and signing a file."""
2100
2100
  # Number of threads to use in the test
2101
- # We are pushing it here, as we want to test with thread count one to two orders of magnitude
2102
- # higher than "usual" max numbers of cores on (server) machines may be.
2103
-
2104
2101
  TOTAL_THREADS_USED = 12
2105
2102
 
2106
- # Get list of files from files-for-reading-tests directory
2107
- reading_dir = os.path.join(self.data_dir, "files-for-reading-tests")
2108
-
2109
- # Filter for JPG and PNG files only
2110
- all_files = [
2111
- f for f in os.listdir(reading_dir)
2112
- if os.path.isfile(os.path.join(reading_dir, f))
2113
- and os.path.splitext(f)[1].lower() in {'.jpg', '.jpeg', '.png'}
2103
+ # Define the specific files to use as ingredients
2104
+ # THose files should be valid to use as ingredient
2105
+ ingredient_files = [
2106
+ os.path.join(self.data_dir, "A_thumbnail.jpg"),
2107
+ os.path.join(self.data_dir, "C.jpg"),
2108
+ os.path.join(self.data_dir, "cloud.jpg")
2114
2109
  ]
2115
2110
 
2116
- # Ensure we have enough files
2117
- self.assertGreaterEqual(
2118
- len(all_files),
2119
- 3,
2120
- "Need at least 3 JPG/PNG files for testing")
2121
-
2122
2111
  # Thread synchronization
2123
2112
  thread_results = {}
2124
2113
  completed_threads = 0
2114
+ thread_lock = threading.Lock() # Lock for thread-safe access to shared data
2125
2115
 
2126
2116
  def thread_work(thread_id):
2127
2117
  nonlocal completed_threads
@@ -2129,24 +2119,17 @@ class TestBuilderWithThreads(unittest.TestCase):
2129
2119
  # Create a new builder for this thread
2130
2120
  builder = Builder.from_json(self.manifestDefinition)
2131
2121
 
2132
- # Select 3 random files for ingredients
2133
- # Use thread_id as seed for reproducibility
2134
- random.seed(thread_id)
2135
- ingredient_files = random.sample(all_files, 3)
2136
-
2137
2122
  # Add each ingredient
2138
- for i, file_name in enumerate(ingredient_files, 1):
2139
- file_path = os.path.join(reading_dir, file_name)
2123
+ for i, file_path in enumerate(ingredient_files, 1):
2140
2124
  ingredient_json = json.dumps({
2141
- "title": f"Thread {thread_id} Ingredient {i} - {file_name}"
2125
+ "title": f"Thread {thread_id} Ingredient {i} - {os.path.basename(file_path)}"
2142
2126
  })
2143
2127
 
2144
2128
  with open(file_path, 'rb') as f:
2145
2129
  builder.add_ingredient(ingredient_json, "image/jpeg", f)
2146
2130
 
2147
- # Select a random file for signing
2148
- sign_file = random.choice(all_files)
2149
- sign_file_path = os.path.join(reading_dir, sign_file)
2131
+ # Use A.jpg as the file to sign
2132
+ sign_file_path = os.path.join(self.data_dir, "A.jpg")
2150
2133
 
2151
2134
  # Sign the file
2152
2135
  with open(sign_file_path, "rb") as file:
@@ -2168,11 +2151,13 @@ class TestBuilderWithThreads(unittest.TestCase):
2168
2151
  manifest_data = json.loads(json_data)
2169
2152
 
2170
2153
  # Store results for verification
2171
- thread_results[thread_id] = {
2172
- 'manifest': manifest_data,
2173
- 'ingredient_files': ingredient_files,
2174
- 'sign_file': sign_file
2175
- }
2154
+ with thread_lock:
2155
+ thread_results[thread_id] = {
2156
+ 'manifest': manifest_data,
2157
+ 'ingredient_files': [os.path.basename(f) for f in ingredient_files],
2158
+ 'sign_file': os.path.basename(sign_file_path),
2159
+ 'manifest_hash': hash(json.dumps(manifest_data, sort_keys=True)) # Add hash for comparison
2160
+ }
2176
2161
 
2177
2162
  # Clean up streams
2178
2163
  output.close()
@@ -2181,11 +2166,13 @@ class TestBuilderWithThreads(unittest.TestCase):
2181
2166
  builder.close()
2182
2167
 
2183
2168
  except Exception as e:
2184
- thread_results[thread_id] = {
2185
- 'error': str(e)
2186
- }
2169
+ with thread_lock:
2170
+ thread_results[thread_id] = {
2171
+ 'error': str(e)
2172
+ }
2187
2173
  finally:
2188
- completed_threads += 1
2174
+ with thread_lock:
2175
+ completed_threads += 1
2189
2176
 
2190
2177
  # Create and start threads
2191
2178
  threads = []
@@ -2199,26 +2186,31 @@ class TestBuilderWithThreads(unittest.TestCase):
2199
2186
  thread.join()
2200
2187
 
2201
2188
  # Verify all threads completed
2202
- self.assertEqual(completed_threads, TOTAL_THREADS_USED, f"All {
2203
- TOTAL_THREADS_USED} threads should have completed")
2189
+ self.assertEqual(completed_threads, TOTAL_THREADS_USED, f"All {TOTAL_THREADS_USED} threads should have completed")
2204
2190
  self.assertEqual(
2205
2191
  len(thread_results),
2206
2192
  TOTAL_THREADS_USED,
2207
2193
  f"Should have results from all {TOTAL_THREADS_USED} threads")
2208
2194
 
2195
+ # Collect all manifest hashes for comparison
2196
+ manifest_hashes = set()
2197
+ thread_manifest_data = {}
2198
+
2209
2199
  # Verify results for each thread
2210
2200
  for thread_id in range(1, TOTAL_THREADS_USED + 1):
2211
2201
  result = thread_results[thread_id]
2212
2202
 
2213
2203
  # Check if thread encountered an error
2214
2204
  if 'error' in result:
2215
- self.fail(
2216
- f"Thread {thread_id} failed with error: {
2217
- result['error']}")
2205
+ self.fail(f"Thread {thread_id} failed with error: {result['error']}")
2218
2206
 
2219
2207
  manifest_data = result['manifest']
2220
2208
  ingredient_files = result['ingredient_files']
2221
- sign_file = result['sign_file']
2209
+ manifest_hash = result['manifest_hash']
2210
+
2211
+ # Store manifest data for cross-thread comparison
2212
+ thread_manifest_data[thread_id] = manifest_data
2213
+ manifest_hashes.add(manifest_hash)
2222
2214
 
2223
2215
  # Verify active manifest exists
2224
2216
  self.assertIn("active_manifest", manifest_data)
@@ -2234,16 +2226,44 @@ class TestBuilderWithThreads(unittest.TestCase):
2234
2226
  self.assertIsInstance(active_manifest["ingredients"], list)
2235
2227
  self.assertEqual(len(active_manifest["ingredients"]), 3)
2236
2228
 
2237
- # Verify all ingredients exist with correct thread ID and file
2238
- # names
2239
- ingredient_titles = [ing["title"]
2240
- for ing in active_manifest["ingredients"]]
2229
+ # Verify all ingredients exist with correct thread ID and file names
2230
+ ingredient_titles = [ing["title"] for ing in active_manifest["ingredients"]]
2241
2231
  for i, file_name in enumerate(ingredient_files, 1):
2242
- expected_title = f"Thread {
2243
- thread_id} Ingredient {i} - {file_name}"
2244
- self.assertIn(expected_title, ingredient_titles, f"Thread {
2245
- thread_id} should have ingredient with title {expected_title}")
2232
+ expected_title = f"Thread {thread_id} Ingredient {i} - {file_name}"
2233
+ self.assertIn(expected_title, ingredient_titles, f"Thread {thread_id} should have ingredient with title {expected_title}")
2234
+
2235
+ # Verify no cross-thread contamination in ingredient titles
2236
+ for other_thread_id in range(1, TOTAL_THREADS_USED + 1):
2237
+ if other_thread_id != thread_id:
2238
+ for title in ingredient_titles:
2239
+ # Check for exact thread ID pattern to avoid false positives
2240
+ self.assertNotIn(
2241
+ f"Thread {other_thread_id} Ingredient",
2242
+ title,
2243
+ f"Thread {thread_id}'s manifest contains ingredient data from thread {other_thread_id}")
2244
+
2245
+ # Verify all manifests are unique (no data scrambling between threads)
2246
+ self.assertEqual(
2247
+ len(manifest_hashes),
2248
+ TOTAL_THREADS_USED,
2249
+ "Each thread should have a unique manifest (no data scrambling)")
2246
2250
 
2251
+ # Additional verification: Compare manifest structures between threads
2252
+ for thread_id in range(1, TOTAL_THREADS_USED + 1):
2253
+ current_manifest = thread_manifest_data[thread_id]
2254
+
2255
+ # Verify manifest structure is consistent
2256
+ self.assertIn("active_manifest", current_manifest)
2257
+ self.assertIn("manifests", current_manifest)
2258
+
2259
+ # Verify no cross-thread contamination in manifest data
2260
+ for other_thread_id in range(1, TOTAL_THREADS_USED + 1):
2261
+ if other_thread_id != thread_id:
2262
+ other_manifest = thread_manifest_data[other_thread_id]
2263
+ self.assertNotEqual(
2264
+ current_manifest["active_manifest"],
2265
+ other_manifest["active_manifest"],
2266
+ f"Thread {thread_id} and {other_thread_id} share the same active manifest ID")
2247
2267
 
2248
2268
  if __name__ == '__main__':
2249
2269
  unittest.main()
@@ -1,156 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: c2pa-python
3
- Version: 0.10.0
4
- Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
5
- Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
6
- Maintainer-email: Gavin Peacock <gpeacock@adobe.com>
7
- License: MIT OR Apache-2.0
8
- Project-URL: homepage, https://contentauthenticity.org
9
- Project-URL: repository, https://github.com/contentauth/c2pa-python
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Operating System :: MacOS
12
- Classifier: Operating System :: POSIX :: Linux
13
- Classifier: Operating System :: Microsoft :: Windows
14
- Requires-Python: >=3.10
15
- Description-Content-Type: text/markdown
16
- Requires-Dist: wheel>=0.41.2
17
- Requires-Dist: setuptools>=68.0.0
18
- Requires-Dist: toml>=0.10.2
19
- Requires-Dist: pytest>=7.4.0
20
- Requires-Dist: cryptography>=41.0.0
21
- Requires-Dist: requests>=2.0.0
22
- Dynamic: requires-python
23
-
24
- # Python API for C2PA
25
-
26
- This project provides a Python API for working with [C2PA](https://c2pa.org/) (Coalition for Content Provenance and Authenticity) manifests. It includes functionality for creating, signing, and verifying C2PA manifests, as well as working with assets and assertions.
27
-
28
- ## Features
29
-
30
- - Create and sign C2PA manifests using various signing algorithms.
31
- - Verify C2PA manifests and extract metadata.
32
- - Add assertions and ingredients to assets.
33
- - Examples and unit tests to demonstrate usage.
34
-
35
- ## Project Structure
36
-
37
- ```bash
38
- .
39
- ├── .github/ # GitHub configuration files
40
- ├── artifacts/ # Platform-specific libraries for building (per subfolder)
41
- │ └── your_target_platform/ # Platform-specific artifacts
42
- ├── docs/ # Project documentation
43
- ├── examples/ # Example scripts demonstrating usage
44
- ├── scripts/ # Utility scripts (eg. artifacts download)
45
- ├── src/ # Source code
46
- │ └── c2pa/ # Main package directory
47
- │ └── libs/ # Platform-specific libraries
48
- ├── tests/ # Unit tests and benchmarks
49
- ├── .gitignore # Git ignore rules
50
- ├── Makefile # Build and development commands
51
- ├── pyproject.toml # Python project configuration
52
- ├── requirements.txt # Python dependencies
53
- ├── requirements-dev.txt # Development dependencies
54
- └── setup.py # Package setup script
55
- ```
56
-
57
- ## Package installation
58
-
59
- The c2pa-python package is published to PyPI. You can install it from there by running:
60
-
61
- ```bash
62
- pip install c2pa-python
63
- ```
64
-
65
- To use the module in your Python code, import like this:
66
-
67
- ```python
68
- import c2pa
69
- ```
70
-
71
- ## Examples
72
-
73
- ### Adding a "Do Not Train" Assertion
74
-
75
- The `examples/training.py` script demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
76
-
77
- ### Signing and Verifying Assets
78
-
79
- The `examples/sign.py` script shows how to sign an asset with a C2PA manifest and verify it.
80
-
81
- ## Development Setup
82
-
83
- 1. Create and activate a virtual environment with native dependencies:
84
-
85
- ```bash
86
- # Create virtual environment
87
- python -m venv .venv
88
-
89
- # Activate virtual environment
90
- # On Windows:
91
- .venv\Scripts\activate
92
- # On macOS/Linux:
93
- source .venv/bin/activate
94
-
95
- # load project dependencies
96
- pip install -r requirements.txt
97
- pip install -r requirements-dev.txt
98
-
99
- # download library artifacts for the current version you want, eg v0.55.0
100
- python scripts/download_artifacts.py c2pa-v0.55.0
101
- ```
102
-
103
- 2. Install the package in development mode:
104
-
105
- ```bash
106
- pip install -e .
107
- ```
108
-
109
- This will:
110
-
111
- - Copy the appropriate libraries for your platform from `artifacts/` to `src/c2pa/libs/`
112
- - Install the package in development mode, allowing you to make changes to the Python code without reinstalling
113
-
114
- ## Building Wheels
115
-
116
- To build wheels for all platforms that have libraries in the `artifacts/` directory:
117
-
118
- ```bash
119
- python setup.py bdist_wheel
120
- ```
121
-
122
- You can use `twine` to verify the wheels have correct metadata:
123
-
124
- ```bash
125
- twine check dist/*
126
- ```
127
-
128
- This will create platform-specific wheels in the `dist/` directory.
129
-
130
- ## Running Tests
131
-
132
- Run the tests:
133
-
134
- ```bash
135
- make test
136
- ```
137
-
138
- Alternatively, install pytest (if not already installed):
139
-
140
- ```bash
141
- pip install pytest
142
- ```
143
-
144
- And run:
145
-
146
- ```bash
147
- pytest
148
- ```
149
-
150
- ## Contributing
151
-
152
- Contributions are welcome! Please fork the repository and submit a pull request.
153
-
154
- ## License
155
-
156
- This project is licensed under the Apache License 2.0 or the MIT License. See the LICENSE-MIT and LICENSE-APACHE files for details.
@@ -1,133 +0,0 @@
1
- # Python API for C2PA
2
-
3
- This project provides a Python API for working with [C2PA](https://c2pa.org/) (Coalition for Content Provenance and Authenticity) manifests. It includes functionality for creating, signing, and verifying C2PA manifests, as well as working with assets and assertions.
4
-
5
- ## Features
6
-
7
- - Create and sign C2PA manifests using various signing algorithms.
8
- - Verify C2PA manifests and extract metadata.
9
- - Add assertions and ingredients to assets.
10
- - Examples and unit tests to demonstrate usage.
11
-
12
- ## Project Structure
13
-
14
- ```bash
15
- .
16
- ├── .github/ # GitHub configuration files
17
- ├── artifacts/ # Platform-specific libraries for building (per subfolder)
18
- │ └── your_target_platform/ # Platform-specific artifacts
19
- ├── docs/ # Project documentation
20
- ├── examples/ # Example scripts demonstrating usage
21
- ├── scripts/ # Utility scripts (eg. artifacts download)
22
- ├── src/ # Source code
23
- │ └── c2pa/ # Main package directory
24
- │ └── libs/ # Platform-specific libraries
25
- ├── tests/ # Unit tests and benchmarks
26
- ├── .gitignore # Git ignore rules
27
- ├── Makefile # Build and development commands
28
- ├── pyproject.toml # Python project configuration
29
- ├── requirements.txt # Python dependencies
30
- ├── requirements-dev.txt # Development dependencies
31
- └── setup.py # Package setup script
32
- ```
33
-
34
- ## Package installation
35
-
36
- The c2pa-python package is published to PyPI. You can install it from there by running:
37
-
38
- ```bash
39
- pip install c2pa-python
40
- ```
41
-
42
- To use the module in your Python code, import like this:
43
-
44
- ```python
45
- import c2pa
46
- ```
47
-
48
- ## Examples
49
-
50
- ### Adding a "Do Not Train" Assertion
51
-
52
- The `examples/training.py` script demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
53
-
54
- ### Signing and Verifying Assets
55
-
56
- The `examples/sign.py` script shows how to sign an asset with a C2PA manifest and verify it.
57
-
58
- ## Development Setup
59
-
60
- 1. Create and activate a virtual environment with native dependencies:
61
-
62
- ```bash
63
- # Create virtual environment
64
- python -m venv .venv
65
-
66
- # Activate virtual environment
67
- # On Windows:
68
- .venv\Scripts\activate
69
- # On macOS/Linux:
70
- source .venv/bin/activate
71
-
72
- # load project dependencies
73
- pip install -r requirements.txt
74
- pip install -r requirements-dev.txt
75
-
76
- # download library artifacts for the current version you want, eg v0.55.0
77
- python scripts/download_artifacts.py c2pa-v0.55.0
78
- ```
79
-
80
- 2. Install the package in development mode:
81
-
82
- ```bash
83
- pip install -e .
84
- ```
85
-
86
- This will:
87
-
88
- - Copy the appropriate libraries for your platform from `artifacts/` to `src/c2pa/libs/`
89
- - Install the package in development mode, allowing you to make changes to the Python code without reinstalling
90
-
91
- ## Building Wheels
92
-
93
- To build wheels for all platforms that have libraries in the `artifacts/` directory:
94
-
95
- ```bash
96
- python setup.py bdist_wheel
97
- ```
98
-
99
- You can use `twine` to verify the wheels have correct metadata:
100
-
101
- ```bash
102
- twine check dist/*
103
- ```
104
-
105
- This will create platform-specific wheels in the `dist/` directory.
106
-
107
- ## Running Tests
108
-
109
- Run the tests:
110
-
111
- ```bash
112
- make test
113
- ```
114
-
115
- Alternatively, install pytest (if not already installed):
116
-
117
- ```bash
118
- pip install pytest
119
- ```
120
-
121
- And run:
122
-
123
- ```bash
124
- pytest
125
- ```
126
-
127
- ## Contributing
128
-
129
- Contributions are welcome! Please fork the repository and submit a pull request.
130
-
131
- ## License
132
-
133
- This project is licensed under the Apache License 2.0 or the MIT License. See the LICENSE-MIT and LICENSE-APACHE files for details.
@@ -1,156 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: c2pa-python
3
- Version: 0.10.0
4
- Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
5
- Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
6
- Maintainer-email: Gavin Peacock <gpeacock@adobe.com>
7
- License: MIT OR Apache-2.0
8
- Project-URL: homepage, https://contentauthenticity.org
9
- Project-URL: repository, https://github.com/contentauth/c2pa-python
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Operating System :: MacOS
12
- Classifier: Operating System :: POSIX :: Linux
13
- Classifier: Operating System :: Microsoft :: Windows
14
- Requires-Python: >=3.10
15
- Description-Content-Type: text/markdown
16
- Requires-Dist: wheel>=0.41.2
17
- Requires-Dist: setuptools>=68.0.0
18
- Requires-Dist: toml>=0.10.2
19
- Requires-Dist: pytest>=7.4.0
20
- Requires-Dist: cryptography>=41.0.0
21
- Requires-Dist: requests>=2.0.0
22
- Dynamic: requires-python
23
-
24
- # Python API for C2PA
25
-
26
- This project provides a Python API for working with [C2PA](https://c2pa.org/) (Coalition for Content Provenance and Authenticity) manifests. It includes functionality for creating, signing, and verifying C2PA manifests, as well as working with assets and assertions.
27
-
28
- ## Features
29
-
30
- - Create and sign C2PA manifests using various signing algorithms.
31
- - Verify C2PA manifests and extract metadata.
32
- - Add assertions and ingredients to assets.
33
- - Examples and unit tests to demonstrate usage.
34
-
35
- ## Project Structure
36
-
37
- ```bash
38
- .
39
- ├── .github/ # GitHub configuration files
40
- ├── artifacts/ # Platform-specific libraries for building (per subfolder)
41
- │ └── your_target_platform/ # Platform-specific artifacts
42
- ├── docs/ # Project documentation
43
- ├── examples/ # Example scripts demonstrating usage
44
- ├── scripts/ # Utility scripts (eg. artifacts download)
45
- ├── src/ # Source code
46
- │ └── c2pa/ # Main package directory
47
- │ └── libs/ # Platform-specific libraries
48
- ├── tests/ # Unit tests and benchmarks
49
- ├── .gitignore # Git ignore rules
50
- ├── Makefile # Build and development commands
51
- ├── pyproject.toml # Python project configuration
52
- ├── requirements.txt # Python dependencies
53
- ├── requirements-dev.txt # Development dependencies
54
- └── setup.py # Package setup script
55
- ```
56
-
57
- ## Package installation
58
-
59
- The c2pa-python package is published to PyPI. You can install it from there by running:
60
-
61
- ```bash
62
- pip install c2pa-python
63
- ```
64
-
65
- To use the module in your Python code, import like this:
66
-
67
- ```python
68
- import c2pa
69
- ```
70
-
71
- ## Examples
72
-
73
- ### Adding a "Do Not Train" Assertion
74
-
75
- The `examples/training.py` script demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
76
-
77
- ### Signing and Verifying Assets
78
-
79
- The `examples/sign.py` script shows how to sign an asset with a C2PA manifest and verify it.
80
-
81
- ## Development Setup
82
-
83
- 1. Create and activate a virtual environment with native dependencies:
84
-
85
- ```bash
86
- # Create virtual environment
87
- python -m venv .venv
88
-
89
- # Activate virtual environment
90
- # On Windows:
91
- .venv\Scripts\activate
92
- # On macOS/Linux:
93
- source .venv/bin/activate
94
-
95
- # load project dependencies
96
- pip install -r requirements.txt
97
- pip install -r requirements-dev.txt
98
-
99
- # download library artifacts for the current version you want, eg v0.55.0
100
- python scripts/download_artifacts.py c2pa-v0.55.0
101
- ```
102
-
103
- 2. Install the package in development mode:
104
-
105
- ```bash
106
- pip install -e .
107
- ```
108
-
109
- This will:
110
-
111
- - Copy the appropriate libraries for your platform from `artifacts/` to `src/c2pa/libs/`
112
- - Install the package in development mode, allowing you to make changes to the Python code without reinstalling
113
-
114
- ## Building Wheels
115
-
116
- To build wheels for all platforms that have libraries in the `artifacts/` directory:
117
-
118
- ```bash
119
- python setup.py bdist_wheel
120
- ```
121
-
122
- You can use `twine` to verify the wheels have correct metadata:
123
-
124
- ```bash
125
- twine check dist/*
126
- ```
127
-
128
- This will create platform-specific wheels in the `dist/` directory.
129
-
130
- ## Running Tests
131
-
132
- Run the tests:
133
-
134
- ```bash
135
- make test
136
- ```
137
-
138
- Alternatively, install pytest (if not already installed):
139
-
140
- ```bash
141
- pip install pytest
142
- ```
143
-
144
- And run:
145
-
146
- ```bash
147
- pytest
148
- ```
149
-
150
- ## Contributing
151
-
152
- Contributions are welcome! Please fork the repository and submit a pull request.
153
-
154
- ## License
155
-
156
- This project is licensed under the Apache License 2.0 or the MIT License. See the LICENSE-MIT and LICENSE-APACHE files for details.
File without changes
File without changes
File without changes