PyLD 3.1.0__tar.gz → 3.2.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.
Files changed (48) hide show
  1. {pyld-3.1.0 → pyld-3.2.0}/CHANGELOG.md +16 -0
  2. {pyld-3.1.0/lib/PyLD.egg-info → pyld-3.2.0}/PKG-INFO +4 -2
  3. {pyld-3.1.0 → pyld-3.2.0}/README.md +1 -1
  4. {pyld-3.1.0 → pyld-3.2.0}/README.txt +1 -1
  5. {pyld-3.1.0 → pyld-3.2.0/lib/PyLD.egg-info}/PKG-INFO +4 -2
  6. {pyld-3.1.0 → pyld-3.2.0}/lib/PyLD.egg-info/SOURCES.txt +4 -2
  7. {pyld-3.1.0 → pyld-3.2.0}/lib/PyLD.egg-info/requires.txt +3 -0
  8. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/__about__.py +1 -1
  9. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/__init__.py +2 -0
  10. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/requests.py +9 -6
  11. pyld-3.2.0/lib/pyld/documentloader/requests_sqlite_cache.py +55 -0
  12. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/jsonld.py +191 -188
  13. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/nquads.py +2 -1
  14. pyld-3.2.0/lib/pyld/options.py +193 -0
  15. {pyld-3.1.0 → pyld-3.2.0}/setup.py +1 -0
  16. {pyld-3.1.0 → pyld-3.2.0}/tests/test_document_loader.py +26 -0
  17. {pyld-3.1.0 → pyld-3.2.0}/tests/test_jsonld.py +150 -0
  18. pyld-3.2.0/tests/test_sqlite_cache_requests_document_loader.py +125 -0
  19. pyld-3.1.0/tests/test_api.py +0 -25
  20. {pyld-3.1.0 → pyld-3.2.0}/LICENSE +0 -0
  21. {pyld-3.1.0 → pyld-3.2.0}/MANIFEST.in +0 -0
  22. {pyld-3.1.0 → pyld-3.2.0}/lib/PyLD.egg-info/dependency_links.txt +0 -0
  23. {pyld-3.1.0 → pyld-3.2.0}/lib/PyLD.egg-info/top_level.txt +0 -0
  24. {pyld-3.1.0 → pyld-3.2.0}/lib/c14n/Canonicalize.py +0 -0
  25. {pyld-3.1.0 → pyld-3.2.0}/lib/c14n/NumberToJson.py +0 -0
  26. {pyld-3.1.0 → pyld-3.2.0}/lib/c14n/__init__.py +0 -0
  27. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/canon.py +0 -0
  28. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/context_resolver.py +0 -0
  29. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/__init__.py +0 -0
  30. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/aiohttp.py +0 -0
  31. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/base.py +0 -0
  32. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/__init__.py +0 -0
  33. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/activitystreams.jsonld +0 -0
  34. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/credentials-v1.jsonld +0 -0
  35. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/credentials-v2.jsonld +0 -0
  36. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/did-v1.jsonld +0 -0
  37. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/security-ed25519-2020-v1.jsonld +0 -0
  38. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/security-jws-2020-v1.jsonld +0 -0
  39. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/security-v1.jsonld +0 -0
  40. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/documentloader/frozen/bundled/security-v2.jsonld +0 -0
  41. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/identifier_issuer.py +0 -0
  42. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/iri_resolver.py +0 -0
  43. {pyld-3.1.0 → pyld-3.2.0}/lib/pyld/resolved_context.py +0 -0
  44. {pyld-3.1.0 → pyld-3.2.0}/pyproject.toml +0 -0
  45. {pyld-3.1.0 → pyld-3.2.0}/setup.cfg +0 -0
  46. {pyld-3.1.0 → pyld-3.2.0}/tests/test_frozen_document_loader.py +0 -0
  47. {pyld-3.1.0 → pyld-3.2.0}/tests/test_iri_resolver.py +0 -0
  48. {pyld-3.1.0 → pyld-3.2.0}/tests/test_manifests.py +0 -0
@@ -1,5 +1,21 @@
1
1
  # pyld ChangeLog
2
2
 
