Files
FreeCADWasmDev/tools/generate_python_api_runtime_evidence.py
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

71 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Index native Python API names from passing P6 runtime evidence."""
from __future__ import annotations
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
P6 = ROOT / "docs/p6"
OUT = P6 / "python-api-runtime-evidence.json"
def names(value):
if isinstance(value, str):
return [item.strip() for item in value.replace("\n", ",").split(",") if item.strip()]
if isinstance(value, list):
return [str(item).strip() for item in value if str(item).strip()]
if isinstance(value, dict):
result = []
for item in value.values():
result.extend(names(item))
return result
return []
evidence = {}
for path in sorted(P6.glob("*.json")):
try:
report = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
continue
result_value = report.get("result", report.get("status"))
if not isinstance(result_value, str) or result_value not in {"pass", "passed", "completed"}:
continue
action = report.get("action")
explicit_python = action == "python-api" or "python" in path.stem.lower()
if not explicit_python:
continue
module = report.get("module")
if not isinstance(module, str) or not module:
stem = path.stem.lower()
inferred = [("openscad", "OpenSCAD"), ("meshpart", "MeshPart"), ("points", "Points"), ("sketcher", "Sketcher"), ("techdraw", "TechDraw"), ("robot", "Robot"), ("measure", "Measure"), ("surface", "Surface"), ("spreadsheet", "Spreadsheet"), ("inspection", "Inspection"), ("sandbox", "Sandbox")]
module = next((value for token, value in inferred if token in stem), None)
if not isinstance(module, str) or not module:
continue
found = []
def walk(value, key=""):
if isinstance(value, dict):
for child_key, child in value.items():
if child_key.lower() in {"apinames", "pythonapi", "pythonapinames", "api_names"}:
found.extend(names(child))
walk(child, child_key)
elif isinstance(value, list):
for child in value:
walk(child, key)
walk(report)
for name in found:
normalized = name.strip()
if normalized:
key = f"{module}:{normalized}"
evidence.setdefault(key, []).append(str(path.relative_to(ROOT)))
report = {
"schema": "freecad-web-python-api-runtime-evidence/v1",
"policy": "only passing python-api-named runtime artifacts are indexed; source-only inventory is excluded",
"names": [{"module": key.split(":", 1)[0], "name": key.split(":", 1)[1], "artifacts": sorted(set(paths))} for key, paths in sorted(evidence.items())],
"count": len(evidence),
}
OUT.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(json.dumps({"output": str(OUT.relative_to(ROOT)), "names": len(evidence)}, ensure_ascii=False))