This Register provides a central location for storing production and testing data related to printed circuit board assembly (PCBA) services. It was created for storing data produced by the Testomatic PCB test jig system, but it doesn't require Testomatic to operate. You can use this Register independently, even without a PCB testing system at all. Its job is simply to store and report information about individual PCBs regardless of how the data is obtained.
It includes:
- A database for storage of information relating to individual boards
- Image storage to associate images with test records or boards
- File asset storage to associate design files, BOMs, firmware binaries, and other documents with board designs
- An internal web UI for managing records of boards and tests
- An external web UI for customers to look up details of specific boards
- An API for updating data stored in the system
- Supporting scripts to process photos of PCBs, extract serial numbers from barcodes, and store them
Data is stored in a hierarchical manner:
Organisations can represent customers such as companies that have purchased or commissioned the assembly of boards.
Users have access to the system through a username and password, and are associated with one or more organisations.
Designs represent a type of circuit board, and are associated with an organisation. Design files, BOMs, firmware binaries, and other assets can be attached directly to a design for easy reference.
Boards represent individual circuit boards with a serial number assigned, which are an embodiment of a design.
It's written as a Django + React application and can use either SQLite or MariaDB / MySQL.
The Parts library can look up component data from LCSC, DigiKey, and Mouser to auto-populate part source records (manufacturer SKU, stock, packaging, description, and product image).
LCSC lookup uses the lcsc Python library and requires no API key or account. It works out of the box.
DigiKey lookup requires a free DigiKey developer account and a one-time OAuth setup.
- Sign in or create an account at developer.digikey.com
- Create a new application and subscribe it to the Production Information V4 API product
- When asked for an OAuth Callback URL, enter:
(For a production deployment, use your actual domain, e.g.
https://localhost:8000/parts/source/digikey-callback/https://register.example.com/parts/source/digikey-callback/) - Once the application is created, copy the Client ID and Client Secret
Create a directory to store the OAuth token:
mkdir pyproj/.digikeyAdd the following to pyproj/.env:
DIGIKEY_CLIENT_ID = "your-client-id"
DIGIKEY_CLIENT_SECRET = "your-client-secret"
DIGIKEY_STORAGE_PATH = "/absolute/path/to/pyproj/.digikey"
DIGIKEY_CLIENT_SANDBOX = False
Set DIGIKEY_CLIENT_SANDBOX = True if your DigiKey application only has sandbox (not production) API access. Note that the sandbox catalog contains only a limited set of test parts.
DigiKey requires HTTPS for the OAuth callback, even on localhost. The easiest approach uses mkcert to create a locally-trusted certificate and runserver_plus (included with django-extensions, which is already installed) to serve over HTTPS.
Install mkcert and generate a localhost certificate:
brew install mkcert
mkcert -install
cd pyproj
mkcert localhostThis creates localhost.pem and localhost-key.pem in pyproj/.
Start the development server with SSL:
cd pyproj
source venv/bin/activate
python manage.py runserver_plus --cert-file localhost.pem --key-file localhost-key.pemThen visit:
https://localhost:8000/parts/source/digikey-connect/
This redirects to the DigiKey login page. After you log in and grant access, DigiKey redirects back to the app, which exchanges the code for a token and saves it to DIGIKEY_STORAGE_PATH. The token refreshes automatically on subsequent use — this step is only needed once (or if the refresh token expires).
Note: For day-to-day use after the token is saved, you can run the normal
python manage.py runserverwithout SSL — HTTPS is only needed for the initial OAuth flow.
Mouser lookup requires a free Mouser developer account. Unlike DigiKey, authentication is a simple API key — no OAuth flow is needed.
- Sign in or create an account at mouser.com/api-hub
- Under Search API, generate an API key
- Copy the key
Add the following to pyproj/.env:
MOUSER_API_KEY = "your-api-key"
Restart the development server and the Mouser fetch button will be active immediately — no further setup is required.
Element14 lookup (also covers Farnell and Newark regional storefronts) requires a free developer account. Like Mouser, it uses a simple API key — no OAuth flow is needed.
- Sign in or create an account at partner.element14.com
- Create a new application and note the API key
Add the following to pyproj/.env:
ELEMENT14_API_KEY = "your-api-key"
ELEMENT14_STORE_ID = "au.element14.com"
Set ELEMENT14_STORE_ID to the regional storefront you source from:
| Region | Store ID |
|---|---|
| Australia / Asia-Pacific | au.element14.com |
| UK / Europe | uk.farnell.com |
| USA | www.newark.com |
Restart the development server and the E14 fetch button will be active immediately.
All application data (database records and uploaded media files) can be exported to a self-contained ZIP archive and imported into another installation.
cd pyproj
python manage.py export_data [output.zip]If no output path is given, the archive is written to the current directory as
register-export-YYYY-MM-DD.zip.
The archive contains:
manifest.json— export timestamp, app version, record countdata.json— all records from thecrm,device, anderpappsmedia/— all uploaded files (design assets, device assets, images, etc.)
User accounts are not included; users must be re-created on the target installation manually. Thumbnail cache files are also excluded — they regenerate on first access.
cd pyproj
python manage.py import_data export.zipThe command shows details from the archive and asks for confirmation before
making any changes. To skip the prompt (e.g. in a script), pass --yes:
python manage.py import_data export.zip --yesThe import permanently deletes all existing application data before loading the archive. This is a clean-slate replace, not a merge. Make sure you have your own export or backup before running this on an installation with data you want to keep.
The import is database-transactional: if loading the records fails for any reason, the database is rolled back to its state before the import started. Media file restoration happens after the database is committed and is not transactional; if it is interrupted, re-running the import from the same archive will restore a consistent state.
Copyright (C) 2026 SuperHouse Automation Pty Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Because this software is licensed under the AGPL, if you run a modified version as a network service, you must make the corresponding source code available to users of that service. The source code for this project is available at https://github.com/SuperHouse/register.
