API Reference

Complete reference for kicad-sch-api. For practical examples, see RECIPES.md.

Table of Contents

  1. Creating Schematics

  2. Component Operations

  3. Wire Operations

  4. Connectivity Analysis ⭐ NEW

  5. Hierarchy Management ⭐ NEW

  6. Label Operations

  7. Collections API

  8. Configuration

  9. File Operations


Creating Schematics

create_schematic(name: str) β†’ Schematic

Create a new blank schematic.

import kicad_sch_api as ksa

sch = ksa.create_schematic("My Circuit")

Parameters:

  • name (str): Schematic name (appears in title block)

Returns: Schematic object


load_schematic(filepath: str) β†’ Schematic

Load an existing KiCAD schematic file.

sch = ksa.load_schematic("existing.kicad_sch")

Parameters:

  • filepath (str): Path to .kicad_sch file

Returns: Schematic object

Raises:

  • FileNotFoundError: If file doesn’t exist

  • ValueError: If file is not valid KiCAD format


Component Operations

Schematic.components

ComponentCollection object providing access to all components.

components.add(lib_id, reference, value, position, **kwargs) β†’ Component

Add a component to the schematic.

resistor = sch.components.add(
    lib_id="Device:R",
    reference="R1",
    value="10k",
    position=(100, 100),
    footprint="Resistor_SMD:R_0805_2012Metric"
)

Parameters:

  • lib_id (str): Library and component name (e.g., β€œDevice:R”)

  • reference (str, optional): Component reference (e.g., β€œR1”). Auto-generated if None.

  • value (str): Component value (e.g., β€œ10k”, β€œ100nF”)

  • position (tuple or Point, optional): (x, y) position in mm. Auto-placed if None.

  • footprint (str, optional): PCB footprint

  • unit (int, optional): Unit number for multi-unit components. Default: 1

  • component_uuid (str, optional): Specific UUID. Auto-generated if None.

  • **properties: Additional properties as keyword arguments

Returns: Component object

Raises:

  • ValidationError: If lib_id invalid or reference already exists

Example:

# Minimal
r = sch.components.add("Device:R", "R1", "10k", (100, 100))

# With all options
r = sch.components.add(
    lib_id="Device:R",
    reference="R1",
    value="10k",
    position=(100, 100),
    footprint="Resistor_SMD:R_0805_2012Metric",
    unit=1,
    Tolerance="1%",
    Power="0.125W",
    MPN="RC0805FR-0710KL"
)

components.get(reference: str) β†’ Optional[Component]

Get component by reference.

resistor = sch.components.get("R1")
if resistor:
    print(f"R1 value: {resistor.value}")

Parameters:

  • reference (str): Component reference

Returns: Component object or None if not found


Component Removal

Three methods for removing components:

components.remove(reference: str) β†’ bool

Remove component by reference (primary method).

# Remove by reference
removed = sch.components.remove("R1")
print(f"Removed: {removed}")  # True if removed, False if not found

Parameters:

  • reference (str): Component reference

Returns: True if removed, False if not found

Raises: TypeError if reference is not a string


components.remove_by_uuid(uuid: str) β†’ bool

Remove component by UUID.

# When you have the UUID
component_uuid = resistor.uuid
removed = sch.components.remove_by_uuid(component_uuid)

Parameters:

  • uuid (str): Component UUID

Returns: True if removed, False if not found

Use When: You have the UUID but not the reference, or working with UUIDs directly.


components.remove_component(component: Component) β†’ bool

Remove component object directly.

# When you have the component object
resistor = sch.components.get("R1")
if resistor:
    removed = sch.components.remove_component(resistor)

Parameters:

  • component (Component): Component object to remove

Returns: True if removed, False if not found

Raises: TypeError if argument is not a Component instance

Use When: You have the Component object from iteration or search.


Note: When the last component of a specific lib_id is removed, the associated lib_symbol is automatically cleaned up from the schematic file.


