I’ve found that, so far, 1 I’m able to do all of the layout queries and manipulations I’ve wanted to do.
Edit April 3, 2018 The comment below about 4.0.5 is not true. Even the most recent 4.0.7 is missing a ton of python related stuff. Until kicad 5.0 comes out, I recommend using one of the nightly builds from the kicad downloads page. End Edit
Note that these examples don’t work on the latest release as of Feb 2017 (4.0.5). You want one of the nightly builds, also in the kicad download area. Or you can build it
The interface is lacking some consistency but it’s fine if you have a map of the classes (click for a larger version or download it from here):

In this post, I’ll focus on querying a board for information about it’s contents. The code can be found in this github repo.

Getting started

To invoke any of these examples, you’ll want pcbnew’s scripting window. Tools->scripting console
You’ll probably want these in your scripts

import pcbnew
# most queries start with a board
board = pcbnew.GetBoard()


Want to know all of the nets in your board?
Nets can be looked up in two ways:

  • by name
  • by netcode – a unique integer identifier for your net.

If you run this code:

# returns a dictionary netcode:netinfo_item
netcodes = board.GetNetsByNetcode()
# list off all of the nets in the board.
for netcode, net in netcodes.items():
    print("netcode {}, name {}".format(netcode, net.GetNetname()))
# here's another way of doing the same thing.
print("here's the other way to do it")
nets = board.GetNetsByName()
for netname, net in nets.items():
    print("method2 netcode {}, name{}".format(net.GetNet(), netname))
# maybe you just want a single net
# the find method returns an iterator to all matching nets.
# the value of an iterator is a tuple: name, netinfo
clknet = nets.find("/clk").value()[1]
clkclass = clknet.GetNetClass()
print("net {} is on netclass {}".format(clknet.GetNetname(),

You’ll get something like this:

netcode 49, name /ihg
netcode 50, name /ihh
netcode 51, name /data_in
netcode 52, name /data_out
netcode 53, name /clk
here's the other way to do it
method2 netcode 0, name
method2 netcode 23, name+5V
method2 netcode 53, name/clk
method2 netcode 55, name/data_contd
method2 netcode 51, name/data_in

Physical dimensions

The coordinate space of kicad_pcb is in mm. At the beginning of this wiki about Kicad’s Board_File_Format

“All physical units are in mils (1/1000th inch) unless otherwise noted.”

Then later in historical notes, it says,

“As of 2013, the PCBnew application creates ‘.kicad_pcb’ files that begin with (kicad_pcb (version 3)”. All distances are in millimeters.

In short, for the data that I’ve recently created, the internal coordinate space of pcbnew is 10E-6 mm. (a millionth of a mm)
For example, the coordinate 121550000 corresponds to 121.550000mm

SCALE = 1000000.0
boardbbox = board.ComputeBoundingBox()
boardxl = boardbbox.GetX()
boardyl = boardbbox.GetY()
boardwidth = boardbbox.GetWidth()
boardheight = boardbbox.GetHeight()
print("this board is at position {},{} {} wide and {} high".format(boardxl,


Each of your placed modules can be found with its reference name. The module connection points are pads, of course.

# generate a LUT with shape integers to a string
padshapes = {
# new in the most recent kicad code
if hasattr(pcbnew, 'PAD_SHAPE_ROUNDRECT'):
modref = "U1"
mod = board.FindModuleByReference(modref)
for pad in mod.Pads():
    print("pad {}({}) on {}({}) at {},{} shape {} size {},{}"
                pad.GetPosition().x, pad.GetPosition().y,
                pad.GetSize().x, pad.GetSize().y

Gives you this:

pad 1(/ilb) on U1(74HC595) at 127635000,106520000 shape PAD_SHAPE_RECT size 1500000,600000
pad 2(/ilc) on U1(74HC595) at 126365000,106520000 shape PAD_SHAPE_RECT size 1500000,600000
pad 3(/ild) on U1(74HC595) at 125095000,106520000 shape PAD_SHAPE_RECT size 1500000,600000


Most of the pcb data is on a layer. pcbnew stores layers as numbers. Here we can print them all out

layertable = {}
numlayers = pcbnew.LAYER_ID_COUNT
   for i in range(numlayers):
       layertable[i] = board.GetLayerName(i)
       print("{} {}".format(i, board.GetLayerName(i)))

Which gives you this:

0 F.Cu
1 In1.Cu
2 In2.Cu
3 In3.Cu

Tracks (wires and vias)

A wire is stored in a TRACK object. Vias are in a class derived from TRACK. Let’s list some of them.

# clk net was defined above as was SCALE
clktracks = board.TracksInNet(clknet.GetNet())
   for track in clktracks:
       print("{},{}->{},{} width {} layer {}".format(track.GetStart().x/SCALE,

And here are the wires

121.92,97.79->126.492,97.79 width 0.25 layer F.Cu
127.762,100.33->125.984,100.33 width 0.25 layer F.Cu
127.762,99.314->127.762,100.33 width 0.25 layer B.Cu

So that’s how to query data. In my next post, I’ll talk about making changes

The basics of scripting in pcbnew

  1. thanks to recent work by Kicad contributor/developer Dick Hollenbeck

7 thoughts on “The basics of scripting in pcbnew

  • Pingback:modifying pcbnew layout from python – Kicad Scripting blog

  • Pingback:Querying pcbnew to generate a basic svg file – Kicad Scripting blog

    • May 21, 2017 at 3:36 pm

      I’m glad you got it work work. Sorry I didn’t see your comment before now.

  • August 23, 2018 at 10:18 pm

    I tried to put your tutorial into practice, but my console wont start up within pcbnew
    Only a DialogBox appears that says
    “Error: unable to create the python console”
    Are you familiar with that error and know any solutions to that?

    • September 7, 2018 at 7:57 am

      The Kicad 5.0 release has some issues with the Python interface. AFAIK, getting python to work again is the main point of kicad 5.1
      I’ve found the nightlies work well on ubuntu 16.04. They do not work on ubuntu 18 and by extension the recent Mints. I don’t use windows or Mac so I can’t speak to those. I haven’t read anything about those platforms, so I can’t be helpful for those platforms.

  • December 28, 2018 at 6:24 am

    Good Examples. Thanks mmccoo!
    In the above layer example,
    “numlayers = pcbnew.LAYER_ID_COUNT ”
    is not working. so may be corrected as
    “numlayers = pcbnew.PCB_LAYER_ID_COUNT”


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.