Skip to content

Commit 6f51e55

Browse files
committed
Merge branch 'gpeacock/no_rust' into tran/test-coverage
2 parents 92af391 + c19e8e2 commit 6f51e55

File tree

13 files changed

+235
-118
lines changed

13 files changed

+235
-118
lines changed

.github/workflows/build-wheel.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ on:
1616
required: true
1717
type: string
1818
default: 'ubuntu-latest'
19+
c2pa-version:
20+
required: true
21+
type: string
1922
secrets:
2023
github-token:
2124
required: true
@@ -27,6 +30,7 @@ permissions:
2730

2831
env:
2932
GITHUB_TOKEN: ${{ secrets.github-token }}
33+
C2PA_VERSION: ${{ inputs.c2pa-version }}
3034

3135
jobs:
3236
build:
@@ -59,7 +63,7 @@ jobs:
5963
cd /io &&
6064
/opt/python/cp310-cp310/bin/pip install -r requirements.txt -r requirements-dev.txt &&
6165
/opt/python/cp310-cp310/bin/pip install toml &&
62-
C2PA_LIBS_PLATFORM=\"${{ inputs.architecture == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }}\" /opt/python/cp310-cp310/bin/python scripts/download_artifacts.py c2pa-v0.55.0 &&
66+
C2PA_LIBS_PLATFORM=\"${{ inputs.architecture == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }}\" /opt/python/cp310-cp310/bin/python scripts/download_artifacts.py $C2PA_VERSION &&
6367
for PYBIN in /opt/python/cp3{10,11}-*/bin; do
6468
\${PYBIN}/pip install --upgrade pip wheel &&
6569
\${PYBIN}/pip install toml &&
@@ -92,7 +96,15 @@ jobs:
9296
pip install wheel
9397
9498
# Download native artifacts
95-
python scripts/download_artifacts.py c2pa-v0.55.0
99+
Write-Host "Starting artifact download process..."
100+
Write-Host "C2PA_VERSION: $env:C2PA_VERSION"
101+
102+
python scripts/download_artifacts.py "$env:C2PA_VERSION"
103+
104+
Write-Host "Artifacts directory contents:"
105+
Get-ChildItem -Recurse -Path artifacts
106+
Write-Host "src/c2pa/libs directory contents:"
107+
Get-ChildItem -Recurse -Path src/c2pa/libs
96108
97109
# Build wheel
98110
python setup.py bdist_wheel --plat-name win_amd64
@@ -111,7 +123,7 @@ jobs:
111123
pip install wheel
112124
113125
# Download native artifacts
114-
python scripts/download_artifacts.py c2pa-v0.55.0
126+
python scripts/download_artifacts.py $C2PA_VERSION
115127
116128
# Build wheel
117129
python setup.py bdist_wheel --plat-name macosx_11_0_arm64

.github/workflows/build.yml

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,20 @@ permissions:
2525
actions: read
2626

2727
jobs:
28+
read-version:
29+
name: Read C2PA version
30+
runs-on: ubuntu-latest
31+
outputs:
32+
c2pa-native-version: ${{ steps.read-version.outputs.version }}
33+
steps:
34+
- uses: actions/checkout@v4
35+
- name: Read version from file
36+
id: read-version
37+
run: echo "version=$(cat c2pa-native-version.txt | tr -d '\r\n')" >> $GITHUB_OUTPUT
38+
2839
tests-unix:
2940
name: Unit tests for developer setup (Unix)
41+
needs: read-version
3042
if: |
3143
github.event_name != 'pull_request' ||
3244
github.event.pull_request.author_association == 'COLLABORATOR' ||
@@ -69,7 +81,7 @@ jobs:
6981
run: |
7082
# Ensure the token is being used
7183
echo "Using GitHub token for authentication"
72-
python3 scripts/download_artifacts.py c2pa-v0.55.0
84+
python3 scripts/download_artifacts.py ${{ needs.read-version.outputs.c2pa-native-version }}
7385
7486
- name: Install package in development mode
7587
run: |
@@ -85,6 +97,7 @@ jobs:
8597

