Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion c2pa-native-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c2pa-v0.91.10
c2pa-v0.92.0-rc.1
1 change: 0 additions & 1 deletion docs/class-diagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ classDiagram

class Builder {
+from_json(manifest_json, context) Builder$
+from_archive(stream) Builder$
+get_supported_mime_types() list~str~$
+set_no_embed()
+set_remote_url(url)
Expand Down
5 changes: 2 additions & 3 deletions docs/context-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,9 @@ with open("source.jpg", "rb") as src, open("output.jpg", "w+b") as dst:

Archives (`.c2pa` files) store only the manifest definition. They do **not** store settings or context:

- **`Builder.from_archive(stream)`** creates a context-free builder. All settings revert to SDK defaults regardless of what context the original builder had.
- **`Builder({}, ctx).with_archive(stream)`** creates a builder with a context first, then loads the archived manifest definition into it. The context settings are preserved.

Use `with_archive()`. `from_archive()` is deprecated and will be removed when c2pa-python moves to c2pa-rs 0.92.0.
Use `with_archive()`. `Builder.from_archive()` was removed in c2pa-rs 0.92.0.

```py
ctx = Context.from_dict({
Expand Down Expand Up @@ -754,7 +753,7 @@ assert isinstance(ctx, ContextProvider) # True

## Migrating from load_settings

The `load_settings()` function is deprecated and will be removed when c2pa-python moves to c2pa-rs 0.92.0. Replace it with `Settings` and `Context` APIs:
The `load_settings()` function was removed in c2pa-rs 0.92.0. Replace it with `Settings` and `Context` APIs:

| Aspect | `load_settings` (legacy) | `Context` |
|--------|--------------------------|-----------|
Expand Down
2 changes: 1 addition & 1 deletion docs/intents.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ You can set the intent on a `Builder` instance by:
- [Using Context](#using-context)
- [Using `set_intent` on the `Builder`](#using-set_intent-on-the-builder)

The deprecated `load_settings()` function no longer sets the intent for a `Builder`. To migrate existing code, see [Context and settings - Migrating from load_settings](context-settings.md#migrating-from-load_settings).
The removed `load_settings()` function no longer set the intent for a `Builder`. To migrate existing code, see [Context and settings - Migrating from load_settings](context-settings.md#migrating-from-load_settings).

### Using Context

Expand Down
2 changes: 1 addition & 1 deletion docs/project-contributions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ make download-native-artifacts
```

Without `make`, pass the tag from `c2pa-native-version.txt` directly to
`python scripts/download_artifacts.py` (currently `c2pa-v0.91.7`).
`python scripts/download_artifacts.py` (currently `c2pa-v0.92.0-rc.1`).

Install the package in development mode:

Expand Down
4 changes: 2 additions & 2 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

### TLS trust stores

Release builds select c2pa-rs `c2pa-v0.91.7` through
Release builds select c2pa-rs `c2pa-v0.92.0-rc.1` through
`c2pa-native-version.txt`. Rebuild or upgrade installed wheels to update the
bundled native library; updating Python dependencies alone does not update it.
Local source builds and externally supplied libraries must also use patched
Expand Down Expand Up @@ -39,7 +39,7 @@ Migration:
- Instead of `Builder.add_ingredient_from_file_path(json, format, filepath)`, open the
file and call `Builder.add_ingredient_from_stream(json, format, stream)`.

The `Builder.sign_file` method and `load_settings` are unaffected and remain available.
The `Builder.sign_file` method is unaffected and remains available. (`load_settings`, `Builder.from_archive` and `format_embeddable` were later removed with c2pa-rs 0.92.0.)

## Version 0.6.0

Expand Down
2 changes: 1 addition & 1 deletion docs/selective-manifests.md
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ with Builder({
```

> [!NOTE]
> When restoring from an archive, `with_archive()` preserves context settings. The deprecated `from_archive()` creates a builder with SDK default settings. See [Working with archives](working-stores.md#working-with-archives) for the full comparison.
> When restoring from an archive, `with_archive()` preserves context settings (`from_archive()` was removed in c2pa-rs 0.92.0). See [Working with archives](working-stores.md#working-with-archives) for the full comparison.

**Step 2:** Read the archive and extract ingredients:

Expand Down
2 changes: 1 addition & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ The built-in `Context` class is the standard `ContextProvider` implementation. C

### Migrating from load_settings

The `load_settings()` function is deprecated. Replace it with `Settings` and `Context`. See [Migrating from load_settings](context-settings.md#migrating-from-load_settings) for details.
The `load_settings()` function was removed in c2pa-rs 0.92.0. Replace it with `Settings` and `Context`. See [Migrating from load_settings](context-settings.md#migrating-from-load_settings) for details.

## File-based operation

Expand Down
6 changes: 2 additions & 4 deletions src/c2pa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
Context,
ContextBuilder,
ContextProvider,
sdk_version,
load_settings
sdk_version
) # NOQA

# Re-export C2paError and its subclasses
Expand All @@ -50,6 +49,5 @@
'Context',
'ContextBuilder',
'ContextProvider',
'sdk_version',
'load_settings'
'sdk_version'
]
191 changes: 0 additions & 191 deletions src/c2pa/c2pa.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@
'c2pa_version',
# Error retriever and parser
'c2pa_error',
# Legacy APIs, deprecated.
'c2pa_load_settings',
'c2pa_builder_from_archive',
'c2pa_format_embeddable',
# Stream
'c2pa_create_stream',
'c2pa_release_stream',
Expand Down Expand Up @@ -1305,9 +1301,6 @@ def _setup_function(func, argtypes, restype=None):
# Set up function prototypes not attached to an API object
_setup_function(_lib.c2pa_version, [], ctypes.c_void_p)
_setup_function(_lib.c2pa_error, [], ctypes.c_void_p)
_setup_function(
_lib.c2pa_load_settings, [
ctypes.c_char_p, ctypes.c_char_p], ctypes.c_int)
_setup_function(
_lib.c2pa_free_string_array,
[ctypes.POINTER(ctypes.c_char_p), ctypes.c_size_t],
Expand Down Expand Up @@ -1343,9 +1336,6 @@ def _setup_function(func, argtypes, restype=None):
)

# Set up Builder function prototypes
_setup_function(_lib.c2pa_builder_from_archive,
[ctypes.POINTER(C2paStream)],
ctypes.POINTER(C2paBuilder))
_setup_function(
_lib.c2pa_builder_with_archive,
[ctypes.POINTER(C2paBuilder), ctypes.POINTER(C2paStream)],
Expand Down Expand Up @@ -1390,12 +1380,6 @@ def _setup_function(func, argtypes, restype=None):
ctypes.POINTER(C2paSigner),
ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte))],
ctypes.c_int64)
_setup_function(
_lib.c2pa_format_embeddable, [
ctypes.c_char_p, ctypes.POINTER(
ctypes.c_ubyte), ctypes.c_size_t, ctypes.POINTER(
ctypes.POINTER(
ctypes.c_ubyte))], ctypes.c_int64)
_setup_function(_lib.c2pa_signer_create,
[ctypes.c_void_p,
SignerCallback,
Expand Down Expand Up @@ -1956,72 +1940,6 @@ def _warn_deprecated_api(message: str, stacklevel: int) -> None:
)


@overload
def load_settings(settings: str, format: str = "json") -> None:
...


@overload
def load_settings(settings: dict) -> None:
...


def load_settings(settings: Union[str, dict], format: str = "json") -> None:
"""Load C2PA settings into thread-local storage from a string or dict.

.. deprecated::
Use :class:`Settings` and :class:`Context` for
per-instance configuration instead. Settings and
Context will propagate configurations through object instances,
no thread-local configurations. Avoid mixing Context APIs
and legacy load_settings usage.
c2pa-rs 0.92.0 removes c2pa_load_settings, so this function
will be removed when c2pa-python moves to that release.
Reader and Builder no longer read these settings: without a
Context they use one with default settings. Only the deprecated
Builder.from_archive() still reads them.

Args:
settings: The settings string or dict to load
format: The format of the settings string (default: "json").
Ignored when settings is a dict.

Raises:
C2paError: If there was an error loading the settings
"""
_warn_deprecated_api(
"load_settings() is deprecated. Reader and Builder no longer read"
" these settings. Use Settings and Context for per-instance"
" configuration.",
stacklevel=2,
)

# Convert to JSON string as necessary
try:
if isinstance(settings, dict):
settings_str = json.dumps(settings)
format = "json"
else:
settings_str = settings
except (TypeError, ValueError) as e:
raise C2paError(f"Failed to serialize settings to JSON: {e}")

try:
_check_cstr_arg("settings", settings_str)
_check_cstr_arg("format", format)
settings_bytes = settings_str.encode('utf-8')
format_bytes = format.encode('utf-8')
except (AttributeError, UnicodeEncodeError) as e:
raise C2paError(f"Failed to encode settings to UTF-8: {e}")

with _native_section():
result = _lib.c2pa_load_settings(settings_bytes, format_bytes)
_check_ffi_operation_result(
result,
"Error loading settings",
check=lambda r: r != 0)


@contextlib.contextmanager
def _context_guard(context):
"""Hold a caller-supplied context valid across a native call.
Expand Down Expand Up @@ -3960,57 +3878,6 @@ def from_json(
"""
return cls(manifest_json, context=context)

@classmethod
def from_archive(
cls,
stream: Any,
) -> 'Builder':
"""Create a new Builder from an archive stream.

This creates builder without a context. To use a context,
create a Builder with a context first, then call with_archive() on it.

.. deprecated::
Use ``Builder({}, context=Context()).with_archive(stream)``.
c2pa-rs 0.92.0 removes c2pa_builder_from_archive, so this method
will be removed when c2pa-python moves to that release.

Args:
stream: The stream containing the archive
(any Python stream-like object)

Returns:
A new Builder instance (without any context)

Raises:
C2paError: If there was an error creating the builder
from archive
"""
_warn_deprecated_api(
"Builder.from_archive() is deprecated. Use"
" Builder({}, context=Context()).with_archive(stream).",
stacklevel=2,
)

stream_obj = Stream(stream)

try:
with _native_section():
handle = _lib.c2pa_builder_from_archive(stream_obj._stream)

_check_ffi_operation_result(
handle, "Failed to create builder from archive")

try:
# A builder from an archive here carries no context.
return cls._wrap_native_handle(handle)
except Exception:
# No instance took ownership, so the handle is still ours.
ManagedResource._free_native_ptr(handle)
raise
finally:
stream_obj.close()

@overload
def __init__(
self,
Expand Down Expand Up @@ -4661,62 +4528,6 @@ def sign_file(
raise C2paError(f"Error signing file: {str(e)}") from e


def format_embeddable(format: str, manifest_bytes: bytes) -> tuple[int, bytes]:
"""Convert a binary C2PA manifest into an embeddable version.

.. deprecated::
c2pa-rs 0.92.0 removes c2pa_format_embeddable, so this function
will be removed when c2pa-python moves to that release.

Args:
format: The MIME type or extension of the target format
manifest_bytes: The raw manifest bytes

Returns:
A tuple of (size of result bytes, embeddable manifest bytes)

Raises:
C2paError: If there was an error converting the manifest
"""
_warn_deprecated_api(
"format_embeddable() is deprecated.", stacklevel=2)

_check_cstr_arg("format", format)
format_str = format.encode('utf-8')
manifest_array = (ctypes.c_ubyte * len(manifest_bytes)).from_buffer_copy(
manifest_bytes
)
result_bytes_ptr = ctypes.POINTER(ctypes.c_ubyte)()

with _native_section():
result = _lib.c2pa_format_embeddable(
format_str,
manifest_array,
len(manifest_bytes),
ctypes.byref(result_bytes_ptr)
)

_check_ffi_operation_result(
result,
"Failed to format embeddable manifest",
check=lambda r: r < 0)

size = result
if not result_bytes_ptr:
raise C2paError(
"Failed to format embeddable manifest: no data returned")
try:
result_bytes = ctypes.string_at(result_bytes_ptr, size)
except Exception as e:
raise C2paError(
f"Failed to convert embeddable manifest bytes: {e}"
) from e
finally:
_lib.c2pa_free(result_bytes_ptr)

return size, result_bytes


def create_signer(
callback: Callable[[bytes], bytes],
alg: C2paSigningAlg,
Expand Down Expand Up @@ -4864,8 +4675,6 @@ def ed25519_sign(data: bytes, private_key: str) -> bytes:
'Reader',
'Builder',
'Signer',
'load_settings',
'format_embeddable',
'version',
'sdk_version'
]
14 changes: 2 additions & 12 deletions tests/perf/baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"_meta": {
"memray_version": "1.19.3",
"python_version": "3.12.13",
"c2pa_native_version": "c2pa-v0.90.16",
"c2pa_native_version": "c2pa-v0.92.0-rc.1",
"iterations": 200,
"perf_env": "python-3.12-slim",
"arch": "aarch64"
Expand Down Expand Up @@ -142,11 +142,6 @@
"leaked_bytes": 3545507,
"total_allocations": 3432412
},
"builder_from_archive_roundtrip": {
"peak_bytes": 14353258,
"leaked_bytes": 3542427,
"total_allocations": 3024501
},
"builder_with_archive_swap": {
"peak_bytes": 3753525,
"leaked_bytes": 3421374,
Expand Down Expand Up @@ -282,11 +277,6 @@
"leaked_bytes": 3525035,
"total_allocations": 37359891
},
"fork_contended_mutex_wrap": {
"peak_bytes": 7140341,
"leaked_bytes": 3522965,
"total_allocations": 34204380
},
"fork_consumed_signer": {
"peak_bytes": 3421645,
"leaked_bytes": 3359803,
Expand All @@ -302,4 +292,4 @@
"leaked_bytes": 3412690,
"total_allocations": 2448668
}
}
}
Loading
Loading