kicad-sch-api 0.4.1__py3-none-any.whl → 0.5.1__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.
- kicad_sch_api/__init__.py +67 -2
- kicad_sch_api/cli/kicad_to_python.py +169 -0
- kicad_sch_api/collections/__init__.py +23 -8
- kicad_sch_api/collections/base.py +369 -59
- kicad_sch_api/collections/components.py +1376 -187
- kicad_sch_api/collections/junctions.py +129 -289
- kicad_sch_api/collections/labels.py +391 -287
- kicad_sch_api/collections/wires.py +202 -316
- kicad_sch_api/core/__init__.py +37 -2
- kicad_sch_api/core/component_bounds.py +34 -12
- kicad_sch_api/core/components.py +146 -7
- kicad_sch_api/core/config.py +25 -12
- kicad_sch_api/core/connectivity.py +692 -0
- kicad_sch_api/core/exceptions.py +175 -0
- kicad_sch_api/core/factories/element_factory.py +3 -1
- kicad_sch_api/core/formatter.py +24 -7
- kicad_sch_api/core/geometry.py +94 -5
- kicad_sch_api/core/managers/__init__.py +4 -0
- kicad_sch_api/core/managers/base.py +76 -0
- kicad_sch_api/core/managers/file_io.py +3 -1
- kicad_sch_api/core/managers/format_sync.py +3 -2
- kicad_sch_api/core/managers/graphics.py +3 -2
- kicad_sch_api/core/managers/hierarchy.py +661 -0
- kicad_sch_api/core/managers/metadata.py +4 -2
- kicad_sch_api/core/managers/sheet.py +52 -14
- kicad_sch_api/core/managers/text_elements.py +3 -2
- kicad_sch_api/core/managers/validation.py +3 -2
- kicad_sch_api/core/managers/wire.py +112 -54
- kicad_sch_api/core/parsing_utils.py +63 -0
- kicad_sch_api/core/pin_utils.py +103 -9
- kicad_sch_api/core/schematic.py +343 -29
- kicad_sch_api/core/types.py +79 -7
- kicad_sch_api/exporters/__init__.py +10 -0
- kicad_sch_api/exporters/python_generator.py +610 -0
- kicad_sch_api/exporters/templates/default.py.jinja2 +65 -0
- kicad_sch_api/geometry/__init__.py +15 -3
- kicad_sch_api/geometry/routing.py +211 -0
- kicad_sch_api/parsers/elements/label_parser.py +30 -8
- kicad_sch_api/parsers/elements/symbol_parser.py +255 -83
- kicad_sch_api/utils/logging.py +555 -0
- kicad_sch_api/utils/logging_decorators.py +587 -0
- kicad_sch_api/utils/validation.py +16 -22
- kicad_sch_api/wrappers/__init__.py +14 -0
- kicad_sch_api/wrappers/base.py +89 -0
- kicad_sch_api/wrappers/wire.py +198 -0
- kicad_sch_api-0.5.1.dist-info/METADATA +540 -0
- kicad_sch_api-0.5.1.dist-info/RECORD +114 -0
- kicad_sch_api-0.5.1.dist-info/entry_points.txt +4 -0
- {kicad_sch_api-0.4.1.dist-info → kicad_sch_api-0.5.1.dist-info}/top_level.txt +1 -0
- mcp_server/__init__.py +34 -0
- mcp_server/example_logging_integration.py +506 -0
- mcp_server/models.py +252 -0
- mcp_server/server.py +357 -0
- mcp_server/tools/__init__.py +32 -0
- mcp_server/tools/component_tools.py +516 -0
- mcp_server/tools/connectivity_tools.py +532 -0
- mcp_server/tools/consolidated_tools.py +1216 -0
- mcp_server/tools/pin_discovery.py +333 -0
- mcp_server/utils/__init__.py +38 -0
- mcp_server/utils/logging.py +127 -0
- mcp_server/utils.py +36 -0
- kicad_sch_api-0.4.1.dist-info/METADATA +0 -491
- kicad_sch_api-0.4.1.dist-info/RECORD +0 -87
- kicad_sch_api-0.4.1.dist-info/entry_points.txt +0 -2
- {kicad_sch_api-0.4.1.dist-info → kicad_sch_api-0.5.1.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.4.1.dist-info → kicad_sch_api-0.5.1.dist-info}/licenses/LICENSE +0 -0
kicad_sch_api/__init__.py
CHANGED
|
@@ -42,17 +42,24 @@ Advanced Usage:
|
|
|
42
42
|
print(f"Found {len(issues)} validation issues")
|
|
43
43
|
"""
|
|
44
44
|
|
|
45
|
-
__version__ = "0.
|
|
45
|
+
__version__ = "0.5.0"
|
|
46
46
|
__author__ = "Circuit-Synth"
|
|
47
47
|
__email__ = "info@circuit-synth.com"
|
|
48
48
|
|
|
49
49
|
from .core.components import Component, ComponentCollection
|
|
50
50
|
from .core.config import KiCADConfig, config
|
|
51
|
+
from .core.types import PinInfo
|
|
51
52
|
|
|
52
53
|
# Core imports for public API
|
|
53
54
|
from .core.schematic import Schematic
|
|
54
55
|
from .library.cache import SymbolLibraryCache, get_symbol_cache
|
|
55
56
|
from .utils.validation import ValidationError, ValidationIssue
|
|
57
|
+
# Commonly-used exceptions (ValidationError re-exported from utils for backward compat)
|
|
58
|
+
from .core.exceptions import (
|
|
59
|
+
KiCadSchError,
|
|
60
|
+
ElementNotFoundError,
|
|
61
|
+
DuplicateElementError,
|
|
62
|
+
)
|
|
56
63
|
|
|
57
64
|
# Version info
|
|
58
65
|
VERSION_INFO = (0, 4, 0)
|
|
@@ -63,14 +70,18 @@ __all__ = [
|
|
|
63
70
|
"Schematic",
|
|
64
71
|
"Component",
|
|
65
72
|
"ComponentCollection",
|
|
73
|
+
"PinInfo",
|
|
66
74
|
"SymbolLibraryCache",
|
|
67
75
|
"get_symbol_cache",
|
|
68
76
|
# Configuration
|
|
69
77
|
"KiCADConfig",
|
|
70
78
|
"config",
|
|
71
79
|
# Exceptions
|
|
80
|
+
"KiCadSchError",
|
|
72
81
|
"ValidationError",
|
|
73
82
|
"ValidationIssue",
|
|
83
|
+
"ElementNotFoundError",
|
|
84
|
+
"DuplicateElementError",
|
|
74
85
|
# Version info
|
|
75
86
|
"__version__",
|
|
76
87
|
"VERSION_INFO",
|
|
@@ -112,5 +123,59 @@ def create_schematic(name: str = "Untitled") -> "Schematic":
|
|
|
112
123
|
return Schematic.create(name)
|
|
113
124
|
|
|
114
125
|
|
|
126
|
+
def schematic_to_python(
|
|
127
|
+
input_path: str,
|
|
128
|
+
output_path: str,
|
|
129
|
+
template: str = 'default',
|
|
130
|
+
include_hierarchy: bool = True,
|
|
131
|
+
format_code: bool = True,
|
|
132
|
+
add_comments: bool = True
|
|
133
|
+
):
|
|
134
|
+
"""
|
|
135
|
+
Convert KiCad schematic to Python code (one-line convenience function).
|
|
136
|
+
|
|
137
|
+
Loads a KiCad schematic and generates executable Python code that
|
|
138
|
+
recreates it using the kicad-sch-api library.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
input_path: Input .kicad_sch file
|
|
142
|
+
output_path: Output .py file
|
|
143
|
+
template: Code template style ('minimal', 'default', 'verbose', 'documented')
|
|
144
|
+
include_hierarchy: Include hierarchical sheets
|
|
145
|
+
format_code: Format code with Black
|
|
146
|
+
add_comments: Add explanatory comments
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Path to generated Python file
|
|
150
|
+
|
|
151
|
+
Raises:
|
|
152
|
+
FileNotFoundError: If input file doesn't exist
|
|
153
|
+
CodeGenerationError: If code generation fails
|
|
154
|
+
|
|
155
|
+
Example:
|
|
156
|
+
>>> import kicad_sch_api as ksa
|
|
157
|
+
>>> ksa.schematic_to_python('input.kicad_sch', 'output.py')
|
|
158
|
+
PosixPath('output.py')
|
|
159
|
+
|
|
160
|
+
>>> ksa.schematic_to_python('input.kicad_sch', 'output.py',
|
|
161
|
+
... template='minimal',
|
|
162
|
+
... add_comments=False)
|
|
163
|
+
PosixPath('output.py')
|
|
164
|
+
"""
|
|
165
|
+
from pathlib import Path
|
|
166
|
+
|
|
167
|
+
# Load schematic
|
|
168
|
+
schematic = Schematic.load(input_path)
|
|
169
|
+
|
|
170
|
+
# Export to Python
|
|
171
|
+
return schematic.export_to_python(
|
|
172
|
+
output_path=output_path,
|
|
173
|
+
template=template,
|
|
174
|
+
include_hierarchy=include_hierarchy,
|
|
175
|
+
format_code=format_code,
|
|
176
|
+
add_comments=add_comments
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
115
180
|
# Add convenience functions to __all__
|
|
116
|
-
__all__.extend(["load_schematic", "create_schematic"])
|
|
181
|
+
__all__.extend(["load_schematic", "create_schematic", "schematic_to_python"])
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
KiCad-to-Python CLI Command
|
|
4
|
+
|
|
5
|
+
Convert KiCad schematic files to executable Python code.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
kicad-to-python input.kicad_sch output.py
|
|
9
|
+
kicad-to-python input.kicad_sch output.py --template verbose
|
|
10
|
+
kicad-to-python project.kicad_pro output_dir/ --include-hierarchy
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Optional
|
|
17
|
+
|
|
18
|
+
import kicad_sch_api as ksa
|
|
19
|
+
from kicad_sch_api.exporters.python_generator import (
|
|
20
|
+
PythonCodeGenerator,
|
|
21
|
+
CodeGenerationError,
|
|
22
|
+
TemplateNotFoundError
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main(argv: Optional[list] = None) -> int:
|
|
27
|
+
"""
|
|
28
|
+
Main CLI entry point.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
argv: Command-line arguments (None = sys.argv)
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Exit code (0 = success, 1 = error)
|
|
35
|
+
"""
|
|
36
|
+
parser = argparse.ArgumentParser(
|
|
37
|
+
prog='kicad-to-python',
|
|
38
|
+
description='Convert KiCad schematics to Python code',
|
|
39
|
+
epilog='For more information: https://github.com/circuit-synth/kicad-sch-api'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Positional arguments
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
'input',
|
|
45
|
+
type=Path,
|
|
46
|
+
help='Input KiCad schematic (.kicad_sch) or project (.kicad_pro)'
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
'output',
|
|
51
|
+
type=Path,
|
|
52
|
+
help='Output Python file (.py) or directory (for hierarchical)'
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Options
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
'--template',
|
|
58
|
+
choices=['minimal', 'default', 'verbose', 'documented'],
|
|
59
|
+
default='default',
|
|
60
|
+
help='Code template style (default: default)'
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
'--include-hierarchy',
|
|
65
|
+
action='store_true',
|
|
66
|
+
help='Include hierarchical sheets'
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
'--no-format',
|
|
71
|
+
action='store_true',
|
|
72
|
+
help='Skip Black code formatting'
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
parser.add_argument(
|
|
76
|
+
'--no-comments',
|
|
77
|
+
action='store_true',
|
|
78
|
+
help='Skip explanatory comments'
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
parser.add_argument(
|
|
82
|
+
'--verbose', '-v',
|
|
83
|
+
action='store_true',
|
|
84
|
+
help='Verbose output'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
args = parser.parse_args(argv)
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
# Validate input file
|
|
91
|
+
if not args.input.exists():
|
|
92
|
+
print(f"❌ Error: Input file not found: {args.input}", file=sys.stderr)
|
|
93
|
+
return 1
|
|
94
|
+
|
|
95
|
+
if args.input.suffix not in ['.kicad_sch', '.kicad_pro']:
|
|
96
|
+
print(
|
|
97
|
+
f"❌ Error: Input must be .kicad_sch or .kicad_pro file",
|
|
98
|
+
file=sys.stderr
|
|
99
|
+
)
|
|
100
|
+
return 1
|
|
101
|
+
|
|
102
|
+
# Load schematic
|
|
103
|
+
if args.verbose:
|
|
104
|
+
print(f"📖 Loading schematic: {args.input}")
|
|
105
|
+
|
|
106
|
+
schematic = ksa.Schematic.load(args.input)
|
|
107
|
+
|
|
108
|
+
if args.verbose:
|
|
109
|
+
comp_count = len(list(schematic.components))
|
|
110
|
+
wire_count = len(list(schematic.wires))
|
|
111
|
+
label_count = len(list(schematic.labels))
|
|
112
|
+
print(f" Found {comp_count} components")
|
|
113
|
+
print(f" Found {wire_count} wires")
|
|
114
|
+
print(f" Found {label_count} labels")
|
|
115
|
+
|
|
116
|
+
# Generate Python code
|
|
117
|
+
if args.verbose:
|
|
118
|
+
print(f"🔨 Generating Python code...")
|
|
119
|
+
|
|
120
|
+
generator = PythonCodeGenerator(
|
|
121
|
+
template=args.template,
|
|
122
|
+
format_code=not args.no_format,
|
|
123
|
+
add_comments=not args.no_comments
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
code = generator.generate(
|
|
127
|
+
schematic=schematic,
|
|
128
|
+
include_hierarchy=args.include_hierarchy,
|
|
129
|
+
output_path=args.output
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Report success
|
|
133
|
+
lines = len(code.split('\n'))
|
|
134
|
+
print(f"✅ Generated {args.output} ({lines} lines)")
|
|
135
|
+
|
|
136
|
+
if args.verbose:
|
|
137
|
+
print(f" Template: {args.template}")
|
|
138
|
+
print(f" Formatted: {not args.no_format}")
|
|
139
|
+
print(f" Comments: {not args.no_comments}")
|
|
140
|
+
|
|
141
|
+
return 0
|
|
142
|
+
|
|
143
|
+
except FileNotFoundError as e:
|
|
144
|
+
print(f"❌ File not found: {e}", file=sys.stderr)
|
|
145
|
+
return 1
|
|
146
|
+
|
|
147
|
+
except CodeGenerationError as e:
|
|
148
|
+
print(f"❌ Code generation error: {e}", file=sys.stderr)
|
|
149
|
+
return 1
|
|
150
|
+
|
|
151
|
+
except TemplateNotFoundError as e:
|
|
152
|
+
print(f"❌ Template error: {e}", file=sys.stderr)
|
|
153
|
+
return 1
|
|
154
|
+
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"❌ Unexpected error: {e}", file=sys.stderr)
|
|
157
|
+
if args.verbose:
|
|
158
|
+
import traceback
|
|
159
|
+
traceback.print_exc()
|
|
160
|
+
return 1
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def entry_point():
|
|
164
|
+
"""Entry point for setuptools console_scripts."""
|
|
165
|
+
sys.exit(main())
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == '__main__':
|
|
169
|
+
sys.exit(main())
|
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Modern collection architecture for KiCAD schematic elements.
|
|
3
3
|
|
|
4
|
-
This module provides a unified collection framework
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
This module provides a unified collection framework with:
|
|
5
|
+
- Centralized index management via IndexRegistry
|
|
6
|
+
- Lazy index rebuilding for performance
|
|
7
|
+
- Configurable validation levels
|
|
8
|
+
- Auto-tracking property dictionaries
|
|
9
|
+
- Batch mode for bulk operations
|
|
7
10
|
"""
|
|
8
11
|
|
|
9
|
-
from .base import
|
|
10
|
-
|
|
12
|
+
from .base import (
|
|
13
|
+
BaseCollection,
|
|
14
|
+
IndexSpec,
|
|
15
|
+
IndexRegistry,
|
|
16
|
+
PropertyDict,
|
|
17
|
+
ValidationLevel,
|
|
18
|
+
)
|
|
19
|
+
from .components import Component, ComponentCollection
|
|
11
20
|
from .junctions import JunctionCollection
|
|
12
|
-
from .labels import LabelCollection
|
|
21
|
+
from .labels import LabelCollection, LabelElement
|
|
13
22
|
from .wires import WireCollection
|
|
14
23
|
|
|
15
24
|
__all__ = [
|
|
16
|
-
"
|
|
25
|
+
"BaseCollection",
|
|
26
|
+
"IndexSpec",
|
|
27
|
+
"IndexRegistry",
|
|
28
|
+
"PropertyDict",
|
|
29
|
+
"ValidationLevel",
|
|
30
|
+
"Component",
|
|
17
31
|
"ComponentCollection",
|
|
18
|
-
"WireCollection",
|
|
19
32
|
"JunctionCollection",
|
|
20
33
|
"LabelCollection",
|
|
34
|
+
"LabelElement",
|
|
35
|
+
"WireCollection",
|
|
21
36
|
]
|