8698
tests-windows:
8799
name: Unit tests for developer setup (Windows)
100+
needs: read-version
88101
if: |
89102
github.event_name != 'pull_request' ||
90103
github.event.pull_request.author_association == 'COLLABORATOR' ||
@@ -134,7 +147,7 @@ jobs:
134147
run: |
135148
# Ensure the token is being used
136149
echo "Using GitHub token for authentication"
137-
python scripts\download_artifacts.py c2pa-v0.55.0
150+
python scripts\download_artifacts.py ${{ needs.read-version.outputs.c2pa-native-version }}
138151
139152
- name: Install package in development mode
140153
run: |
@@ -151,12 +164,13 @@ jobs:
151164
build-linux-wheel:
152165
name: Build Linux wheel
153166
uses: ./.github/workflows/build-wheel.yml
154-
needs: tests-unix
167+
needs: [tests-unix, read-version]
155168
with:
156169
python-version: "3.10"
157170
architecture: ${{ matrix.target }}
158171
artifact-name: wheels-linux-${{ matrix.target }}
159172
runs-on: ${{ matrix.runs-on }}
173+
c2pa-version: ${{ needs.read-version.outputs.c2pa-native-version }}
160174
secrets:
161175
github-token: ${{ secrets.GITHUB_TOKEN }}
162176
strategy:
@@ -231,12 +245,13 @@ jobs:
231245
build-windows-wheel:
232246
name: Build Windows wheel
233247
uses: ./.github/workflows/build-wheel.yml
234-
needs: tests-windows
248+
needs: [tests-windows, read-version]
235249
with:
236250
python-version: "3.10"
237251
architecture: ${{ matrix.target }}
238252
artifact-name: wheels-windows-${{ matrix.target }}
239253
runs-on: windows-latest
254+
c2pa-version: ${{ needs.read-version.outputs.c2pa-native-version }}
240255
secrets:
241256
github-token: ${{ secrets.GITHUB_TOKEN }}
242257
strategy:
@@ -309,11 +324,12 @@ jobs:
309324
build-macos-wheel:
310325
name: Build macOS wheel
311326
uses: ./.github/workflows/build-wheel.yml
312-
needs: tests-unix
327+
needs: [tests-unix, read-version]
313328
with:
314329
python-version: "3.10"
315330
artifact-name: wheels-macos-${{ matrix.target }}
316331
runs-on: macos-latest
332+
c2pa-version: ${{ needs.read-version.outputs.c2pa-native-version }}
317333
secrets:
318334
github-token: ${{ secrets.GITHUB_TOKEN }}
319335
strategy:
@@ -402,7 +418,7 @@ jobs:
402418
- name: Install dev dependencies for build
403419
run: pip install -r requirements-dev.txt
404420
- name: Build sdist
405-
run: python setup.py sdist
421+
run: python -m build --sdist
406422
- name: Upload sdist
407423
uses: actions/upload-artifact@v4
408424
with:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ __pycache__/
77
scripts/artifacts
88
tests/fixtures/temp_data
99

10+
# For the examples
11+
/output
12+
1013

1114
# C extensions
1215
*.so

Makefile

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# For Python bindings ===========================================================
22

3+
# Version of C2PA to use
4+
C2PA_VERSION := $(shell cat c2pa-native-version.txt)
5+
36
# Start from clean env: Delete `.venv`, then `python3 -m venv .venv`
47
# Pre-requisite: Python virtual environment is active (source .venv/bin/activate)
58
# Run Pytest tests in virtualenv: .venv/bin/pytest tests/test_unit_tests.py -v
@@ -27,7 +30,12 @@ build-python:
2730
rebuild: clean-c2pa-env install-deps download-native-artifacts build-python
2831
@echo "Development rebuild done!"
2932

