Cap import_netlist inline response size for large netlists
Netlists exceeding INLINE_RESULT_THRESHOLD (20 nets) now return a compact summary with the top nets by connection count as a preview. Full data is always written to the sidecar JSON file. Small netlists still return everything inline.
This commit is contained in:
parent
a129b292e4
commit
003749fe3e
@ -15,6 +15,7 @@ import re
|
||||
from typing import Any
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from mckicad.config import INLINE_RESULT_THRESHOLD
|
||||
from mckicad.server import mcp
|
||||
from mckicad.utils.file_utils import write_detail_file
|
||||
|
||||
@ -405,14 +406,7 @@ def import_netlist(
|
||||
stats["net_count"], stats["component_count"], stats["connection_count"],
|
||||
)
|
||||
|
||||
result: dict[str, Any] = {
|
||||
"success": True,
|
||||
"format_detected": fmt,
|
||||
"source_path": source_path,
|
||||
**parsed,
|
||||
}
|
||||
|
||||
# Write output JSON
|
||||
# Write full parsed data to output JSON (always — this is the complete data)
|
||||
if output_path:
|
||||
out = os.path.abspath(os.path.expanduser(output_path))
|
||||
os.makedirs(os.path.dirname(out) or ".", exist_ok=True)
|
||||
@ -423,6 +417,31 @@ def import_netlist(
|
||||
source_path, "imported_netlist.json", parsed,
|
||||
)
|
||||
|
||||
result["output_path"] = out
|
||||
result: dict[str, Any] = {
|
||||
"success": True,
|
||||
"format_detected": fmt,
|
||||
"source_path": source_path,
|
||||
"output_path": out,
|
||||
"statistics": stats,
|
||||
}
|
||||
|
||||
nets = parsed["nets"]
|
||||
if stats["net_count"] <= INLINE_RESULT_THRESHOLD:
|
||||
# Small netlist — return everything inline
|
||||
result["nets"] = nets
|
||||
result["components"] = parsed["components"]
|
||||
if "pin_metadata" in parsed:
|
||||
result["pin_metadata"] = parsed["pin_metadata"]
|
||||
else:
|
||||
# Large netlist — compact summary inline, full data in output file
|
||||
# Sort nets by connection count (most connected first) for useful preview
|
||||
sorted_nets = sorted(nets.items(), key=lambda kv: len(kv[1]), reverse=True)
|
||||
result["nets_preview"] = dict(sorted_nets[:INLINE_RESULT_THRESHOLD])
|
||||
result["nets_preview_note"] = (
|
||||
f"Showing top {INLINE_RESULT_THRESHOLD} of {stats['net_count']} nets "
|
||||
f"by connection count. Full data in output_path."
|
||||
)
|
||||
# Include component count but not full component dict
|
||||
result["component_refs"] = sorted(parsed["components"].keys())
|
||||
|
||||
return result
|
||||
|
||||
@ -430,3 +430,83 @@ class TestOutputFile:
|
||||
assert result["success"] is True
|
||||
assert "output_path" in result
|
||||
assert os.path.isfile(result["output_path"])
|
||||
|
||||
def test_large_netlist_returns_preview(self, tmp_output_dir):
|
||||
"""Netlists exceeding INLINE_RESULT_THRESHOLD return a preview, not full data."""
|
||||
from mckicad.config import INLINE_RESULT_THRESHOLD
|
||||
from mckicad.tools.netlist import import_netlist
|
||||
|
||||
# Generate a netlist with more nets than the threshold
|
||||
net_count = INLINE_RESULT_THRESHOLD + 5
|
||||
net_lines = []
|
||||
comp_lines = []
|
||||
refs_seen: set[str] = set()
|
||||
for i in range(1, net_count + 1):
|
||||
ref_a = f"R{i}"
|
||||
ref_b = f"C{i}"
|
||||
comp_lines.append(f'<comp ref="{ref_a}"><value>{i}k</value></comp>')
|
||||
comp_lines.append(f'<comp ref="{ref_b}"><value>{i}00nF</value></comp>')
|
||||
refs_seen.update([ref_a, ref_b])
|
||||
net_lines.append(
|
||||
f'<net code="{i}" name="NET{i}">'
|
||||
f'<node ref="{ref_a}" pin="1"/>'
|
||||
f'<node ref="{ref_b}" pin="2"/>'
|
||||
f'</net>'
|
||||
)
|
||||
|
||||
xml = (
|
||||
'<export version="D"><components>'
|
||||
+ "".join(comp_lines)
|
||||
+ "</components><nets>"
|
||||
+ "".join(net_lines)
|
||||
+ "</nets></export>"
|
||||
)
|
||||
src = os.path.join(tmp_output_dir, "large.xml")
|
||||
with open(src, "w") as f:
|
||||
f.write(xml)
|
||||
|
||||
result = import_netlist(source_path=src)
|
||||
assert result["success"] is True
|
||||
assert result["statistics"]["net_count"] == net_count
|
||||
|
||||
# Should NOT have full nets inline
|
||||
assert "nets" not in result
|
||||
# Should have preview
|
||||
assert "nets_preview" in result
|
||||
assert len(result["nets_preview"]) == INLINE_RESULT_THRESHOLD
|
||||
assert "nets_preview_note" in result
|
||||
|
||||
# Should have component refs list instead of full component dict
|
||||
assert "component_refs" in result
|
||||
assert "components" not in result
|
||||
|
||||
# Full data should be in the output file
|
||||
assert os.path.isfile(result["output_path"])
|
||||
with open(result["output_path"]) as f:
|
||||
full_data = json.load(f)
|
||||
assert len(full_data["nets"]) == net_count
|
||||
|
||||
def test_small_netlist_returns_inline(self, tmp_output_dir):
|
||||
"""Netlists within INLINE_RESULT_THRESHOLD return full data inline."""
|
||||
from mckicad.tools.netlist import import_netlist
|
||||
|
||||
xml = textwrap.dedent("""\
|
||||
<export version="D">
|
||||
<components><comp ref="R1"><value>1k</value></comp></components>
|
||||
<nets>
|
||||
<net code="1" name="GND"><node ref="R1" pin="2"/></net>
|
||||
</nets>
|
||||
</export>
|
||||
""")
|
||||
src = os.path.join(tmp_output_dir, "small.xml")
|
||||
with open(src, "w") as f:
|
||||
f.write(xml)
|
||||
|
||||
result = import_netlist(source_path=src)
|
||||
assert result["success"] is True
|
||||
# Should have full data inline
|
||||
assert "nets" in result
|
||||
assert "components" in result
|
||||
# Should NOT have preview keys
|
||||
assert "nets_preview" not in result
|
||||
assert "component_refs" not in result
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user