EmbeddedSigner 0.1.4.dev17__tar.gz → 0.1.5.dev1__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.
@@ -1,28 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: EmbeddedSigner
3
- Version: 0.1.4.dev17
3
+ Version: 0.1.5.dev1
4
4
  Summary: Embed XMP metadata and sign media assets using Swarmauri plugins.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
7
7
  Keywords: xmp,signing,swarmauri,metadata,security,digital-rights-management,drm,license-rights,embedded-licensing,tamper-proofing,tamper-evidence,content-protection,png,gif,jpeg,svg,webp,tiff,pdf,mp4,digital-asset-security,metadata-signing,workflow-automation,plugin-orchestration,asyncio,plugin,digital-asset-workflows,cms,pkcs7,cades,jws,openpgp,pdf-signatures,xmldsig
8
8
  Author: Jacob Stewart
9
9
  Author-email: jacob@swarmauri.com
10
- Requires-Python: >=3.10,<3.13
10
+ Requires-Python: >=3.10,<3.15
11
11
  Classifier: Development Status :: 1 - Planning
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Natural Language :: English
14
- Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3 :: Only
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
14
  Classifier: Framework :: AsyncIO
21
15
  Classifier: Topic :: Security :: Cryptography
22
16
  Classifier: Operating System :: OS Independent
23
17
  Classifier: Topic :: Multimedia :: Graphics
24
18
  Classifier: Topic :: Multimedia :: Video
25
19
  Classifier: Intended Audience :: Developers
20
+ Classifier: Programming Language :: Python
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3 :: Only
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Programming Language :: Python :: 3.14
26
28
  Provides-Extra: full
27
29
  Provides-Extra: local
28
30
  Provides-Extra: memory
@@ -96,161 +98,21 @@ Project-URL: Issues, https://github.com/swarmauri/swarmauri-sdk/issues
96
98
  Project-URL: Source, https://github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer
97
99
  Description-Content-Type: text/markdown
98
100
 
99
- <p align="center">
100
- <img src="../../../assets/swarmauri.brand.theme.svg" alt="Swarmauri logotype" width="420" />
101
- </p>
102
-
103
- <h1 align="center">EmbeddedSigner</h1>
101
+ ![Swarmauri Logo](https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/swarmauri_sdk_brand.png)
104
102
 
105
103
  <p align="center">
106
- <a href="https://img.shields.io/pypi/dm/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/dm/EmbeddedSigner?style=for-the-badge" alt="PyPI - Downloads" /></a>
107
- <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer/"><img src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer.svg?style=for-the-badge" alt="Repo views" /></a>
108
- <a href="https://img.shields.io/pypi/pyversions/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/pyversions/EmbeddedSigner?style=for-the-badge" alt="Supported Python versions" /></a>
109
- <a href="https://img.shields.io/pypi/l/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/l/EmbeddedSigner?style=for-the-badge" alt="License" /></a>
110
- <a href="https://img.shields.io/pypi/v/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/v/EmbeddedSigner?style=for-the-badge" alt="Latest release" /></a>
104
+ <a href="https://pepy.tech/project/EmbeddedSigner/">
105
+ <img src="https://static.pepy.tech/badge/EmbeddedSigner/month" alt="PyPI - Downloads"/></a>
106
+ <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer/">
107
+ <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer.svg"/></a>
108
+ <a href="https://pypi.org/project/EmbeddedSigner/">
109
+ <img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
110
+ <a href="https://pypi.org/project/EmbeddedSigner/">
111
+ <img src="https://img.shields.io/pypi/l/EmbeddedSigner" alt="PyPI - License"/></a>
112
+ <a href="https://pypi.org/project/EmbeddedSigner/">
113
+ <img src="https://img.shields.io/pypi/v/EmbeddedSigner?label=EmbeddedSigner&color=green" alt="PyPI - EmbeddedSigner"/></a>
111
114
  </p>
112
115
 
