Metadata-Version: 2.4
Name: python-kicad
Version: 0.6.1
Summary: Pydantic models and parsers for KiCad 6 and newer design files
Author: esophagoose
License-Expression: MIT
Project-URL: Homepage, https://github.com/esophagoose/python-kicad
Project-URL: Repository, https://github.com/esophagoose/python-kicad
Project-URL: Issues, https://github.com/esophagoose/python-kicad/issues
Keywords: kicad,eda,pcb,schematic,parser,pydantic
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic<3,>=2.10.6
Provides-Extra: dev
Requires-Dist: build>=1.2.2; extra == "dev"
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=6.2.1; extra == "dev"
Requires-Dist: twine>=6.1.0; extra == "dev"
Dynamic: license-file

# python-kicad

`python-kicad` provides Pydantic models and parsers for KiCad schematic,
PCB, and exported netlist files.

- KiCad 6 and newer
- Python 3.10 and newer
- No KiCad installation required
- MIT licensed

## Installation

```console
python -m pip install python-kicad
```

The distribution is named `python-kicad`, while the import package remains
`pykicad`:

```python
from pykicad import Pcb, Schematic, read_from_file

document = read_from_file("project.kicad_pcb")
if isinstance(document.model, Pcb):
    print(document.model.version)
    print(len(document.model.footprint))
elif isinstance(document.model, Schematic):
    print(document.model.version)
    print(len(document.model.symbols))
```

An older, unrelated distribution already uses the `pykicad` name on PyPI and
installs into the same Python import namespace. Do not install `pykicad` and
`python-kicad` into the same environment.

## JSON command line interface

Inspect any supported KiCad document without loading its S-expression syntax
into another tool:

```console
pykicad inspect project.kicad_pcb
pykicad json project.kicad_pcb
pykicad json reusable-footprint.kicad_mod
```

`python -m pykicad` provides the same commands. Both commands accept `-` for
UTF-8 standard input and `--compact` for single-line output:

```console
cat project.kicad_sch | pykicad inspect - --compact
```

Full exports use a versioned envelope:

```json
{
  "schema": "pykicad.document",
  "schema_version": 1,
  "document_type": "pcb",
  "document": {}
}
```

The semantic document uses plural collection names, omits absent optional
fields, and preserves unknown KiCad tags in an `extensions` object. PCB
footprints include resolved `reference` and `value` fields, pads include both
local `position` and board-level `absolute_position`, and PCB net references
use consistent `code`/`name` objects. Placed schematic symbols similarly expose
their resolved reference, value, and footprint.

The same data is available from Python:

```python
from pykicad import export_json_data, inspect_document, read_from_file

document = read_from_file("project.kicad_pcb")
payload = export_json_data(document)
summary = inspect_document(document)
```

### Bundled agent skill

The installed distribution includes a `pykicad-cli` agent skill with the CLI
workflow, query patterns, schema documentation, and a machine-readable JSON
Schema. Copy it into a repository's project skills with:

```console
pykicad skill copy .agents/skills
```

The destination parent defaults to `.agents/skills`, so `pykicad skill copy`
creates `.agents/skills/pykicad-cli`. The command refuses to overwrite an
existing skill directory.

The complete export is designed to compose with standard JSON tools instead of
providing a separate query language. For example:

```console
# Footprint references, values, and positions
pykicad json board.kicad_pcb | jq '.document.footprints[] | {reference, value, position}'

# Pads belonging to U1
pykicad json board.kicad_pcb | jq '.document.footprints[] | select(.reference == "U1") | .pads[]'

# Unique connected net names
pykicad json board.kicad_pcb | jq '[.document.footprints[].pads[].net.name] | map(select(. != null)) | unique'

# Placed schematic symbols
pykicad json design.kicad_sch | jq '.document.symbols[] | {reference, value, footprint, position}'

# Tracks and copper zones
pykicad json board.kicad_pcb | jq '{tracks: .document.tracks, zones: .document.zones}'
```

