part2kicad
From an LCSC number to a finished KiCad part with traceable provenance — symbol, footprint and 3D model — straight into your own project.
What sets this apart from the existing tools is not convenience but traceability. Today that means: every generated part carries its provenance as fields on the symbol — source, fetch date and part number, and for parts taken from a search also price and stock together with the date they were fetched. The report that shows, field by field, where a value came from and which KLC rules it satisfies does not exist yet — it is the goal and it arrives with phase 3.
Status
Early development, but the path from the number to a wired-in part stands:
part2kicad search and part2kicad add create symbol, footprint and 3D model in the
KiCad project and register both library tables. What is still missing — multi-unit
parts, normalised field names, the quality report, the local cache — is listed in full
under Known limits.
Requirements
-
Python 3.11 or newer
-
KiCad 10.0 or newer. The tool invokes
kicad-clias a separate process. Ifkicad-cliis not on the search path — on Windows that is the normal case — it is looked for in the usual installation locations. Failing that, set the path explicitly:set PART2KICAD_KICAD_CLI=C:\Program Files\KiCad\10.0\bin\kicad-cli.exe
Installation
From PyPI:
uv pip install part2kicad
The package is a pure py3-none-any wheel; no compiler is needed on the target 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 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.
Usage
part2kicad search rp2040 # search, pick, take it in — all in one invocation
part2kicad add C2040 # when the part number is already known
part2kicad add C2040 --force # replace a part that is already present
The target project is looked up the way git does it: from the working directory upwards,
looking for a .kicad_pro file. --project <path> states it explicitly. If none is
found, the tool stops rather than writing somewhere arbitrary.
--json prints machine-readable output and asks nothing; --verbose writes one line per
fetch to stderr, with the address and the status code.
Importing the same part a second time
If the part is already in the project library, part2kicad reports that together with
the date of the first fetch and writes nothing. Anyone who has touched up the 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
"Update Symbols from Library".
What ends up on the generated part
| Group | Fields |
|---|---|
| Provenance and traceability | Supplier Part, Manufacturer, Manufacturer Part, Datasheet, Source, Fetch Date |
| Commercial data | Price and Stock, each with Price Date resp. Stock Date — the date they were fetched |
| Technical parameters | whatever the source delivers, under its unchanged field names |
| Assembly | JLCPCB Part Class (Basic/Extended) — it decides the assembly cost |
Price and stock only appear in the search response. Whoever needs them on the part gets
it via part2kicad search; the fetch by part number does not bring them along, and
part2kicad does not invent a price. Every field except Reference and Value is
created hidden, so the schematic stays readable.
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.
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 |
Symbol and footprint come from one fetch; there is no second one for the footprint.
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 |
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 cap
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 does not
exist yet — 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.
Known limits
Honest rather than sounding complete:
- 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.
- 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. For macOS the search path tokicad-cliis on file as well, but nobody has run it there either. - Parts made of several units are detected and explicitly refused, rather than filing a symbol with zero pins. Merging them comes later.
- 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.
- The quality report does not exist yet. Provenance and fetch date are on the part as fields; a report that shows the provenance field by field and lists the KLC rules checked together with their outcome arrives with phase 3. Until then, "checked" is the guarantee that every value comes from the source — not that a rule check has run.
- A local cache does not exist yet. Every fetch goes to the counterpart; a second
add … --forcefetches the same geometry again. The cache arrives with phase 5, see also the exclusion list above. - Price and stock are only available via
part2kicad search, see above.
Tests
| 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.2.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.2.0.tar.gz | 204.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| part2kicad-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 285.4 kB
Release files / part2kicad-0.2.0.tar.gz
| Download URL | part2kicad-0.2.0.tar.gz |
|---|---|
| Size | 204.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
508c0e880d105ec3e3321038b1ef8ad4ac85cfc05a7c489aa15edb81fe5b2664
|
|
BLAKE2b-256 checksum How to use checksums |
ca1422ffaafae810d61e22aa73023eb58afe4c20880c064de4b0043572d98f65
|
| 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.2.0-py3-none-any.whl
| Download URL | part2kicad-0.2.0-py3-none-any.whl |
|---|---|
| Size | 80.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
827a6ad1c1af086b5120838c38a15fa228ce1eed6097959b1b2148f97a827758
|
|
BLAKE2b-256 checksum How to use checksums |
7c6477e806d956d499eb259a386aa3adc2428aab1aa946c6f974dd0a11b6fe7e
|
| 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}
|