components.filter(**criteria) β†’ List[Component]

Filter components by criteria.

# By library
resistors = sch.components.filter(lib_id="Device:R")

# By value
ten_k_resistors = sch.components.filter(value="10k")

# By footprint
smd_parts = sch.components.filter(footprint="*SMD*")

# Multiple criteria
ten_k_smd_resistors = sch.components.filter(
    lib_id="Device:R",
    value="10k",
    footprint="*SMD*"
)

Parameters:

  • lib_id (str, optional): Library ID to match

  • value (str, optional): Value to match (exact)

  • value_pattern (str, optional): Value pattern (substring)

  • reference_pattern (str, optional): Reference regex pattern

  • footprint (str, optional): Footprint to match

  • in_area (tuple, optional): (x1, y1, x2, y2) bounding box

  • has_property (str, optional): Must have this property

Returns: List of matching components


components.bulk_update(criteria: Dict, updates: Dict) β†’ int

Update multiple components at once.

# Update all resistors
count = sch.components.bulk_update(
    criteria={'lib_id': 'Device:R'},
    updates={'properties': {'Tolerance': '1%', 'Power': '0.125W'}}
)
print(f"Updated {count} resistors")

Parameters:

  • criteria (dict): Selection criteria

  • updates (dict): Updates to apply

Returns: Number of components updated


Component Object

Represents a single component.

Properties

comp = sch.components.get("R1")

# Read/write properties
comp.reference      # str: "R1"
comp.value         # str: "10k"
comp.footprint     # Optional[str]: "Resistor_SMD:R_0805_2012Metric"
comp.position      # Point: Point(x=100, y=100)
comp.rotation      # float: Rotation in degrees
comp.lib_id        # str: "Device:R"
comp.uuid          # str: UUID
comp.properties    # Dict[str, str]: All properties

# Read-only properties
comp.library       # str: "Device"
comp.symbol_name   # str: "R"
comp.pins          # List[SchematicPin]: Pin information

Methods

# Property management
comp.set_property("MPN", "RC0805FR-0710KL")
comp.get_property("MPN", default="")
"MPN" in comp.properties  # Check if property exists
comp.remove_property("MPN")

# Pin operations
pin = comp.get_pin("1")  # Get pin by number
pin_pos = comp.get_pin_position("1")  # Get absolute position

# Text effects (formatting, colors, fonts)
effects = comp.get_property_effects("Reference")  # Get all effects
comp.set_property_effects("Reference", {"bold": True, "color": (255, 0, 0, 1.0)})

# Validation
issues = comp.validate()  # List[ValidationIssue]

# Conversion
comp_dict = comp.to_dict()  # Convert to dictionary

Text Effects

Get and modify text effects for component properties (Reference, Value, Footprint).

comp = sch.components.get("R1")

# Get all effects for a property
effects = comp.get_property_effects("Reference")
# Returns dictionary with:
# {
#     'position': (x, y),           # Position relative to component
#     'rotation': float,            # Rotation in degrees
#     'font_face': str,             # Font name (e.g., 'Arial')
#     'font_size': (h, w),          # Font size (height, width) in mm
#     'font_thickness': float,      # Line thickness
#     'bold': bool,                 # Bold flag
#     'italic': bool,               # Italic flag
#     'color': (r, g, b, a),        # RGBA color (0-255, 0-1 alpha)
#     'justify_h': str,             # 'left', 'right', 'center'
#     'justify_v': str,             # 'top', 'bottom'
#     'visible': bool,              # True = visible, False = hidden
# }

# Modify effects (partial updates - preserves other effects)
comp.set_property_effects("Reference", {
    "color": (0, 255, 0, 1.0),  # Green
    "bold": True,
    "font_size": (2.0, 2.0)
})

# Hide a property
comp.set_property_effects("Footprint", {"visible": False})

# Rotate and style value
comp.set_property_effects("Value", {
    "rotation": 90.0,
    "italic": True,
    "justify_h": "left",
    "color": (160, 32, 240, 1.0)  # Purple
})

Supported Properties:

  • Reference, Value, Footprint (standard properties)

  • Any custom property that exists in the component

Effect Properties:

  • position (tuple): (x, y) position relative to component

  • rotation (float): Rotation angle in degrees (stored in (at x y rotation) section)

  • font_face (str): Font name (e.g., β€œArial”, β€œCourier New”)

  • font_size (tuple): (height, width) in mm

  • font_thickness (float): Line thickness for text

  • bold (bool): Bold text flag

  • italic (bool): Italic text flag

  • color (tuple): (r, g, b, alpha) - RGB 0-255, alpha 0.0-1.0

  • justify_h (str): Horizontal justification - β€œleft”, β€œright”, β€œcenter”

  • justify_v (str): Vertical justification - β€œtop”, β€œbottom”

  • visible (bool): Visibility flag (False = hidden)

Notes:

  • Effects are merged - only specified properties are changed, others preserved

  • Works on both loaded components (preserves existing) and newly created components (creates defaults)

  • Format preservation - exact KiCAD S-expression format maintained


Wire Operations

Schematic.wires

WireCollection object providing access to all wires.

wires.add(start=None, end=None, points=None, **kwargs) β†’ str

Add a wire.

# Simple 2-point wire
wire_uuid = sch.wires.add(start=(100, 100), end=(150, 100))

# Multi-point wire (L-shaped)
wire_uuid = sch.wires.add(
    points=[
        (100, 100),
        (100, 120),
        (150, 120)
    ]
)

Parameters:

  • start (tuple or Point, optional): Start point for 2-point wire

  • end (tuple or Point, optional): End point for 2-point wire

  • points (List[tuple or Point], optional): List of points for multi-point wire

  • wire_type (WireType, optional): Wire type. Default: WireType.WIRE

  • stroke_width (float, optional): Line width. Default: 0.0

  • uuid (str, optional): Specific UUID

Returns: Wire UUID (string)

Raises:

  • ValueError: If neither start/end nor points provided


add_wire_between_pins(from_ref, from_pin, to_ref, to_pin) β†’ Optional[str]

Connect two component pins automatically.

# Connect R1 pin 2 to R2 pin 1
wire_uuid = sch.add_wire_between_pins("R1", "2", "R2", "1")

Parameters:

  • from_ref (str): Source component reference

  • from_pin (str): Source pin number

  • to_ref (str): Destination component reference

  • to_pin (str): Destination pin number

Returns: Wire UUID or None if components/pins not found


add_wire_to_pin(point, component_ref, pin) β†’ Optional[str]

Connect a point to a component pin.

# Connect external point to R1 pin 1
sch.add_wire_to_pin((50, 100), "R1", "1")

# Using Point object
from kicad_sch_api.core.types import Point
sch.add_wire_to_pin(Point(50, 100), "R1", "1")

Parameters:

  • point (tuple or Point): External point coordinates

  • component_ref (str): Component reference

  • pin (str): Pin number

Returns: Wire UUID or None if component/pin not found


wires.get(uuid: str) β†’ Optional[Wire]

Get wire by UUID.

wire = sch.wires.get(wire_uuid)

wires.remove(uuid: str) β†’ bool

Remove wire by UUID.

removed = sch.wires.remove(wire_uuid)

wires.get_by_point(point, tolerance=None) β†’ List[Wire]

Find wires near a point.

wires = sch.wires.get_by_point((100, 100), tolerance=1.0)

Connectivity Analysis

NEW in v0.5.0 - Comprehensive electrical connectivity analysis.

are_pins_connected(ref1, pin1, ref2, pin2) β†’ bool

Check if two component pins are electrically connected.

# Check direct or indirect connection
if sch.are_pins_connected("R1", "2", "R2", "1"):
    print("Pins are connected!")

Traces through:

  • Direct wire connections

  • Connections through junctions

  • Local labels (same sheet)

  • Global labels (cross-sheet)

  • Hierarchical labels (parent-child)

  • Power symbols (VCC, GND, etc.)

  • Sheet pins

Parameters:

  • ref1 (str): First component reference (e.g., β€œR1”)

  • pin1 (str): First pin number (e.g., β€œ2”)

  • ref2 (str): Second component reference

  • pin2 (str): Second pin number

Returns: True if pins are electrically connected, False otherwise

Implementation Notes:

  • Uses lazy-initialized connectivity analyzer

  • Automatically caches results

  • Cache invalidates on schematic changes (add/remove wires)

  • Always uses hierarchical mode for multi-sheet designs


get_net_for_pin(component_ref, pin_number) β†’ Optional[Net]

Get the electrical net connected to a specific pin.

# Get net information
net = sch.get_net_for_pin("R1", "2")
if net:
    print(f"Net name: {net.name}")
    print(f"Total pins: {len(net.pins)}")

    # Iterate pins on this net
    for pin in net.pins:
        print(f"  {pin.reference}.{pin.pin_number}")

Parameters:

  • component_ref (str): Component reference

  • pin_number (str): Pin number

Returns: Net object or None if pin not connected

Net Object Attributes:

  • name (str): Net name (from label or auto-generated)

  • pins (Set[PinConnection]): All pins on this net

  • labels (Set[str]): All label names on this net

  • is_power (bool): Whether net is a power net

PinConnection Attributes:

  • reference (str): Component reference

  • pin_number (str): Pin number

  • position (Point): Absolute pin position


get_connected_pins(component_ref, pin_number) β†’ List[Tuple[str, str]]

Get all pins electrically connected to a specific pin.

# Get list of connected pins
connected = sch.get_connected_pins("R1", "2")
for ref, pin in connected:
    print(f"Connected to: {ref}.{pin}")

Parameters:

  • component_ref (str): Component reference

  • pin_number (str): Pin number

Returns: List of (reference, pin_number) tuples

Note: Does not include the queried pin itself in results.

Example - Finding All Components on a Net:

# Find all components connected to VCC
vcc_net = sch.get_net_for_pin("U1", "VCC")
if vcc_net:
    components = {pin.reference for pin in vcc_net.pins}
    print(f"Components on VCC: {components}")

Connectivity Cache Management

Connectivity analysis is automatically cached for performance:

# First query: Builds connectivity graph (slow on large schematics)
result1 = sch.are_pins_connected("R1", "2", "R2", "1")

# Subsequent queries: Use cached graph (fast)
result2 = sch.get_net_for_pin("R1", "2")
result3 = sch.get_connected_pins("R1", "2")

# Cache invalidates automatically when schematic changes
sch.wires.add((100, 100), (150, 100))  # Cache now invalid

# Next query: Rebuilds connectivity graph
result4 = sch.are_pins_connected("R1", "1", "R3", "1")

Cache Invalidation Triggers:

  • Adding wires

  • Removing wires

  • Adding components

  • Removing components

  • Modifying labels

  • Any schematic changes affecting connectivity


Hierarchy Management

NEW in v0.5.0 - Advanced hierarchical schematic management.

For complete documentation, see HIERARCHY_FEATURES.md.

hierarchy.build_hierarchy_tree(root_schematic, root_path) β†’ HierarchyNode

Build complete hierarchy tree from root schematic.

from pathlib import Path

# Build tree
schematic_path = Path("my_project.kicad_sch")
tree = sch.hierarchy.build_hierarchy_tree(sch, schematic_path)

# Access tree
print(f"Root: {tree.name}")
for child in tree.children:
    print(f"  Child: {child.name} ({child.filename})")

Parameters:

  • root_schematic: Root Schematic object

  • root_path (Path, optional): Path to root schematic file (required for loading child sheets)

Returns: HierarchyNode object representing the root

HierarchyNode Attributes:

  • path (str): Hierarchical path (e.g., β€œ/”, β€œ/sheet_uuid/”)

  • name (str): Sheet name

  • filename (str): Schematic filename

  • schematic: Loaded Schematic object

  • parent (HierarchyNode): Parent node

  • children (List[HierarchyNode]): Child nodes

  • is_root (bool): Whether this is the root node


hierarchy.find_reused_sheets() β†’ Dict[str, List[SheetInstance]]

Find sheets that are used multiple times.

# Find reused sheets
reused = sch.hierarchy.find_reused_sheets()
for filename, instances in reused.items():
    print(f"{filename} used {len(instances)} times:")
    for instance in instances:
        print(f"  Path: {instance.path}")

Returns: Dictionary mapping filename β†’ list of SheetInstance objects

SheetInstance Attributes:

  • sheet_uuid (str): Sheet UUID in parent

  • sheet_name (str): Sheet name

  • filename (str): Referenced schematic file

  • path (str): Hierarchical path

  • schematic: Loaded Schematic object

  • sheet_pins (List[Dict]): Sheet pin definitions


hierarchy.validate_sheet_pins() β†’ List[SheetPinConnection]

Validate sheet pin connections against hierarchical labels.

# Validate all sheet connections
connections = sch.hierarchy.validate_sheet_pins()

# Check for errors
errors = sch.hierarchy.get_validation_errors()
for error in errors:
    print(f"Error: {error['pin_name']} - {error['error']}")

Returns: List of SheetPinConnection objects

SheetPinConnection Attributes:

  • sheet_path (str): Path to sheet instance

  • sheet_pin_name (str): Pin name

  • sheet_pin_type (str): Pin type (input/output/bidirectional)

  • hierarchical_label_name (str): Matching label in child

  • validated (bool): Whether connection is valid

  • validation_errors (List[str]): Error messages

Validation Checks:

  • Sheet pins have matching hierarchical labels

  • Pin types are compatible

  • Pin names match exactly

  • No duplicate pins


hierarchy.trace_signal_path(signal_name, start_path=None) β†’ List[SignalPath]

Trace signal through hierarchical boundaries.

# Trace VCC through hierarchy
paths = sch.hierarchy.trace_signal_path("VCC")
for path in paths:
    print(f"Signal: {path.signal_name}")
    print(f"From: {path.start_path}")
    print(f"To: {path.end_path}")
    print(f"Sheet crossings: {path.sheet_crossings}")

Parameters:

  • signal_name (str): Signal/label name to trace

  • start_path (str, optional): Starting hierarchical path

Returns: List of SignalPath objects

SignalPath Attributes:

  • signal_name (str): Signal name

  • start_path (str): Starting hierarchical path

  • end_path (str): Ending hierarchical path

  • connections (List[str]): Connection points

  • sheet_crossings (int): Number of sheet boundaries crossed


hierarchy.flatten_hierarchy(prefix_references=False) β†’ Dict

Flatten hierarchical design into single-level representation.

# Flatten design
flattened = sch.hierarchy.flatten_hierarchy(prefix_references=True)

print(f"Components: {len(flattened['components'])}")
print(f"Wires: {len(flattened['wires'])}")

# Check original locations
for ref, path in flattened['hierarchy_map'].items():
    print(f"{ref} was in {path}")

Parameters:

  • prefix_references (bool): Whether to prefix references with sheet path

Returns: Dictionary with keys:

  • components (List): All components

  • wires (List): All wires

  • labels (List): All labels

  • hierarchy_map (Dict): Mapping reference β†’ original path

Example - Prefixed References:

# Without prefix: R1, R2, R3
# With prefix: /R1, /sheet_uuid/R2, /sheet_uuid/R3

hierarchy.visualize_hierarchy(include_stats=False) β†’ str

Generate text-based hierarchy tree visualization.

# Visualize tree
viz = sch.hierarchy.visualize_hierarchy(include_stats=True)
print(viz)

# Output:
# β”œβ”€β”€ Main Board (5 components, 8 wires)
# β”‚   β”œβ”€β”€ PowerSupply [power.kicad_sch] (3 components)
# β”‚   β”œβ”€β”€ MCU [mcu.kicad_sch] (12 components)

Parameters:

  • include_stats (bool): Include component/wire counts

Returns: String with tree visualization


Label Operations

Schematic.labels

LabelCollection object providing access to all labels.

add_label(text, position, **kwargs) β†’ str

Add a label (net name).

label_uuid = sch.add_label("VCC", position=(100, 50))

# With options
label_uuid = sch.add_label(
    text="SDA",
    position=(150, 100),
    rotation=0.0,
    size=1.27
)

Parameters:

  • text (str): Label text

  • position (tuple or Point): Position

  • rotation (float, optional): Rotation in degrees. Default: 0.0

  • size (float, optional): Text size. Default: 1.27

  • label_uuid (str, optional): Specific UUID

Returns: Label UUID


labels.find_by_text(text, exact=True) β†’ List[LabelElement]

Find labels by text.

# Exact match
vcc_labels = sch.labels.find_by_text("VCC", exact=True)

# Substring match
power_labels = sch.labels.find_by_text("VCC", exact=False)

labels.remove(uuid: str) β†’ bool

Remove label by UUID.

removed = sch.labels.remove(label_uuid)

Collections API

All collections (components, wires, labels, etc.) inherit from BaseCollection.

Common Methods

# Length
count = len(sch.components)

# Iteration
for comp in sch.components:
    print(comp.reference)

# Indexing by UUID
comp = sch.components[uuid]

# Indexing by position
first_comp = sch.components[0]

# Contains check
if "R1" in sch.components:  # Checks reference for ComponentCollection
    print("R1 exists")

# Get by UUID
comp = sch.components.get(uuid)

# Find with predicate
matching = sch.components.find(lambda c: c.value == "10k")

# Remove
removed = sch.components.remove(uuid)

# Clear all
sch.components.clear()

# Statistics
stats = sch.components.get_statistics()

Modification Tracking

# Check if modified
if sch.components.is_modified():
    print("Components have been modified")

# Reset flag (usually after save)
sch.components.reset_modified_flag()

Configuration

Global configuration accessible via ksa.config.

Property Positioning

# Adjust label positions
ksa.config.properties.reference_y = -2.0  # Reference label offset
ksa.config.properties.value_y = 2.0       # Value label offset
ksa.config.properties.footprint_y = 4.0   # Footprint label offset

Tolerances

# Position matching tolerance
ksa.config.tolerance.position_tolerance = 0.01  # mm

# Wire segment minimum length
ksa.config.tolerance.wire_segment_min = 0.005  # mm

Defaults

# Default values for new elements
ksa.config.defaults.project_name = "My Project"
ksa.config.defaults.stroke_width = 0.1
ksa.config.defaults.text_size = 1.27

Grid and Spacing

# Grid settings
ksa.config.grid.size = 2.54  # KiCAD grid size (0.1 inch)
ksa.config.grid.unit_spacing = 10.0  # Multi-unit IC spacing
ksa.config.grid.component_spacing = 5.0  # Component spacing

Sheet Settings

# Hierarchical sheet settings
ksa.config.sheet.name_offset_y = -1.0
ksa.config.sheet.file_offset_y = 1.0

File Operations

Schematic.save(filepath: str = None)

Save schematic to file.

# Save to original path (if loaded)
sch.save()

# Save to new path
sch.save("new_circuit.kicad_sch")

Parameters:

  • filepath (str, optional): Save path. Uses original if None.

Raises:

  • ValueError: If filepath is None and schematic wasn’t loaded from file


Hierarchical Sheets

add_hierarchical_sheet(name, filename, position, size, **kwargs)

Add a hierarchical sheet.