113
- EmbeddedSigner composes the dynamic XMP embedding utilities from
114
- [`EmbedXMP`](../EmbedXMP) with the signing facade exposed by
115
- [`MediaSigner`](../media_signer). It embeds metadata into media assets and then
116
- routes signing requests to the appropriate media-aware signer in either
117
- attached or detached mode. The class orchestrates key provider plugins so that
118
- opaque key references can be resolved automatically before signatures are
119
- produced.
120
-
121
- ## Features
122
-
123
- - **One-shot embed & sign** – inject XMP metadata and produce signatures with a
124
- single call.
125
- - **Media-aware detection** – delegates to all registered `EmbedXmpBase`
126
- handlers so PNG, GIF, JPEG, SVG, WEBP, TIFF, PDF, and MP4 assets are
127
- processed consistently.
128
- - **Pluggable signers** – forwards signing requests to every
129
- `SigningBase` registered with `MediaSigner`, including CMS, JWS, OpenPGP, PDF,
130
- and XMLDSig providers.
131
- - **Key provider integration** – loads providers from the
132
- `swarmauri.key_providers` entry point group and resolves opaque key reference
133
- strings (e.g. `local://kid@2`) before invoking a signer.
134
- - **Attached or detached output** – toggle between embedded signatures or
135
- detached artifacts via a simple flag.
136
- - **File and byte workflows** – operate on in-memory payloads or update files
137
- on disk with helpers for embedding, reading, removing, and signing.
138
- - **Command line tooling** – bundle a ready-to-use `embedded-signer` CLI for
139
- ad-hoc embedding, signing, and combined workflows.
140
-
141
- ## Installation
142
-
143
- ### Using `uv`
144
-
145
- ```bash
146
- uv add EmbeddedSigner
147
- ```
148
-
149
- Optional dependencies align with the available key providers, EmbedXMP handlers,
150
- and MediaSigner backends:
151
-
152
- ```bash
153
- uv add "EmbeddedSigner[local]" # enable LocalKeyProvider resolution
154
- uv add "EmbeddedSigner[memory]" # enable InMemoryKeyProvider resolution
155
- uv add "EmbeddedSigner[xmp_png]" # add PNG embedding support
156
- uv add "EmbeddedSigner[xmp_all]" # install every EmbedXMP handler
157
- uv add "EmbeddedSigner[signing_pdf]" # enable PDF signer backend
158
- uv add "EmbeddedSigner[signing_all]" # install every MediaSigner backend
159
- uv add "EmbeddedSigner[full]" # bring in all extras and key providers
160
- ```
161
-
162
- ### Using `pip`
163
-
164
- ```bash
165
- pip install EmbeddedSigner
166
- ```
167
-
168
- Extras mirror the `uv` workflow:
169
-
170
- ```bash
171
- pip install "EmbeddedSigner[local]"
172
- pip install "EmbeddedSigner[memory]"
173
- pip install "EmbeddedSigner[xmp_png]"
174
- pip install "EmbeddedSigner[xmp_all]"
175
- pip install "EmbeddedSigner[signing_pdf]"
176
- pip install "EmbeddedSigner[signing_all]"
177
- pip install "EmbeddedSigner[full]"
178
- ```
179
-
180
- ### Extras overview
181
-
182
- | Extra name | Purpose |
183
- | --- | --- |
184
- | `local` / `memory` | Enable Swarmauri key provider resolution for local filesystem and in-memory secrets. |
185
- | `xmp_gif`, `xmp_jpeg`, `xmp_png`, `xmp_svg`, `xmp_webp`, `xmp_tiff`, `xmp_pdf`, `xmp_mp4` | Pull in the corresponding `swarmauri_xmp_*` handler so EmbedXMP can embed metadata for that media format. |
186
- | `xmp_all` | Install every EmbedXMP media handler dependency at once. |
187
- | `signing_cms`, `signing_jws`, `signing_openpgp`, `signing_pdf`, `signing_xmld` | Add the matching MediaSigner backend plugin for CMS, JWS, OpenPGP, PDF, or XMLDSig signing. |
188
- | `signing_all` | Install all MediaSigner backends together. |
189
- | `full` | Bring in every key provider, EmbedXMP handler, and MediaSigner backend for maximum coverage. |
190
-
191
- ## Usage
192
-
193
- ```python
194
- import asyncio
195
- from pathlib import Path
196
-
197
- from EmbeddedSigner import EmbedSigner
198
-
199
- xmp_xml = """
200
- <x:xmpmeta xmlns:x="adobe:ns:meta/">
201
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
202
- <rdf:Description rdf:about=""/>
203
- </rdf:RDF>
204
- </x:xmpmeta>
205
- """.strip()
206
-
207
- async def embed_and_sign() -> None:
208
- signer = EmbedSigner()
209
- media_bytes = Path("image.png").read_bytes()
210
- embedded, signatures = await signer.embed_and_sign_bytes(
211
- media_bytes,
212
- fmt="JWSSigner",
213
- xmp_xml=xmp_xml,
214
- key={"kind": "raw", "key": b"\x00" * 32},
215
- path="image.png",
216
- attached=True,
217
- signer_opts={"alg": "HS256"},
218
- )
219
- Path("image.signed.png").write_bytes(embedded)
220
- print(signatures[0].mode) # "attached"
221
-
222
- asyncio.run(embed_and_sign())
223
- ```
224
-
225
- ### Key provider integration
226
-
227
- When you install a key provider plugin such as
228
- `swarmauri_keyprovider_local`, EmbeddedSigner can resolve string key references
229
- on the fly:
230
-
231
- ```python
232
- signer = EmbedSigner(key_provider_name="LocalKeyProvider")
233
- embedded, signatures = await signer.embed_and_sign_file(
234
- Path("report.pdf"),
235
- fmt="PDFSigner",
236
- xmp_xml=xmp_xml,
237
- key="LocalKeyProvider://a1b2c3@1",
238
- attached=False,
239
- signer_opts={"alg": "SHA256"},
240
- )
241
- ```
242
-
243
- EmbeddedSigner parses the opaque reference, looks up the provider by name, and
244
- retrieves the specified key version using the provider's asynchronous API.
245
-
246
- ### File helpers
247
-
248
- `EmbedSigner` offers mirrored helpers that operate on file paths when you need
249
- to persist updates directly on disk:
250
-
251
- ```python
252
- signer = EmbedSigner()
253
-
254
116
  # Embed metadata into a file and write it back in place.
255
117
  signer.embed_file("image.png", xmp_xml)
256
118
 
@@ -320,8 +182,8 @@ embedded-signer embed-sign example.png \
320
182
 
321
183
  ## Project Resources
322
184
 
323
- - Source: <https://github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer>
324
- - Documentation: <https://github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer#readme>
185
+ - Source: <https://github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer>
186
+ - Documentation: <https://github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer#readme>
325
187
  - Issues: <https://github.com/swarmauri/swarmauri-sdk/issues>
326
188
  - Releases: <https://github.com/swarmauri/swarmauri-sdk/releases>
327
189
  - Discussions: <https://github.com/orgs/swarmauri/discussions>
@@ -0,0 +1,94 @@
1
+ ![Swarmauri Logo](https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/swarmauri_sdk_brand.png)
2
+
3
+ <p align="center">
4
+ <a href="https://pepy.tech/project/EmbeddedSigner/">
5
+ <img src="https://static.pepy.tech/badge/EmbeddedSigner/month" alt="PyPI - Downloads"/></a>
6
+ <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer/">
7
+ <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer.svg"/></a>
8
+ <a href="https://pypi.org/project/EmbeddedSigner/">
9
+ <img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
10
+ <a href="https://pypi.org/project/EmbeddedSigner/">
11
+ <img src="https://img.shields.io/pypi/l/EmbeddedSigner" alt="PyPI - License"/></a>
12
+ <a href="https://pypi.org/project/EmbeddedSigner/">
13
+ <img src="https://img.shields.io/pypi/v/EmbeddedSigner?label=EmbeddedSigner&color=green" alt="PyPI - EmbeddedSigner"/></a>
14
+ </p>
15
+
16
+ # Embed metadata into a file and write it back in place.
17
+ signer.embed_file("image.png", xmp_xml)
18
+
19
+ # Read embedded metadata without materialising the bytes in memory.
20
+ print(signer.read_xmp_file("image.png"))
21
+
22
+ # Remove metadata and persist the stripped bytes to a new path.
23
+ signer.remove_xmp_file("image.png", write_back=True)
24
+
25
+ # Sign file contents without manual IO boilerplate.
26
+ signatures = asyncio.run(
27
+ signer.sign_file(
28
+ "image.png",
29
+ fmt="JWSSigner",
30
+ key="LocalKeyProvider://img-key",
31
+ attached=True,
32
+ )
33
+ )
34
+ ```
35
+
36
+ ### Command line interface
37
+
38
+ Installing the package exposes an `embedded-signer` executable that wraps the
39
+ most common workflows:
40
+
41
+ ```bash
42
+ # Embed metadata from a file into an image in place.
43
+ embedded-signer embed example.png --xmp-file metadata.xmp
44
+
45
+ # Read metadata to stdout (non-zero exit if none is embedded).
46
+ embedded-signer read example.png
47
+
48
+ # Remove metadata and write the result to a new file.
49
+ embedded-signer remove example.png --output clean.png
50
+
51
+ # Sign using a key reference exposed by a provider plugin.
52
+ embedded-signer sign example.png --format JWSSigner --key-ref local://img-key
53
+
54
+ # Embed and sign in one step, writing signatures to JSON.
55
+ embedded-signer embed-sign example.png \
56
+ --xmp-file metadata.xmp \
57
+ --format JWSSigner \
58
+ --key-ref local://img-key \
59
+ --signature-output signatures.json
60
+ ```
61
+
62
+ ## Development
63
+
64
+ 1. Install development dependencies:
65
+
66
+ ```bash
67
+ uv pip install -e ".[dev]"
68
+ ```
69
+
70
+ 2. Format and lint code with `ruff`:
71
+
72
+ ```bash
73
+ uv run ruff format .
74
+ uv run ruff check . --fix
75
+ ```
76
+
77
+ 3. Run the unit tests in isolation:
78
+
79
+ ```bash
80
+ uv run --package EmbeddedSigner --directory plugins/embedded_signer pytest
81
+ ```
82
+
83
+ ## Project Resources
84
+
85
+ - Source: <https://github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer>
86
+ - Documentation: <https://github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/plugins/embedded_signer#readme>
87
+ - Issues: <https://github.com/swarmauri/swarmauri-sdk/issues>
88
+ - Releases: <https://github.com/swarmauri/swarmauri-sdk/releases>
89
+ - Discussions: <https://github.com/orgs/swarmauri/discussions>
90
+
91
+ ## License
92
+
93
+ EmbeddedSigner is released under the Apache 2.0 License. See the
94
+ [LICENSE](LICENSE) file for details.
@@ -1,26 +1,28 @@
1
1
  [project]
