swarmauri_xmp_webp 0.1.1.dev32__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.
@@ -0,0 +1,2 @@
1
+ This project is licensed under the Apache License 2.0.
2
+ See the root LICENSE file of the swarmauri-sdk repository.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: swarmauri_xmp_webp
3
+ Version: 0.1.1.dev32
4
+ Summary: WebP handler scaffold for embedding and extracting XMP packets in Swarmauri runtimes.
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ Keywords: swarmauri,sdk,standards,xmp,webp
8
+ Author: Jacob Stewart
9
+ Author-email: jacob@swarmauri.com
10
+ Requires-Python: >=3.10,<3.13
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Development Status :: 2 - Pre-Alpha
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Requires-Dist: swarmauri_base
22
+ Requires-Dist: swarmauri_core
23
+ Project-URL: Homepage, https://github.com/swarmauri/swarmauri-sdk
24
+ Description-Content-Type: text/markdown
25
+
26
+ ![Swarmauri Logo](https://github.com/swarmauri/swarmauri-sdk/blob/3d4d1cfa949399d7019ae9d8f296afba773dfb7f/assets/swarmauri.brand.theme.svg)
27
+
28
+
29
+ <p align="center">
30
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
31
+ <img src="https://img.shields.io/pypi/dm/swarmauri_xmp_webp" alt="PyPI - Downloads"/></a>
32
+ <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_xmp_webp/">
33
+ <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_xmp_webp.svg"/></a>
34
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
35
+ <img src="https://img.shields.io/pypi/pyversions/swarmauri_xmp_webp" alt="PyPI - Python Version"/></a>
36
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
37
+ <img src="https://img.shields.io/pypi/l/swarmauri_xmp_webp" alt="PyPI - License"/></a>
38
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
39
+ <img src="https://img.shields.io/pypi/v/swarmauri_xmp_webp?label=swarmauri_xmp_webp&color=green" alt="PyPI - swarmauri_xmp_webp"/></a>
40
+ </p>
41
+
42
+ ---
43
+
44
+ # swarmauri_xmp_webp
45
+
46
+ `swarmauri_xmp_webp` declares the `WebPXMP` handler scaffold for RIFF/WEBP containers and prepares the dynamic registry for a full implementation.
47
+
48
+ ## Features
49
+
50
+ - **Forward compatible** – establishes class signatures today so future implementations slot straight into existing workflows.
51
+ - **Registry aligned** – inherits from `EmbedXmpBase`, enabling automatic discovery through Swarmauri's dynamic registry.
52
+ - **Clear contracts** – raises `NotImplementedError` for read/write/remove until the RIFF logic is complete.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ # pip
58
+ pip install swarmauri_xmp_webp
59
+
60
+ # uv
61
+ uv add swarmauri_xmp_webp
62
+ ```
63
+
64
+ ## Usage
65
+
66
+ ```python
67
+ from swarmauri_xmp_webp import WebPXMP
68
+
69
+ handler = WebPXMP()
70
+
71
+ # Raises NotImplementedError until read/write/remove are implemented
72
+ try:
73
+ handler.read_xmp(b"RIFF....WEBP")
74
+ except NotImplementedError:
75
+ print("WebP XMP support is forthcoming.")
76
+ ```
77
+
78
+ ### Why it works
79
+
80
+ - **Forward compatible** – declaring the handler today reserves the RIFF chunk namespace for future work.
81
+ - **Registry alignment** – subclassing `EmbedXmpBase` means discovery logic will work without code changes once implemented.
82
+ - **Clear contracts** – explicit `NotImplementedError` exceptions communicate the remaining work to contributors.
83
+
84
+ ## Project Resources
85
+
86
+ - Source: <https://github.com/swarmauri/swarmauri-sdk>
87
+ - License: Apache 2.0
88
+
@@ -0,0 +1,62 @@
1
+ ![Swarmauri Logo](https://github.com/swarmauri/swarmauri-sdk/blob/3d4d1cfa949399d7019ae9d8f296afba773dfb7f/assets/swarmauri.brand.theme.svg)
2
+
3
+
4
+ <p align="center">
5
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
6
+ <img src="https://img.shields.io/pypi/dm/swarmauri_xmp_webp" alt="PyPI - Downloads"/></a>
7
+ <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_xmp_webp/">
8
+ <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_xmp_webp.svg"/></a>
9
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
10
+ <img src="https://img.shields.io/pypi/pyversions/swarmauri_xmp_webp" alt="PyPI - Python Version"/></a>
11
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
12
+ <img src="https://img.shields.io/pypi/l/swarmauri_xmp_webp" alt="PyPI - License"/></a>
13
+ <a href="https://pypi.org/project/swarmauri_xmp_webp/">
14
+ <img src="https://img.shields.io/pypi/v/swarmauri_xmp_webp?label=swarmauri_xmp_webp&color=green" alt="PyPI - swarmauri_xmp_webp"/></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ # swarmauri_xmp_webp
20
+
21
+ `swarmauri_xmp_webp` declares the `WebPXMP` handler scaffold for RIFF/WEBP containers and prepares the dynamic registry for a full implementation.
22
+
23
+ ## Features
24
+
25
+ - **Forward compatible** – establishes class signatures today so future implementations slot straight into existing workflows.
26
+ - **Registry aligned** – inherits from `EmbedXmpBase`, enabling automatic discovery through Swarmauri's dynamic registry.
27
+ - **Clear contracts** – raises `NotImplementedError` for read/write/remove until the RIFF logic is complete.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ # pip
33
+ pip install swarmauri_xmp_webp
34
+
35
+ # uv
36
+ uv add swarmauri_xmp_webp
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```python
42
+ from swarmauri_xmp_webp import WebPXMP
43
+
44
+ handler = WebPXMP()
45
+
46
+ # Raises NotImplementedError until read/write/remove are implemented
47
+ try:
48
+ handler.read_xmp(b"RIFF....WEBP")
49
+ except NotImplementedError:
50
+ print("WebP XMP support is forthcoming.")
51
+ ```
52
+
53
+ ### Why it works
54
+
55
+ - **Forward compatible** – declaring the handler today reserves the RIFF chunk namespace for future work.
56
+ - **Registry alignment** – subclassing `EmbedXmpBase` means discovery logic will work without code changes once implemented.
57
+ - **Clear contracts** – explicit `NotImplementedError` exceptions communicate the remaining work to contributors.
58
+
59
+ ## Project Resources
60
+
61
+ - Source: <https://github.com/swarmauri/swarmauri-sdk>
62
+ - License: Apache 2.0
@@ -0,0 +1,51 @@
1
+ [project]
2
+ name = "swarmauri_xmp_webp"
3
+ version = "0.1.1.dev32"
4
+ description = "WebP handler scaffold for embedding and extracting XMP packets in Swarmauri runtimes."
5
+ license = "Apache-2.0"
6
+ readme = "README.md"
7
+ requires-python = ">=3.10,<3.13"
8
+ classifiers = [
9
+ "License :: OSI Approved :: Apache Software License",
10
+ "Natural Language :: English",
11
+ "Programming Language :: Python :: 3.10",
12
+ "Programming Language :: Python :: 3.11",
13
+ "Programming Language :: Python :: 3.12",
14
+ "Programming Language :: Python :: 3.13",
15
+ "Development Status :: 2 - Pre-Alpha",
16
+ "Programming Language :: Python",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ ]
20
+ authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
21
+ dependencies = [
22
+ "swarmauri_core",
23
+ "swarmauri_base",
24
+ ]
25
+ keywords = [
26
+ 'swarmauri',
27
+ 'sdk',
28
+ 'standards',
29
+ 'xmp',
30
+ 'webp',
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/swarmauri/swarmauri-sdk"
35
+
36
+ [project.entry-points.'swarmauri.xmp_handlers']
37
+ WebPXMP = "swarmauri_xmp_webp:WebPXMP"
38
+
39
+ [tool.uv.sources]
40
+ swarmauri_core = { workspace = true }
41
+ swarmauri_base = { workspace = true }
42
+
43
+ [build-system]
44
+ requires = ["poetry-core>=1.0.0"]
45
+ build-backend = "poetry.core.masonry.api"
46
+
47
+ [dependency-groups]
48
+ dev = [
49
+ "pytest>=8.0",
50
+ "ruff>=0.9",
51
+ ]
@@ -0,0 +1,92 @@
1
+ """WebP XMP handler implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import ClassVar, Iterator, Tuple
6
+
7
+ from swarmauri_base import register_type
8
+ from swarmauri_base.xmp import EmbedXmpBase
9
+
10
+
11
+ @register_type(resource_type=EmbedXmpBase)
12
+ class WebPXMP(EmbedXmpBase):
13
+ """Embed and extract XMP packets using WebP ``XMP `` chunks."""
14
+
15
+ SIGNATURE: ClassVar[bytes] = b"RIFF"
16
+ FORMAT: ClassVar[bytes] = b"WEBP"
17
+ XMP_CHUNK: ClassVar[bytes] = b"XMP "
18
+
19
+ def _validate(self, data: bytes) -> None:
20
+ if len(data) < 12 or not data.startswith(self.SIGNATURE):
21
+ raise ValueError("Not a WebP payload")
22
+ if data[8:12] != self.FORMAT:
23
+ raise ValueError("RIFF container is not WebP formatted")
24
+
25
+ def _iter_chunks(self, data: bytes) -> Iterator[Tuple[int, bytes, int, int]]:
26
+ self._validate(data)
27
+ pos = 12
28
+ end = len(data)
29
+ while pos + 8 <= end:
30
+ ctype = data[pos : pos + 4]
31
+ size = int.from_bytes(data[pos + 4 : pos + 8], "little")
32
+ data_start = pos + 8
33
+ data_end = data_start + size
34
+ if data_end > end:
35
+ raise ValueError("Truncated WebP chunk")
36
+ yield pos, ctype, data_start, size
37
+ pos = data_end + (size & 1)
38
+ if pos != end:
39
+ # Allow a single padding byte
40
+ if not (pos == end - 1 and data[-1] == 0):
41
+ raise ValueError("Unexpected trailer in WebP payload")
42
+
43
+ def supports(self, header: bytes, path: str) -> bool:
44
+ return path.lower().endswith(".webp") or (
45
+ header.startswith(self.SIGNATURE) and header[8:12] == self.FORMAT
46
+ )
47
+
48
+ def read_xmp(self, data: bytes) -> str | None:
49
+ for _offset, ctype, data_off, data_len in self._iter_chunks(data):
50
+ if ctype != self.XMP_CHUNK:
51
+ continue
52
+ payload = data[data_off : data_off + data_len]
53
+ return payload.decode("utf-8", errors="ignore")
54
+ return None
55
+
56
+ def _chunk_bytes(self, ctype: bytes, payload: bytes) -> bytes:
57
+ chunk = bytearray()
58
+ chunk.extend(ctype)
59
+ chunk.extend(len(payload).to_bytes(4, "little"))
60
+ chunk.extend(payload)
61
+ if len(payload) & 1:
62
+ chunk.append(0)
63
+ return bytes(chunk)
64
+
65
+ def write_xmp(self, data: bytes, xmp_xml: str) -> bytes:
66
+ xmp_bytes = self._ensure_xml(xmp_xml)
67
+ self._validate(data)
68
+ chunks = []
69
+ for _offset, ctype, data_off, data_len in self._iter_chunks(data):
70
+ if ctype == self.XMP_CHUNK:
71
+ continue
72
+ payload = data[data_off : data_off + data_len]
73
+ chunks.append(self._chunk_bytes(ctype, payload))
74
+ chunks.append(self._chunk_bytes(self.XMP_CHUNK, xmp_bytes))
75
+ body = b"".join(chunks)
76
+ size = len(body) + len(self.FORMAT)
77
+ return self.SIGNATURE + size.to_bytes(4, "little") + self.FORMAT + body
78
+
79
+ def remove_xmp(self, data: bytes) -> bytes:
80
+ self._validate(data)
81
+ chunks = []
82
+ for _offset, ctype, data_off, data_len in self._iter_chunks(data):
83
+ if ctype == self.XMP_CHUNK:
84
+ continue
85
+ payload = data[data_off : data_off + data_len]
86
+ chunks.append(self._chunk_bytes(ctype, payload))
87
+ body = b"".join(chunks)
88
+ size = len(body) + len(self.FORMAT)
89
+ return self.SIGNATURE + size.to_bytes(4, "little") + self.FORMAT + body
90
+
91
+
92
+ __all__ = ["WebPXMP"]