Schema version 1 guarantees the envelope and modeled semantic field names.
Additional modeled fields may be added compatibly; removing a field or changing
its meaning requires a new schema version. Contents of `extensions` are
best-effort and are not part of that compatibility guarantee. JSON export is
read-only and does not retain source whitespace, comments, quoting choices, or
exact numeric spelling.

## Supported documents

`read_from_file()` and `read_from_string()` return a `KicadDocument` containing
the parsed model and its original source. They recognize:

- `.kicad_pcb` board files as `Pcb`
- `.kicad_mod` footprint files as `Footprint`
- `.kicad_sch` schematic files as `Schematic`
- KiCad-exported S-expression netlists as `Netlist`

The parser uses one Pydantic model family for released KiCad 6 and newer file
variants. Unknown enum values and malformed S-expressions remain validation
errors.

```python
from pydantic import ValidationError
from pykicad import read_from_string

try:
    document = read_from_string(
        "(kicad_pcb (version 20240101) (generator pcbnew))"
    )
    board = document.model
except (ValueError, ValidationError) as error:
    print(f"Invalid KiCad document: {error}")
```

## Writing

PCB documents loaded through `read_from_file()` or `read_from_string()` retain
their original source. Writing a parsed `KicadDocument` updates only changed
S-expression nodes, preserving the formatting and numeric spelling of untouched
content. Inserted and changed content follows KiCad 10 formatting, including
local indentation, aligned multiline closing parentheses, and compact numeric
spelling such as `0` instead of `0.0`. Bare PCB models constructed in Python use
the same formatting with tab indentation:

```python
from pykicad import read_from_file, write_to_file

document = read_from_file("project.kicad_pcb")
write_to_file(document, "copy.kicad_pcb")
```

Use `PcbBuilder.create()` to construct an empty KiCad 10 board. Standalone
`.kicad_mod` footprints can also be read and written. Models remain declarative
data structures; document I/O, serialization, and authoring live in dedicated
modules. Schematic writing is not implemented.

Common authoring operations are available through builders:

```python
from pykicad import BoardSide, FootprintBuilder, PcbBuilder, write_to_file
from pykicad.models.base import Point
from pykicad.models.pcb import Position

board = PcbBuilder.create(copper_layer_count=4)
ground = board.ensure_net("GND")
board.add_via(Position(x=10, y=10), size=0.6, drill=0.3, net=ground)
board.add_graphic_rect(
    Point(x=0, y=0), Point(x=20, y=20), layer="Edge.Cuts"
)

footprint = FootprintBuilder.create("Example:Part")
footprint.set_reference("U1", at=Position(x=0, y=-2), layer="F.SilkS")
footprint.place(Position(x=5, y=5), side=BoardSide.BACK)
board.add_footprint(footprint.build())

write_to_file(board.build(), "authored.kicad_pcb")
```

Place a `.kicad_mod` file directly onto a board with a reference and pad-net
mapping. Each placement receives fresh identifiers, so the same file can be
reused safely:

```python
from pykicad import BoardSide, PcbBuilder, write_to_file
from pykicad.models.pcb import Position

board = PcbBuilder.create()
board.add_footprint_file(
    "Package_SO.pretty/SOIC-8.kicad_mod",
    reference="U1",
    at=Position(x=25, y=40, angle=90),
    side=BoardSide.BACK,
    pad_nets={"1": "GND", "8": "VCC"},
)
write_to_file(board.build(), "placed.kicad_pcb")
```

## Development

Create an environment and install the development dependencies:

```console
python -m pip install -e ".[dev]"
python -m pytest
```

Build and validate release artifacts with:

```console
python -m build
python -m twine check dist/*
python scripts/check_distribution.py dist/*
```

See [RELEASING.md](RELEASING.md) for the trusted-publishing release process.
