Skip to content

A lightweight home network web app to track electronics parts

License

Notifications You must be signed in to change notification settings

chiefenne/Electronics-Inventory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Electronics Inventory

A lightweight web app to track electronics parts (category, subcategory, description, package, container, quantity, notes) with a simple HTML UI โ€” including optional links to datasheets and pinouts.

Note

If youโ€™re looking for a more professional-grade (and free) inventory system with broader features, you may want to check out InvenTree (it might be a better fit depending on your needs).

Features

  • Add, inline-edit, and delete parts
  • Duplicate parts (pre-fills add form for quick variations)
  • AI Auto-Fill (optional): automatically populate part data from a description using OpenAI + Tavily web search
  • Part detail page: click any part description to view a dedicated page with all metadata, images, and datasheet in an organized layout
  • Maintenance page: manage lookup values (categories, subcategories, containers, packages) with add/rename/delete operations and usage tracking
  • Search + filter by category, subcategory, and container (free-text search also matches container codes like BX-50)
  • Click a container chip in the table to open the container page
  • CSV export
  • Optional links per part: datasheet + pinout (quick-open buttons in the table)
  • Optional images per part: device photo + pinout image (hover preview in the table)
  • Optional stock levels (low-stock warning colors) for quantity
  • Container pages and printable container labels with QR codes
  • Uses a local SQLite database file (no server required)

Maintenance Page

The maintenance page (/maintenance) lets you manage the lookup values used for suggestions and dropdowns throughout the app.

Features

  • Accordion interface: Collapsible sections for Categories, Subcategories, Containers, and Packages โ€” remembers which section you last opened
  • Usage tracking: Each section header shows the total count and how many items are unused (e.g., "9 (2 unused)")
  • Visual distinction: Unused items appear with a dashed orange border so you can quickly identify candidates for cleanup
  • Interactive tags: Click any existing item tag to auto-select it in the rename and delete dropdowns
  • Inline feedback: Success/error messages appear within the relevant section, not at the top of the page

Operations

  • Add: Create a new category, subcategory, container, or package
  • Rename: Rename an existing value โ€” all parts using the old value are automatically updated (useful for merging duplicates)
  • Delete: Remove an unused value โ€” blocked if any parts still reference it

Quantity + stock levels

The Qty chip can be color-coded using optional stock levels:

  • Enter levels as hi:lo (example: 10:5)
    • Green: quantity $\ge$ hi
    • Yellow: lo $\le$ quantity $<$ hi
    • Red: quantity $<$ lo
  • Enter a single number like 5 to use the same value for both (5:5).
  • Leave empty to disable levels (chip stays neutral).

Part detail page

Click any part description in the main table to open its detail page, which shows:

  • All metadata (description, package, category, subcategory, container, notes, timestamps)
  • Quantity controls with +/โˆ’ buttons and inline editing (same as main page)
  • Device image and pinout image side-by-side (with placeholders if missing)
  • Datasheet/documentation link for quick access

This provides a focused view of a single part with all its information organized in one place. Use the Back to Inventory button to return to the main table.

Editing images and datasheets on the detail page

The detail page allows you to add or update images and datasheets for existing parts:

  1. Click the โœ๏ธ edit icon next to "Device Image", "Pinout", or "Datasheet / Documentation"
  2. An edit form appears with:
    • Text input: enter a filename (for local images) or URL manually
    • ๐Ÿ” AI Search button: search for images or datasheets using AI (requires API keys)
  3. For images, the AI search opens a modal with image results โ€” click one to download and save it locally
  4. For datasheets, the AI search shows a list of PDF links from electronics distributors โ€” click one to use that URL
  5. Click Save to update the part, or Cancel to discard changes

This is especially useful for parts that were added without images or datasheets โ€” you can easily populate them later.

Screenshots

Fig. 1: Main inventory screen with search, filters, and inline editing.

Main inventory screen

Fig. 2 & 3: Printable container labels โ€“ combined QR + text.

Container label with QR code and text Container label with QR code and text

Fig. 4: Contents of box BX-41 in Gridfinity bins with part labels.

Container BX-41 contents

More screenshots:

Tech stack

  • FastAPI (serves HTML)
  • Jinja2 templates
  • SQLite (stored in inventory.db)
  • OpenAI API (optional, for AI Auto-Fill)
  • Tavily API (optional, for web/image search)

AI Auto-Fill (optional)

The โœจ Auto-Fill button uses AI to automatically populate part data from a description. It searches the web for datasheets and specifications, then extracts structured data.

How it works

  1. Enter a part description (e.g., "LM358 DIP" or "ADS1115 I2C ADC module")
  2. Click โœจ Auto-Fill
  3. The system uses Tavily to search for datasheets and technical information
  4. OpenAI extracts and structures the data (package, category, subcategory, notes, datasheet URL)
  5. Form fields are populated automatically โ€” review and adjust as needed

Image search

The ๐Ÿ“ท (part image) and ๐Ÿ“ (pinout image) buttons let you search for images:

  1. Click the camera or pinout button next to the image field
  2. A modal displays image results from Tavily image search
  3. Click an image to select it โ€” the image is downloaded and saved locally:
    • Part images are saved to static/images/
    • Pinout images are saved to static/pinouts/
    • The filename (based on the part description) is inserted into the field

This ensures images are stored permanently and won't break if external sources change or go offline.

Note: Image search is also available on the Part Detail page for updating existing parts โ€” click the edit icon next to the image section and use the ๐Ÿ” search button.

Setup

To enable AI features, set these environment variables:

export OPENAI_API_KEY="sk-..."
export TAVILY_API_KEY="tvly-..."

Both keys are required. If either is missing, the Auto-Fill and image search buttons will be disabled.

Get API keys:

Dependencies

The AI features require additional Python packages (already in requirements.txt):

pip install openai tavily-python

If these packages are not installed, AI features will be gracefully disabled.

Quickstart (local)

1) Create a virtualenv

python3 -m venv .venv
source .venv/bin/activate

2) Install dependencies

pip install -r requirements.txt

QR code support is included via the qrcode dependency in requirements.txt.

3) Run the server

This app uses a login page + server-side sessions. You must configure credentials via environment variables.

Local-only (no authentication):

INVENTORY_DISABLE_AUTH=1 \
INVENTORY_BASE_URL="http://127.0.0.1:8001" \
uvicorn app:app --reload --host 127.0.0.1 --port 8001

Do not use INVENTORY_DISABLE_AUTH on an internet-exposed instance.

If you run behind a reverse proxy (recommended for HTTPS), also set INVENTORY_BASE_URL so label QR codes point to the correct external hostname.

Example (behind reverse proxy + HTTPS):

export INVENTORY_BASE_URL="https://inventory.reverseproxy.com"

Dev (auto-reload on code changes):

INVENTORY_USER="andreas" \
INVENTORY_PASS_HASH='$pbkdf2-sha256$...$...$...' \
INVENTORY_BASE_URL="http://127.0.0.1:8001" \
uvicorn app:app --reload --host 0.0.0.0 --port 8001 --proxy-headers

Prod (no reload):

INVENTORY_USER="andreas" \
INVENTORY_PASS_HASH='$pbkdf2-sha256$...$...$...' \
INVENTORY_BASE_URL="http://127.0.0.1:8001" \
uvicorn app:app --host 0.0.0.0 --port 8001 --proxy-headers

Open:

Data storage

On startup, the app creates/uses a SQLite database at inventory.db (in the repo directory).

  • To reset all data: stop the server and delete inventory.db.

Useful routes

  • / โ€“ main inventory table
  • /parts/{uuid} โ€“ detail page for a specific part
  • /help โ€“ help page
  • /export.csv โ€“ download CSV export (respects current filters via query params)
  • /containers/{code} โ€“ show parts in a specific container
  • /containers/labels โ€“ printable labels with QR codes

Images (device + pinout)

Each part can store optional image URLs:

  • image_url โ€“ photo of the IC/module/device

Pinouts are stored in pinout_url. If pinout_url points directly to an image, the table shows a hover preview.

Recommended: store images in static/

Store images under the repo's static/ folder (for example static/images/ and static/pinouts/). Then reference them with a URL starting with /static/...:

  • image_url: /static/images/MP2307_HW133ABC_board.jpg
  • pinout_url: /static/pinouts/MP2307_pinout.jpg

Shortcut: when editing image_url / pinout_url, you can paste just the filename (for example MP2307_HW133ABC_board.jpg or MP2307_pinout.jpg). The app will automatically resolve it under /static/images/ or /static/pinouts/.

Note: static/images/ and static/pinouts/ are present in the repo (via .gitkeep), but the actual image files are intentionally ignored by git.

Hover preview behavior

If the URL ends with an image extension (.png, .jpg, .jpeg, .gif, .webp, .svg), the table shows a hover preview. Clicking the preview opens the image in a new tab.

On touch devices (mobile/tablet), previews are shown by tapping the icon (instead of hovering). Use the ร— button to close the preview.

QR label URLs (important)

Container label QR codes are generated using BASE_URL in app.py.

  • Configure the external base URL via INVENTORY_BASE_URL so QR codes point to a reachable URL (LAN IP or public HTTPS hostname).

Label printing layouts

The app supports two types of labels:

Container labels

  • QR only (1 label) โ€“ container code + QR code
  • Text only (1 label) โ€“ container code + descriptive text
  • QR + text (1 label) โ€“ container code + QR code + optional text on one label
  • QR + text (2 labels) โ€“ creates two labels per container

Container label selection also supports:

  • Quantity per container โ€“ set how many copies to print for each selected container.
  • Multiple containers per sheet โ€“ when selecting multiple containers, labels fill the sheet leftโ†’right and wrap to the next row based on the chosen preset.

Part labels

Part labels are designed for small compartments inside containers, e.g, Gridfinity bins or other. Each label shows:

  • Container โ€“ which container the part is in (top, small)
  • Description โ€“ part name/description (large, prominent)
  • Notes โ€“ additional details (smaller)
  • Subcategory โ€“ part classification (bottom, italic)

To print part labels:

  1. Go to Labels in the navigation
  2. Select Part Labels (mutually exclusive with container labels)
  3. Filter parts by search text, category, or container
  4. Check the parts you want to label
  5. Select a preset and print

Note: Part label text sizes automatically scale down for smaller presets (like Avery 3666) via CSS custom properties.

Starting position (skip used labels)

If your Avery sheet has some labels already used, set "Start at position" to skip them. Positions are counted row-wise (left to right, top to bottom). The number of columns depends on your label preset.

Example for a 2-column layout (like Avery 3425):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”
โ”‚  1  โ”‚  2  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  3  โ”‚  4  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  5  โ”‚  6  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”˜

For example, if positions 1โ€“2 are used, set start position to 3 to begin on the second row.

Layout files

Label printing is implemented as:

  • Shared label UI/print styles: static/labels.css
  • One layout file per Avery preset: static/avery_<preset>.css (e.g. static/avery_3425.css)

Trademark notice: Averyยฎ is a registered trademark of its respective owner (commonly Avery Products Corporation and/or affiliated entities). This project is not affiliated with, sponsored, or endorsed by Avery. The Avery name and label numbers are used only to indicate intended compatibility with commonly available label sheets.

To add a new layout:

  1. Create static/avery_<new-id>.css
  2. Add a metadata comment near the top of the file:
    /* Meta: columns=2, rows=8, label_size=105x57mm */
    This enables the UI to show grid info (e.g., "2ร—8 = 16 labels") and position hints.
  3. Reload the Labels page โ€” the preset list is discovered automatically from static/avery_*.css

Print calibration (offset + spacing)

Printers often introduce small feed/margin offsets even with โ€œMargins: noneโ€. Each preset CSS supports knobs:

  • --label_offset_x / --label_offset_y (shift the whole sheet; negative moves left/up)
  • --label_gap_x / --label_gap_y (space between labels)

Example (move 5mm left and 1mm up):

--label_offset_x: -5mm;
--label_offset_y: -1mm;

Outlines (calibration vs Avery sheets)

By default, label borders are not printed (best for real Avery sheets where tiny alignment offsets can make printed outlines look off).

For calibration or printing on plain paper (where you want cut guides), enable Print cut outlines on the Labels page before printing (always shown on screen; printed only when enabled).

Authentication

This app uses a login page + server-side sessions (stored in SQLite) for all routes.

Configure it with:

  • INVENTORY_USER โ€“ username
  • INVENTORY_PASS_HASH โ€“ password hash in Passlib pbkdf2_sha256 format
  • INVENTORY_BASE_URL โ€“ optional; external base URL used for container label QR codes

Optional (local-only):

  • INVENTORY_DISABLE_AUTH โ€“ when set to 1/true, disables authentication entirely. Use only for fully local deployments (e.g. bound to 127.0.0.1). Do not enable this on an internet-exposed instance.

Note: the session cookie is configured as secure, so you should access the app via HTTPS (directly or via reverse proxy).

Generate a hash (example):

python3 -c "from passlib.hash import pbkdf2_sha256; print(pbkdf2_sha256.hash('change-me'))"

Run with credentials (example):

export INVENTORY_USER="andreas"
export INVENTORY_PASS_HASH='<paste-hash-here>'
uvicorn app:app --host 0.0.0.0 --port 8001 --proxy-headers

If INVENTORY_USER / INVENTORY_PASS_HASH are not set, the login page will show an error because auth is not configured.

Note: the Passlib hash contains $ characters. Use single quotes around INVENTORY_PASS_HASH (or escape $) to avoid shell expansion.

Notes

  • Security: even with Basic Auth, treat this as a trusted-LAN tool. Do not expose it directly to the public internet.
  • If you need remote access, prefer a VPN and restrict access.

License

MIT โ€” see LICENSE.

About

A lightweight home network web app to track electronics parts

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published