|
| 1 | +""" |
| 2 | +Jupytext converter with a small on-disk cache for docs builds. |
| 3 | +""" |
| 4 | + |
| 5 | +import hashlib |
| 6 | +import os |
| 7 | +from pathlib import Path |
| 8 | + |
| 9 | +import jupytext |
| 10 | +import nbformat |
| 11 | + |
| 12 | + |
| 13 | +def _get_cache_dir(): |
| 14 | + """ |
| 15 | + Return cache directory for converted jupytext notebooks. |
| 16 | + """ |
| 17 | + override = os.environ.get("UPLT_DOCS_JUPYTEXT_CACHE_DIR", "").strip() |
| 18 | + if override: |
| 19 | + return Path(override).expanduser() |
| 20 | + if os.environ.get("READTHEDOCS", "") == "True": |
| 21 | + return Path.home() / ".cache" / "ultraplot" / "jupytext" |
| 22 | + return Path(__file__).resolve().parent.parent / "_build" / ".jupytext-cache" |
| 23 | + |
| 24 | + |
| 25 | +def reads_cached(inputstring, *, fmt="py:percent"): |
| 26 | + """ |
| 27 | + Convert Jupytext source to a notebook and cache by content hash. |
| 28 | + """ |
| 29 | + disabled = os.environ.get("UPLT_DOCS_DISABLE_JUPYTEXT_CACHE", "").strip().lower() |
| 30 | + if disabled in {"1", "true", "yes", "on"}: |
| 31 | + return jupytext.reads(inputstring, fmt=fmt) |
| 32 | + |
| 33 | + key = hashlib.sha256( |
| 34 | + (fmt + "\0" + getattr(jupytext, "__version__", "") + "\0" + inputstring).encode( |
| 35 | + "utf-8" |
| 36 | + ) |
| 37 | + ).hexdigest() |
| 38 | + cache_file = _get_cache_dir() / f"{key}.ipynb" |
| 39 | + if cache_file.is_file(): |
| 40 | + try: |
| 41 | + return nbformat.read(cache_file, as_version=4) |
| 42 | + except Exception: |
| 43 | + cache_file.unlink(missing_ok=True) |
| 44 | + |
| 45 | + notebook = jupytext.reads(inputstring, fmt=fmt) |
| 46 | + try: |
| 47 | + cache_file.parent.mkdir(parents=True, exist_ok=True) |
| 48 | + nbformat.write(notebook, cache_file) |
| 49 | + except Exception: |
| 50 | + pass |
| 51 | + return notebook |
0 commit comments