openbadgeslib 3.9.0__tar.gz → 3.11.0__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.
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/Changelog.txt +120 -0
- {openbadgeslib-3.9.0/openbadgeslib.egg-info → openbadgeslib-3.11.0}/PKG-INFO +4 -2
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/__init__.py +24 -9
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/badge.py +4 -4
- openbadgeslib-3.11.0/openbadgeslib/issue.py +516 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob1/__init__.py +15 -14
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/__init__.py +5 -2
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/__init__.py +11 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/credential.py +188 -14
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/ldp.py +98 -9
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/openbadges_publish.py +74 -6
- openbadgeslib-3.11.0/openbadgeslib/openbadges_signer.py +473 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/openbadges_verifier.py +25 -3
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/signer.py +4 -4
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/util.py +1 -1
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/verifier.py +4 -4
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0/openbadgeslib.egg-info}/PKG-INFO +4 -2
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib.egg-info/SOURCES.txt +11 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib.egg-info/requires.txt +4 -1
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/pyproject.toml +16 -4
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conformance/test_official_validators.py +71 -0
- openbadgeslib-3.11.0/tests/test_baking.py +104 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_cli_json.py +35 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_cli_smoke.py +2 -1
- openbadgeslib-3.11.0/tests/test_examples.py +31 -0
- openbadgeslib-3.11.0/tests/test_issue.py +252 -0
- openbadgeslib-3.11.0/tests/test_keys.py +70 -0
- openbadgeslib-3.11.0/tests/test_mail.py +85 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob1_deprecation.py +14 -13
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob1_signer.py +1 -1
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob2_cli.py +46 -6
- openbadgeslib-3.11.0/tests/test_ob2_error_branches.py +173 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_conformance_schema.py +31 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_credential.py +105 -1
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_ldp.py +6 -2
- openbadgeslib-3.11.0/tests/test_ob3_ldp_ecdsa_sd.py +142 -0
- openbadgeslib-3.11.0/tests/test_ob3_ldp_errors.py +123 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_publish_cli.py +82 -0
- openbadgeslib-3.11.0/tests/test_signer_batch.py +182 -0
- openbadgeslib-3.11.0/tests/test_verifier_cli_coverage.py +284 -0
- openbadgeslib-3.9.0/openbadgeslib/openbadges_signer.py +0 -500
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/LICENSE.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/MANIFEST.in +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/README.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/SECURITY.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/docs/README.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/_jws/__init__.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/_jws/exceptions.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/_jws/utils.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/baking.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/config.ini.example +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/confparser.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/errors.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/keys.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/logs.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/mail.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob1/badge.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob1/signer.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob1/verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob2/__init__.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob2/models.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob2/signer.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob2/verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/credentials-v2.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.1.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.2.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.3.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/security-data-integrity-v2.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/contexts/security-multikey-v1.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/did.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/eudi.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/signer.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/status.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/status_list.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/status_registry.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/ob3/verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/openbadges_init.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/openbadges_keygenerator.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib/py.typed +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib.egg-info/dependency_links.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib.egg-info/entry_points.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/openbadgeslib.egg-info/top_level.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/setup.cfg +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/config1.ini +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conformance/Dockerfile.ob3 +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conformance/README.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conformance/conftest.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conformance/docker-compose.yml +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/conftest.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/ob_schemas/README.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/ob_schemas/ob_v3p0_achievementcredential_schema.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/ob_schemas/ob_v3p0_profile_schema.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/ob_schemas/refresh.sh +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/README.md +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/credentials-examples-v2.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/doc-hash.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/key-pair.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/proof-config-hash.txt +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/fixtures/vc_di_eddsa/signed-credential.json +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/images/sample1.png +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/images/sample1.svg +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/images/userimage01.svg +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/ldp_helpers.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/logo Python Espan/314/203a.svg" +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/logo Python Espa/303/261a.svg" +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_confparser.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_docs.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_eddsa.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_jws.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_key_operation.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob1_badge_io.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob1_verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob2_models.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob2_signer.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob2_verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_contexts.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_did.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_did_doc.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_endorsement.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_eudi_sd_jwt.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_ldp_cli.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_ldp_sign.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_signer.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_signer_cli_ldp.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_status.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_status_list.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_status_registry.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_ob3_verifier.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_sign_ecc.pem +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_sign_rsa.pem +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_util.py +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_verify_ecc.pem +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/test_verify_rsa.pem +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/withoutxmlheader.svg +0 -0
- {openbadgeslib-3.9.0 → openbadgeslib-3.11.0}/tests/withxmlheader.svg +0 -0
|
@@ -4,6 +4,126 @@ OpenBadgesLib - Changelog
|
|
|
4
4
|
Newest first. Dates are ISO 8601 (YYYY-MM-DD).
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
* v3.11.0 - 2026-07-09
|
|
8
|
+
|
|
9
|
+
- feat(ldp): verify OpenBadges 3.0 credentials secured with the
|
|
10
|
+
**ecdsa-sd-2023** (selective disclosure) Data Integrity cryptosuite — the
|
|
11
|
+
verify-only slice of #171. A derived proof is verified by delegating the
|
|
12
|
+
large, security-sensitive selective-disclosure crypto (CBOR base/derived
|
|
13
|
+
proofs, HMAC label maps, per-statement P-256 signatures) to openvc-core's
|
|
14
|
+
audited `EcdsaSdProofSuite`; openbadgeslib keeps the OB3 model, the trust
|
|
15
|
+
binding (proof `verificationMethod` ↔ credential issuer) and the lifecycle
|
|
16
|
+
checks around it, and hands the delegate its pinned OB3 `@context`
|
|
17
|
+
allowlist so canonicalization stays fail-closed and never touches the
|
|
18
|
+
network. It plugs into the `_CRYPTOSUITES` registry beside eddsa-rdfc-2022,
|
|
19
|
+
so `OB3LdpVerifier` accepts both transparently. Verify-only for Displayer
|
|
20
|
+
parity (1EdTech OB3 certification requires verifying both suites); issuing
|
|
21
|
+
ecdsa-sd-2023 stays out of scope. Needs the new `[ldp-sd]` extra
|
|
22
|
+
(`openvc-core[data-integrity]`, self-contained — pulls its own pyld); a
|
|
23
|
+
missing extra fails closed with an actionable install hint. (Closes #171)
|
|
24
|
+
|
|
25
|
+
* v3.10.0 - 2026-07-08
|
|
26
|
+
|
|
27
|
+
- feat(publish): `openbadges-publish -V 3 --check-live` completes #164. After
|
|
28
|
+
(re)publishing, it downloads each written artifact — `did.json`, the signed
|
|
29
|
+
status lists, `verify.pem` — from `publish_url` and byte-compares it against
|
|
30
|
+
the local copy, turning the "re-upload so the change takes effect" reminder
|
|
31
|
+
into a verifiable guarantee. Exit 2 (`--json`, listed in `live_check.stale`)
|
|
32
|
+
or 1 (human) if any artifact is stale or missing on the server. The rest of
|
|
33
|
+
#164 (status-list `validUntil` + opt-in list-proof verification + issuer
|
|
34
|
+
binding) shipped in v3.8.0. (Closes #164)
|
|
35
|
+
|
|
36
|
+
- docs(examples): #168 library integration tutorial + runnable examples. New
|
|
37
|
+
`examples/` scripts — issue+verify an OB 3.0 JWT-VC, issue with a Data
|
|
38
|
+
Integrity (LDP) proof, and issue from a config section via the high-level API
|
|
39
|
+
(single + batch) — each self-contained and executed in CI (`test_examples.py`,
|
|
40
|
+
anti-drift, same philosophy as `test_docs.py`). Two new wiki pages: the
|
|
41
|
+
"Library Integration Tutorial" narrating them end to end (issue → sign →
|
|
42
|
+
publish → revoke → verify) and a "Certification Cookbook" on passing the
|
|
43
|
+
official 1EdTech OB 3.0 conformance tests without the paid membership.
|
|
44
|
+
(Closes #168)
|
|
45
|
+
|
|
46
|
+
- test(coverage): #169 targeted-coverage round. New dedicated suites for the
|
|
47
|
+
shared token carrier (`test_baking.py` — embed/extract round-trips per
|
|
48
|
+
format, compression and malformed-iTXt edges), mail (`test_mail.py` — SMTP
|
|
49
|
+
mocked) and the key helpers (`test_keys.py`), plus error-branch coverage for
|
|
50
|
+
the OB2 signer/verifier, the OB3 Data Integrity (LDP) path and the verifier
|
|
51
|
+
CLI (`openbadges_verifier.py` 74% → 95%). Total coverage crosses 93% and the
|
|
52
|
+
enforced `fail_under` floor is raised from 91 to 93. An opt-in OB2
|
|
53
|
+
**SignedBadge** conformance case joins the existing hosted one (the
|
|
54
|
+
crypto-sensitive path, Docker-gated). (Closes #169)
|
|
55
|
+
|
|
56
|
+
- docs(ob1): OpenBadges 1.0 is reclassified from "deprecated, removal in
|
|
57
|
+
4.0.0" to a **supported legacy surface with no removal planned**. Removing a
|
|
58
|
+
working, dependency-free legacy path (OB1 has carried no unique dependencies
|
|
59
|
+
since #167) was judged excessive; OB1 stays fully functional and maintained,
|
|
60
|
+
simply superseded by OB 2.0/3.0 for new work. The library
|
|
61
|
+
`DeprecationWarning`s and the `-V 1` CLI notices are reworded to steer new
|
|
62
|
+
work to OB2/OB3 without promising removal, and the "OpenBadges 1.0
|
|
63
|
+
lifecycle" wiki page records the policy — including why a `[legacy]`/`[ob1]`
|
|
64
|
+
install extra stays rejected: a Python extra gates *dependencies*, not code,
|
|
65
|
+
and OB1 has none to gate (it would install the same bytes). Reverses the
|
|
66
|
+
removal side of #159/#170.
|
|
67
|
+
|
|
68
|
+
- feat(cli): batch issuance — `openbadges-signer` now issues to many recipients
|
|
69
|
+
in one run. Repeat `-r EMAIL`, or pass `--recipients-file FILE` (one email per
|
|
70
|
+
line or comma-separated; blank lines and `#`-comments ignored); a single `-r`
|
|
71
|
+
keeps the historical single-badge behaviour byte-for-byte. For a revocable OB3
|
|
72
|
+
badge every status-list index is allocated in a SINGLE registry transaction
|
|
73
|
+
(load once, allocate N, save once) rather than N load/save cycles — the piece
|
|
74
|
+
that makes thousands-scale issuance practical. An already-existing output file
|
|
75
|
+
is skipped (batch) or aborts (single) unless the new `--force`/`--overwrite`
|
|
76
|
+
overwrites it, and one bad recipient does not abort the rest. `--json` emits a
|
|
77
|
+
per-recipient summary `{signed, skipped, failed}` under the shared exit
|
|
78
|
+
contract (0 all signed, 2 some skipped/failed, 1 a batch-level error). The
|
|
79
|
+
library entry point is `openbadgeslib.issue.issue_batch_from_conf`, returning
|
|
80
|
+
one `BatchResult` per recipient. (Closes #165)
|
|
81
|
+
|
|
82
|
+
- feat(api): extract the issuance orchestration from the CLI into a reusable
|
|
83
|
+
library API — the single biggest adoption gap. `openbadgeslib.issue` exposes
|
|
84
|
+
`issue_from_conf(conf, badge, recipient, ob_version, ...)` (also re-exported
|
|
85
|
+
as `openbadgeslib.issue_from_conf`), returning a `SignResult` dataclass with
|
|
86
|
+
the signed badge bytes and metadata and doing no user-facing I/O — no
|
|
87
|
+
prints, no sys.exit, no file write; a config or policy problem raises
|
|
88
|
+
`IssuanceError`. The ~230 lines of business logic that lived in
|
|
89
|
+
openbadges-signer (credential construction from config, salt generation, the
|
|
90
|
+
OB2 hosted-vs-signed decision, the OB3 status-registry→sign transactional
|
|
91
|
+
order and the Data Integrity verificationMethod policy — did:web trusted vs
|
|
92
|
+
a derived self-asserted did:key) now live there and are unit-tested
|
|
93
|
+
directly, not only reachable by driving the CLI. The signer entrypoints are
|
|
94
|
+
reduced to flag parsing, I/O and display over that API; behaviour — including
|
|
95
|
+
the historical per-version exit conventions — is unchanged. Prerequisite for
|
|
96
|
+
batch signing (#165) and any unified CLI. OpenBadges 1.0 issuance stays
|
|
97
|
+
CLI-only (it is deprecated). (Closes #160)
|
|
98
|
+
|
|
99
|
+
- feat(ob3): complete the broadened OB 3.0 credential model started in
|
|
100
|
+
v3.9.0 — closing the remaining data-model gap versus the spec. New `Result`
|
|
101
|
+
(a measured outcome: value, status, achievedLevel and the linked
|
|
102
|
+
resultDescription), `ResultDescription` (an achievement's possible results:
|
|
103
|
+
resultType, allowedValue, valueMin/valueMax, requiredValue/requiredLevel)
|
|
104
|
+
and `IdentityObject` (a hashed or plaintext `credentialSubject.identifier`,
|
|
105
|
+
the alternative to `credentialSubject.id`) dataclasses, plus `creditsEarned`
|
|
106
|
+
on the subject and a `resultDescription` list on `Achievement`. All follow
|
|
107
|
+
the house style (dataclasses + mypy, no Pydantic), parse from a verified
|
|
108
|
+
credential, round-trip through `to_vc`, and satisfy the offline conformance
|
|
109
|
+
schema — a fully-populated credential (identifier-only subject, result +
|
|
110
|
+
linked resultDescription, alignment, credits) validates against 1EdTech's
|
|
111
|
+
AchievementCredential schema. `openbadges-verifier` now surfaces the
|
|
112
|
+
broadened fields — achievementType, creditsAvailable/creditsEarned and the
|
|
113
|
+
alignment/result/identifier counts — in both `--json` and `--show`. Two
|
|
114
|
+
round-trip fixes fall out: a subject conveying identity solely through
|
|
115
|
+
`identifier` now re-serialises with it (the identifier was silently dropped
|
|
116
|
+
on parse before), and a lone `alignment` object not wrapped in an array is
|
|
117
|
+
no longer discarded. (Closes #162)
|
|
118
|
+
|
|
119
|
+
- fix(cli): `openbadges-publish -V 1/-V 2` now exits with a clear message when
|
|
120
|
+
the `[issuer]` section is missing `publish_url` or `revocationList`, instead
|
|
121
|
+
of raising a raw `KeyError` traceback partway through — after the output
|
|
122
|
+
directory had already been created. The OB3 path already validated this; the
|
|
123
|
+
hosted OB1/OB2 paths now share the same guard. Last item of the quick-fix
|
|
124
|
+
round. (Closes #156)
|
|
125
|
+
|
|
126
|
+
|
|
7
127
|
* v3.9.0 - 2026-07-08
|
|
8
128
|
|
|
9
129
|
- feat(ob3): broaden the credential data model toward the OB 3.0 spec — the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openbadgeslib
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.11.0
|
|
4
4
|
Summary: Production-ready Python library & CLI for Open Badges 3.0 (W3C Verifiable Credentials): issue, verify, and revoke JWT-VC credentials with Bitstring Status Lists and did:web — plus strict OB 2.0 and legacy OB 1.0.
|
|
5
5
|
Author-email: Luis González Fernández <luisgf@luisgf.es>, Jesús Cea Avión <jcea@jcea.es>
|
|
6
6
|
License: LGPLv3
|
|
@@ -36,7 +36,9 @@ Requires-Dist: defusedxml>=0.7
|
|
|
36
36
|
Provides-Extra: ldp
|
|
37
37
|
Requires-Dist: pyld>=2.0.4; extra == "ldp"
|
|
38
38
|
Provides-Extra: eudi
|
|
39
|
-
Requires-Dist: openvc-core<2,>=1.
|
|
39
|
+
Requires-Dist: openvc-core<2,>=1.13; extra == "eudi"
|
|
40
|
+
Provides-Extra: ldp-sd
|
|
41
|
+
Requires-Dist: openvc-core[data-integrity]<2,>=1.13; extra == "ldp-sd"
|
|
40
42
|
Provides-Extra: dev
|
|
41
43
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
42
44
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
@@ -39,13 +39,23 @@ from .keys import KeyFactory, KeyRSA, KeyECC # noqa: F401
|
|
|
39
39
|
from .util import __version__ # noqa: F401
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
# ── Issuance API ─────────────────────────────────────────────────────────────
|
|
43
|
+
# "Issue badge X to Y per config" as a library call — the orchestration the CLI
|
|
44
|
+
# wraps, returning a SignResult instead of writing files (openbadgeslib.issue).
|
|
45
|
+
# Resolved lazily (PEP 562, below) because openbadgeslib.issue pulls in the
|
|
46
|
+
# shared Badge model from the ob1 leaf module; a bare `import openbadgeslib`
|
|
47
|
+
# must not drag that in. `from openbadgeslib.issue import ...` works directly.
|
|
48
|
+
_ISSUE_API = ('IssuanceError', 'SignResult', 'issue_from_conf')
|
|
49
|
+
|
|
50
|
+
|
|
42
51
|
# ── OpenBadges 1.0 (legacy) ──────────────────────────────────────────────────
|
|
43
52
|
# The unprefixed OB1 names (Signer, Verifier, Badge, …) stay importable from
|
|
44
|
-
# the top-level package for backward compatibility
|
|
45
|
-
# OpenBadges 1.0 surface: accessing one
|
|
46
|
-
#
|
|
47
|
-
# They are resolved lazily from the ob1 leaf modules (PEP
|
|
48
|
-
# `import openbadgeslib` neither warns nor drags in the ob1
|
|
53
|
+
# the top-level package for backward compatibility. They are the legacy
|
|
54
|
+
# OpenBadges 1.0 surface: accessing one emits a DeprecationWarning steering new
|
|
55
|
+
# work to openbadgeslib.ob2 / openbadgeslib.ob3. OB 1.0 itself remains supported
|
|
56
|
+
# (no removal planned). They are resolved lazily from the ob1 leaf modules (PEP
|
|
57
|
+
# 562), so a bare `import openbadgeslib` neither warns nor drags in the ob1
|
|
58
|
+
# package.
|
|
49
59
|
_OB1_API = {
|
|
50
60
|
'Signer': 'signer', 'Verifier': 'verifier', 'VerifyInfo': 'verifier',
|
|
51
61
|
'Badge': 'badge', 'BadgeSigned': 'badge', 'Assertion': 'badge',
|
|
@@ -55,6 +65,11 @@ _OB1_API = {
|
|
|
55
65
|
|
|
56
66
|
|
|
57
67
|
def __getattr__(name: str) -> Any:
|
|
68
|
+
if name in _ISSUE_API:
|
|
69
|
+
# The modern issuance API — lazy so a bare import stays ob1-free, but
|
|
70
|
+
# warning-free (unlike the OB1 names below).
|
|
71
|
+
import importlib
|
|
72
|
+
return getattr(importlib.import_module('.issue', __name__), name)
|
|
58
73
|
module = _OB1_API.get(name)
|
|
59
74
|
if module is None:
|
|
60
75
|
raise AttributeError(
|
|
@@ -62,9 +77,9 @@ def __getattr__(name: str) -> Any:
|
|
|
62
77
|
import importlib
|
|
63
78
|
import warnings
|
|
64
79
|
warnings.warn(
|
|
65
|
-
'openbadgeslib.%s is the legacy OpenBadges 1.0 API
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'1.0 lifecycle" wiki page.' % name,
|
|
80
|
+
'openbadgeslib.%s is the legacy OpenBadges 1.0 API; prefer '
|
|
81
|
+
'openbadgeslib.ob2 (strict OB 2.0) or openbadgeslib.ob3 (OB 3.0) for '
|
|
82
|
+
'new work. OpenBadges 1.0 remains supported (no removal planned). See '
|
|
83
|
+
'the "OpenBadges 1.0 lifecycle" wiki page.' % name,
|
|
69
84
|
DeprecationWarning, stacklevel=2)
|
|
70
85
|
return getattr(importlib.import_module('.ob1.' + module, __name__), name)
|
|
@@ -8,10 +8,10 @@ from .ob1.badge import (
|
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
warnings.warn(
|
|
11
|
-
'openbadgeslib.badge is a legacy OpenBadges 1.0 compatibility shim
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
11
|
+
'openbadgeslib.badge is a legacy OpenBadges 1.0 compatibility shim; prefer '
|
|
12
|
+
'openbadgeslib.ob2 (strict OB 2.0) or openbadgeslib.ob3 (OB 3.0) for new '
|
|
13
|
+
'work. OpenBadges 1.0 remains supported (no removal planned). See the '
|
|
14
|
+
'"OpenBadges 1.0 lifecycle" wiki page.',
|
|
15
15
|
DeprecationWarning, stacklevel=2)
|
|
16
16
|
|
|
17
17
|
__all__ = [
|