30-
# Runs the unit tests
33+
run-examples:
34+
python3 ./examples/sign.py
35+
python3 ./examples/training.py
36+
rm -rf output/
37+
38+
# Runs the examples, then the unit tests
3139
test:
3240
python3 ./tests/test_unit_tests.py
3341
python3 ./tests/test_unit_tests_threaded.py
@@ -42,7 +50,7 @@ test-local-wheel-build:
4250
# Clean any existing builds
4351
rm -rf build/ dist/
4452
# Download artifacts and place them where they should go
45-
python scripts/download_artifacts.py c2pa-v0.55.0
53+
python scripts/download_artifacts.py $(C2PA_VERSION)
4654
# Install Python
4755
python3 -m pip install -r requirements.txt
4856
python3 -m pip install -r requirements-dev.txt
@@ -60,12 +68,12 @@ test-local-sdist-build:
6068
# Clean any existing builds
6169
rm -rf build/ dist/
6270
# Download artifacts and place them where they should go
63-
python scripts/download_artifacts.py c2pa-v0.55.0
71+
python scripts/download_artifacts.py $(C2PA_VERSION)
6472
# Install Python
6573
python3 -m pip install -r requirements.txt
6674
python3 -m pip install -r requirements-dev.txt
6775
# Build sdist package
68-
python -m build --sdist
76+
python setup.py sdist
6977
# Install local build in venv
7078
pip install $$(ls dist/*.tar.gz)
7179
# Verify installation in local venv
@@ -90,4 +98,4 @@ format:
9098

9199
# Downloads the required native artifacts for the specified version
92100
download-native-artifacts:
93-
python3 scripts/download_artifacts.py c2pa-v0.55.0
101+
python3 scripts/download_artifacts.py $(C2PA_VERSION)

README.md

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,51 @@ This project provides a Python API for working with [C2PA](https://c2pa.org/) (C
1313

1414
```bash
1515
.
16-
├── .github/ # GitHub configuration files
17-
├── artifacts/ # Platform-specific libraries for building (per subfolder)
18-
│ └── linux_x86_64/ # Linux ARM64 libraries
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
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
3232
```
3333

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+
3458
## Development Setup
3559

36-
1. Create and activate a virtual environment:
60+
1. Create and activate a virtual environment with native dependencies:
3761

3862
```bash
3963
# Create virtual environment
@@ -100,16 +124,6 @@ And run:
100124
pytest
101125
```
102126

103-
## Examples
104-
105-
### Adding a "Do Not Train" Assertion
106-
107-
The `examples/training.py` script demonstrates how to add a "Do Not Train" assertion to an asset and verify it.
108-
109-
### Signing and Verifying Assets
110-
111-
The `examples/test.py` script shows how to sign an asset with a C2PA manifest and verify it.
112-
113127
## Contributing
114128

115129
Contributions are welcome! Please fork the repository and submit a pull request.

c2pa-native-version.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c2pa-v0.55.0

examples/sign.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Copyright 2025 Adobe. All rights reserved.
2+
# This file is licensed to you under the Apache License,
3+
# Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
4+
# or the MIT license (http://opensource.org/licenses/MIT),
5+
# at your option.
6+
# Unless required by applicable law or agreed to in writing,
7+
# this software is distributed on an "AS IS" BASIS, WITHOUT
8+
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
9+
# implied. See the LICENSE-MIT and LICENSE-APACHE files for the
10+
# specific language governing permissions and limitations under
11+
# each license.
12+
13+
# This example shows how to sign an image with a C2PA manifest
14+
# and read the metadata added to the image.
15+
16+
import os
17+
import c2pa
18+
19+
fixtures_dir = os.path.join(os.path.dirname(__file__), "../tests/fixtures/")
20+
output_dir = os.path.join(os.path.dirname(__file__), "../output/")
21+
22+
# ensure the output directory exists
23+
if not os.path.exists(output_dir):
24+
os.makedirs(output_dir)
25+
26+
print("c2pa version:")
27+
version = c2pa.sdk_version()
28+
print(version)
29+
30+
# Read existing C2PA metadata from the file
31+
print("\nReading existing C2PA metadata:")
32+
with open(fixtures_dir + "C.jpg", "rb") as file:
33+
reader = c2pa.Reader("image/jpeg", file)
34+
print(reader.json())
35+
36+
# Create a signer from certificate and key files
37+
certs = open(fixtures_dir + "es256_certs.pem", "rb").read()
38+
key = open(fixtures_dir + "es256_private.key", "rb").read()
39+
40+
signer_info = c2pa.C2paSignerInfo(
41+
alg=b"es256", # Use bytes instead of encoded string
42+
sign_cert=certs,
43+
private_key=key,
44+
ta_url=b"http://timestamp.digicert.com" # Use bytes and add timestamp URL
45+
)
46+
47+
signer = c2pa.Signer.from_info(signer_info)
48+
49+
# Create a manifest definition as a dictionary
50+
manifest_definition = {
51+
"claim_generator": "python_example",
52+
"claim_generator_info": [{
53+
"name": "python_example",
54+
"version": "0.0.1",
55+
}],
56+
"format": "image/jpeg",
57+
"title": "Python Example Image",
58+
"ingredients": [],
59+
"assertions": [
60+
{
61+
'label': 'stds.schema-org.CreativeWork',
62+
'data': {
63+
'@context': 'http://schema.org/',
64+
'@type': 'CreativeWork',
65+
'author': [
66+
{'@type': 'Person', 'name': 'Example User'}
67+
]
68+
},
69+
'kind': 'Json'
70+
}
71+
]
72+
}
73+
74+
builder = c2pa.Builder(manifest_definition)
75+
76+
# Sign the image
77+
print("\nSigning the image...")
78+
with open(fixtures_dir + "C.jpg", "rb") as source:
79+
with open(output_dir + "C_signed.jpg", "wb") as dest:
80+
result = builder.sign(signer, "image/jpeg", source, dest)
81+
82+
# Read the signed image to verify
83+
print("\nReading signed image metadata:")
84+
with open(output_dir + "C_signed.jpg", "rb") as file:
85+
reader = c2pa.Reader("image/jpeg", file)
86+
print(reader.json())
87+
88+
print("\nExample completed successfully!")
89+

0 commit comments

Comments
 (0)