Well to be fair, I did intend to have a bit more documentation ready before “going public” with the API at 9.0.0 release. That is why there has been no widespread announcement of it yet; I just sent an email to the dev list saying that people who are happy working with zero documentation and just reading the source code should try it out.
This was not a criticism of you or the rest of the dev team, you’re doing awesome things!
I’m not even in this mailing list. I got this from this forum, the git log and your talks at KiCon.
I hope it’s okay to hijack this thread with a few more questions. I was waiting for the documentation, but this thread made me curious.
When installing an IPC plugin using PCM, will the specified requirements be installed as well? If so, will they be installed in the system Python interpreter, or in a venv in the KiCad 3rd-party-plugin folder?
When launching the plugin from KiCad, I’m assuming that the plugin “knows” from which KiCad process it was launched, and which board is open in that process?
If launching the plugin from an IDE, or from the system Python interpreter, is there a way to list running KiCad processes and have the user select which process the plugin should interact with?
I read somewhere that the API currently doesn’t have support for plotting. Are there plans to add this ability? If not I could probably work with the CLI, but if there are plans I would much rather wait for the IPC API to support plotting.
On that same note, can I get the path to the CLI binary and the path to the board-file from API calls?
If I implement plotting like this, the board probably have to be saved before plotting, which is ashame. Also, I’m assuming that the plotting will also take much longer since my plugin (Board2Pdf) usually makes a lot of separate plot-calls. I’m not that familiar with the CLI, but I want the ability to have different plotting settings for different layers that shall be plotted.
Yes, into a venv (but not in the plugin folder, in a separate cache folder)
When launching from KiCad, the plugin can know which KiCad process launched it. It can query to find the open board, if it needs that info.
Not at the moment, but if you only have one instance of KiCad open, it will use the default API socket path and the Python side will automatically talk to it.
It is not a priority right now. We are pushing users to kicad-cli
for plotting. Maybe plotting through the API will be added someday, but I would not recommend waiting around. If there are any plotting/exporting things that don’t work for you through kicad-cli
, please open bug reports about them.
You can make a feature request for plotting through the API (I guess the “file needs to be saved first” thing won’t ever be fixed for the CLI) and we can see how popular it is
Board file yes, CLI binary path no. You could add a feature request for this.
You could save it to a temporary location?
Thanks a lot for your answers! It’s good to know that I shouldn’t wait around for plotting to be added.
Thanks! I’ll do that.
Yea, that idea came to me as well. If the API supports exporting the open board file to a temporary location that would be a decent workaround. As long as that doesn’t change where the open board is saved, so that when the user clicks save next time it saves to his/her file and not to the temporary created file.
Are there plans to add this support, or should I add a feature request? More often than not I tend to have several KiCad projects open at the same time.
EDIT: Nevermind… Since the plugin will probably be opened from a KiCad instance this won’t be a problem.
No plans at the moment. There is not really a way to query other than by searching known paths. I would suggest that when you are developing a plugin, just keep one instance open.
For Board2PDF I would say the new API is not quite ready. The focus of the initial API is on manipulating things on the board, so for your plugin that focuses only on a form of exporting, things are not really possible yet that you can do in SWIG. It would be good to capture those in feature requests once you have a chance to see what you need.
Yea, no problem for development! As long as it works with multiple instances when the plugin is loaded from KiCad I see no reason to be able to query for instances.
I’ll do that! Apart from plotting pdfs Board2Pdf doesn’t need much. The only things that I remember from the top of my mind is that it retrieves a list of all layers (not just layers that are being used in the board). It fetches id, standard name and user defined name. It also retrieves the path for the plugin and the path for the board file. I’ll write it up in a feature request when I find the time. Although it would be preferable to see the upcoming documentation first to see what’s in there.
I’m definitely not experienced enough to work without documentation. I’ve had a really hard time with the Doxygen documentation for the SWIG API. As anyone who have looked at my code can probably agree to; I’m not a software engineer.
Just downloaded the latest Nightly for Windows and gave the IPC API a quick try.
It didn’t auto-detect my python interpreter when I clicked the Detect Automatically button, but maybe this was fixed after Jan 1 2025 06:17:19 when the Nightly was built. Python is in my path, and it’s installed using the standard Windows Installer.
I enabled the API under Preferences → Plugins → Enable KiCad API and selected my python environment.
I opened a terminal, cloned the kicad-python repo, went into the examples\round_tracks directory and ran:
- pip install -r requirements.txt
- python round_tracks_action.py
The plugin started and seems to work!
Also tried hello.py and it worked flawless.
$ python hello.py
Connected to KiCad 9.0.0-rc1-273-g6c43c25b4c
However, create_zone.py doesn’t seem to work.
$ python create_zone.py
Traceback (most recent call last):
File “C:\git\other-repos\kicad-python\examples\create_zone.py”, line 33, in
outline.append(PolyLineNode.from_xy(from_mm(100), from_mm(100)))
^^^^^^^^^^^^^^^^^^^^
AttributeError: type object ‘PolyLineNode’ has no attribute ‘from_xy’
Nether does layer_indicator.py
$ python layer_indicator.py
Traceback (most recent call last):
File “C:\git\other-repos\kicad-python\examples\layer_indicator\layer_indicator.py”, line 40, in
char_width = board.get_text_extents(sizing_text).size.x
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: ‘Board’ object has no attribute ‘get_text_extents’
Parhaps these two plugins needs some features on the pcb that it doesn’t have.
Also, when closing the round_tracks_action.py window (either by pressing Run or the X in the upper corner), the script doesn’t close in the terminal. I have to press Ctrl+C in order for it to exit.
What I cannot figure out is how to “install” a plugin in KiCad, to be able to start the plugin from the PCB Editor.
I tried placing the round_tracks folder in C:\Users\denne\Documents\KiCad\9.0\scripting\plugins, but that didn’t make it appear. Also tried zipping its content and to install it from the PCM, but PCM expects it to contain a metadata.json file.
I’m assuming that there should be a init.py file in round_tracks folder for it to work from PCB Editor?
Application: KiCad PCB Editor x64 on x64
Version: 9.0.0-rc1-273-g6c43c25b4c, release build
Libraries:
wxWidgets 3.2.6
FreeType 2.13.3
HarfBuzz 10.0.1
FontConfig 2.15.0
libcurl/8.10.1-DEV Schannel zlib/1.3.1
Platform: Windows 11 (build 22631), 64-bit edition, 64 bit, Little endian, wxMSW
OpenGL: Intel, Intel(R) Iris(R) Xe Graphics, 4.6.0 - Build 32.0.101.6127
Build Info:
Date: Jan 1 2025 06:17:19
wxWidgets: 3.2.6 (wchar_t,wx containers)
Boost: 1.86.0
OCC: 7.8.1
Curl: 8.10.1-DEV
ngspice: 43
Compiler: Visual C++ 1942 without C++ ABI
KICAD_IPC_API=ON
Locale:
Lang: sv_SE
Enc: UTF-8
Num: 1 234,5
Encoded кΩ丈: D0BACEA9E4B888 (sys), D0BACEA9E4B888 (utf8)
I didn’t do that. I only enabled the API and assumed that for internal plugins (no external access that you used) this would suffice.
You put it either in Documents\KiCad\9.0\3rdparty\plugins
or Documents\KiCad\9.0\scripting\plugins
. However, the plugin load is currently broken. This is the issue I observed.
No, the new plugin.json has an entrypoint
definition that points to a python file. I assume this does the initialization. This file now also contains the name and icon definitions, which previously had been done in python.
Right when I hit send, a new Nightly popped up. Uninstalled the previous version and installed kicad-nightly-9.0.0.rc1.329.g89a50a3dcf-x86_64-lite.exe.
Now the Python Interpreter that comes with KiCad was automatically found (without even clicking the “Detect Automatically” button).
Ah, I see! Thanks for clarifying.
Okay, that would certainly explain why it wasn’t working.
I would assume the same. Although, if you don’t install the plugin using PCM but just copy it to the correct location, you probably have to run “pip install -r requirements.txt” in the selected Python environment?
Having the ability to run the plugin externally will really help when developing!
Could also be because the path is now stored in the config files. Does this still work when you delete the path and press the auto detect button?
Absolutely, yes!
Yes it does! And when I used the previous Nightly I pointed out Python installed on my system. When uninstalling that Nightly I choose to remove all settings. After firing up the new Nightly it found Python that came with KiCad.
I’ve added your testing to the issue: IPC Python Plugin Loading Broken in Windows (#19465) · Issues · KiCad / KiCad Source Code / kicad · GitLab
Thanks! I was just about to do the same.
To be clear: there is no difference between “internal plugins” and running stuff from your terminal or IDE. There is no shortcut for internal plugins to talk to KiCad, and there is no shortcut for installing all the required Python dependencies (including the kicad-python wrapper itself)
This is currently broken for Windows only, it works on Mac and Linux. Working on it.
You are using an unreleased version of kicad-python
source code paired with the released (on PyPI) version of the installed library, which is older and has features/fixes missing. You should be able to do pip install -e .
inside the kicad-python
source directory to update your Python environment with the development version.
I see… So even if I start a plugin from KiCad, it won’t know which KiCad process that started it. The user must always close all instances of PCB Editor except one, before using a plugin that communicates with KiCad over the new API? I hope that this gets fixed in the future.
Except for when the plugin is installed from PCM? Or else I misunderstood your reply yesterday:
This is currently broken for Windows only, it works on Mac and Linux. Working on it.
You’re awesome!
You are using an unreleased version of
kicad-python
source code paired with the released (on PyPI) version of the installed library, which is older and has features/fixes missing. You should be able to dopip install -e .
inside thekicad-python
source directory to update your Python environment with the development version.
Ah! Didn’t think of that. Thanks!
Unfortunately it didn’t want to get built. Tested in both KiCad Python and System Python. Seems like some process used for building isn’t found.
File “C:\Program Files\Python311\Lib\subprocess.py”, line 1509, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified
Full output:
C:\git\other-repos\kicad-python>pip install -e .
Defaulting to user installation because normal site-packages is not writeable
Obtaining file:///C:/git/other-repos/kicad-python
Installing build dependencies … done
Checking if build backend supports build_editable … done
Getting requirements to build editable … done
Preparing editable metadata (pyproject.toml) … done
Requirement already satisfied: furo<2025.0.0,>=2024.8.6 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from kicad-python==0.1.1) (2024.8.6)
Requirement already satisfied: protobuf<6.0,>=5.29 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from kicad-python==0.1.1) (5.29.2)
Requirement already satisfied: pynng<0.9.0,>=0.8.0 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from kicad-python==0.1.1) (0.8.0)
Requirement already satisfied: sphinx==7.4 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from kicad-python==0.1.1) (7.4.0)
Requirement already satisfied: sphinxcontrib-applehelp in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.0.0)
Requirement already satisfied: sphinxcontrib-devhelp in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.0.0)
Requirement already satisfied: sphinxcontrib-jsmath in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (1.0.1)
Requirement already satisfied: sphinxcontrib-htmlhelp>=2.0.0 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.1.0)
Requirement already satisfied: sphinxcontrib-serializinghtml>=1.1.9 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.0.0)
Requirement already satisfied: sphinxcontrib-qthelp in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.0.0)
Requirement already satisfied: Jinja2>=3.1 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (3.1.5)
Requirement already satisfied: Pygments>=2.17 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.18.0)
Requirement already satisfied: docutils<0.22,>=0.20 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (0.21.2)
Requirement already satisfied: snowballstemmer>=2.2 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.2.0)
Requirement already satisfied: babel>=2.13 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.16.0)
Requirement already satisfied: alabaster~=0.7.14 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (0.7.16)
Requirement already satisfied: imagesize>=1.3 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (1.4.1)
Requirement already satisfied: requests>=2.30.0 in c:\program files\kicad\9.0\bin\lib\site-packages (from sphinx==7.4->kicad-python==0.1.1) (2.32.3)
Requirement already satisfied: packaging>=23.0 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (24.2)
Requirement already satisfied: colorama>=0.4.6 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from sphinx==7.4->kicad-python==0.1.1) (0.4.6)
Requirement already satisfied: beautifulsoup4 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from furo<2025.0.0,>=2024.8.6->kicad-python==0.1.1) (4.12.3)
Requirement already satisfied: sphinx-basic-ng>=1.0.0.beta2 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from furo<2025.0.0,>=2024.8.6->kicad-python==0.1.1) (1.0.0b2)
Requirement already satisfied: cffi in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from pynng<0.9.0,>=0.8.0->kicad-python==0.1.1) (1.17.1)
Requirement already satisfied: sniffio in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from pynng<0.9.0,>=0.8.0->kicad-python==0.1.1) (1.3.1)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from Jinja2>=3.1->sphinx==7.4->kicad-python==0.1.1) (3.0.2)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\program files\kicad\9.0\bin\lib\site-packages (from requests>=2.30.0->sphinx==7.4->kicad-python==0.1.1) (3.4.1)
Requirement already satisfied: idna<4,>=2.5 in c:\program files\kicad\9.0\bin\lib\site-packages (from requests>=2.30.0->sphinx==7.4->kicad-python==0.1.1) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\program files\kicad\9.0\bin\lib\site-packages (from requests>=2.30.0->sphinx==7.4->kicad-python==0.1.1) (2.3.0)
Requirement already satisfied: certifi>=2017.4.17 in c:\program files\kicad\9.0\bin\lib\site-packages (from requests>=2.30.0->sphinx==7.4->kicad-python==0.1.1) (2024.12.14)
Requirement already satisfied: soupsieve>1.2 in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from beautifulsoup4->furo<2025.0.0,>=2024.8.6->kicad-python==0.1.1) (2.6)
Requirement already satisfied: pycparser in c:\users\denne\documents\kicad\9.0\3rdparty\python311\site-packages (from cffi->pynng<0.9.0,>=0.8.0->kicad-python==0.1.1) (2.22)
Building wheels for collected packages: kicad-python
Building editable for kicad-python (pyproject.toml) … error
error: subprocess-exited-with-error
× Building editable for kicad-python (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [43 lines of output]
Generating protobuf wrappers…
Generating Python classes from protobuf files…
Traceback (most recent call last):
File “C:\git\other-repos\kicad-python\setup.py”, line 38, in
build(setup_kwargs)
File “C:\git\other-repos\kicad-python\build.py”, line 32, in build
pre_build()
File “C:\git\other-repos\kicad-python\build.py”, line 28, in pre_build
generate_protos(proto_in, proto_out)
File “C:\git\other-repos\kicad-python\tools\generate_protos.py”, line 41, in generate_protos
subprocess.run([protoc,
File “C:\Program Files\KiCad\9.0\bin\Lib\subprocess.py”, line 548, in run
with Popen(*popenargs, **kwargs) as process:
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Program Files\KiCad\9.0\bin\Lib\subprocess.py”, line 1026, in init
self._execute_child(args, executable, preexec_fn, close_fds,
File “C:\Program Files\KiCad\9.0\bin\Lib\subprocess.py”, line 1538, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [WinError 2] The system cannot find the file specified
Traceback (most recent call last):
File “C:\Program Files\KiCad\9.0\bin\Lib\site-packages\pip_vendor\pyproject_hooks_in_process_in_process.py”, line 353, in
main()
File “C:\Program Files\KiCad\9.0\bin\Lib\site-packages\pip_vendor\pyproject_hooks_in_process_in_process.py”, line 335, in main
json_out[‘return_val’] = hook(**hook_input[‘kwargs’])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Program Files\KiCad\9.0\bin\Lib\site-packages\pip_vendor\pyproject_hooks_in_process_in_process.py”, line 273, in build_editable
return hook(wheel_directory, config_settings, metadata_directory)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\denne\AppData\Local\Temp\pip-build-env-u_jddzhv\overlay\Lib\site-packages\poetry\core\masonry\api.py”, line 82, in build_editable
return WheelBuilder.make_in(
^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\denne\AppData\Local\Temp\pip-build-env-u_jddzhv\overlay\Lib\site-packages\poetry\core\masonry\builders\wheel.py”, line 88, in make_in
wb.build(target_dir=directory)
File “C:\Users\denne\AppData\Local\Temp\pip-build-env-u_jddzhv\overlay\Lib\site-packages\poetry\core\masonry\builders\wheel.py”, line 117, in build
self._build(zip_file)
File “C:\Users\denne\AppData\Local\Temp\pip-build-env-u_jddzhv\overlay\Lib\site-packages\poetry\core\masonry\builders\wheel.py”, line 182, in _build
self._run_build_command(setup)
File “C:\Users\denne\AppData\Local\Temp\pip-build-env-u_jddzhv\overlay\Lib\site-packages\poetry\core\masonry\builders\wheel.py”, line 242, in _run_build_command
subprocess.check_call([
File “C:\Program Files\KiCad\9.0\bin\Lib\subprocess.py”, line 413, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘[‘C:/Program Files/KiCad/9.0/bin/python.exe’, ‘C:\git\other-repos\kicad-python\setup.py’, ‘build_ext’, ‘–inplace’]’ returned non-zero exit status 1.
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building editable for kicad-python
Failed to build kicad-python
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (kicad-python)
So even if I start a plugin from KiCad, it won’t know which KiCad process that started it.
No. It will know, because the correct info will be passed via environment variables. This will all be more clear when it is documented, I suggest not worrying about it right now.
Unfortunately it didn’t want to get built. Tested in both KiCad Python and System Python. Seems like some process used for building isn’t found.
Looks like you are probably missing protobuf-compiler. You can get this standalone or from vcpkg if you have a kicad development environment.
No. It will know, because the correct info will be passed via environment variables. This will all be more clear when it is documented, I suggest not worrying about it right now.
Perfect!
Looks like you are probably missing protobuf-compiler. You can get this standalone or from vcpkg if you have a kicad development environment.
Thanks! I currently don’t have a kicad development environment. I’ll install vcpkg and the protobuf-compiler some other day.
Thanks! I’ll do that.
I went ahead and added this already, it was easy