Core KiCad parser, round-trip, and 2D rendering tooling
Project description
KiCad Monkey
▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓░░░░░░▓▓░░░░░░▓▓▓▓
░░░░▓▓░░░░░░░░░░░░░░░░░░▓▓░░░░
░░░░▓▓░░ ░░░░░░ ░░▓▓░░░░
░░▓▓░░ ██░░░░░░ ██░░▓▓░░
▓▓░░░░░░░░░░░░░░░░░░▓▓
▓▓░░░░░░░░░░░░░░▓▓
▓▓▓▓░░░░░░▓▓▓▓
░░ ▓▓▓▓▓▓
▓▓ ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓░░▓▓░░▓▓▓▓
kicad_monkey is a focused Python package for KiCad source-file parsing,
round-trip modeling, close-to-format utilities, and IR-backed 2D rendering.
Use it when you need Python code to inspect or modify KiCad files directly:
- read
.kicad_pro,.kicad_sch,.kicad_pcb,.kicad_sym, and.kicad_modfiles; - query schematic and PCB objects through typed model facades;
- compile KiCad-native design netlists and design JSON;
- render schematic, PCB, symbol, and footprint views through plotter IR and SVG;
- make focused model edits, then write KiCad files back out.
This package is the low-level parser/model/rendering library. Larger workflow commands and application orchestration should live in downstream packages.
Install
For library use inside an existing Python environment:
pip install kicad-monkey
For development:
git clone https://github.com/wavenumber-eng/kicad_monkey.git
cd kicad_monkey
uv sync --extra test
Quick Examples
Load A Design And Inspect Nets
from kicad_monkey import KiCadDesign
design = KiCadDesign.from_project_file("hardware/demo.kicad_pro")
netlist = design.to_netlist()
for net in netlist.nets:
terminals = ", ".join(
f"{terminal.designator}.{terminal.pin}"
for terminal in net.terminals
)
print(f"{net.name}: {terminals}")
Save the KiCad-native design JSON used by higher-level review tools:
design.save_json("build/design.json")
Render PCB SVG
from pathlib import Path
from kicad_monkey import KiCadDesign
design = KiCadDesign.from_project_file("hardware/demo.kicad_pro")
out_dir = Path("build/svg")
out_dir.mkdir(parents=True, exist_ok=True)
svg = design.to_pcb_svg(
layers=["Edge.Cuts", "F.Cu", "F.SilkS"],
profile="enriched",
)
(out_dir / "front-copper.svg").write_text(svg, encoding="utf-8")
Use profile="oracle" when comparing against KiCad CLI output. Use
profile="enriched" when an app needs metadata on SVG elements.
Render Every Schematic Sheet Instance
Hierarchical designs can instantiate one .kicad_sch file more than once.
KiCadSchematicInstance represents each concrete sheet view.
from pathlib import Path
from kicad_monkey import KiCadDesign, render_ir_to_svg
design = KiCadDesign.from_project_file("hardware/demo.kicad_pro")
out_dir = Path("build/schematic-svg")
out_dir.mkdir(parents=True, exist_ok=True)
for sheet in design.schematic_instances():
doc = design.to_schematic_instance_ir(sheet)
svg = render_ir_to_svg(doc)
safe_name = sheet.sheet_name.replace("/", "_").replace("\\", "_")
(out_dir / f"{sheet.instance_index:02d}_{safe_name}.svg").write_text(
svg,
encoding="utf-8",
)
To find where a reused child schematic appears:
for instance in design.schematic_instances_for("hardware/LED_Controller.kicad_sch"):
print(instance.sheet_name, instance.sheet_path, instance.sheet_instance_path)
Query And Mutate Schematic Objects
The .objects property is a live read-only query view over model-owned
objects. Mutate the returned objects, then call save().
from kicad_monkey import KiCadSchematic
schematic = KiCadSchematic.from_file("hardware/demo.kicad_sch")
for symbol in schematic.objects.where("SchSymbol"):
if symbol.reference.startswith("R"):
symbol.set_property_value("Value", "10 kOhm")
for label in schematic.objects.where("SchLabel"):
if label.effects is not None and label.effects.font is not None:
label.effects.font.size_x = 1.5
label.effects.font.size_y = 1.5
schematic.save("hardware/demo.edited.kicad_sch")
Query And Mutate PCB Objects
from kicad_monkey import KiCadPcb
board = KiCadPcb.from_file("hardware/demo.kicad_pcb")
for footprint in board.objects.where("Footprint"):
reference = footprint.get_property_value("Reference")
if reference.startswith("U"):
footprint.set_property_value("Reviewed", "yes", create=True)
for text in board.objects.where("GrText", layer="F.SilkS"):
text.effects.font.size_x = 1.0
text.effects.font.size_y = 1.0
text.text = text.text.strip()
board.save("hardware/demo.edited.kicad_pcb")
Object queries also work with class objects when you prefer typed imports:
from kicad_monkey import Footprint, KiCadPcb
board = KiCadPcb.from_file("hardware/demo.kicad_pcb")
connectors = [
footprint
for footprint in board.objects.where(Footprint)
if footprint.get_property_value("Reference").startswith("J")
]
Testing
Rack is the primary public gate:
uv run --extra test python tests/rack.py run L0_foundation
uv run --extra test python tests/rack.py run L99_signoff
L99_signoff checks release metadata, changelog coverage, public API contract
resolution, API design-doc ownership, Rack test ownership, corpus archive
hygiene, and the current ruff/pyright ratchet state.
The redistributable KiCad corpus is transported as tests/corpus/kicad.zip.
The loose mirror is ignored locally; test helpers extract it on demand when no
external corpus is configured.
API Shape
Stable package-root exports are recorded in
kicad_monkey.kicad_api_contract. Those names are the public API that
downstream code should rely on. The broader package __all__ remains a
discovery surface while downstream integrations prove which additional symbols
should become stable public exports.
The public OOP facade groups and supporting public classes are documented under docs/design/api. L99 fails when a stable public class or major interface is missing design documentation or Rack test ownership.
Typical entrypoints:
from kicad_monkey import KiCadDesign, KiCadFootprint, KiCadPcb, KiCadSchematic
from kicad_monkey import KiCadSymbolLib
schematic = KiCadSchematic.from_file("design.kicad_sch")
board = KiCadPcb.from_file("board.kicad_pcb")
design = KiCadDesign.from_project_file("project.kicad_pro")
symbols = KiCadSymbolLib.from_file("library.kicad_sym")
footprint = KiCadFootprint.from_file("package.kicad_mod")
Fixture Model
Public fixtures should be redistributable and package-local when possible. Broader fixture families should use this shape:
input/reference_output/output/
output/ is transient and should stay local or temporary.
Documentation
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kicad_monkey-2026.6.18.tar.gz.
File metadata
- Download URL: kicad_monkey-2026.6.18.tar.gz
- Upload date:
- Size: 3.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95a4cdb9f5feb9e7f1839dcc24199645b12bab8cbe81c9da1a008155741419d0
|
|
| MD5 |
85e61330812df2a7961a0307856f0870
|
|
| BLAKE2b-256 |
549697461f2ad2cbad37d61873c64f92e02c0aa57b06767d08423d65e0c06e08
|
Provenance
The following attestation bundles were made for kicad_monkey-2026.6.18.tar.gz:
Publisher:
release.yml on wavenumber-eng/kicad_monkey
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kicad_monkey-2026.6.18.tar.gz -
Subject digest:
95a4cdb9f5feb9e7f1839dcc24199645b12bab8cbe81c9da1a008155741419d0 - Sigstore transparency entry: 1864410605
- Sigstore integration time:
-
Permalink:
wavenumber-eng/kicad_monkey@27f3e83ba2651d19f6106ccbfd9dda78649989ea -
Branch / Tag:
refs/tags/v2026.6.18 - Owner: https://github.com/wavenumber-eng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@27f3e83ba2651d19f6106ccbfd9dda78649989ea -
Trigger Event:
release
-
Statement type:
File details
Details for the file kicad_monkey-2026.6.18-py3-none-any.whl.
File metadata
- Download URL: kicad_monkey-2026.6.18-py3-none-any.whl
- Upload date:
- Size: 668.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5eeed8ebfdc09139b63188c6a5dbe4305fb3d5efa2cf3f7d97ff2a2ef4884cbd
|
|
| MD5 |
c049f0bcede69442242d1ae725e2c85e
|
|
| BLAKE2b-256 |
8f83897fdd37c394e60ccc45afae04fcca5eee0a99f7561b9fbd59b5f0b1752a
|
Provenance
The following attestation bundles were made for kicad_monkey-2026.6.18-py3-none-any.whl:
Publisher:
release.yml on wavenumber-eng/kicad_monkey
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kicad_monkey-2026.6.18-py3-none-any.whl -
Subject digest:
5eeed8ebfdc09139b63188c6a5dbe4305fb3d5efa2cf3f7d97ff2a2ef4884cbd - Sigstore transparency entry: 1864410663
- Sigstore integration time:
-
Permalink:
wavenumber-eng/kicad_monkey@27f3e83ba2651d19f6106ccbfd9dda78649989ea -
Branch / Tag:
refs/tags/v2026.6.18 - Owner: https://github.com/wavenumber-eng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@27f3e83ba2651d19f6106ccbfd9dda78649989ea -
Trigger Event:
release
-
Statement type: