bomkit 0.1.0__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.
- bomkit-0.1.0/.claude/settings.local.json +7 -0
- bomkit-0.1.0/.github/workflows/test.yml +27 -0
- bomkit-0.1.0/.gitignore +119 -0
- bomkit-0.1.0/CHANGELOG.md +43 -0
- bomkit-0.1.0/Example/Parts List.xlsx +0 -0
- bomkit-0.1.0/Example/SKA-100.xlsx +0 -0
- bomkit-0.1.0/Example/TR-01.xlsx +0 -0
- bomkit-0.1.0/Example/WH-01.xlsx +0 -0
- bomkit-0.1.0/LICENSE +21 -0
- bomkit-0.1.0/PKG-INFO +280 -0
- bomkit-0.1.0/README.md +257 -0
- bomkit-0.1.0/bomkit/BOM.py +457 -0
- bomkit-0.1.0/bomkit/__init__.py +1 -0
- bomkit-0.1.0/bomkit/__main__.py +77 -0
- bomkit-0.1.0/bomkit/browser.py +322 -0
- bomkit-0.1.0/doc/Makefile +20 -0
- bomkit-0.1.0/doc/images/TUI-browser-main-screen.png +0 -0
- bomkit-0.1.0/doc/make.bat +35 -0
- bomkit-0.1.0/doc/src/conf.py +56 -0
- bomkit-0.1.0/doc/src/index.rst +134 -0
- bomkit-0.1.0/pyproject.toml +44 -0
- bomkit-0.1.0/tests/__init__.py +0 -0
- bomkit-0.1.0/tests/conftest.py +88 -0
- bomkit-0.1.0/tests/test_bom.py +200 -0
- bomkit-0.1.0/tests/test_browser.py +240 -0
- bomkit-0.1.0/tests/test_cli.py +34 -0
- bomkit-0.1.0/uv.lock +1164 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install package
|
|
24
|
+
run: pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: pytest tests/
|
bomkit-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Created by https://www.gitignore.io/api/python
|
|
2
|
+
# Edit at https://www.gitignore.io/?templates=python
|
|
3
|
+
|
|
4
|
+
.vscode/
|
|
5
|
+
development/
|
|
6
|
+
temp/
|
|
7
|
+
*.code-workspace
|
|
8
|
+
scratch/
|
|
9
|
+
run/
|
|
10
|
+
Example/_*.xlsx
|
|
11
|
+
env/
|
|
12
|
+
.venv/
|
|
13
|
+
|
|
14
|
+
### Python ###
|
|
15
|
+
# Byte-compiled / optimized / DLL files
|
|
16
|
+
__pycache__/
|
|
17
|
+
*.py[cod]
|
|
18
|
+
*$py.class
|
|
19
|
+
|
|
20
|
+
# C extensions
|
|
21
|
+
*.so
|
|
22
|
+
|
|
23
|
+
# Distribution / packaging
|
|
24
|
+
.Python
|
|
25
|
+
build/
|
|
26
|
+
develop-eggs/
|
|
27
|
+
dist/
|
|
28
|
+
downloads/
|
|
29
|
+
eggs/
|
|
30
|
+
.eggs/
|
|
31
|
+
lib/
|
|
32
|
+
lib64/
|
|
33
|
+
parts/
|
|
34
|
+
sdist/
|
|
35
|
+
var/
|
|
36
|
+
wheels/
|
|
37
|
+
pip-wheel-metadata/
|
|
38
|
+
share/python-wheels/
|
|
39
|
+
*.egg-info/
|
|
40
|
+
.installed.cfg
|
|
41
|
+
*.egg
|
|
42
|
+
MANIFEST
|
|
43
|
+
|
|
44
|
+
# PyInstaller
|
|
45
|
+
# Usually these files are written by a python script from a template
|
|
46
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
47
|
+
*.manifest
|
|
48
|
+
*.spec
|
|
49
|
+
|
|
50
|
+
# Installer logs
|
|
51
|
+
pip-log.txt
|
|
52
|
+
pip-delete-this-directory.txt
|
|
53
|
+
|
|
54
|
+
# Unit test / coverage reports
|
|
55
|
+
htmlcov/
|
|
56
|
+
.tox/
|
|
57
|
+
.nox/
|
|
58
|
+
.coverage
|
|
59
|
+
.coverage.*
|
|
60
|
+
.cache
|
|
61
|
+
nosetests.xml
|
|
62
|
+
coverage.xml
|
|
63
|
+
*.cover
|
|
64
|
+
.hypothesis/
|
|
65
|
+
.pytest_cache/
|
|
66
|
+
|
|
67
|
+
# Translations
|
|
68
|
+
*.mo
|
|
69
|
+
*.pot
|
|
70
|
+
|
|
71
|
+
# Scrapy stuff:
|
|
72
|
+
.scrapy
|
|
73
|
+
|
|
74
|
+
# Sphinx documentation
|
|
75
|
+
docs/_build/
|
|
76
|
+
|
|
77
|
+
# PyBuilder
|
|
78
|
+
target/
|
|
79
|
+
|
|
80
|
+
# pyenv
|
|
81
|
+
.python-version
|
|
82
|
+
|
|
83
|
+
# pipenv
|
|
84
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
85
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
86
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
87
|
+
# install all needed dependencies.
|
|
88
|
+
#Pipfile.lock
|
|
89
|
+
|
|
90
|
+
# celery beat schedule file
|
|
91
|
+
celerybeat-schedule
|
|
92
|
+
|
|
93
|
+
# SageMath parsed files
|
|
94
|
+
*.sage.py
|
|
95
|
+
|
|
96
|
+
# Spyder project settings
|
|
97
|
+
.spyderproject
|
|
98
|
+
.spyproject
|
|
99
|
+
|
|
100
|
+
# Rope project settings
|
|
101
|
+
.ropeproject
|
|
102
|
+
|
|
103
|
+
# Mr Developer
|
|
104
|
+
.mr.developer.cfg
|
|
105
|
+
.project
|
|
106
|
+
.pydevproject
|
|
107
|
+
|
|
108
|
+
# mkdocs documentation
|
|
109
|
+
/site
|
|
110
|
+
|
|
111
|
+
# mypy
|
|
112
|
+
.mypy_cache/
|
|
113
|
+
.dmypy.json
|
|
114
|
+
dmypy.json
|
|
115
|
+
|
|
116
|
+
# Pyre type checker
|
|
117
|
+
.pyre/
|
|
118
|
+
|
|
119
|
+
# End of https://www.gitignore.io/api/python
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-03-02
|
|
11
|
+
Initial public release as `bomkit` (formerly `pybom`).
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Interactive TUI browser (`--browse` mode) powered by Textual
|
|
15
|
+
- Initial test suite
|
|
16
|
+
- GitHub Actions CI workflow
|
|
17
|
+
- Type hints throughout `BOM.py`
|
|
18
|
+
- Assembly BOM name read from Excel sheet name
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- `BOM.from_file()` made private (`_from_file()`)
|
|
22
|
+
- `QTY` method returning Python integers
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Pre-release history (as `pybom`)
|
|
29
|
+
|
|
30
|
+
## 0.2.0 - 2023
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- `BOM.single_file()` for single-file BOMs
|
|
34
|
+
|
|
35
|
+
## 0.1.0 - 2020
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- Core `BOM`, `Item`, `ItemLink`, and `PartsDB` data model
|
|
39
|
+
- `BOM.from_folder()` for multi-file BOMs
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
[Unreleased]: https://github.com/robsiegwart/bomkit/compare/v0.1.0...HEAD
|
|
43
|
+
[0.1.0]: https://github.com/robsiegwart/bomkit/releases/tag/v0.1.0
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
bomkit-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Rob Siegwart
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bomkit-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bomkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Bill of materials processing utilities
|
|
5
|
+
Author-email: Rob Siegwart <rob@robsiegwart.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: bom,engineering,manufacturing
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Manufacturing
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Requires-Dist: anytree>=2.12
|
|
16
|
+
Requires-Dist: openpyxl>=3.1
|
|
17
|
+
Requires-Dist: pandas>=2.0
|
|
18
|
+
Requires-Dist: textual>=0.50
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# bomkit
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
A Python program for flattening a layered bill-of-material (BOM) based on Excel
|
|
29
|
+
files. Part quantities are combined and a total quantity or
|
|
30
|
+
minimum-required-package-to-buy amount is calculated, in addition to extended
|
|
31
|
+
costs. A tree structure of the BOM hierarchy can also be created and converted
|
|
32
|
+
to DOT syntax for further graphics generation.
|
|
33
|
+
|
|
34
|
+
The functionality can be accessed in three ways:
|
|
35
|
+
|
|
36
|
+
| Method | Description |
|
|
37
|
+
|--------|-------------|
|
|
38
|
+
| Interactive TUI (terminal-based interface) | Launch with `bomkit [directory]` |
|
|
39
|
+
| API | In Python, use `from bomkit import BOM`, then `BOM.from_folder()` or `BOM.single_file()` |
|
|
40
|
+
| Command line | Run with `bomkit [-h] (-f FILE \| -d FOLDER) action` |
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## Motivation
|
|
44
|
+
|
|
45
|
+
The main problem solved is to combine identical parts from various
|
|
46
|
+
sub-assemblies and locations in your product BOM. Additionally, it is designed
|
|
47
|
+
to be used with Excel since Excel is common and does not require a separate
|
|
48
|
+
program or server.
|
|
49
|
+
|
|
50
|
+
Flattening tells you the total QTY of a part when it may be used in many
|
|
51
|
+
sub-assemblies and levels in your product structure. This is necessary to
|
|
52
|
+
calculate the total QTY of a part and therefore determine the mininum packages
|
|
53
|
+
of the product to buy, since many parts come in packs greater than QTY 1.
|
|
54
|
+
|
|
55
|
+
## Structure
|
|
56
|
+
|
|
57
|
+
There are two methods for storing data for parts and assemblies: multi-file or
|
|
58
|
+
single file.
|
|
59
|
+
|
|
60
|
+
### Multi-File
|
|
61
|
+
|
|
62
|
+
In a separate directory, put an Excel file named *Parts List.xlsx* to serve as
|
|
63
|
+
the master parts list \"database\". Then, each additional assembly is described
|
|
64
|
+
by a separate .xlsx file. Thus you might have:
|
|
65
|
+
|
|
66
|
+
my_project/
|
|
67
|
+
Parts list.xlsx <-- master parts list
|
|
68
|
+
SKA-100.xlsx <-- top level/root assembly
|
|
69
|
+
TR-01.xlsx <-- subassembly
|
|
70
|
+
WH-01.xlsx <-- subassembly
|
|
71
|
+
|
|
72
|
+
Root and sub-assemblies are inferred from item number relationships and are not
|
|
73
|
+
required to be explicitly identified.
|
|
74
|
+
|
|
75
|
+
*Parts list.xlsx* serves as the single point of reference for part information.
|
|
76
|
+
For example, it may have the following:
|
|
77
|
+
|
|
78
|
+
| PN | Name | Description | Supplier | Supplier PN | Pkg QTY | Pkg Price |
|
|
79
|
+
| --------- | ----------- | ------------------------------ | ---------------------- | ------------- | --------- | ---------- |
|
|
80
|
+
| SK1001-01 | Deck | Pavement Pro 9" Maple Deck | Grindstone Supply Co. | BRX-02 | 1 | 67.95 |
|
|
81
|
+
| SK1002-01 | Truck | HollowKing Standard Trucks | Grindstone Supply Co. | TR1-A | 1 | 28.95 |
|
|
82
|
+
| SK1003-01 | Bearing | ABEC-7 Steel Bearings | BoltRun Hardware | 74295-942 | 1 | 9.95 |
|
|
83
|
+
| SK1004-01 | Wheel | SlickCore 54mm Cruiser Wheels | Grindstone Supply Co. | WHL-PRX | 4 | 44.95 |
|
|
84
|
+
| SK1005-01 | Screw | 10-32, 1", Phillips | BoltRun Hardware | 92220A | 25 | 12.49 |
|
|
85
|
+
| SK1006-01 | Nut | 10-32 | BoltRun Hardware | 95479A | 25 | 9.89 |
|
|
86
|
+
| SK1007-01 | Grip Tape | SuperStick 9" | BoltRun Hardware | GTSS99 | 1 | 8.95 |
|
|
87
|
+
|
|
88
|
+
For each assembly, all that is required is the part identification number and
|
|
89
|
+
quantity which correspond to the following fields:
|
|
90
|
+
|
|
91
|
+
- PN
|
|
92
|
+
- QTY
|
|
93
|
+
|
|
94
|
+
Example wheel assembly (1 wheel + 2 bearings):
|
|
95
|
+
|
|
96
|
+
| PN | QTY |
|
|
97
|
+
| ----------- | ----- |
|
|
98
|
+
| SK1004-01 | 1 |
|
|
99
|
+
| SK1003-01 | 2 |
|
|
100
|
+
|
|
101
|
+
Certain fields are used in calculating totals, such as in `BOM.BOM.summary`,
|
|
102
|
+
which are:
|
|
103
|
+
|
|
104
|
+
`Pkg QTY`
|
|
105
|
+
: The quantity of items in a specific supplier SKU (i.e. a bag of 100 screws)
|
|
106
|
+
|
|
107
|
+
`Pkg Price`
|
|
108
|
+
: The cost of a specific supplier SKU
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
### Single File
|
|
112
|
+
|
|
113
|
+
A single Excel file is used to store all part and assembly data through the use
|
|
114
|
+
of Excel tabs.
|
|
115
|
+
|
|
116
|
+
The conventions for the single file approach are the same as the multi-file
|
|
117
|
+
approach, with the following exceptions:
|
|
118
|
+
|
|
119
|
+
- The first (left-most) Excel tab is treated as the Parts List "database",
|
|
120
|
+
regardless of its name
|
|
121
|
+
- All tabs/sheets to the right are interpreted as assemblies, with the sheet
|
|
122
|
+
name as the assembly part number (PN)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
## Usage
|
|
126
|
+
|
|
127
|
+
Install with pip via `pip install .` <!-- TODO: add PyPI link when published -->
|
|
128
|
+
|
|
129
|
+
Set up your data with either the multi-file or single file approach.
|
|
130
|
+
|
|
131
|
+
### TUI Browser
|
|
132
|
+
|
|
133
|
+
In a terminal, browse to the folder containing your BOM files and issue the
|
|
134
|
+
command `bomkit` with no arguments (or issue the path to your directiry, e.g.
|
|
135
|
+
`bomkit /path/to/your/project`). This will cause it to enter the browser mode
|
|
136
|
+
where you can interact with your BOM hierarchy and view derived properties such
|
|
137
|
+
as the aggregated parts list and tree structure.
|
|
138
|
+
|
|
139
|
+
The default screen shows the top-level assembly and its direct-child parts and
|
|
140
|
+
assemblies. You can navigate down the hierarchy with the ⬆️ and ⬇️ arrow keys
|
|
141
|
+
and by selecting an assembly and pressing `Enter` to view its child parts and
|
|
142
|
+
assemblies. Pressing `Enter` on a part will show its details. Use the left arrow
|
|
143
|
+
key ⬅️ or `Esc` to return to the parent assembly. You can also access different
|
|
144
|
+
views and derived properties using the command keys listed at the bottom of the
|
|
145
|
+
screen, such as `t` for a tree view. Assemblies are shown in cyan and bold text.
|
|
146
|
+
The top row shows a breadcrumb of the current location in the BOM hierarchy.
|
|
147
|
+
|
|
148
|
+
The commands at the bottom of the screen are:
|
|
149
|
+
|
|
150
|
+
- `t` for a tree view of the full BOM hierarchy
|
|
151
|
+
- `p` for a part list view (all the parts in the Parts List file
|
|
152
|
+
- `a` for a list of all the assemblies in the BOM
|
|
153
|
+
- `s` for a summary view (aggregated parts list with total QTY and purchase
|
|
154
|
+
QTY)
|
|
155
|
+
|
|
156
|
+

|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
### API Usage
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from bomkit import BOM
|
|
163
|
+
|
|
164
|
+
# Multi-file
|
|
165
|
+
bom = BOM.from_folder(FOLDER)
|
|
166
|
+
|
|
167
|
+
# Single file
|
|
168
|
+
bom = BOM.single_file(FILENAME)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
This returns a `BOM` object with properties on it you can retrieve:
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
`BOM.parts`
|
|
175
|
+
: Get a list of all direct-child parts
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
>>> print(bom.parts)
|
|
179
|
+
[Part SK1001-01, Part SK1005-01, Part SK1006-01, Part SK1007-01]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`BOM.assemblies`
|
|
183
|
+
: Get a list of all direct-child assemblies
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
>>> print(bom.assemblies)
|
|
187
|
+
[TR-01]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`BOM.aggregate`
|
|
191
|
+
: Get the aggregated quantity of each part/assembly from the current
|
|
192
|
+
BOM level down
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
>>> print(bom.aggregate)
|
|
196
|
+
{'SK1001-01': 1, 'SK1005-01': 8, 'SK1006-01': 8, 'SK1007-01': 1, 'SK1002-01': 2, 'SK1004-01': 4, 'SK1003-01': 8}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`BOM.summary`
|
|
200
|
+
: Get a summary in the form of a DataFrame containing the master parts
|
|
201
|
+
list with each item's aggregated quantity and the required packages
|
|
202
|
+
to buy (`Purchase QTY`) if the `Pkg QTY` field is not 1.
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
>>> print(bom.summary)
|
|
206
|
+
PN Name Description ... Total QTY Purchase QTY Subtotal
|
|
207
|
+
0 SK1001-01 Deck Pavement Pro 9" Maple Deck ... 1 1 67.95
|
|
208
|
+
1 SK1002-01 Truck HollowKing Standard Trucks ... 2 2 57.90
|
|
209
|
+
2 SK1003-01 Bearing ABEC-7 Steel Bearings ... 8 8 27.92
|
|
210
|
+
3 SK1004-01 Wheel SlickCore 54mm Cruiser Wheels ... 4 1 44.95
|
|
211
|
+
4 SK1005-01 Screw 10-32, 1”, Phillips ... 8 1 12.49
|
|
212
|
+
5 SK1006-01 Nut 10-32 ... 8 1 9.89
|
|
213
|
+
6 SK1007-01 Grip tape SuperStick 9” ... 1 1 8.95
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`BOM.tree`
|
|
217
|
+
: Return a string representation of the BOM tree hierarchy
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
>>> print(bom.tree)
|
|
221
|
+
SKA-100
|
|
222
|
+
├── Part SK1001-01
|
|
223
|
+
├── TR-01
|
|
224
|
+
│ ├── Part SK1002-01
|
|
225
|
+
│ └── WH-01
|
|
226
|
+
│ ├── Part SK1004-01
|
|
227
|
+
│ └── Part SK1003-01
|
|
228
|
+
├── Part SK1005-01
|
|
229
|
+
├── Part SK1006-01
|
|
230
|
+
└── Part SK1007-01
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Calling this on child assemblies shows the tree from that reference point:
|
|
234
|
+
```
|
|
235
|
+
>>> bom.assemblies
|
|
236
|
+
[TR-01]
|
|
237
|
+
>>> print(bom.assemblies[0].tree)
|
|
238
|
+
TR-01
|
|
239
|
+
├── Part SK1002-01
|
|
240
|
+
└── WH-01
|
|
241
|
+
├── Part SK1004-01
|
|
242
|
+
└── Part SK1003-01
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Command Line Usage
|
|
246
|
+
|
|
247
|
+
Functionality is extended to the command line where the flags `-f` and `-d` are
|
|
248
|
+
used to specify the name of a file for single-file mode or a folder for
|
|
249
|
+
multi-file mode, respectively.
|
|
250
|
+
|
|
251
|
+
`action` is what to do with the imported data, which just maps to a property
|
|
252
|
+
on the top-level `BOM` object.
|
|
253
|
+
|
|
254
|
+
This method is not persistent and is meant for quick one-off retrieval of information.
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
> bomkit [-h] (-f FILE | -d FOLDER) action
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
> bomkit -d Example tree
|
|
262
|
+
SKA-100
|
|
263
|
+
├── Part SK1001-01
|
|
264
|
+
├── TR-01
|
|
265
|
+
│ ├── Part SK1002-01
|
|
266
|
+
│ └── WH-01
|
|
267
|
+
│ ├── Part SK1004-01
|
|
268
|
+
│ └── Part SK1003-01
|
|
269
|
+
├── Part SK1005-01
|
|
270
|
+
├── Part SK1006-01
|
|
271
|
+
└── Part SK1007-01
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Dependencies
|
|
275
|
+
------------
|
|
276
|
+
|
|
277
|
+
- *pandas*
|
|
278
|
+
- *anytree*
|
|
279
|
+
- *openpyxl*
|
|
280
|
+
- *textual*
|