"""ANSYS Mechanical 2024 R2 declarative geometry-inspection adapter.""" from __future__ import annotations import json import os import sys from importlib.metadata import version from pathlib import Path from typing import Any sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from ansys_geometry import ( # noqa: E402 ANSYS_REVISION, EXECUTION_GATE, artifact_manifest, atomic_json, export_geometry_image, file_sha256, geometry_inventory, import_geometry, input_file, probe, terminal, validate_artifact, ) ADAPTER_VERSION = "0.3.0" _ARTIFACTS = { "geometry-manifest.json": ("geometry_manifest", "application/json"), "geometry-preview.png": ("geometry_preview", "image/png"), "provenance.json": ("provenance", "application/json"), } def _validate_semantics(request: dict[str, Any]) -> None: inspect = request["operation"]["inspect"] input_keys = {item["key"] for item in request["inputs"]} if inspect["geometry"]["input"] not in input_keys: raise ValueError("GEOMETRY_INPUT_NOT_BOUND") if request["outputs"]: raise ValueError("INSPECT_OUTPUTS_MUST_BE_EMPTY") def _load_request(job_dir: Path) -> dict[str, Any]: record = json.loads( (job_dir / "request" / "request.json").read_text(encoding="utf-8") ) request = record.get("request") if not isinstance(request, dict): raise TypeError("JOB_REQUEST_MISSING") _validate_semantics(request) return record def run(job_dir: Path) -> list[dict[str, Any]]: job_dir = job_dir.resolve(strict=True) record = _load_request(job_dir) request = record["request"] inspect = request["operation"]["inspect"] geometry = input_file(job_dir, inspect["geometry"]["input"]) output = job_dir / "output" output.mkdir(exist_ok=True) from ansys.mechanical.core import App software_version: int | None = None manifest_path = output / "geometry-manifest.json" preview_path = output / "geometry-preview.png" with App(version=ANSYS_REVISION, private_appdata=True) as app: software_version = app.version api: dict[str, Any] = {} app.update_globals(api) import_geometry(app, api, geometry) inventory, _ = geometry_inventory(app) inventory.update( { "title": inspect["title"], "software": "ANSYS Mechanical", "software_version": software_version, } ) atomic_json(manifest_path, inventory) export_geometry_image(app, api, preview_path) provenance_path = output / "provenance.json" atomic_json( provenance_path, { "adapter_version": ADAPTER_VERSION, "pymechanical_version": version("ansys-mechanical-core"), "ansys_revision": ANSYS_REVISION, "request_digest": record["request_digest"], "input": { "key": inspect["geometry"]["input"], "filename": geometry.name, "sha256": file_sha256(geometry), }, }, ) paths = [manifest_path, preview_path, provenance_path] for path in paths: validate_artifact(path) return [artifact_manifest(path, _ARTIFACTS) for path in paths] def main() -> int: if sys.argv[1:] == ["--probe"]: return probe(ADAPTER_VERSION) if len(sys.argv) != 2: print("[ERR] Usage: worker.py ", file=sys.stderr) return 2 job_dir = Path(sys.argv[1]) record: dict[str, Any] = {} try: record = _load_request(job_dir) if os.environ.get(EXECUTION_GATE) != "1": raise RuntimeError("ANSYS_242_REAL_LICENSE_ACCEPTANCE_REQUIRED") artifacts = run(job_dir) atomic_json(job_dir / "artifacts.json", artifacts) atomic_json(job_dir / "terminal.json", terminal(record, "succeeded", artifacts, {})) print("[OK] ANSYS Mechanical geometry inspection completed.") return 0 except Exception as exc: # noqa: BLE001 - terminal.json must capture vendor failures atomic_json( job_dir / "terminal.json", terminal( record, "failed", [], {"code": type(exc).__name__, "detail": str(exc)[:500]}, ), ) print(f"[ERR] {type(exc).__name__}: {exc}", file=sys.stderr) return 1 if __name__ == "__main__": raise SystemExit(main())