feat(pid): pid_from_spec — a whole P&ID in one transaction, graph and critique returned
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
6aded6bbf0
commit
d80ae17411
@@ -0,0 +1,61 @@
|
||||
"""Render the P&ID the README shows, using only the server's own tools.
|
||||
|
||||
The sheet is ``EXAMPLE_SPEC`` from ``engineering/pid/spec.py`` -- the same
|
||||
document ``pid_from_spec`` draws in one transaction -- placed and routed
|
||||
through the same backend methods the MCP tools call, then rendered headlessly.
|
||||
If a symbol builder or the router regresses, the picture changes with it.
|
||||
|
||||
Reproduce:
|
||||
|
||||
AUTOCAD_MCP_BACKEND=ezdxf uv run --frozen python scripts/render_readme_pid.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
DEFAULT_OUTPUT = ROOT / "docs" / "assets" / "pid-showcase.png"
|
||||
|
||||
|
||||
async def render(output: Path) -> dict:
|
||||
from backends.ezdxf_backend import EzdxfBackend
|
||||
from engineering.layers import apply_layer_set
|
||||
from engineering.pid.spec import EXAMPLE_SPEC, run_spec
|
||||
|
||||
backend = EzdxfBackend()
|
||||
await backend.connect()
|
||||
try:
|
||||
await backend.drawing_new()
|
||||
await apply_layer_set(backend, "pid")
|
||||
result = await run_spec(backend, EXAMPLE_SPEC)
|
||||
png = await backend.view_screenshot()
|
||||
if not png:
|
||||
raise RuntimeError("view_screenshot returned no PNG (is matplotlib installed?)")
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
output.write_bytes(png)
|
||||
return {
|
||||
"output": str(output),
|
||||
"bytes": len(png),
|
||||
"dangling": result["graph"]["stats"]["dangling"],
|
||||
"critique": len(result["critique"]),
|
||||
}
|
||||
finally:
|
||||
await backend.disconnect()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
|
||||
args = parser.parse_args()
|
||||
print(asyncio.run(render(args.output)))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user