aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/referencing/retrieval.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/referencing/retrieval.py')
-rw-r--r--.venv/lib/python3.12/site-packages/referencing/retrieval.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/referencing/retrieval.py b/.venv/lib/python3.12/site-packages/referencing/retrieval.py
new file mode 100644
index 00000000..53e0512b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/referencing/retrieval.py
@@ -0,0 +1,92 @@
+"""
+Helpers related to (dynamic) resource retrieval.
+"""
+
+from __future__ import annotations
+
+from functools import lru_cache
+from typing import TYPE_CHECKING, Callable
+import json
+
+try:
+ from typing_extensions import TypeVar
+except ImportError: # pragma: no cover
+ from typing import TypeVar
+
+from referencing import Resource
+
+if TYPE_CHECKING:
+ from referencing.typing import URI, D, Retrieve
+
+#: A serialized document (e.g. a JSON string)
+_T = TypeVar("_T", default=str)
+
+
+def to_cached_resource(
+ cache: Callable[[Retrieve[D]], Retrieve[D]] | None = None,
+ loads: Callable[[_T], D] = json.loads,
+ from_contents: Callable[[D], Resource[D]] = Resource.from_contents,
+) -> Callable[[Callable[[URI], _T]], Retrieve[D]]:
+ """
+ Create a retriever which caches its return values from a simpler callable.
+
+ Takes a function which returns things like serialized JSON (strings) and
+ returns something suitable for passing to `Registry` as a retrieve
+ function.
+
+ This decorator both reduces a small bit of boilerplate for a common case
+ (deserializing JSON from strings and creating `Resource` objects from the
+ result) as well as makes the probable need for caching a bit easier.
+ Retrievers which otherwise do expensive operations (like hitting the
+ network) might otherwise be called repeatedly.
+
+ Examples
+ --------
+
+ .. testcode::
+
+ from referencing import Registry
+ from referencing.typing import URI
+ import referencing.retrieval
+
+
+ @referencing.retrieval.to_cached_resource()
+ def retrieve(uri: URI):
+ print(f"Retrieved {uri}")
+
+ # Normally, go get some expensive JSON from the network, a file ...
+ return '''
+ {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "foo": "bar"
+ }
+ '''
+
+ one = Registry(retrieve=retrieve).get_or_retrieve("urn:example:foo")
+ print(one.value.contents["foo"])
+
+ # Retrieving the same URI again reuses the same value (and thus doesn't
+ # print another retrieval message here)
+ two = Registry(retrieve=retrieve).get_or_retrieve("urn:example:foo")
+ print(two.value.contents["foo"])
+
+ .. testoutput::
+
+ Retrieved urn:example:foo
+ bar
+ bar
+
+ """
+ if cache is None:
+ cache = lru_cache(maxsize=None)
+
+ def decorator(retrieve: Callable[[URI], _T]):
+ @cache
+ def cached_retrieve(uri: URI):
+ response = retrieve(uri)
+ contents = loads(response)
+ return from_contents(contents)
+
+ return cached_retrieve
+
+ return decorator