part2kicad
Type an LCSC number, get a finished KiCad part in your project — symbol, footprint and 3D model, with a note on the symbol saying where every value came from.
cd my-kicad-project
part2kicad add C12594
TL074CDR (C12594) → my-kicad-project
14 pins in 4 units
Footprint SOIC-14_3.9x8.7mm_P1.27mm, 14 pads
3D model TL074CDR.step
Fetched on 2026-08-14
Open the schematic, press A, and the part is in the list. No download folder, no manual library table, no copying files around.
What you get
- Symbol, footprint and 3D model in one go. They land in your project's own library and both library tables are registered for you.
- Multi-unit parts come out as one part. A quad op-amp becomes one symbol with four
units —
U1AtoU1D— not four separate parts. - Provenance on the part. Source, part number and fetch date are fields on the symbol, so in six months you can still tell where it came from.
- Nothing is overwritten by accident. A part that is already in the library is reported, not replaced.
- Search without leaving the terminal.
part2kicad search rp2040lists hits with price and stock, you pick one, it is taken in.
Requirements
-
Python 3.11 or newer
-
KiCad 10.0 or newer. The tool calls
kicad-cli, which ships with KiCad. On Windows that program is normally not on the search path, sopart2kicadlooks in the usual installation folders. If it still cannot find it, say where it is:set PART2KICAD_KICAD_CLI=C:\Program Files\KiCad\10.0\bin\kicad-cli.exeIn PowerShell the same line reads:
$env:PART2KICAD_KICAD_CLI = "C:\Program Files\KiCad\10.0\bin\kicad-cli.exe"
Installation
uv pip install part2kicad
Plain pip install part2kicad works just as well. The package is a pure
py3-none-any wheel, so no compiler is needed on your machine.
Or from a wheel you build yourself, which is the route while working on the tool:
uv build
uv pip install dist/part2kicad-*.whl
Publishing to PyPI was a step of its own rather than a side effect of development,
because it cannot be taken back: it claims the name permanently and turns the command
layout (search, add) into a published interface that scripts and tutorials will
anchor themselves to. A released version can be yanked, but its number can never be
reused.
Your first part
-
Open a terminal in your KiCad project folder — the one holding the
.kicad_profile.part2kicadfinds the project the way git finds a repository: from the working directory upwards. If there is none, it stops instead of writing somewhere arbitrary. -
Take a part in. If you know the LCSC number:
part2kicad add C12594If you do not, search by manufacturer part number or by description:
part2kicad search tl074You get a numbered list with package, price, stock and whether CAD data exists at all. Pick a number, and that part is taken in — search and import are one invocation.
-
Open the schematic in KiCad and press A to place a symbol. The library is named after your project and is already in the list; you do not have to add anything under Preferences → Manage Symbol Libraries.
-
Check the 3D model. Open the board, press Alt+3. The model is stored inside the project, so the folder still works on a machine that has never seen
part2kicad.
If KiCad was already open while the part was written, use Preferences → Manage Symbol Libraries → OK or restart it — KiCad reads the library tables once at start.
Everyday use
part2kicad add C2040 # take a part in by number
part2kicad search rp2040 # search, pick, take it in — one invocation
part2kicad add C2040 --force # replace a part that is already there
part2kicad add C2040 --project ../my-board # name the project explicitly
part2kicad add C2040 --json # machine-readable output, asks nothing
part2kicad add C2040 --verbose # one line per fetch on stderr
Taking the same part in twice
If the part is already in the project library, part2kicad says so along with the date
of the first fetch and writes nothing. Anyone who has touched up a part by hand does
not lose that work to a careless second invocation.
--force replaces it. A symbol already placed in the schematic then has to be brought up
to date there, via Tools → Update Symbols from Library.
What ends up on the part
| Group | Fields |
|---|---|
| Provenance | Supplier Part, Manufacturer, Manufacturer Part, Datasheet, Source, Fetch Date |
| Commercial data | Price and Stock, each with the date it was fetched |
| Technical parameters | whatever the source delivers, under its unchanged field names |
| Assembly | JLCPCB Part Class (Basic/Extended) — it decides the assembly cost |
Every field except Reference and Value is created hidden, so the schematic stays
readable. Price and stock only come with part2kicad search; the fetch by part number
does not carry them, and part2kicad does not invent a price.
The Datasheet link is checked before it is written: one HEAD request asks the server
what it would actually deliver. Many links that end in .pdf return a web page, and the
field says so rather than pretending.
When something goes wrong
| What you see | What it means | What to do |
|---|---|---|
kicad-cli not found |
KiCad is not installed, or not where the tool looked | Set PART2KICAD_KICAD_CLI to the full path, see Requirements |
no KiCad project found |
You are not inside a project folder | cd into the folder holding the .kicad_pro file, or pass --project |
this part has no CAD data |
The supplier has the part but no symbol or footprint for it | The message names the part and links its datasheet; draw it by hand or pick another part |
already in the library |
The part was taken in before | That is the safeguard, not an error. --force replaces it |
| The library does not show in KiCad | KiCad read its library tables at start | Preferences → Manage Symbol Libraries → OK, or restart KiCad |
| Everything hangs for two minutes | The supplier is throttling you | Leave it running; it waits and retries. Ctrl-C stops it cleanly at any time |
What it cannot do yet
Honest rather than sounding complete:
- The report does not exist yet. Provenance and fetch date are on the part as fields; a report that shows field by field where each value came from, and which KLC rules were checked with what outcome, arrives with phase 3. Until then, "traceable" means every value comes from the source — not that a rule check has run.
- A local result store does not exist yet, so a second
add … --forcefetches the same geometry again. It arrives with phase 5. - The field names of the technical parameters stay as the source delivers them — so, inconsistent. Unifying them is a step of its own and has not been taken yet.
- macOS is untested, and nobody has run this on Linux yet. Development and testing
happen on Windows. For Linux the platform assumptions are pinned down statically — no
hard-wired path, no shell invocation, no file access without a stated encoding,
configuration folder from
platformdirs— but a run is still outstanding. - Two concurrent invocations on the same library can lose a symbol. The swap of the finished file is atomic; the read-modify-write before it is not. For an interactive single-workstation tool, a file lock has deliberately not been built in.
- Price and stock are only available via
part2kicad search, see above.
How this tool treats the data sources
part2kicad queries foreign servers that have no contract with us to serve it. What it
does while doing so is written out here in full, because a user is entitled to know what
runs in their name.
Endpoints used
All the addresses live in src/part2kicad/recipe.toml and not in the program code.
If the counterpart changes, the repair is an edit there — not a program update.
| Purpose | Address | When |
|---|---|---|
| Search | https://pro.easyeda.com/api/eda/product/search |
once per search invocation |
| Geometry (symbol and footprint) | https://easyeda.com/api/products/{lcsc}/components |
once per part taken in |
| 3D model (STEP) | https://modules.easyeda.com/…/{uuid} |
once per part taken in, if one is on file |
| Datasheet check | whichever address the response names — measured, atta., item. and so.szlcsc.com |
one HEAD request per part taken in |
Symbol and footprint come from one fetch; there is no second one for the footprint.
The datasheet check is a HEAD request: it asks what the server would deliver and reads no
body. If a part is already in the library, no fetch happens at all without --force.
Identification
part2kicad identifies itself as
part2kicad/<version> (+https://pypi.org/project/part2kicad/)
An honest identification that names the product. Explicitly not: a faked browser user agent, or bending name resolution to get around a block. This is not decoration — measured, the honest route gets through, and the dishonest one would not be acceptable even if it were necessary.
The identification can be changed without touching the program: your own recipe.toml
in the platform's configuration folder (Windows %LOCALAPPDATA%\part2kicad\, Linux
~/.config/part2kicad/) overrides individual values selectively:
[identity]
user_agent = "my-identification/1.0 (+https://example.example)"
Minimum intervals and behaviour when blocked
Every endpoint has its own time budget — the block we measured is tied to the path, and a shared budget would slow the search down as soon as a geometry fetch is due.
| Endpoint | Minimum interval | Maximum attempts |
|---|---|---|
| Search | 2.5 s | 3 |
| Geometry | 3.0 s | 3 |
| 3D model | 1.0 s | 3 |
| Datasheet check | 1.0 s | 3 |
The counterpart starts blocking after roughly 45 fetches within a few minutes —
cumulatively, not by peak rate. It then answers with a bare HTTP 403, without
Retry-After and without HTTP 429; the block therefore cannot be predicted, only
recognised. It clears by itself after about two minutes.
In that case part2kicad waits, starting at 120 seconds and doubling per attempt, for at
most three attempts — 120 + 240 = six minutes in total. More would be out of
proportion: measured, the block clears after around two minutes, and if it is still there
after three times that, it is not the ordinary rate limit; waiting longer is then no
better a bet than telling the user. The wait is shown as a status line — two minutes of
silence could not be told apart from a crash — and Ctrl-C ends it at any time with a
message instead of a stack trace. If the counterpart still will not let up, the
invocation stops with a message saying that it is not your machine's fault. Nothing is
written along the way: as long as not all the pieces are together, the library stays
untouched.
The numbers all live in recipe.toml and can be changed in your own user file — a limit
hard-coded in the program would take that option away.
The counterpart's exclusion list
easyeda.com/robots.txt disallows //api/ paths — and with them the geometry endpoint.
That is named openly here rather than passed over:
- The route is used deliberately, because there is no other one that would yield a part's CAD data.
- It is minimised: one fetch per part, never a full catalogue, and none at all for a part that is already present.
- A result store that would also spare the repeated fetch of the same part is still
missing — it arrives with phase 5. So a second
part2kicad add C2040 --forcefetches the geometry a second time. This is stated here because a disclosure that lists a measure not yet taken is not a disclosure. - The search traffic — that is, the volume — goes to
pro.easyeda.com, whose own exclusion list names only/loginand a set of named SEO bots, not/api/.
Anyone who judges this differently can leave part2kicad add alone and use the tool for
searching only.
Development
git clone https://github.com/AltF4Quit/part2kicad
uv sync
| Run | Command |
|---|---|
| Fast lane, without KiCad | pytest -m "not kicad and not live" |
| Full run (default) | pytest -m "not live" |
| Live tests against the real counterpart | pytest -m live --live |
Live tests never run by accident: they need both the marker and the --live switch.
Tests that need an installed KiCad skip themselves with a visible reason when none is
found.
License
GPL-3.0-or-later, see LICENSE.
Metadata
Release files for part2kicad 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| part2kicad-0.3.0.tar.gz | 289.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| part2kicad-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 391.4 kB
Release files / part2kicad-0.3.0.tar.gz
| Download URL | part2kicad-0.3.0.tar.gz |
|---|---|
| Size | 289.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6cc4a8bcce4324feb3e58d88cde9df125bebcde3165373eacffd3eea59ef6164
|
|
BLAKE2b-256 checksum How to use checksums |
ac48d97a6f307dc19133fbcb2d231c3187b4317b9d9437e7d8583b824740c7f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / part2kicad-0.3.0-py3-none-any.whl
| Download URL | part2kicad-0.3.0-py3-none-any.whl |
|---|---|
| Size | 101.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e5df0b6232d3ea11df81507ef02e7bdd54fd4bf21fec865a884ba2ca12ef5b49
|
|
BLAKE2b-256 checksum How to use checksums |
cc48d844935bd7533302537e26ed85234c5d7da350a51b1ceae9fdcddcf24f4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|