EmbeddedSigner 0.1.5.dev1__py3-none-any.whl → 0.11.0.dev1__py3-none-any.whl

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.
@@ -53,7 +53,9 @@ class EmbedSigner:
53
53
  self._default_provider = key_provider
54
54
  self._default_provider_name = key_provider.__class__.__name__
55
55
  elif key_provider_name is not None:
56
- self._default_provider = self._instantiate_provider(key_provider_name)
56
+ self._default_provider = self._instantiate_provider(
57
+ key_provider_name
58
+ )
57
59
  self._default_provider_name = key_provider_name
58
60
 
59
61
  provider_for_signer = self._default_provider
@@ -78,7 +80,9 @@ class EmbedSigner:
78
80
  Exception
79
81
  ): # pragma: no cover - defensive against broken entry points
80
82
  continue
81
- if not inspect.isclass(provider_cls) and not callable(provider_cls):
83
+ if not inspect.isclass(provider_cls) and not callable(
84
+ provider_cls
85
+ ):
82
86
  continue
83
87
  factories[entry.name] = provider_cls
84
88
  return factories
@@ -104,9 +108,16 @@ class EmbedSigner:
104
108
  if self._default_provider_name is not None:
105
109
  return self._instantiate_provider(self._default_provider_name)
106
110
  raise ValueError(
107
- "No default key provider configured; include a provider name in the key reference."
111
+ (
112
+ "No default key provider configured; include a provider "
113
+ "name "
114
+ "in the key reference."
115
+ )
108
116
  )
109
- if name == self._default_provider_name and self._default_provider is not None:
117
+ if (
118
+ name == self._default_provider_name
119
+ and self._default_provider is not None
120
+ ):
110
121
  return self._default_provider
111
122
  return self._instantiate_provider(name)
112
123
 
@@ -142,7 +153,9 @@ class EmbedSigner:
142
153
  ) from exc
143
154
  if not kid:
144
155
  raise ValueError("Key reference must include a key identifier")
145
- return _ParsedKeyRef(provider=provider_name, kid=kid, version=version_number)
156
+ return _ParsedKeyRef(
157
+ provider=provider_name, kid=kid, version=version_number
158
+ )
146
159
 
147
160
  async def _resolve_key(
148
161
  self, key: KeyRef | Mapping[str, Any] | str
@@ -155,10 +168,14 @@ class EmbedSigner:
155
168
  ref = self._parse_key_reference(key)
156
169
  provider = self._get_provider(ref.provider)
157
170
  try:
158
- resolved = await provider.get_key_by_ref(ref.kid, include_secret=True)
171
+ resolved = await provider.get_key_by_ref(
172
+ ref.kid, include_secret=True
173
+ )
159
174
  except NotImplementedError:
160
175
  resolved = None
161
- except AttributeError: # pragma: no cover - provider without method
176
+ except (
177
+ AttributeError
178
+ ): # pragma: no cover - provider without method
162
179
  resolved = None
163
180
  if resolved is None:
164
181
  resolved = await provider.get_key(
@@ -166,7 +183,10 @@ class EmbedSigner:
166
183
  )
167
184
  return resolved
168
185
  raise TypeError(
169
- "key must be a Mapping, KeyRef, or string reference understood by EmbedSigner"
186
+ (
187
+ "key must be a Mapping, KeyRef, or string reference "
188
+ "understood by EmbedSigner"
189
+ )
170
190
  )
171
191
 
172
192
  # ------------------------------------------------------------------
@@ -178,13 +198,17 @@ class EmbedSigner:
178
198
  ref = str(path) if path is not None else None
179
199
  return self._embedder.embed(data, xmp_xml, ref)
180
200
 
181
- def read_xmp(self, data: bytes, *, path: str | Path | None = None) -> str | None:
201
+ def read_xmp(
202
+ self, data: bytes, *, path: str | Path | None = None
203
+ ) -> str | None:
182
204
  """Read XMP metadata from *data* using the configured handlers."""
183
205
 
184
206
  ref = str(path) if path is not None else None
185
207
  return self._embedder.read(data, ref)
186
208
 
187
- def remove_xmp(self, data: bytes, *, path: str | Path | None = None) -> bytes:
209
+ def remove_xmp(
210
+ self, data: bytes, *, path: str | Path | None = None
211
+ ) -> bytes:
188
212
  """Remove XMP metadata from *data* using the configured handlers."""
189
213
 
190
214
  ref = str(path) if path is not None else None
@@ -201,7 +225,9 @@ class EmbedSigner:
201
225
  """Embed XMP metadata directly into a file on disk."""
202
226
 
203
227
  file_path = Path(path)
204
- updated = self.embed_bytes(file_path.read_bytes(), xmp_xml, path=file_path)
228
+ updated = self.embed_bytes(
229
+ file_path.read_bytes(), xmp_xml, path=file_path
230
+ )
205
231
  target = Path(output) if output is not None else file_path
206
232
  if write_back:
207
233
  target.write_bytes(updated)
@@ -220,7 +246,9 @@ class EmbedSigner:
220
246
  write_back: bool = False,
221
247
  output: str | Path | None = None,
222
248
  ) -> bytes:
223
- """Remove XMP metadata from a file, optionally persisting the result."""
249
+ """
250
+ Remove XMP metadata from a file, optionally persisting the result.
251
+ """
224
252
 
225
253
  file_path = Path(path)
226
254
  updated = self.remove_xmp(file_path.read_bytes(), path=file_path)
@@ -240,7 +268,9 @@ class EmbedSigner:
240
268
  alg: Optional[str] = None,
241
269
  signer_opts: Optional[Mapping[str, Any]] = None,
242
270
  ) -> Sequence[Signature]:
243
- """Produce signatures for *payload* using the requested signer format."""
271
+ """
272
+ Produce signatures for *payload* using the requested signer format.
273
+ """
244
274
 
245
275
  resolved_key = await self._resolve_key(key)
246
276
  opts: dict[str, Any] = dict(signer_opts or {})
@@ -286,7 +316,9 @@ class EmbedSigner:
286
316
  signer_opts: Optional[Mapping[str, Any]] = None,
287
317
  write_back: bool = False,
288
318
  ) -> tuple[bytes, Sequence[Signature]]:
289
- """Embed metadata into *path* and optionally persist the signed bytes."""
319
+ """
320
+ Embed metadata into *path* and optionally persist the signed bytes.
321
+ """
290
322
 
291
323
  file_path = Path(path)
292
324
  embedded, signatures = await self.embed_and_sign_bytes(
@@ -336,6 +368,7 @@ class EmbedSigner:
336
368
  )
337
369
 
338
370
  def supported_signers(self) -> Sequence[str]:
339
- """Expose signer formats advertised by the underlying :class:`MediaSigner`."""
371
+ """Expose signer formats advertised by the underlying
372
+ :class:`MediaSigner`."""
340
373
 
341
374
  return tuple(self._signer.supported_formats())
EmbeddedSigner/cli.py CHANGED
@@ -30,14 +30,18 @@ def _resolve_key_argument(args: argparse.Namespace) -> Any:
30
30
  if value is not None
31
31
  ]
32
32
  if len(provided) != 1:
33
- raise SystemExit("Provide exactly one of --key-ref, --key-json, or --key-file.")
33
+ raise SystemExit(
34
+ "Provide exactly one of --key-ref, --key-json, or --key-file."
35
+ )
34
36
  if args.key_ref:
35
37
  return args.key_ref
36
38
  if args.key_json:
37
39
  try:
38
40
  return json.loads(args.key_json)
39
41
  except json.JSONDecodeError as exc: # pragma: no cover - defensive
40
- raise SystemExit(f"Invalid JSON passed to --key-json: {exc}") from exc
42
+ raise SystemExit(
43
+ f"Invalid JSON passed to --key-json: {exc}"
44
+ ) from exc
41
45
  if args.key_file:
42
46
  return json.loads(Path(args.key_file).read_text(encoding="utf-8"))
43
47
  raise SystemExit("A key reference or JSON description must be supplied.")
@@ -120,7 +124,9 @@ def _command_sign(args: argparse.Namespace) -> int:
120
124
  for token in args.option:
