Files
wehub-resource-sync 0ef5fcb1c5
Security / Dependency audit (pip-audit) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
Security / CodeQL (python) (push) Has been cancelled
Security / Secret scan (gitleaks) (push) Has been cancelled
rust / test (ubuntu) (push) Has been cancelled
rust / simulator e2e (macos-latest) (push) Has been cancelled
rust / simulator e2e (ubuntu-latest) (push) Has been cancelled
rust / simulator e2e (windows-latest) (push) Has been cancelled
rust / wheels (aarch64-apple-darwin) (push) Has been cancelled
rust / wheels (x86_64-unknown-linux-gnu) (push) Has been cancelled
rust / wheels (x86_64-apple-darwin) (push) Has been cancelled
rust / audit (push) Has been cancelled
rust / parity (nightly, allowed to fail during Phase 0) (push) Has been cancelled
CI / commitlint (push) Has been skipped
Dev Containers / validate (.devcontainer/devcontainer.json, default) (push) Failing after 0s
Dev Containers / validate (.devcontainer/memory-stack/devcontainer.json, memory-stack) (push) Failing after 0s
Dev Containers / validate-worktree (push) Failing after 0s
CI / changes (push) Failing after 4s
Deploy Documentation / validate (push) Has been skipped
Deploy Documentation / deploy (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, claude) (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, codex) (push) Failing after 1s
Install Native E2E / install-native (ubuntu-latest) (push) Failing after 1s
OpenCode Plugin / typecheck + build + test (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, copilot) (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
Wrap E2E / docker-wrap-e2e (push) Failing after 1s
Wrap Native E2E / wrap-native (ubuntu-latest) (push) Failing after 1s
Init E2E / docker-init-e2e (push) Failing after 4s
Merge Conflicts / merge-conflicts (push) Failing after 4s
CI / lint (push) Has been cancelled
CI / build-wheel (push) Has been cancelled
CI / build-wheel-windows (push) Has been cancelled
CI / prefetch-model (push) Has been cancelled
CI / test-dashboard-ui (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test-extras (push) Has been cancelled
CI / test-agno (push) Has been cancelled
CI / build (push) Has been cancelled
CI / workflow-validation (push) Has been cancelled
CI / docker-native-e2e (push) Has been cancelled
CI / windows-native-wrapper (push) Has been cancelled
CI / macos-native-wrapper (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / promote-latest (push) Has been cancelled
Init Native E2E / init-native (macos-latest, claude) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, codex) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, copilot) (push) Has been cancelled
Install Native E2E / install-native (macos-latest) (push) Has been cancelled
Wrap Native E2E / wrap-native (macos-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:03:20 +08:00

129 lines
4.8 KiB
Python

"""Pin the ONNX Runtime dylib for the Rust core on dynamic-ORT platforms.
Why this module exists
----------------------
On Windows and Intel macOS (``x86_64-apple-darwin``), ``headroom._core``
consumers of the ``ort`` crate (magika content detection, fastembed
embeddings) are built with ``ort-load-dynamic``: the native ONNX Runtime
library is resolved at *runtime*.
Windows: unless ``ORT_DYLIB_PATH`` is set, ort falls back to a bare
``LoadLibrary("onnxruntime.dll")`` and the Windows DLL search order
applies — and ``C:\\Windows\\System32`` wins. Windows 11 24H2+ ships
``System32\\onnxruntime.dll`` as part of Windows ML (observed:
1.17.2603 "os-germanium"). Initializing an ort 2.x session against that
OS build does not fail — it deadlocks indefinitely at 0% CPU, which the
tiered detection fallback cannot catch (a hang is not an ``Err``).
Reproduced and bracketed with ``scripts/diag_magika_windows.py``: the
identical session inits in ~400ms when ``ORT_DYLIB_PATH`` points at the
``onnxruntime`` pip package's DLL (which ``headroom-ai[proxy]`` already
depends on).
Intel macOS: ``ort-sys 2.0.0-rc.12`` does not ship prebuilt ONNX Runtime
binaries for ``x86_64-apple-darwin``, so the wheel/sdist build uses
``ort-load-dynamic`` and expects a pip-installed ``onnxruntime`` dylib
at runtime (same contract as Windows).
The fix: before anything can import ``headroom._core``, resolve the
pip-installed ``onnxruntime`` native library and export it via
``ORT_DYLIB_PATH``. ``headroom/__init__.py`` calls this hook, which
guarantees ordering for every package-level consumer.
Behavior contract
-----------------
- Active on Windows and Intel macOS only; a no-op elsewhere.
- Respects a pre-set ``ORT_DYLIB_PATH`` (user override wins).
- Locates the ``onnxruntime`` package via ``find_spec`` WITHOUT
importing it (importing would load its native code; this hook must
stay ~microseconds and side-effect free).
- Never raises: import-time failure of an optional accelerator must
not break ``import headroom``. Without a pin, detection still
degrades gracefully through HEADROOM_MAGIKA_INIT_TIMEOUT_SECS and
the non-ML tiers.
"""
from __future__ import annotations
import importlib.util
import logging
import os
import platform
import sys
from pathlib import Path
logger = logging.getLogger(__name__)
_ENV_VAR = "ORT_DYLIB_PATH"
# Tri-state module cache: unset sentinel / resolved path / None (no pin).
_UNSET = object()
_pinned: object = _UNSET
def ensure_ort_dylib_pinned() -> str | None:
"""Export ``ORT_DYLIB_PATH`` for the Rust core's ort runtime.
Returns the effective dylib path (pinned now or already present in
the environment), or ``None`` when no pin applies (platforms that
bundle ORT at build time, or no ``onnxruntime`` package to point at).
Idempotent and exception-free.
"""
global _pinned
if _pinned is not _UNSET:
return _pinned # type: ignore[return-value]
_pinned = _resolve_and_pin()
return _pinned # type: ignore[return-value]
def _needs_ort_dylib_pin() -> bool:
if sys.platform.startswith("win"):
return True
return sys.platform == "darwin" and platform.machine() == "x86_64"
def _resolve_ort_native_library(capi_dir: Path) -> Path | None:
if sys.platform.startswith("win"):
candidate = capi_dir / "onnxruntime.dll"
return candidate if candidate.is_file() else None
matches = sorted(capi_dir.glob("libonnxruntime*.dylib"))
return matches[0] if matches else None
def _resolve_and_pin() -> str | None:
if not _needs_ort_dylib_pin():
return None
try:
existing = os.environ.get(_ENV_VAR)
if existing:
logger.debug("%s already set; respecting user override: %s", _ENV_VAR, existing)
return existing
spec = importlib.util.find_spec("onnxruntime")
if spec is None or not spec.origin:
logger.debug(
"onnxruntime package not found; %s left unset. Rust ML detection "
"needs a pip-installed onnxruntime on this platform (install "
"headroom-ai[proxy] or set %s explicitly).",
_ENV_VAR,
_ENV_VAR,
)
return None
native = _resolve_ort_native_library(Path(spec.origin).parent / "capi")
if native is None:
logger.debug(
"onnxruntime package found but no native library under %s; %s left unset",
Path(spec.origin).parent / "capi",
_ENV_VAR,
)
return None
os.environ[_ENV_VAR] = str(native)
logger.info("Pinned %s to bundled ONNX Runtime: %s", _ENV_VAR, native)
return str(native)
except Exception as exc: # never break `import headroom` over an accelerator pin
logger.debug("ort dylib pin skipped: %s: %s", type(exc).__name__, exc)
return None