46 lines
1.3 KiB
Python
46 lines
1.3 KiB
Python
"""Thin wrapper around the pybind11 engine module (`bindings/python/`).
|
|||
|
|
|
||
|
|
The wrapper exists so routers depend on this module, not on the pybind11
|
||
|
|
import directly. That keeps routers testable when the engine is absent
|
||
|
|
(Phase 0) and gives us one place to translate engine error types into
|
||
|
|
HTTP responses later.
|
||
|
|
|
||
|
|
The pybind11 module is not built yet; importing it is expected to fail
|
||
|
|
in Phase 0. `is_available()` is the public probe.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
_engine: Any | None = None
|
||
|
|
_import_error: Exception | None = None
|
||
|
|
|
||
|
|
|
||
|
|
def _try_import() -> None:
|
||
|
|
global _engine, _import_error
|
||
|
|
if _engine is not None or _import_error is not None:
|
||
|
|
return
|
||
|
|
try:
|
||
|
|
import pdfengine as _mod # type: ignore[import-not-found]
|
||
|
|
|
||
|
|
_engine = _mod
|
||
|
|
except ImportError as exc:
|
||
|
|
_import_error = exc
|
||
|
|
|
||
|
|
|
||
|
|
def is_available() -> bool:
|
||
|
|
_try_import()
|
||
|
|
return _engine is not None
|
||
|
|
|
||
|
|
|
||
|
|
def require() -> Any:
|
||
|
|
"""Return the engine module or raise — callers should prefer ``is_available``
|
||
|
|
and return 501 themselves so the error surface is consistent."""
|
||
|
|
_try_import()
|
||
|
|
if _engine is None:
|
||
|
|
raise RuntimeError(
|
||
|
|
"pdfengine pybind11 module is not built — see bindings/python/."
|
||
|
|
) from _import_error
|
||
|
|
return _engine
|