121
125
  name, _, value = token.partition("=")
122
126
  if not name:
123
- raise SystemExit("Signer options must use the form name=value.")
127
+ raise SystemExit(
128
+ "Signer options must use the form name=value."
129
+ )
124
130
  opts[name] = value
125
131
  signatures = asyncio.run(
126
132
  _async_sign(
@@ -180,7 +186,9 @@ def _command_embed_sign(args: argparse.Namespace) -> int:
180
186
  for token in args.option:
181
187
  name, _, value = token.partition("=")
182
188
  if not name:
183
- raise SystemExit("Signer options must use the form name=value.")
189
+ raise SystemExit(
190
+ "Signer options must use the form name=value."
191
+ )
184
192
  opts[name] = value
185
193
  output_path = Path(args.output) if args.output else None
186
194
  signatures = asyncio.run(
@@ -206,7 +214,9 @@ def _command_embed_sign(args: argparse.Namespace) -> int:
206
214
 
207
215
 
208
216
  def build_parser() -> argparse.ArgumentParser:
209
- parser = argparse.ArgumentParser(description="Embed XMP metadata and sign media.")
217
+ parser = argparse.ArgumentParser(
218
+ description="Embed XMP metadata and sign media."
219
+ )
210
220
  parser.add_argument(
211
221
  "--key-provider",
212
222
  dest="key_provider",
@@ -217,11 +227,17 @@ def build_parser() -> argparse.ArgumentParser:
217
227
  embed_parser = subparsers.add_parser("embed", help="Embed XMP into a file")
218
228
  embed_parser.add_argument("input", help="Path to the media file")
219
229
  embed_parser.add_argument("--xmp", help="Inline XMP XML payload")
220
- embed_parser.add_argument("--xmp-file", help="Read the XMP payload from a file")
221
- embed_parser.add_argument("--output", help="Write the embedded media to this path")
230
+ embed_parser.add_argument(
231
+ "--xmp-file", help="Read the XMP payload from a file"
232
+ )
233
+ embed_parser.add_argument(
234
+ "--output", help="Write the embedded media to this path"
235
+ )
222
236
  embed_parser.set_defaults(func=_command_embed)
223
237
 
224
- read_parser = subparsers.add_parser("read", help="Read XMP metadata from a file")
238
+ read_parser = subparsers.add_parser(
239
+ "read", help="Read XMP metadata from a file"
240
+ )
225
241
  read_parser.add_argument("input", help="Path to the media file")
226
242
  read_parser.set_defaults(func=_command_read)
227
243
 
@@ -229,13 +245,21 @@ def build_parser() -> argparse.ArgumentParser:
229
245
  "remove", help="Strip XMP metadata from a file"
230
246
  )
231
247
  remove_parser.add_argument("input", help="Path to the media file")
232
- remove_parser.add_argument("--output", help="Write the stripped media to this path")
248
+ remove_parser.add_argument(
249
+ "--output", help="Write the stripped media to this path"
250
+ )
233
251
  remove_parser.set_defaults(func=_command_remove)
234
252
 
235
- sign_parser = subparsers.add_parser("sign", help="Generate signatures for a file")
253
+ sign_parser = subparsers.add_parser(
254
+ "sign", help="Generate signatures for a file"
255
+ )
236
256
  sign_parser.add_argument("input", help="Path to the media file")
237
- sign_parser.add_argument("--format", required=True, help="MediaSigner format name")
238
- sign_parser.add_argument("--key-ref", dest="key_ref", help="Key reference string")
257
+ sign_parser.add_argument(
258
+ "--format", required=True, help="MediaSigner format name"
259
+ )
260
+ sign_parser.add_argument(
261
+ "--key-ref", dest="key_ref", help="Key reference string"
262
+ )
239
263
  sign_parser.add_argument(
240
264
  "--key-json",
241
265
  dest="key_json",
@@ -291,7 +315,9 @@ def build_parser() -> argparse.ArgumentParser:
291
315
  action="append",
292
316
  help="Additional signer option in the form name=value",
293
317
  )
294
- embed_sign_parser.add_argument("--alg", help="Explicit algorithm identifier")
318
+ embed_sign_parser.add_argument(
319
+ "--alg", help="Explicit algorithm identifier"
320
+ )
295
321
  embed_sign_parser.add_argument(
296
322
  "--detached",
297
323
  action="store_true",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: EmbeddedSigner
3
- Version: 0.1.5.dev1
3
+ Version: 0.11.0.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
@@ -111,7 +111,8 @@ Description-Content-Type: text/markdown
111
111
  <img src="https://img.shields.io/pypi/l/EmbeddedSigner" alt="PyPI - License"/></a>
112
112
  <a href="https://pypi.org/project/EmbeddedSigner/">
113
113
  <img src="https://img.shields.io/pypi/v/EmbeddedSigner?label=EmbeddedSigner&color=green" alt="PyPI - EmbeddedSigner"/></a>
114
- </p>
114
+ <a href="https://discord.gg/N4UpBuQv8T">
115
+ <img src="https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white" alt="Discord"/></a></p>
115
116
 
116
117
  # Embed metadata into a file and write it back in place.
117
118
  signer.embed_file("image.png", xmp_xml)
@@ -193,3 +194,5 @@ embedded-signer embed-sign example.png \
193
194
  EmbeddedSigner is released under the Apache 2.0 License. See the
194
195
  [LICENSE](LICENSE) file for details.
195
196
 
197
+
198
+
@@ -0,0 +1,8 @@
1
+ EmbeddedSigner/__init__.py,sha256=PTcO_55bD8K70SqZmI0KzgYjkqmhI7rLpHdQTwvOCbU,119
2
+ EmbeddedSigner/_embed_signer.py,sha256=dtgOwTwX0e3ewG_uacUdivg5p3K_xUJzZJAMo9lYVX4,12984
3
+ EmbeddedSigner/cli.py,sha256=V6RIE1evkMmJKVwqBF1GvUnXrGyhzjPFJXE3S258wN8,10791
4
+ embeddedsigner-0.11.0.dev1.dist-info/METADATA,sha256=g7zfYpIqh-357eQYSYKHajRv-PxYaJRUhQY-8JbSur4,8520
5
+ embeddedsigner-0.11.0.dev1.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
6
+ embeddedsigner-0.11.0.dev1.dist-info/entry_points.txt,sha256=EwpGp4nYOLoLHwGiNMGvCjOb6RmHd3kOnKcV40Ce6kM,59
7
+ embeddedsigner-0.11.0.dev1.dist-info/licenses/LICENSE,sha256=djUXOlCxLVszShEpZXshZ7v33G-2qIC_j9KXpWKZSzQ,11359
8
+ embeddedsigner-0.11.0.dev1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.4.0
2
+ Generator: poetry-core 2.4.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,8 +0,0 @@
1
- EmbeddedSigner/__init__.py,sha256=PTcO_55bD8K70SqZmI0KzgYjkqmhI7rLpHdQTwvOCbU,119
2
- EmbeddedSigner/_embed_signer.py,sha256=rorOvU5Bp9u6chWmRvOYxNinpXmMWpaOuXJcmwGyjb4,12547
3
- EmbeddedSigner/cli.py,sha256=3xRzdMkrjA5NQ1QAutwxTSWWGMxsSrsBYAJ2aOn913k,10537
4
- embeddedsigner-0.1.5.dev1.dist-info/METADATA,sha256=gXkOmVdvPTWvSKBiRMn9rDRTjKrK87_LTo0mQkaF7RI,8349
5
- embeddedsigner-0.1.5.dev1.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
6
- embeddedsigner-0.1.5.dev1.dist-info/entry_points.txt,sha256=EwpGp4nYOLoLHwGiNMGvCjOb6RmHd3kOnKcV40Ce6kM,59
7
- embeddedsigner-0.1.5.dev1.dist-info/licenses/LICENSE,sha256=djUXOlCxLVszShEpZXshZ7v33G-2qIC_j9KXpWKZSzQ,11359
8
- embeddedsigner-0.1.5.dev1.dist-info/RECORD,,