kicad-sch-api 0.4.0__py3-none-any.whl → 0.4.2__py3-none-any.whl
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.
Potentially problematic release.
This version of kicad-sch-api might be problematic. Click here for more details.
- kicad_sch_api/__init__.py +2 -2
- kicad_sch_api/cli/__init__.py +45 -0
- kicad_sch_api/cli/base.py +302 -0
- kicad_sch_api/cli/bom.py +164 -0
- kicad_sch_api/cli/erc.py +229 -0
- kicad_sch_api/cli/export_docs.py +289 -0
- kicad_sch_api/cli/netlist.py +94 -0
- kicad_sch_api/cli/types.py +43 -0
- kicad_sch_api/core/collections/__init__.py +5 -0
- kicad_sch_api/core/collections/base.py +248 -0
- kicad_sch_api/core/component_bounds.py +5 -0
- kicad_sch_api/core/components.py +142 -47
- kicad_sch_api/core/config.py +85 -3
- kicad_sch_api/core/factories/__init__.py +5 -0
- kicad_sch_api/core/factories/element_factory.py +276 -0
- kicad_sch_api/core/formatter.py +22 -5
- kicad_sch_api/core/junctions.py +26 -75
- kicad_sch_api/core/labels.py +28 -52
- kicad_sch_api/core/managers/file_io.py +3 -2
- kicad_sch_api/core/managers/metadata.py +6 -5
- kicad_sch_api/core/managers/validation.py +3 -2
- kicad_sch_api/core/managers/wire.py +7 -1
- kicad_sch_api/core/nets.py +38 -43
- kicad_sch_api/core/no_connects.py +29 -53
- kicad_sch_api/core/parser.py +75 -1765
- kicad_sch_api/core/schematic.py +211 -148
- kicad_sch_api/core/texts.py +28 -55
- kicad_sch_api/core/types.py +59 -18
- kicad_sch_api/core/wires.py +27 -75
- kicad_sch_api/parsers/elements/__init__.py +22 -0
- kicad_sch_api/parsers/elements/graphics_parser.py +564 -0
- kicad_sch_api/parsers/elements/label_parser.py +194 -0
- kicad_sch_api/parsers/elements/library_parser.py +165 -0
- kicad_sch_api/parsers/elements/metadata_parser.py +58 -0
- kicad_sch_api/parsers/elements/sheet_parser.py +352 -0
- kicad_sch_api/parsers/elements/symbol_parser.py +313 -0
- kicad_sch_api/parsers/elements/text_parser.py +250 -0
- kicad_sch_api/parsers/elements/wire_parser.py +242 -0
- kicad_sch_api/parsers/utils.py +80 -0
- kicad_sch_api/validation/__init__.py +25 -0
- kicad_sch_api/validation/erc.py +171 -0
- kicad_sch_api/validation/erc_models.py +203 -0
- kicad_sch_api/validation/pin_matrix.py +243 -0
- kicad_sch_api/validation/validators.py +391 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/METADATA +17 -9
- kicad_sch_api-0.4.2.dist-info/RECORD +87 -0
- kicad_sch_api/core/manhattan_routing.py +0 -430
- kicad_sch_api/core/simple_manhattan.py +0 -228
- kicad_sch_api/core/wire_routing.py +0 -380
- kicad_sch_api/parsers/label_parser.py +0 -254
- kicad_sch_api/parsers/symbol_parser.py +0 -222
- kicad_sch_api/parsers/wire_parser.py +0 -99
- kicad_sch_api-0.4.0.dist-info/RECORD +0 -67
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/entry_points.txt +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/licenses/LICENSE +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ERC validators: PinType, Connectivity, Component, Power.
|
|
3
|
+
|
|
4
|
+
Individual validators for different categories of electrical rules.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
|
|
9
|
+
|
|
10
|
+
from kicad_sch_api.validation.erc_models import ERCViolation
|
|
11
|
+
from kicad_sch_api.validation.pin_matrix import PinConflictMatrix, PinSeverity
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from kicad_sch_api.core.schematic import Schematic
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseValidator:
|
|
18
|
+
"""Base class for ERC validators."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, schematic: "Schematic") -> None:
|
|
21
|
+
"""Initialize validator.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
schematic: Schematic to validate
|
|
25
|
+
"""
|
|
26
|
+
self.schematic = schematic
|
|
27
|
+
|
|
28
|
+
def validate(self) -> List[ERCViolation]:
|
|
29
|
+
"""Run validation and return violations.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
List of violations found
|
|
33
|
+
"""
|
|
34
|
+
raise NotImplementedError("Subclasses must implement validate()")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class PinTypeValidator(BaseValidator):
|
|
38
|
+
"""Validates pin-to-pin connections for electrical conflicts.
|
|
39
|
+
|
|
40
|
+
Checks all nets for pin type compatibility using the pin conflict matrix.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, schematic: "Schematic", pin_matrix: Optional[PinConflictMatrix] = None) -> None:
|
|
44
|
+
"""Initialize pin type validator.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
schematic: Schematic to validate
|
|
48
|
+
pin_matrix: Optional custom pin conflict matrix
|
|
49
|
+
"""
|
|
50
|
+
super().__init__(schematic)
|
|
51
|
+
self.pin_matrix = pin_matrix or PinConflictMatrix()
|
|
52
|
+
|
|
53
|
+
def validate(self) -> List[ERCViolation]:
|
|
54
|
+
"""Validate pin connections on all nets.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
List of pin conflict violations
|
|
58
|
+
"""
|
|
59
|
+
violations: List[ERCViolation] = []
|
|
60
|
+
|
|
61
|
+
# Build nets from wires and components
|
|
62
|
+
nets = self._build_nets()
|
|
63
|
+
|
|
64
|
+
# Check each net for pin conflicts
|
|
65
|
+
for net_name, pins in nets.items():
|
|
66
|
+
net_violations = self._check_net_pins(net_name, pins)
|
|
67
|
+
violations.extend(net_violations)
|
|
68
|
+
|
|
69
|
+
return violations
|
|
70
|
+
|
|
71
|
+
def _build_nets(self) -> Dict[str, List[Tuple[str, str, str]]]:
|
|
72
|
+
"""Build net connectivity map.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Dict mapping net name to list of (component_ref, pin_num, pin_type) tuples
|
|
76
|
+
"""
|
|
77
|
+
# TODO: Implement net tracing from wires and components
|
|
78
|
+
# For now, return placeholder
|
|
79
|
+
# This will be implemented when we have full net connectivity analysis
|
|
80
|
+
return {}
|
|
81
|
+
|
|
82
|
+
def _check_net_pins(self, net_name: str, pins: List[Tuple[str, str, str]]) -> List[ERCViolation]:
|
|
83
|
+
"""Check all pin pairs on a net for conflicts.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
net_name: Net name
|
|
87
|
+
pins: List of (component_ref, pin_num, pin_type) tuples
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
List of violations found on this net
|
|
91
|
+
"""
|
|
92
|
+
violations: List[ERCViolation] = []
|
|
93
|
+
|
|
94
|
+
# Check all pairs of pins
|
|
95
|
+
for i, (ref1, pin1_num, pin1_type) in enumerate(pins):
|
|
96
|
+
for ref2, pin2_num, pin2_type in pins[i + 1:]:
|
|
97
|
+
severity = self.pin_matrix.check_connection(pin1_type, pin2_type)
|
|
98
|
+
|
|
99
|
+
if severity == PinSeverity.ERROR:
|
|
100
|
+
violations.append(ERCViolation(
|
|
101
|
+
violation_type="pin_conflict",
|
|
102
|
+
severity="error",
|
|
103
|
+
message=f"Pin conflict: {pin1_type} ({ref1}) connected to {pin2_type} ({ref2})",
|
|
104
|
+
component_refs=[ref1, ref2],
|
|
105
|
+
net_name=net_name,
|
|
106
|
+
pin_numbers=[pin1_num, pin2_num],
|
|
107
|
+
error_code="E001",
|
|
108
|
+
suggested_fix=f"Remove one output or add buffer between {ref1} and {ref2}"
|
|
109
|
+
))
|
|
110
|
+
elif severity == PinSeverity.WARNING:
|
|
111
|
+
violations.append(ERCViolation(
|
|
112
|
+
violation_type="pin_conflict",
|
|
113
|
+
severity="warning",
|
|
114
|
+
message=f"Pin warning: {pin1_type} ({ref1}) connected to {pin2_type} ({ref2})",
|
|
115
|
+
component_refs=[ref1, ref2],
|
|
116
|
+
net_name=net_name,
|
|
117
|
+
pin_numbers=[pin1_num, pin2_num],
|
|
118
|
+
error_code="W005",
|
|
119
|
+
suggested_fix="Verify this connection is intentional"
|
|
120
|
+
))
|
|
121
|
+
|
|
122
|
+
return violations
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class ConnectivityValidator(BaseValidator):
|
|
126
|
+
"""Validates wire connectivity and net driving.
|
|
127
|
+
|
|
128
|
+
Checks for dangling wires, unconnected pins, and undriven nets.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def validate(self) -> List[ERCViolation]:
|
|
132
|
+
"""Validate connectivity.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
List of connectivity violations
|
|
136
|
+
"""
|
|
137
|
+
violations: List[ERCViolation] = []
|
|
138
|
+
|
|
139
|
+
violations.extend(self.find_dangling_wires())
|
|
140
|
+
violations.extend(self.find_unconnected_pins())
|
|
141
|
+
violations.extend(self.find_undriven_nets())
|
|
142
|
+
|
|
143
|
+
return violations
|
|
144
|
+
|
|
145
|
+
def find_dangling_wires(self) -> List[ERCViolation]:
|
|
146
|
+
"""Find wires with only one connection.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
List of dangling wire violations
|
|
150
|
+
"""
|
|
151
|
+
violations: List[ERCViolation] = []
|
|
152
|
+
|
|
153
|
+
for wire in self.schematic.wires:
|
|
154
|
+
# Check endpoints for connections
|
|
155
|
+
start_connections = self._count_connections_at_point(wire.start)
|
|
156
|
+
end_connections = self._count_connections_at_point(wire.end)
|
|
157
|
+
|
|
158
|
+
if start_connections < 2 or end_connections < 2:
|
|
159
|
+
violations.append(ERCViolation(
|
|
160
|
+
violation_type="dangling_wire",
|
|
161
|
+
severity="warning",
|
|
162
|
+
message=f"Wire has unconnected endpoint at ({wire.start.x}, {wire.start.y})",
|
|
163
|
+
component_refs=[],
|
|
164
|
+
location=wire.start if start_connections < 2 else wire.end,
|
|
165
|
+
error_code="W002",
|
|
166
|
+
suggested_fix="Connect wire to component pin or remove if unused"
|
|
167
|
+
))
|
|
168
|
+
|
|
169
|
+
return violations
|
|
170
|
+
|
|
171
|
+
def find_unconnected_pins(self) -> List[ERCViolation]:
|
|
172
|
+
"""Find input pins with no connections.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
List of unconnected pin violations
|
|
176
|
+
"""
|
|
177
|
+
violations: List[ERCViolation] = []
|
|
178
|
+
|
|
179
|
+
for component in self.schematic.components:
|
|
180
|
+
# TODO: Get pin types from symbol library
|
|
181
|
+
# For now, check if any pins have no wires
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
return violations
|
|
185
|
+
|
|
186
|
+
def find_undriven_nets(self) -> List[ERCViolation]:
|
|
187
|
+
"""Find nets with only input pins (no output driver).
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
List of undriven net violations
|
|
191
|
+
"""
|
|
192
|
+
violations: List[ERCViolation] = []
|
|
193
|
+
|
|
194
|
+
# TODO: Implement net tracing and driver detection
|
|
195
|
+
# This requires full net connectivity analysis
|
|
196
|
+
|
|
197
|
+
return violations
|
|
198
|
+
|
|
199
|
+
def _count_connections_at_point(self, point) -> int:
|
|
200
|
+
"""Count number of connections at a point.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
point: Point to check
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Number of wires/pins at this point
|
|
207
|
+
"""
|
|
208
|
+
# TODO: Implement proper connection counting
|
|
209
|
+
# For now, return 2 (assume connected)
|
|
210
|
+
return 2
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class ComponentValidator(BaseValidator):
|
|
214
|
+
"""Validates component properties and references.
|
|
215
|
+
|
|
216
|
+
Checks for duplicate references, missing values, invalid formats.
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
# Valid reference format: Letter(s) followed by number(s)
|
|
220
|
+
REFERENCE_PATTERN = re.compile(r'^[A-Z]+[0-9]+$', re.IGNORECASE)
|
|
221
|
+
|
|
222
|
+
def validate(self) -> List[ERCViolation]:
|
|
223
|
+
"""Validate components.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
List of component violations
|
|
227
|
+
"""
|
|
228
|
+
violations: List[ERCViolation] = []
|
|
229
|
+
|
|
230
|
+
violations.extend(self.find_duplicate_references())
|
|
231
|
+
violations.extend(self.validate_component_properties())
|
|
232
|
+
|
|
233
|
+
return violations
|
|
234
|
+
|
|
235
|
+
def find_duplicate_references(self) -> List[ERCViolation]:
|
|
236
|
+
"""Find components with duplicate reference designators.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
List of duplicate reference violations
|
|
240
|
+
"""
|
|
241
|
+
violations: List[ERCViolation] = []
|
|
242
|
+
|
|
243
|
+
# Build reference count map
|
|
244
|
+
ref_to_components: Dict[str, List[str]] = {}
|
|
245
|
+
|
|
246
|
+
for component in self.schematic.components:
|
|
247
|
+
ref = component.reference
|
|
248
|
+
if ref not in ref_to_components:
|
|
249
|
+
ref_to_components[ref] = []
|
|
250
|
+
ref_to_components[ref].append(ref)
|
|
251
|
+
|
|
252
|
+
# Find duplicates
|
|
253
|
+
for ref, components in ref_to_components.items():
|
|
254
|
+
if len(components) > 1:
|
|
255
|
+
violations.append(ERCViolation(
|
|
256
|
+
violation_type="duplicate_reference",
|
|
257
|
+
severity="error",
|
|
258
|
+
message=f"Duplicate reference designator: {ref}",
|
|
259
|
+
component_refs=[ref] * len(components),
|
|
260
|
+
error_code="E004",
|
|
261
|
+
suggested_fix=f"Rename duplicate components (e.g., {ref}, {ref}A, {ref}B)"
|
|
262
|
+
))
|
|
263
|
+
|
|
264
|
+
return violations
|
|
265
|
+
|
|
266
|
+
def validate_component_properties(self) -> List[ERCViolation]:
|
|
267
|
+
"""Validate component properties (value, footprint, etc.).
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
List of property violations
|
|
271
|
+
"""
|
|
272
|
+
violations: List[ERCViolation] = []
|
|
273
|
+
|
|
274
|
+
for component in self.schematic.components:
|
|
275
|
+
# Check for missing value
|
|
276
|
+
if not component.value or component.value.strip() == "":
|
|
277
|
+
violations.append(ERCViolation(
|
|
278
|
+
violation_type="missing_value",
|
|
279
|
+
severity="warning",
|
|
280
|
+
message=f"Component {component.reference} has no value",
|
|
281
|
+
component_refs=[component.reference],
|
|
282
|
+
error_code="W008",
|
|
283
|
+
suggested_fix=f"Add value to {component.reference}"
|
|
284
|
+
))
|
|
285
|
+
|
|
286
|
+
# Check for missing footprint
|
|
287
|
+
if not component.footprint or component.footprint.strip() == "":
|
|
288
|
+
violations.append(ERCViolation(
|
|
289
|
+
violation_type="missing_footprint",
|
|
290
|
+
severity="warning",
|
|
291
|
+
message=f"Component {component.reference} has no footprint",
|
|
292
|
+
component_refs=[component.reference],
|
|
293
|
+
error_code="W007",
|
|
294
|
+
suggested_fix=f"Assign footprint to {component.reference}"
|
|
295
|
+
))
|
|
296
|
+
|
|
297
|
+
# Check reference format
|
|
298
|
+
if not self.REFERENCE_PATTERN.match(component.reference):
|
|
299
|
+
violations.append(ERCViolation(
|
|
300
|
+
violation_type="invalid_reference",
|
|
301
|
+
severity="error",
|
|
302
|
+
message=f"Invalid reference format: {component.reference}",
|
|
303
|
+
component_refs=[component.reference],
|
|
304
|
+
error_code="E005",
|
|
305
|
+
suggested_fix="Use format like R1, U1, C1 (letter + number)"
|
|
306
|
+
))
|
|
307
|
+
|
|
308
|
+
return violations
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
class PowerValidator(BaseValidator):
|
|
312
|
+
"""Validates power supply connections.
|
|
313
|
+
|
|
314
|
+
Checks for power flags, power input drivers, and power conflicts.
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
# Common power net names
|
|
318
|
+
POWER_NET_NAMES = {
|
|
319
|
+
"VCC", "VDD", "V+", "+5V", "+3V3", "+12V", "+24V",
|
|
320
|
+
"GND", "GNDA", "GNDD", "VSS", "V-",
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
def validate(self) -> List[ERCViolation]:
|
|
324
|
+
"""Validate power connections.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
List of power violations
|
|
328
|
+
"""
|
|
329
|
+
violations: List[ERCViolation] = []
|
|
330
|
+
|
|
331
|
+
violations.extend(self.validate_power_flags())
|
|
332
|
+
violations.extend(self.check_power_continuity())
|
|
333
|
+
|
|
334
|
+
return violations
|
|
335
|
+
|
|
336
|
+
def validate_power_flags(self) -> List[ERCViolation]:
|
|
337
|
+
"""Check for missing PWR_FLAG on power nets.
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
List of missing power flag violations
|
|
341
|
+
"""
|
|
342
|
+
violations: List[ERCViolation] = []
|
|
343
|
+
|
|
344
|
+
# TODO: Implement power net detection and PWR_FLAG checking
|
|
345
|
+
# This requires:
|
|
346
|
+
# 1. Identify power nets (by name or power input pins)
|
|
347
|
+
# 2. Check for PWR_FLAG symbol or power output on net
|
|
348
|
+
# 3. Generate WARNING (not ERROR per requirements) if missing
|
|
349
|
+
|
|
350
|
+
return violations
|
|
351
|
+
|
|
352
|
+
def check_power_continuity(self) -> List[ERCViolation]:
|
|
353
|
+
"""Check that power inputs are driven by power outputs.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
List of power continuity violations
|
|
357
|
+
"""
|
|
358
|
+
violations: List[ERCViolation] = []
|
|
359
|
+
|
|
360
|
+
# TODO: Implement power driver checking
|
|
361
|
+
# This requires full net tracing with pin type detection
|
|
362
|
+
|
|
363
|
+
return violations
|
|
364
|
+
|
|
365
|
+
def is_power_net(self, net_name: str) -> bool:
|
|
366
|
+
"""Check if net name suggests it's a power net.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
net_name: Net name to check
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
True if likely a power net
|
|
373
|
+
"""
|
|
374
|
+
if not net_name:
|
|
375
|
+
return False
|
|
376
|
+
|
|
377
|
+
net_upper = net_name.upper().strip()
|
|
378
|
+
|
|
379
|
+
# Check against known power names
|
|
380
|
+
if net_upper in self.POWER_NET_NAMES:
|
|
381
|
+
return True
|
|
382
|
+
|
|
383
|
+
# Check for common patterns
|
|
384
|
+
if any(pattern in net_upper for pattern in ["VCC", "VDD", "GND", "VSS"]):
|
|
385
|
+
return True
|
|
386
|
+
|
|
387
|
+
# Check for voltage patterns (+5V, +3.3V, etc.)
|
|
388
|
+
if re.match(r'^\+?\d+\.?\d*V$', net_upper):
|
|
389
|
+
return True
|
|
390
|
+
|
|
391
|
+
return False
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kicad-sch-api
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Professional KiCAD schematic manipulation library with exact format preservation
|
|
5
5
|
Author-email: Circuit-Synth <shane@circuit-synth.com>
|
|
6
6
|
Maintainer-email: Circuit-Synth <shane@circuit-synth.com>
|
|
7
7
|
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/circuit-synth/kicad-sch-api
|
|
9
|
-
Project-URL: Documentation, https://
|
|
9
|
+
Project-URL: Documentation, https://kicad-sch-api.readthedocs.io/
|
|
10
10
|
Project-URL: Repository, https://github.com/circuit-synth/kicad-sch-api.git
|
|
11
11
|
Project-URL: Bug Reports, https://github.com/circuit-synth/kicad-sch-api/issues
|
|
12
12
|
Project-URL: Changelog, https://github.com/circuit-synth/kicad-sch-api/blob/main/CHANGELOG.md
|
|
@@ -44,6 +44,11 @@ Dynamic: license-file
|
|
|
44
44
|
|
|
45
45
|
# KiCAD Schematic API
|
|
46
46
|
|
|
47
|
+
[](https://kicad-sch-api.readthedocs.io/en/latest/?badge=latest)
|
|
48
|
+
[](https://badge.fury.io/py/kicad-sch-api)
|
|
49
|
+
[](https://www.python.org/downloads/)
|
|
50
|
+
[](https://opensource.org/licenses/MIT)
|
|
51
|
+
|
|
47
52
|
**Professional Python library for KiCAD schematic file manipulation with exact format preservation**
|
|
48
53
|
|
|
49
54
|
## Overview
|
|
@@ -355,7 +360,7 @@ net_info = netlist.analyze_net("VCC")
|
|
|
355
360
|
|
|
356
361
|
## 🤖 AI Agent Integration
|
|
357
362
|
|
|
358
|
-
This library serves as the foundation for AI agent integration. For Claude Code or other AI agents, use the **[mcp-kicad-sch-api](https://github.com/circuit-synth/mcp-kicad-sch-api)** MCP server
|
|
363
|
+
This library serves as the foundation for AI agent integration. For Claude Code or other AI agents, use the **[mcp-kicad-sch-api](https://github.com/circuit-synth/mcp-kicad-sch-api)** MCP server.
|
|
359
364
|
|
|
360
365
|
## 🏗️ Architecture
|
|
361
366
|
|
|
@@ -368,8 +373,6 @@ kicad-sch-api/
|
|
|
368
373
|
│ ├── library/ # KiCAD library integration
|
|
369
374
|
│ ├── discovery/ # Component search and indexing
|
|
370
375
|
│ └── utils/ # Validation and utilities
|
|
371
|
-
├── submodules/ # Related projects as submodules
|
|
372
|
-
│ └── mcp-kicad-sch-api/ # MCP server for AI agents
|
|
373
376
|
├── tests/ # Comprehensive test suite
|
|
374
377
|
└── examples/ # Usage examples and tutorials
|
|
375
378
|
```
|
|
@@ -451,10 +454,15 @@ sch.save() # Guaranteed exact KiCAD format
|
|
|
451
454
|
|
|
452
455
|
## 📖 Documentation
|
|
453
456
|
|
|
454
|
-
|
|
457
|
+
Full documentation is available at **[kicad-sch-api.readthedocs.io](https://kicad-sch-api.readthedocs.io/)**
|
|
458
|
+
|
|
459
|
+
Quick links:
|
|
460
|
+
- **[Getting Started Guide](https://kicad-sch-api.readthedocs.io/en/latest/GETTING_STARTED.html)**: Complete beginner's tutorial
|
|
461
|
+
- **[API Reference](https://kicad-sch-api.readthedocs.io/en/latest/API_REFERENCE.html)**: Complete API documentation
|
|
462
|
+
- **[Recipes & Patterns](https://kicad-sch-api.readthedocs.io/en/latest/RECIPES.html)**: Practical examples
|
|
463
|
+
- **[Why Use This Library?](https://kicad-sch-api.readthedocs.io/en/latest/WHY_USE_THIS_LIBRARY.html)**: Value proposition and use cases
|
|
464
|
+
- **[Architecture](https://kicad-sch-api.readthedocs.io/en/latest/ARCHITECTURE.html)**: Internal design details
|
|
455
465
|
- **[Examples](examples/)**: Code examples and tutorials
|
|
456
|
-
- **[MCP Integration](docs/mcp.md)**: AI agent integration guide
|
|
457
|
-
- **[Development](docs/development.md)**: Contributing and development setup
|
|
458
466
|
|
|
459
467
|
## 🤝 Contributing
|
|
460
468
|
|
|
@@ -473,7 +481,7 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
473
481
|
|
|
474
482
|
## 🔗 Related Projects
|
|
475
483
|
|
|
476
|
-
- **[mcp-kicad-sch-api](https://github.com/circuit-synth/mcp-kicad-sch-api)**: MCP server for AI agents built on this library
|
|
484
|
+
- **[mcp-kicad-sch-api](https://github.com/circuit-synth/mcp-kicad-sch-api)**: MCP server for AI agents built on this library
|
|
477
485
|
- **[circuit-synth](https://github.com/circuit-synth/circuit-synth)**: High-level circuit design automation using this library
|
|
478
486
|
- **[Claude Code](https://claude.ai/code)**: AI development environment with MCP support
|
|
479
487
|
- **[KiCAD](https://kicad.org/)**: Open source electronics design automation suite
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
kicad_sch_api/__init__.py,sha256=vAXsTAUFgp7uKF9gAmX06c1__P9sk_-EhK2ncaR_uOg,2919
|
|
2
|
+
kicad_sch_api/cli.py,sha256=ZzmwzfHEvPgGfCiQBU4G2LBAyRtMNiBRoY21pivJSYc,7621
|
|
3
|
+
kicad_sch_api/py.typed,sha256=e4ldqxwpY7pNDG1olbvj4HSKr8sZ9vxgA_2ek8xXn-Q,70
|
|
4
|
+
kicad_sch_api/cli/__init__.py,sha256=mflSYoGLMJw2EFEByw9GD79pgj_Hebi6htJy7cKV5qM,952
|
|
5
|
+
kicad_sch_api/cli/base.py,sha256=9Qpx8xKGmMovbUVaMEXYj-KjtlPKv57dNwnBcu_hnpE,9793
|
|
6
|
+
kicad_sch_api/cli/bom.py,sha256=So3p5VFzjgkwnWP7OY80KG5iyFZgNTfWuJh1-tqbue0,5299
|
|
7
|
+
kicad_sch_api/cli/erc.py,sha256=0qrJMsGL82cZxjTuMA5aIaxyaKeOqqPJrTzvRuItXl8,7181
|
|
8
|
+
kicad_sch_api/cli/export_docs.py,sha256=gsFsHwcuL5EYgHW3l8udwjBw4dm1N4fnpvFoXqfVS38,8778
|
|
9
|
+
kicad_sch_api/cli/netlist.py,sha256=iveRNY2LeC6A_naykmCDuJKleom2OFpwxhDfHxtbxmA,2686
|
|
10
|
+
kicad_sch_api/cli/types.py,sha256=pybFjAFbKGiY8svAt52Sq_F--fz8f836vbyvO710G10,1131
|
|
11
|
+
kicad_sch_api/collections/__init__.py,sha256=I3DSWk0XmGE8J1fcTtiYOETaWrY-fFJPlz3UGUK2qXY,627
|
|
12
|
+
kicad_sch_api/collections/base.py,sha256=7p-WVLg-2_uBS7z7mzwkOpCMwlR_VJZGr2iW_Hd1K3Q,8386
|
|
13
|
+
kicad_sch_api/collections/components.py,sha256=ofH3P38Ube3uxVvk_28gJwJPsdL6KA37rgxWNig6BGM,14023
|
|
14
|
+
kicad_sch_api/collections/junctions.py,sha256=4bjuUKm-tCWSJJTtuPwgjYh0Xglg2SEG8IOAvhULgtg,11728
|
|
15
|
+
kicad_sch_api/collections/labels.py,sha256=zg6_xe4ifwIbc8M1E5MDGTh8Ps57oBeqbS9MclrvxKU,12266
|
|
16
|
+
kicad_sch_api/collections/wires.py,sha256=o2Y_KIwOmFMytdOc2MjgnoUrK4Woj7wR9ROj4uRTuY0,12394
|
|
17
|
+
kicad_sch_api/core/__init__.py,sha256=ur_KeYBlGKl-e1hLpLdxAhGV2A-PCCGkcqd0r6KSeBA,566
|
|
18
|
+
kicad_sch_api/core/component_bounds.py,sha256=Qc-Fazq_RvASVZ57eGg99NahCIgnWq8FFg1J4HfggK0,17917
|
|
19
|
+
kicad_sch_api/core/components.py,sha256=powrqJGgqUBvMevMwhWSobrK6n8W525H7vzpPYCUXTs,28448
|
|
20
|
+
kicad_sch_api/core/config.py,sha256=ECR6WLrC8i0itxRLJAZN3TDthbtOfd5NwNbiU6TSlW4,6224
|
|
21
|
+
kicad_sch_api/core/formatter.py,sha256=ci-URhZFVHdSV4rEfOgTGtJu1tvW5MZEzSI1j2vtexE,22910
|
|
22
|
+
kicad_sch_api/core/geometry.py,sha256=27SgN0padLbQuTi8MV6UUCp6Pyaiv8V9gmYDOhfwny8,2947
|
|
23
|
+
kicad_sch_api/core/ic_manager.py,sha256=Kg0HIOMU-TGXiIkrnwcHFQ1Kfv_3rW2U1cwBKJsKopc,7219
|
|
24
|
+
kicad_sch_api/core/junctions.py,sha256=HdEdaqF5zzFIWuRhJ2HJnVqPah4KJGNmeNv2KzgmFZQ,4757
|
|
25
|
+
kicad_sch_api/core/labels.py,sha256=roiwUrF-YWBOUMD-s2_eyL7x2efOhOde6WWoxI1b5JM,10358
|
|
26
|
+
kicad_sch_api/core/nets.py,sha256=N1n6U7G7eXKRrc-osV48ReA6mOOLwn4TCwcNp2ISkNQ,9773
|
|
27
|
+
kicad_sch_api/core/no_connects.py,sha256=6HCXzdVO124AdUUsQbCv9Y0f7KWmObkQ4OZLimYgET8,8548
|
|
28
|
+
kicad_sch_api/core/parser.py,sha256=uvFVdSVzv5-RZmD_OKnqm51DIatFfsKF7NzLcWx4gfg,28761
|
|
29
|
+
kicad_sch_api/core/pin_utils.py,sha256=XGEow3HzBTyT8a0B_ZC8foMvwzYaENSaqTUwDW1rz24,5417
|
|
30
|
+
kicad_sch_api/core/schematic.py,sha256=W3URcKzjUrsTy3MfDejGuhuLmV2WM2YmFnGTihzGgt0,56489
|
|
31
|
+
kicad_sch_api/core/texts.py,sha256=kBwUxwftqncl-yauiJjdnLXauV6EWq2oLhKw2bAxD_c,9990
|
|
32
|
+
kicad_sch_api/core/types.py,sha256=Rx3Q9PTmzP2RYEJhnb3bw0Gs2N1Gvn27KOPtqTph0hU,15853
|
|
33
|
+
kicad_sch_api/core/wires.py,sha256=lLqcpRodErD4fD4_VMB1HgC9ViPnYPGcT8b-N9S0q-g,7139
|
|
34
|
+
kicad_sch_api/core/collections/__init__.py,sha256=i75_p9v330S2hxi4LrAGLmcVjrF8O0nTlGjCCjNbkq0,118
|
|
35
|
+
kicad_sch_api/core/collections/base.py,sha256=H-g1SC7hKD5QvbXPKVQotCK2e5pn04-y1ipkBQGcy3I,7076
|
|
36
|
+
kicad_sch_api/core/factories/__init__.py,sha256=qFx_rAgcTgWRZ572hvzzKNAze-jE0BOLqLrSFzj7T6M,130
|
|
37
|
+
kicad_sch_api/core/factories/element_factory.py,sha256=VbyBlEuIkVGkKf4soVIT8XUlq-T0-SJ_8w38JBfUH_k,8059
|
|
38
|
+
kicad_sch_api/core/managers/__init__.py,sha256=Ec9H9RSBFt2MeJIhnZFUN9sa2ql0BSrO8FNOa1XsXeU,731
|
|
39
|
+
kicad_sch_api/core/managers/file_io.py,sha256=k7yAfOvS5SqHrn1bCOH_wmOqDQnQe25wvhSPDmI8Cjk,7670
|
|
40
|
+
kicad_sch_api/core/managers/format_sync.py,sha256=ar0FfhwXrU2l5ATV0aW5KtVRfIM2iM1WoyGvXQh-ShY,16963
|
|
41
|
+
kicad_sch_api/core/managers/graphics.py,sha256=-jd-JL1TOuDntNEQcSeJ56Ccrkuudmj1dJkRtLUtRog,18370
|
|
42
|
+
kicad_sch_api/core/managers/metadata.py,sha256=9oJK8UgnzpjDwZ-46I1eW3_P9ZoJsDvutEsgROFmTwc,8004
|
|
43
|
+
kicad_sch_api/core/managers/sheet.py,sha256=jnnEBon0QmMh22-Ls7ZP5A_4FxM7bCyaJOF9AzZT1Kg,14816
|
|
44
|
+
kicad_sch_api/core/managers/text_elements.py,sha256=utZIg488x9NLQID6ALbOcI0ZM2PfvgADVJ1jcbGP9jk,17319
|
|
45
|
+
kicad_sch_api/core/managers/validation.py,sha256=-ZP_9odFsBmFG4CkNc00ZJq6bm_VtyjJHYDkMDku3l4,15757
|
|
46
|
+
kicad_sch_api/core/managers/wire.py,sha256=WZSycnkI7CCBTsYKai7TPBULXi0gs2XE1Xxs-d87IfU,12027
|
|
47
|
+
kicad_sch_api/discovery/__init__.py,sha256=qSuCsnC-hVtaLYE8fwd-Gea6JKwEVGPQ-hSNDNJYsIU,329
|
|
48
|
+
kicad_sch_api/discovery/search_index.py,sha256=KgQT8ipT9OU6ktUwhDZ37Mao0Cba0fJOsxUk9m8ZKbY,15856
|
|
49
|
+
kicad_sch_api/geometry/__init__.py,sha256=hTBXkn8mZZCjzDIrtPv67QsnCYB77L67JjthQgEIX7o,716
|
|
50
|
+
kicad_sch_api/geometry/font_metrics.py,sha256=3f5_9ifxtDUigLDiafglO2pCgPE7JFDKqa-0uhLPkoQ,839
|
|
51
|
+
kicad_sch_api/geometry/symbol_bbox.py,sha256=3zd9-M9ehue5_-Gpdm_Yht4W49CbE0YRsAhAzfqJGEg,24161
|
|
52
|
+
kicad_sch_api/interfaces/__init__.py,sha256=ukuLgCT16e0sPLmrGb4HB_3DhGU1YriDEkeRgEBsQIA,435
|
|
53
|
+
kicad_sch_api/interfaces/parser.py,sha256=J-b0czz1q_O81HlvIp3dHx53cm8UGSgQTd4xe5tBszk,2008
|
|
54
|
+
kicad_sch_api/interfaces/repository.py,sha256=wFnWUCut6wPV9yDDE9k6zkhhijRnflbLteeXYtcU-gM,1763
|
|
55
|
+
kicad_sch_api/interfaces/resolver.py,sha256=2_3et6VVnyZZ8VI5i-Q4C-4bBXKTAgYAEFxAFuOWEGw,2936
|
|
56
|
+
kicad_sch_api/library/__init__.py,sha256=NG9UTdcpn25Bl9tPsYs9ED7bvpaVPVdtLMbnxkQkOnU,250
|
|
57
|
+
kicad_sch_api/library/cache.py,sha256=7na88grl465WHwUOGuOzYrrWwjsMBXhXVtxhnaJ9GBY,33208
|
|
58
|
+
kicad_sch_api/parsers/__init__.py,sha256=4TFc2duJMy6iRuk2dYbW4b7s-9H525iAsGU674_2a-E,357
|
|
59
|
+
kicad_sch_api/parsers/base.py,sha256=vsKGxZkdzTNqrdbRPx11D4b3ebDm3LW65v2Xf4Q06_c,4569
|
|
60
|
+
kicad_sch_api/parsers/registry.py,sha256=LoPvWIiGYysvTRtFfd8kWCXE0i535hoKYpdKs49Ygjs,5098
|
|
61
|
+
kicad_sch_api/parsers/utils.py,sha256=54n1gWQJMoQItB2FcQVHovwsqMq_h9aZvZBhSaOmc-I,2330
|
|
62
|
+
kicad_sch_api/parsers/elements/__init__.py,sha256=Av9oXw5uLsEkRsyWzLWsOgZ0UOrgkAhE4NDfdUUViV8,699
|
|
63
|
+
kicad_sch_api/parsers/elements/graphics_parser.py,sha256=1dnt8OF9lsx6zrlJk7_s4ceZJ4U3-u-hHKqlZFBMT7U,23375
|
|
64
|
+
kicad_sch_api/parsers/elements/label_parser.py,sha256=KL_AV_-BhA_KV1FLlqNpMj1Nu-gHLscjqQ4NePv4elk,7249
|
|
65
|
+
kicad_sch_api/parsers/elements/library_parser.py,sha256=qHQMI3PatLgHtUWvWhQxbKC-NXJqgOVW33hVkMQ9sEU,6321
|
|
66
|
+
kicad_sch_api/parsers/elements/metadata_parser.py,sha256=IFpgk5eLqp1kcjhpZB-jPThBCVyvdgsLo4YRydlvYD4,1897
|
|
67
|
+
kicad_sch_api/parsers/elements/sheet_parser.py,sha256=xZld-yzW7r1FKABaK89K7U-Zenqz2cHUqtMnADhxCeQ,14246
|
|
68
|
+
kicad_sch_api/parsers/elements/symbol_parser.py,sha256=nIKCZ67CLFHo6m62Xw2rLcOtjGLpyq0LhBdd0fPDiiY,12187
|
|
69
|
+
kicad_sch_api/parsers/elements/text_parser.py,sha256=n5G_3czchmPCEdvTVoQsATTW1PQW7KcSjzglqzPlOKQ,9820
|
|
70
|
+
kicad_sch_api/parsers/elements/wire_parser.py,sha256=geWI3jMXM7lZF26k7n7c6RQ55x4gsO4j8Ou0fk0O2j8,8271
|
|
71
|
+
kicad_sch_api/symbols/__init__.py,sha256=NfakJ5-8AQxq5vi8nZVuaUtDpWHfwHm5AD4rC-p9BZI,501
|
|
72
|
+
kicad_sch_api/symbols/cache.py,sha256=pKFjmuyId-9gGPAue-1Rzy4MRsecoC4TMn0hn2n0Yqk,16204
|
|
73
|
+
kicad_sch_api/symbols/resolver.py,sha256=w0jqepp9RwWqlwQHX28FpTn1aSz8iOf7kcJUOBMHwqE,12074
|
|
74
|
+
kicad_sch_api/symbols/validators.py,sha256=5Ryt4rLHxDF3ALViaNLRrI3pYvOreVT51gpvhECTZms,17216
|
|
75
|
+
kicad_sch_api/utils/__init__.py,sha256=1V_yGgI7jro6MUc4Pviux_WIeJ1wmiYFID186SZwWLQ,277
|
|
76
|
+
kicad_sch_api/utils/validation.py,sha256=XlWGRZJb3cOPYpU9sLQQgC_NASwbi6W-LCN7PzUmaPY,15626
|
|
77
|
+
kicad_sch_api/validation/__init__.py,sha256=YZ2KDTpBN9BloD7I__gsw6IiW-g5tZPux0kgyXb3TjU,524
|
|
78
|
+
kicad_sch_api/validation/erc.py,sha256=6WMHyMakKpn1-jXkfO9ltayLRA0OaU1N7GQm-pbZTLg,5160
|
|
79
|
+
kicad_sch_api/validation/erc_models.py,sha256=wFYMH-cbcdRX1j9LPn28IGUYBLioPDr4lP0m2QuhAnI,6628
|
|
80
|
+
kicad_sch_api/validation/pin_matrix.py,sha256=AdBCvEmOByXACOUoskYxYMcwKvIasxrtJOqWM-WgVi0,7456
|
|
81
|
+
kicad_sch_api/validation/validators.py,sha256=3txkQpR3qAUzp0-m-FnDYf3-_GGj6iaGZj4kSYu-Fe4,13166
|
|
82
|
+
kicad_sch_api-0.4.2.dist-info/licenses/LICENSE,sha256=Em65Nvte1G9MHc0rHqtYuGkCPcshD588itTa358J6gs,1070
|
|
83
|
+
kicad_sch_api-0.4.2.dist-info/METADATA,sha256=T5Tn3vERNm5rvjbM0dbd0XMA3O6bFaHJcGZC1WFfJD8,17953
|
|
84
|
+
kicad_sch_api-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
85
|
+
kicad_sch_api-0.4.2.dist-info/entry_points.txt,sha256=VWKsFi2Jv7G_tmio3cNVhhIBfv_OZFaKa-T_ED84lc8,57
|
|
86
|
+
kicad_sch_api-0.4.2.dist-info/top_level.txt,sha256=n0ex4gOJ1b_fARowcGqRzyOGZcHRhc5LZa6_vVgGxcI,14
|
|
87
|
+
kicad_sch_api-0.4.2.dist-info/RECORD,,
|