2
2
  name = "EmbeddedSigner"
3
- version = "0.1.4.dev17"
3
+ version = "0.1.5.dev1"
4
4
  description = "Embed XMP metadata and sign media assets using Swarmauri plugins."
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
7
- requires-python = ">=3.10,<3.13"
7
+ requires-python = ">=3.10,<3.15"
8
8
  classifiers = [
9
9
  "Development Status :: 1 - Planning",
10
10
  "License :: OSI Approved :: Apache Software License",
11
11
  "Natural Language :: English",
12
- "Programming Language :: Python",
13
- "Programming Language :: Python :: 3",
14
- "Programming Language :: Python :: 3 :: Only",
15
- "Programming Language :: Python :: 3.10",
16
- "Programming Language :: Python :: 3.11",
17
- "Programming Language :: Python :: 3.12",
18
12
  "Framework :: AsyncIO",
19
13
  "Topic :: Security :: Cryptography",
20
14
  "Operating System :: OS Independent",
21
15
  "Topic :: Multimedia :: Graphics",
22
16
  "Topic :: Multimedia :: Video",
23
17
  "Intended Audience :: Developers",
18
+ "Programming Language :: Python",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
24
26
  ]
25
27
  authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
26
28
  dependencies = [
@@ -1,234 +0,0 @@
1
- <p align="center">
2
- <img src="../../../assets/swarmauri.brand.theme.svg" alt="Swarmauri logotype" width="420" />
3
- </p>
4
-
5
- <h1 align="center">EmbeddedSigner</h1>
6
-
7
- <p align="center">
8
- <a href="https://img.shields.io/pypi/dm/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/dm/EmbeddedSigner?style=for-the-badge" alt="PyPI - Downloads" /></a>
9
- <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer/"><img src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer.svg?style=for-the-badge" alt="Repo views" /></a>
10
- <a href="https://img.shields.io/pypi/pyversions/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/pyversions/EmbeddedSigner?style=for-the-badge" alt="Supported Python versions" /></a>
11
- <a href="https://img.shields.io/pypi/l/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/l/EmbeddedSigner?style=for-the-badge" alt="License" /></a>
12
- <a href="https://img.shields.io/pypi/v/EmbeddedSigner?style=for-the-badge"><img src="https://img.shields.io/pypi/v/EmbeddedSigner?style=for-the-badge" alt="Latest release" /></a>
13
- </p>
14
-
15
- EmbeddedSigner composes the dynamic XMP embedding utilities from
16
- [`EmbedXMP`](../EmbedXMP) with the signing facade exposed by
17
- [`MediaSigner`](../media_signer). It embeds metadata into media assets and then
18
- routes signing requests to the appropriate media-aware signer in either
19
- attached or detached mode. The class orchestrates key provider plugins so that
20
- opaque key references can be resolved automatically before signatures are
21
- produced.
22
-
23
- ## Features
24
-
25
- - **One-shot embed & sign** – inject XMP metadata and produce signatures with a
26
- single call.
27
- - **Media-aware detection** – delegates to all registered `EmbedXmpBase`
28
- handlers so PNG, GIF, JPEG, SVG, WEBP, TIFF, PDF, and MP4 assets are
29
- processed consistently.
30
- - **Pluggable signers** – forwards signing requests to every
31
- `SigningBase` registered with `MediaSigner`, including CMS, JWS, OpenPGP, PDF,
32
- and XMLDSig providers.
33
- - **Key provider integration** – loads providers from the
34
- `swarmauri.key_providers` entry point group and resolves opaque key reference
35
- strings (e.g. `local://kid@2`) before invoking a signer.
36
- - **Attached or detached output** – toggle between embedded signatures or
37
- detached artifacts via a simple flag.
38
- - **File and byte workflows** – operate on in-memory payloads or update files
39
- on disk with helpers for embedding, reading, removing, and signing.
40
- - **Command line tooling** – bundle a ready-to-use `embedded-signer` CLI for
41
- ad-hoc embedding, signing, and combined workflows.
42
-
43
- ## Installation
44
-
45
- ### Using `uv`
46
-
47
- ```bash
48
- uv add EmbeddedSigner
49
- ```
50
-
51
- Optional dependencies align with the available key providers, EmbedXMP handlers,
52
- and MediaSigner backends:
53
-
54
- ```bash
55
- uv add "EmbeddedSigner[local]" # enable LocalKeyProvider resolution
56
- uv add "EmbeddedSigner[memory]" # enable InMemoryKeyProvider resolution
57
- uv add "EmbeddedSigner[xmp_png]" # add PNG embedding support
58
- uv add "EmbeddedSigner[xmp_all]" # install every EmbedXMP handler
59
- uv add "EmbeddedSigner[signing_pdf]" # enable PDF signer backend
60
- uv add "EmbeddedSigner[signing_all]" # install every MediaSigner backend
61
- uv add "EmbeddedSigner[full]" # bring in all extras and key providers
62
- ```
63
-
64
- ### Using `pip`
65
-
66
- ```bash
67
- pip install EmbeddedSigner
68
- ```
69
-
70
- Extras mirror the `uv` workflow:
71
-
72
- ```bash
73
- pip install "EmbeddedSigner[local]"
74
- pip install "EmbeddedSigner[memory]"
75
- pip install "EmbeddedSigner[xmp_png]"
76
- pip install "EmbeddedSigner[xmp_all]"
77
- pip install "EmbeddedSigner[signing_pdf]"
78
- pip install "EmbeddedSigner[signing_all]"
79
- pip install "EmbeddedSigner[full]"
80
- ```
81
-
82
- ### Extras overview
83
-
84
- | Extra name | Purpose |
85
- | --- | --- |
86
- | `local` / `memory` | Enable Swarmauri key provider resolution for local filesystem and in-memory secrets. |
87
- | `xmp_gif`, `xmp_jpeg`, `xmp_png`, `xmp_svg`, `xmp_webp`, `xmp_tiff`, `xmp_pdf`, `xmp_mp4` | Pull in the corresponding `swarmauri_xmp_*` handler so EmbedXMP can embed metadata for that media format. |
88
- | `xmp_all` | Install every EmbedXMP media handler dependency at once. |
89
- | `signing_cms`, `signing_jws`, `signing_openpgp`, `signing_pdf`, `signing_xmld` | Add the matching MediaSigner backend plugin for CMS, JWS, OpenPGP, PDF, or XMLDSig signing. |
90
- | `signing_all` | Install all MediaSigner backends together. |
91
- | `full` | Bring in every key provider, EmbedXMP handler, and MediaSigner backend for maximum coverage. |
92
-
93
- ## Usage
94
-
95
- ```python
96
- import asyncio
97
- from pathlib import Path
98
-
99
- from EmbeddedSigner import EmbedSigner
100
-
101
- xmp_xml = """
102
- <x:xmpmeta xmlns:x="adobe:ns:meta/">
103
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
104
- <rdf:Description rdf:about=""/>
105
- </rdf:RDF>
106
- </x:xmpmeta>
107
- """.strip()
108
-
109
- async def embed_and_sign() -> None:
110
- signer = EmbedSigner()
111
- media_bytes = Path("image.png").read_bytes()
112
- embedded, signatures = await signer.embed_and_sign_bytes(
113
- media_bytes,
114
- fmt="JWSSigner",
115
- xmp_xml=xmp_xml,
116
- key={"kind": "raw", "key": b"\x00" * 32},
117
- path="image.png",
118
- attached=True,
119
- signer_opts={"alg": "HS256"},
120
- )
121
- Path("image.signed.png").write_bytes(embedded)
122
- print(signatures[0].mode) # "attached"
123
-
124
- asyncio.run(embed_and_sign())
125
- ```
126
-
127
- ### Key provider integration
128
-
129
- When you install a key provider plugin such as
130
- `swarmauri_keyprovider_local`, EmbeddedSigner can resolve string key references
131
- on the fly:
132
-
133
- ```python
134
- signer = EmbedSigner(key_provider_name="LocalKeyProvider")
135
- embedded, signatures = await signer.embed_and_sign_file(
136
- Path("report.pdf"),
137
- fmt="PDFSigner",
138
- xmp_xml=xmp_xml,
139
- key="LocalKeyProvider://a1b2c3@1",
140
- attached=False,
141
- signer_opts={"alg": "SHA256"},
142
- )
143
- ```
144
-
145
- EmbeddedSigner parses the opaque reference, looks up the provider by name, and
146
- retrieves the specified key version using the provider's asynchronous API.
147
-
148
- ### File helpers
149
-
150
- `EmbedSigner` offers mirrored helpers that operate on file paths when you need
151
- to persist updates directly on disk:
152
-
153
- ```python
154
- signer = EmbedSigner()
155
-
156
- # Embed metadata into a file and write it back in place.
157
- signer.embed_file("image.png", xmp_xml)
158
-
159
- # Read embedded metadata without materialising the bytes in memory.
160
- print(signer.read_xmp_file("image.png"))
161
-
162
- # Remove metadata and persist the stripped bytes to a new path.
163
- signer.remove_xmp_file("image.png", write_back=True)
164
-
165
- # Sign file contents without manual IO boilerplate.
166
- signatures = asyncio.run(
167
- signer.sign_file(
168
- "image.png",
169
- fmt="JWSSigner",
170
- key="LocalKeyProvider://img-key",
171
- attached=True,
172
- )
173
- )
174
- ```
175
-
176
- ### Command line interface
177
-
178
- Installing the package exposes an `embedded-signer` executable that wraps the
179
- most common workflows:
180
-
181
- ```bash
182
- # Embed metadata from a file into an image in place.
183
- embedded-signer embed example.png --xmp-file metadata.xmp
184
-
185
- # Read metadata to stdout (non-zero exit if none is embedded).
186
- embedded-signer read example.png
187
-
188
- # Remove metadata and write the result to a new file.
189
- embedded-signer remove example.png --output clean.png
190
-
191
- # Sign using a key reference exposed by a provider plugin.
192
- embedded-signer sign example.png --format JWSSigner --key-ref local://img-key
193
-
194
- # Embed and sign in one step, writing signatures to JSON.
195
- embedded-signer embed-sign example.png \
196
- --xmp-file metadata.xmp \
197
- --format JWSSigner \
198
- --key-ref local://img-key \
199
- --signature-output signatures.json
200
- ```
201
-
202
- ## Development
203
-
204
- 1. Install development dependencies:
205
-
206
- ```bash
207
- uv pip install -e ".[dev]"
208
- ```
209
-
210
- 2. Format and lint code with `ruff`:
211
-
212
- ```bash
213
- uv run ruff format .
214
- uv run ruff check . --fix
215
- ```
216
-
217
- 3. Run the unit tests in isolation:
218
-
219
- ```bash
220
- uv run --package EmbeddedSigner --directory plugins/embedded_signer pytest
221
- ```
222
-
223
- ## Project Resources
224
-
225
- - Source: <https://github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer>
226
- - Documentation: <https://github.com/swarmauri/swarmauri-sdk/tree/main/pkgs/plugins/embedded_signer#readme>
227
- - Issues: <https://github.com/swarmauri/swarmauri-sdk/issues>
228
- - Releases: <https://github.com/swarmauri/swarmauri-sdk/releases>
229
- - Discussions: <https://github.com/orgs/swarmauri/discussions>
230
-
231
- ## License
232
-
233
- EmbeddedSigner is released under the Apache 2.0 License. See the
234
- [LICENSE](LICENSE) file for details.