sheet_uuid = sch.add_hierarchical_sheet(
    name="Power Supply",
    filename="power.kicad_sch",
    position=(100, 100),
    size=(80, 60)
)

Parameters:

  • name (str): Sheet name/title

  • filename (str): Referenced schematic filename

  • position (tuple or Point): Top-left corner position

  • size (tuple or Point): (width, height)

  • project_name (str, optional): Project name

  • page_number (str, optional): Page number

  • uuid (str, optional): Specific UUID

Returns: Sheet UUID


add_hierarchical_label(text, label_type, position, **kwargs)

Add a hierarchical label (sheet connector).

label_uuid = sch.add_hierarchical_label(
    text="VIN",
    label_type="input",
    position=(50, 25)
)

Parameters:

  • text (str): Label text

  • label_type (str): Type: β€œinput”, β€œoutput”, β€œbidirectional”, β€œtri_state”, β€œpassive”

  • position (tuple or Point): Position

  • shape (str, optional): Shape style

  • uuid (str, optional): Specific UUID

Returns: Label UUID


Junctions

junctions.add(position, **kwargs) β†’ str

Add a junction (connection point).

junction_uuid = sch.junctions.add(position=(100, 100))

No-Connect Symbols

no_connects.add(position, **kwargs) β†’ NoConnectElement

Add a no-connect symbol.

nc = sch.no_connects.add(position=(100, 100))

Text Elements

texts.add(text, position, **kwargs) β†’ TextElement

Add text annotation.

text = sch.texts.add(
    text="Important Note",
    position=(100, 100),
    size=2.0,
    rotation=0.0
)

Validation

Schematic.validate() β†’ List[ValidationIssue]

Validate entire schematic.

issues = sch.validate()
for issue in issues:
    print(f"{issue.severity}: {issue.message}")

Utilities

Point Class

from kicad_sch_api.core.types import Point

p1 = Point(100, 100)
p2 = Point(150, 150)

# Distance
dist = p1.distance_to(p2)

# Addition
p3 = p1 + p2  # Component-wise addition

# Access
x = p1.x
y = p1.y

Type Hints

Library provides full type hints:

from kicad_sch_api import Schematic, Component
from kicad_sch_api.core.types import Point
from typing import Optional, List

def process_schematic(sch: Schematic) -> List[str]:
    """Process schematic and return component references."""
    references: List[str] = []

    comp: Component
    for comp in sch.components:
        references.append(comp.reference)

    return references

Error Handling

from kicad_sch_api.utils.validation import ValidationError

try:
    sch.components.add("InvalidLib:Part", "R1", "10k", (100, 100))
except ValidationError as e:
    print(f"Validation error: {e}")

try:
    sch = ksa.load_schematic("missing.kicad_sch")
except FileNotFoundError:
    print("File not found")
except ValueError as e:
    print(f"Invalid file format: {e}")

Complete Example

import kicad_sch_api as ksa

# Create schematic
sch = ksa.create_schematic("Complete Example")

# Add components
r1 = sch.components.add("Device:R", "R1", "10k", (100, 100))
r2 = sch.components.add("Device:R", "R2", "5k", (100, 120))
c1 = sch.components.add("Device:C", "C1", "100nF", (150, 110))

# Set properties
r1.set_property("Tolerance", "1%")
r1.set_property("Power", "0.125W")

# Connect components
sch.add_wire_between_pins("R1", "2", "R2", "1")
sch.add_wire_between_pins("R2", "2", "C1", "1")

# Add labels
sch.add_label("VIN", (100, 90))
sch.add_label("VOUT", (125, 110))
sch.add_label("GND", (150, 130))

# Add junction at connection point
sch.junctions.add((125, 110))

# Validate
issues = sch.validate()
if issues:
    for issue in issues:
        print(f"Warning: {issue.message}")

# Save
sch.save("complete_example.kicad_sch")
print("Schematic created successfully!")

For more examples, see: