bom-helper 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: Python ${{ matrix.python-version }}
12
+ runs-on: python-test-image
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.12", "3.13", "3.14"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Install dependencies
22
+ run: uv sync --frozen --python ${{ matrix.python-version }}
23
+
24
+ - name: Run tests
25
+ run: uv run --python ${{ matrix.python-version }} pytest -m "not network"
26
+
27
+ code-quality:
28
+ name: Code Quality
29
+ runs-on: python-test-image
30
+
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+
34
+ - name: Install dependencies
35
+ run: uv sync --frozen --python 3.12
36
+
37
+ - name: Run code quality checks
38
+ run: cq check . -o score
39
+
40
+ upgrade-test:
41
+ name: Dependency Upgrade Test
42
+ runs-on: python-test-image
43
+ continue-on-error: true
44
+
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+
48
+ - name: Upgrade all dependencies
49
+ run: uv lock --upgrade
50
+
51
+ - name: Run tests with upgraded dependencies
52
+ run: uv sync --frozen --python 3.14 && uv run --python 3.14 pytest -m "not network"
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ env:
10
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ["3.12", "3.13", "3.14"]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v5
24
+
25
+ - name: Set up Python ${{ matrix.python-version }}
26
+ run: uv python install ${{ matrix.python-version }}
27
+
28
+ - name: Run tests
29
+ run: uv run pytest -m "not network"
@@ -0,0 +1,56 @@
1
+ name: Upload Python Package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ env:
11
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
12
+
13
+ jobs:
14
+ release-build:
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v5
22
+
23
+ - name: Set up Python
24
+ run: uv python install
25
+
26
+ - name: Build release distributions
27
+ run: uv build
28
+
29
+ - name: Upload distributions
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: release-dists
33
+ path: dist/
34
+
35
+ pypi-publish:
36
+ runs-on: ubuntu-latest
37
+ needs:
38
+ - release-build
39
+ permissions:
40
+ id-token: write
41
+
42
+ environment:
43
+ name: pypi
44
+ url: https://pypi.org/project/bom-helper/${{ github.event.release.name }}
45
+
46
+ steps:
47
+ - name: Retrieve release distributions
48
+ uses: actions/download-artifact@v4
49
+ with:
50
+ name: release-dists
51
+ path: dist/
52
+
53
+ - name: Publish release distributions to PyPI
54
+ uses: pypa/gh-action-pypi-publish@release/v1
55
+ with:
56
+ packages-dir: dist/
@@ -0,0 +1,14 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ .coverage
12
+
13
+ .*_cache/
14
+ .claude/
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,175 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ `bom-helper` is a Python CLI tool for fetching information about electronic components from LCSC (a Chinese electronics component distributor). It scrapes product pages to extract part specifications, pricing, images, and datasheets.
8
+
9
+ ## Package Management and Environment
10
+
11
+ - **Package Manager**: Use `uv` for all dependency management
12
+ - **Python Version**: 3.12.2 (specified in `.python-version`)
13
+ - **Key Dependencies**:
14
+ - `typer` - CLI framework
15
+ - `rich` - Terminal formatting and progress bars
16
+ - `beautifulsoup4` - HTML parsing for web scraping
17
+ - `requests` - HTTP client
18
+ - `easyeda2kicad` - KiCad library generation (wrapped by kicad.py)
19
+
20
+ ## Commands
21
+
22
+ ### Running the CLI
23
+
24
+ The CLI is installed as the `bom` command via entry point in `pyproject.toml`.
25
+
26
+ **All commands support multiple space-separated part numbers for batch processing:**
27
+
28
+ ```bash
29
+ # Install and run in development mode
30
+ uv run bom --help
31
+
32
+ # Get part information (returns JSON) - single or multiple
33
+ uv run bom info C124378
34
+ uv run bom info C2040 C124378 C100
35
+
36
+ # Download datasheet PDFs - single or multiple
37
+ uv run bom pdf C124378 --dir ./datasheets
38
+ uv run bom pdf C2040 C2041 C2042 --dir ./datasheets
39
+
40
+ # Export to KiCad (symbol + footprint + 3D model) - single or multiple
41
+ uv run bom add C2040
42
+ uv run bom add C2040 C2041 C2042
43
+ uv run bom add C2040 --output ./kicad-libs/lcsc
44
+ uv run bom add C2040 --overwrite
45
+
46
+ # Export individual components - single or multiple
47
+ uv run bom symbol C2040
48
+ uv run bom symbol C2040 C2041
49
+ uv run bom footprint C2040
50
+ uv run bom 3d C2040
51
+ ```
52
+
53
+ ### Testing
54
+
55
+ ```bash
56
+ # Run all tests
57
+ uv run pytest
58
+
59
+ # Run with coverage
60
+ uv run pytest --cov
61
+
62
+ # Run specific test file
63
+ uv run pytest tests/test_lcsc.py
64
+
65
+ # Run specific test
66
+ uv run pytest tests/test_parsing.py::test_getPartDetails
67
+ ```
68
+
69
+ ### Linting and Formatting
70
+
71
+ Uses `ruff` for both linting and formatting:
72
+
73
+ ```bash
74
+ # Format code
75
+ uv run ruff format
76
+
77
+ # Lint code
78
+ uv run ruff check
79
+
80
+ # Auto-fix linting issues
81
+ uv run ruff check --fix
82
+ ```
83
+
84
+ ## Architecture
85
+
86
+ ### Code Structure
87
+
88
+ ```
89
+ src/bom_helper/
90
+ ├── cli.py # CLI commands using Typer
91
+ ├── main.py # Core logic for scraping and PDF handling
92
+ ├── kicad.py # KiCad library export (wraps easyeda2kicad)
93
+ └── __init__.py
94
+
95
+ tests/
96
+ ├── test_lcsc.py # Tests for URL generation and PDF downloading
97
+ └── test_parsing.py # Tests for HTML parsing logic (uses mocks)
98
+ ```
99
+
100
+ ### Key Functions and Data Flow
101
+
102
+ **URL Generation** (`main.py`):
103
+ - `partToUrl(part)` - Converts LCSC part number (e.g., "C124378") to product detail URL
104
+ - `partToPdfUrl(part)` - Converts part number to datasheet PDF URL
105
+
106
+ **PDF Handling** (`main.py`):
107
+ - `savePdf(part, path)` - Downloads datasheet PDF with proper User-Agent headers (LCSC blocks default agents)
108
+
109
+ **Web Scraping** (`main.py:getPartDetails`):
110
+ Scrapes LCSC product pages and returns structured dictionary containing:
111
+ 1. **Basic Info**: Extracted from `table.tableInfoWrap` - includes Manufacturer (with "Asian Brands" suffix stripped), Mfr. Part #, Description
112
+ 2. **Datasheet URL**: Extracted from the Datasheet row, handles relative URLs
113
+ 3. **Specifications**: Parsed from table with "Type" and "Description" headers (Category, Package, etc.)
114
+ 4. **Pricing**: Extracted from `table.priceTable` - returns list of quantity/price tiers
115
+ 5. **Images**: Extracted via regex from embedded JavaScript (`productImages:["url1",...]`)
116
+
117
+ **Special Parsing Notes**:
118
+ - Manufacturer field removes the "Asian Brands" badge/suffix using `copy.copy()` and `.decompose()`
119
+ - Images are extracted from inline JS using regex: `r'productImages\s*:\s*(\[[^\]]*\])'`
120
+ - All HTTP requests include a Chrome User-Agent header to avoid being blocked
121
+
122
+ **KiCad Library Export** (`kicad.py`):
123
+ Wraps the easyeda2kicad Python API to provide a better UX:
124
+ 1. **Core Functions**:
125
+ - `export_symbol(part, output_path, overwrite)` - Export symbol only
126
+ - `export_footprint(part, output_path, overwrite)` - Export footprint only
127
+ - `export_3d_model(part, output_path, overwrite)` - Export 3D model only
128
+ - `export_full(part, output_path, overwrite)` - Export all three
129
+ 2. **Workflow**:
130
+ - Validate part number starts with 'C'
131
+ - Use `EasyedaApi().get_cad_data_of_component()` to fetch CAD data
132
+ - Create library directory structure if needed (`.kicad_sym`, `.pretty`, `.3dshapes`)
133
+ - Check if component already exists (using `id_already_in_symbol_lib`, `fp_already_in_footprint_lib`)
134
+ - If exists and not `--overwrite`: return with status "already_exists" (no error!)
135
+ - If exists and `--overwrite`: update component
136
+ - If new: add component to library
137
+ - Use easyeda2kicad importers (`EasyedaSymbolImporter`, `EasyedaFootprintImporter`, `Easyeda3dModelImporter`)
138
+ - Use easyeda2kicad exporters to generate KiCad format
139
+ - Return paths to created files with status (added/updated/already_exists)
140
+ 3. **Key Behavior**:
141
+ - Default output: `~/Documents/Kicad/easyeda2kicad/easyeda2kicad`
142
+ - Never errors when component exists - just confirms and shows paths
143
+ - Suppresses easyeda2kicad logging (sets to ERROR level only)
144
+ - Handles cases where 3D models might not be available
145
+
146
+ **CLI Integration** (`cli.py`):
147
+ - Uses Typer for command routing
148
+ - Commands: `info` (JSON), `pdf` (datasheet), `add` (full export), `symbol`, `footprint`, `3d`
149
+ - **All commands support multiple parts**: Uses `List[str] = typer.Argument(...)`
150
+ - Multi-part behavior:
151
+ - Shows progress indicator `[1/3] C2040` when processing multiple parts
152
+ - Continues processing if one part fails (error handling with `continue`)
153
+ - Accumulates failed parts and exits with code 1 if any failed
154
+ - Displays results per part
155
+ - All KiCad commands support `--output` and `--overwrite` flags
156
+ - Uses `rich.progress` for progress feedback
157
+ - Uses `rich.table` to display export results
158
+ - Version command using `importlib.metadata.version()`
159
+
160
+ ### Testing Strategy
161
+
162
+ - **Unit Tests**: Mock HTTP responses for parsing tests (`test_parsing.py`)
163
+ - **Integration Tests**: Real network calls for basic URL and PDF tests (`test_lcsc.py`)
164
+ - Mock HTML includes truncated but representative LCSC page structure with all key elements
165
+
166
+ ## Important Patterns
167
+
168
+ 1. **Part Number Validation**: All commands validate part numbers using `validate_lcsc_part_number()` from `main.py`
169
+ - Must start with 'C' followed by digits only (regex: `^C\d+$`)
170
+ - Rejects paths, special characters, spaces, lowercase
171
+ - Examples: Valid: `C2040`, `C124378`; Invalid: `C:\path`, `C123abc`, `c2040`
172
+ 2. **User-Agent Required**: All `requests.get()` calls must include Chrome User-Agent header or LCSC will return HTML instead of expected content
173
+ 3. **Path Handling**: Use `pathlib.Path` throughout; `savePdf` creates directories if they don't exist
174
+ 4. **Error Handling**: Functions raise exceptions that are caught at CLI level and converted to user-friendly messages with exit code 1
175
+ 5. **BeautifulSoup Usage**: Import inside function (`getPartDetails`) rather than module-level
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.4
2
+ Name: bom-helper
3
+ Version: 0.1.1
4
+ Summary: CLI tool for fetching LCSC component info, datasheets, and KiCad library exports
5
+ Project-URL: Repository, https://github.com/rhiza-fr/bom-helper
6
+ Project-URL: Issues, https://github.com/rhiza-fr/bom-helper/issues
7
+ Author-email: Chris Kilner <chris@rhiza.fr>
8
+ License: MIT
9
+ Keywords: bom,components,easyeda,electronics,kicad,lcsc
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: beautifulsoup4>=4.14.3
20
+ Requires-Dist: easyeda2kicad>=0.8.0
21
+ Requires-Dist: requests>=2.32.5
22
+ Requires-Dist: rich>=14.2.0
23
+ Requires-Dist: typer>=0.20.0
24
+ Description-Content-Type: text/markdown
25
+
26
+ # BOM Helper
27
+
28
+ A Python CLI tool for fetching electronic component information from LCSC (a Chinese electronics component distributor). Quickly retrieve part specifications, pricing, datasheets, and images for your Bill of Materials (BOM) management.
29
+
30
+ ## Features
31
+
32
+ - **Batch Processing**: All commands support multiple space-separated part numbers
33
+ - **Part Information**: Retrieve detailed component specifications in JSON format
34
+ - **Datasheet Download**: Automatically download component datasheets as PDFs
35
+ - **KiCad Library Export**: Export symbols, footprints, and 3D models for KiCad
36
+ - **Comprehensive Data Extraction**:
37
+ - Manufacturer and part numbers
38
+ - Technical specifications (package type, category, etc.)
39
+ - Pricing tiers for different quantities
40
+ - Product images
41
+ - Datasheet URLs
42
+
43
+ ## Installation
44
+
45
+ This project uses [uv](https://github.com/astral-sh/uv) for package management. Make sure you have Python 3.12+ installed.
46
+
47
+ ```bash
48
+ # Clone the repository
49
+ git clone https://github.com/rhiza-fr/bom-helper.git
50
+ cd bom-helper
51
+
52
+ # Install the tool (makes `bom` available on your PATH)
53
+ uv tool install .
54
+ ```
55
+
56
+ After installation, use `bom` directly — no `uv run` prefix needed.
57
+
58
+ ## Usage
59
+
60
+ ### Get Component Information
61
+
62
+ Retrieve detailed information about one or more components by LCSC part number:
63
+
64
+ ```bash
65
+ # Single part
66
+ bom info C124378
67
+
68
+ # Multiple parts
69
+ bom info C2040 C124378 C100
70
+ ```
71
+
72
+ This returns a JSON object with all available information:
73
+ ```json
74
+ {
75
+ "url": "https://www.lcsc.com/product-detail/C124378.html",
76
+ "Manufacturer": "hanxia",
77
+ "Mfr. Part #": "HX PM2.54-1x7P TP-YQ",
78
+ "Description": "2.54mm 1kV 7P 3A 1 Gold Brass",
79
+ "Datasheet": "https://www.lcsc.com/datasheet/C124378.pdf",
80
+ "Specifications": {
81
+ "Category": "Connectors",
82
+ "Package": "SMD,P=2.54mm"
83
+ },
84
+ "Pricing": [
85
+ {"Qty": "11+", "Unit Price": "€ 0.2071", "Ext. Price": "€ 2.28"},
86
+ {"Qty": "110+", "Unit Price": "€ 0.1639", "Ext. Price": "€ 18.03"}
87
+ ],
88
+ "Images": [
89
+ "https://assets.lcsc.com/images/lcsc/900x900/front.jpg",
90
+ "https://assets.lcsc.com/images/lcsc/900x900/back.jpg"
91
+ ]
92
+ }
93
+ ```
94
+
95
+ ### Download Datasheet
96
+
97
+ Download datasheets for one or more components:
98
+
99
+ ```bash
100
+ # Save to current directory
101
+ bom pdf C124378
102
+
103
+ # Download multiple datasheets
104
+ bom pdf C2040 C124378 C100
105
+
106
+ # Save to a specific directory
107
+ bom pdf C124378 --dir ./datasheets
108
+
109
+ # Batch download to directory
110
+ bom pdf C2040 C2041 C2042 --dir ./datasheets
111
+ ```
112
+
113
+ ### Export to KiCad
114
+
115
+ Export component symbols, footprints, and 3D models for use in KiCad:
116
+
117
+ ```bash
118
+ # Export everything (symbol + footprint + 3D model) for one part
119
+ bom add C2040
120
+
121
+ # Export multiple parts at once
122
+ bom add C2040 C2041 C2042
123
+
124
+ # Export to a custom location
125
+ bom add C2040 --output ./kicad-libs/lcsc
126
+
127
+ # Update existing components
128
+ bom add C2040 --overwrite
129
+
130
+ # Export only specific parts
131
+ bom symbol C2040 # Symbol only
132
+ bom footprint C2040 # Footprint only
133
+ bom 3d C2040 # 3D model only
134
+
135
+ # All commands support multiple parts
136
+ bom symbol C2040 C2041
137
+ bom footprint C2040 C2041 C2042
138
+ ```
139
+
140
+ **Default location:** `~/Documents/Kicad/easyeda2kicad/`
141
+
142
+ The tool will:
143
+ - Create library files if they don't exist
144
+ - Detect existing components and skip them (use `--overwrite` to update)
145
+ - Show you the paths to all created files
146
+
147
+ ### Check Version
148
+
149
+ ```bash
150
+ bom --version
151
+ ```
152
+
153
+ ## Development
154
+
155
+ ### Setup
156
+
157
+ ```bash
158
+ # Install development dependencies
159
+ uv sync --group dev
160
+ ```
161
+
162
+ ### Running Tests
163
+
164
+ ```bash
165
+ # Run all tests
166
+ uv run pytest
167
+
168
+ # Run with coverage report
169
+ uv run pytest --cov
170
+
171
+ # Run specific test file
172
+ uv run pytest tests/test_lcsc.py
173
+ ```
174
+
175
+ ### Code Quality
176
+
177
+ This project uses [ruff](https://github.com/astral-sh/ruff) for linting and formatting:
178
+
179
+ ```bash
180
+ # Format code
181
+ uv run ruff format
182
+
183
+ # Check for linting issues
184
+ uv run ruff check
185
+
186
+ # Auto-fix linting issues
187
+ uv run ruff check --fix
188
+ ```
189
+
190
+ ## How It Works
191
+
192
+ BOM Helper provides two main capabilities:
193
+
194
+ ### 1. Component Information & Datasheets
195
+ Scrapes the LCSC website to extract component information:
196
+ - Fetches product page HTML for a given part number
197
+ - Parses structured data from tables and embedded JavaScript
198
+ - Returns information in a clean, structured format
199
+
200
+ Edge cases handled:
201
+ - Extracting URLs from relative paths
202
+ - Cleaning manufacturer names (removes "Asian Brands" badges)
203
+ - Parsing pricing tables with quantity tiers
204
+ - Extracting product images from embedded JavaScript
205
+
206
+ ### 2. KiCad Library Export
207
+ Integrates with [easyeda2kicad](https://github.com/uPesy/easyeda2kicad.py) to generate KiCad library files:
208
+ - Fetches CAD data from EasyEDA API
209
+ - Converts symbols, footprints, and 3D models to KiCad format
210
+ - Manages library files and prevents duplicates
211
+ - Built on top of easyeda2kicad with a simpler batch-friendly CLI
212
+
213
+ ## Requirements
214
+
215
+ - Python 3.12 or higher
216
+ - Internet connection (to fetch data from LCSC)
217
+
218
+ ## Part Number Format
219
+
220
+ All commands require valid LCSC part numbers. LCSC part numbers must:
221
+ - Start with 'C' (uppercase)
222
+ - Be followed by one or more digits
223
+ - Contain no other characters (no spaces, hyphens, paths, etc.)
224
+
225
+ **Valid examples:** `C2040`, `C124378`, `C999999999`
226
+ **Invalid examples:** `C:\path`, `C123abc`, `C-123`, `c2040` (lowercase), `C 123` (space)
227
+
228
+ ## License
229
+
230
+ MIT — see [LICENSE](LICENSE).
231
+
232
+ ## Disclaimer
233
+
234
+ This tool is not affiliated with or endorsed by LCSC. It is designed for personal use to help manage Bills of Materials. Please respect LCSC's terms of service and use this tool responsibly.