3
+ ## 3.2.0 - 2026-08-17
4
+
5
+ ### Added
6
+ - `*Options` TypedDict types and a `Context` type alias in `pyld.options` for JSON-LD API option dicts (typing and documentation).
7
+ - `pyld.SqliteCacheRequestsDocumentLoader`: a SQLite-backed HTTP cache document loader using `requests-cache`.
8
+
9
+ ### Fixed
10
+ - If value objects contain array values for `@type` during expansion, an error is now raised. Fixes [expand#ter54](https://w3c.github.io/json-ld-api/tests/expand-manifest.html#ter54) and [toRdf#ter54](https://w3c.github.io/json-ld-api/tests/toRdf-manifest.html#ter54).
11
+ - Inline contexts that try to redefine @context now raise an error. Fixes [expand#ter56](https://w3c.github.io/json-ld-api/tests/expand-manifest.html#ter56) and [toRdf#ter56](https://w3c.github.io/json-ld-api/tests/toRdf-manifest.html#ter56).
12
+ - When using native types, values of `xsd:boolean` and `xsd:integer` are now properly converted. Fixes [fromRdf#t0027](https://w3c.github.io/json-ld-api/tests/fromRdf-manifest.html#t0027).
13
+ - Numbers with 0 as fractional part now parse to an `xsd:integer` instead of `xsd:double`. Fixes [toRdf#ttn02](https://w3c.github.io/json-ld-api/tests/toRdf-manifest.html#ttn02).
14
+ - Zeros are now truncated for numeric values with negative exponent.
15
+ - Blank node prefixes are now also used in IRI expansion.
16
+ - Numbers with no fractions but that are >= 1e21 are now represented as xsd:double in json-ld-1.1 processing mode.
17
+ - In `RequestsDocumentLoader`, constructor-level headers are now removed from `**kwargs` and stored separately, avoiding duplicate `headers=` when calling `session.get`. Per-call `options["headers"]` still takes precedence.
18
+
3
19
  ## 3.1.0 - 2026-06-19
4
20
 
5
21
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyLD
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Python implementation of the JSON-LD API
5
5
  Home-page: https://github.com/digitalbazaar/pyld
6
6
  Author: Digital Bazaar
@@ -24,6 +24,8 @@ Provides-Extra: requests
24
24
  Requires-Dist: requests; extra == "requests"
25
25
  Provides-Extra: aiohttp
26
26
  Requires-Dist: aiohttp; extra == "aiohttp"
27
+ Provides-Extra: requests-cache
28
+ Requires-Dist: requests-cache>=1.3; extra == "requests-cache"
27
29
  Provides-Extra: cachetools
28
30
  Requires-Dist: cachetools; extra == "cachetools"
29
31
  Provides-Extra: frozendict
@@ -258,7 +260,7 @@ attempt to use a locally cached version of contexts (see
258
260
  [§ Cache JSON-LD Contexts](https://w3c.github.io/json-ld-bp/#cache-json-ld-contexts)).
259
261
  Refresh the bundled copies with `make download-bundled-contexts`.
260
262
 
261
- ### Customizing the ContextLoader
263
+ ### Customizing the ContextResolver
262
264
 
263
265
  You can customize the way contexts are loaded and cached by passing an instance
264
266
  of `ContextResolver`. The following example implements a loader with a prefilled
@@ -216,7 +216,7 @@ attempt to use a locally cached version of contexts (see
216
216
  [§ Cache JSON-LD Contexts](https://w3c.github.io/json-ld-bp/#cache-json-ld-contexts)).
217
217
  Refresh the bundled copies with `make download-bundled-contexts`.
218
218
 
219
- ### Customizing the ContextLoader
219
+ ### Customizing the ContextResolver
220
220
 
221
221
  You can customize the way contexts are loaded and cached by passing an instance
222
222
  of `ContextResolver`. The following example implements a loader with a prefilled
@@ -216,7 +216,7 @@ attempt to use a locally cached version of contexts (see
216
216
  [§ Cache JSON-LD Contexts](https://w3c.github.io/json-ld-bp/#cache-json-ld-contexts)).
217
217
  Refresh the bundled copies with `make download-bundled-contexts`.
218
218
 
219
- ### Customizing the ContextLoader
219
+ ### Customizing the ContextResolver
220
220
 
221
221
  You can customize the way contexts are loaded and cached by passing an instance
222
222
  of `ContextResolver`. The following example implements a loader with a prefilled
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyLD
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Python implementation of the JSON-LD API
5
5
  Home-page: https://github.com/digitalbazaar/pyld
6
6
  Author: Digital Bazaar
@@ -24,6 +24,8 @@ Provides-Extra: requests
24
24
  Requires-Dist: requests; extra == "requests"
25
25
  Provides-Extra: aiohttp
26
26
  Requires-Dist: aiohttp; extra == "aiohttp"
27
+ Provides-Extra: requests-cache
28
+ Requires-Dist: requests-cache>=1.3; extra == "requests-cache"
27
29
  Provides-Extra: cachetools
28
30
  Requires-Dist: cachetools; extra == "cachetools"
29
31
  Provides-Extra: frozendict
@@ -258,7 +260,7 @@ attempt to use a locally cached version of contexts (see
258
260
  [§ Cache JSON-LD Contexts](https://w3c.github.io/json-ld-bp/#cache-json-ld-contexts)).
259
261
  Refresh the bundled copies with `make download-bundled-contexts`.
260
262
 
261
- ### Customizing the ContextLoader
263
+ ### Customizing the ContextResolver
262
264
 
263
265
  You can customize the way contexts are loaded and cached by passing an instance
264
266
  of `ContextResolver`. The following example implements a loader with a prefilled
@@ -21,11 +21,13 @@ lib/pyld/identifier_issuer.py
21
21
  lib/pyld/iri_resolver.py
22
22
  lib/pyld/jsonld.py
23
23
  lib/pyld/nquads.py
24
+ lib/pyld/options.py
24
25
  lib/pyld/resolved_context.py
25
26
  lib/pyld/documentloader/__init__.py
26
27
  lib/pyld/documentloader/aiohttp.py
27
28
  lib/pyld/documentloader/base.py
28
29
  lib/pyld/documentloader/requests.py
30
+ lib/pyld/documentloader/requests_sqlite_cache.py
29
31
  lib/pyld/documentloader/frozen/__init__.py
30
32
  lib/pyld/documentloader/frozen/bundled/activitystreams.jsonld
31
33
  lib/pyld/documentloader/frozen/bundled/credentials-v1.jsonld
@@ -35,9 +37,9 @@ lib/pyld/documentloader/frozen/bundled/security-ed25519-2020-v1.jsonld
35
37
  lib/pyld/documentloader/frozen/bundled/security-jws-2020-v1.jsonld
36
38
  lib/pyld/documentloader/frozen/bundled/security-v1.jsonld
37
39
  lib/pyld/documentloader/frozen/bundled/security-v2.jsonld
38
- tests/test_api.py
39
40
  tests/test_document_loader.py
40
41
  tests/test_frozen_document_loader.py
41
42
  tests/test_iri_resolver.py
42
43
  tests/test_jsonld.py
43
- tests/test_manifests.py
44
+ tests/test_manifests.py
45
+ tests/test_sqlite_cache_requests_document_loader.py
@@ -13,3 +13,6 @@ frozendict
13
13
 
14
14
  [requests]
15
15
  requests
16
+
17
+ [requests-cache]
18
+ requests-cache>=1.3
@@ -4,4 +4,4 @@ __all__ = ['__copyright__', '__license__', '__version__']
4
4
 
5
5
  __copyright__ = 'Copyright (c) 2011-2024 Digital Bazaar, Inc.'
6
6
  __license__ = 'BSD 3-Clause "New" or "Revised" License'
7
- __version__ = '3.1.0'
7
+ __version__ = '3.2.0'
@@ -6,6 +6,7 @@ from .documentloader.aiohttp import AioHttpDocumentLoader
6
6
  from .documentloader.base import DocumentLoader, RemoteDocument
7
7
  from .documentloader.frozen import BUNDLED_CONTEXTS, FrozenDocumentLoader
8
8
  from .documentloader.requests import RequestsDocumentLoader
9
+ from .documentloader.requests_sqlite_cache import SqliteCacheRequestsDocumentLoader
9
10
 
10
11
  __all__ = [
11
12
  'AioHttpDocumentLoader',
@@ -15,5 +16,6 @@ __all__ = [
15
16
  'FrozenDocumentLoader',
16
17
  'RequestsDocumentLoader',
17
18
  'RemoteDocument',
19
+ 'SqliteCacheRequestsDocumentLoader',
18
20
  'jsonld',
19
21
  ]
@@ -15,17 +15,20 @@ import urllib.parse as urllib_parse
15
15
 
16
16
  from pyld import iri_resolver
17
17
  from pyld.documentloader.base import DocumentLoader, RemoteDocument
18
- from pyld.jsonld import JsonLdError, parse_link_header, LINK_HEADER_REL
18
+ from pyld.jsonld import LINK_HEADER_REL, JsonLdError, parse_link_header
19
19
 
20
20
 
21
21
  class RequestsDocumentLoader(DocumentLoader):
22
22
  """Remote document loader using Requests."""
23
23
 
24
- def __init__(self, secure=False, **kwargs):
25
- import requests
24
+ def __init__(self, secure=False, session=None, **kwargs):
25
+ if session is None:
26
+ import requests
26
27
 
27
- self.requests = requests
28
+ session = requests.Session()
29
+ self.session = session
28
30
  self.secure = secure
31
+ self.headers = kwargs.pop('headers', None)
29
32
  self.kwargs = kwargs
30
33
 
31
34
  def __call__(self, url, options=None) -> RemoteDocument:
@@ -56,12 +59,12 @@ class RequestsDocumentLoader(DocumentLoader):
56
59
  'the URL\'s scheme is not "https".',
57
60
  'jsonld.InvalidUrl', {'url': url},
58
61
  code='loading document failed')
59
- headers = options.get('headers')
62
+ headers = options.get('headers', self.headers)
60
63
  if headers is None:
61
64
  headers = {
62
65
  'Accept': 'application/ld+json, application/json'
63
66
  }
64
- response = self.requests.get(url, headers=headers, **self.kwargs)
67
+ response = self.session.get(url, headers=headers, **self.kwargs)
65
68
 
66
69
  content_type = response.headers.get('content-type')
67
70
  if not content_type:
@@ -0,0 +1,55 @@
1
+ """
2
+ SQLite-backed HTTP cache document loader using requests-cache.
3
+
4
+ .. module:: jsonld.documentloader.requests_sqlite_cache
5
+ :synopsis: Persistent SQLite HTTP caching for Requests document loader
6
+ """
7
+ from pathlib import Path
8
+
9
+ from pyld.documentloader.base import DocumentLoader, RemoteDocument
10
+ from pyld.documentloader.requests import RequestsDocumentLoader
11
+
12
+
13
+ def _resolve_sqlite_file_path(sqlite_file_path: Path | None) -> Path:
14
+ """Return absolute path to the SQLite cache file."""
15
+ from platformdirs import user_cache_dir
16
+
17
+ if sqlite_file_path is None:
18
+ return (Path(user_cache_dir('pyld')) / 'http_cache.sqlite').resolve()
19
+ path = Path(sqlite_file_path).expanduser()
20
+ if not path.is_absolute():
21
+ raise ValueError(
22
+ 'sqlite_file_path must be an absolute path to the .sqlite file')
23
+ return path.resolve()
24
+
25
+
26
+ class SqliteCacheRequestsDocumentLoader(DocumentLoader):
27
+ """Remote document loader with persistent SQLite HTTP caching.
28
+
29
+ :param secure: require all requests to use HTTPS (default: False).
30
+ :param sqlite_file_path: absolute path to the ``.sqlite`` cache file; when
31
+ omitted, defaults to the platform user cache directory under ``pyld/``.
32
+ """
33
+
34
+ def __init__(
35
+ self,
36
+ secure: bool = False,
37
+ *,
38
+ sqlite_file_path: Path | None = None,
39
+ ):
40
+ from requests_cache import CachedSession
41
+
42
+ path = _resolve_sqlite_file_path(sqlite_file_path)
43
+ self.session = CachedSession(
44
+ cache_name=str(path),
45
+ backend='sqlite',
46
+ cache_control=True,
47
+ # Cache JSON-LD contexts persistently by default; Cache-Control and
48
+ # related response headers still override this when present.
49
+ expire_after=-1,
50
+ )
51
+ self._loader = RequestsDocumentLoader(
52
+ secure=secure, session=self.session)
53
+
54
+ def __call__(self, url, options=None) -> RemoteDocument:
55
+ return self._loader(url, options=options)