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.
Files changed (66) hide show
  1. kicad_sch_api/__init__.py +67 -2
  2. kicad_sch_api/cli/kicad_to_python.py +169 -0
  3. kicad_sch_api/collections/__init__.py +23 -8
  4. kicad_sch_api/collections/base.py +369 -59
  5. kicad_sch_api/collections/components.py +1376 -187
  6. kicad_sch_api/collections/junctions.py +129 -289
  7. kicad_sch_api/collections/labels.py +391 -287
  8. kicad_sch_api/collections/wires.py +202 -316
  9. kicad_sch_api/core/__init__.py +37 -2
  10. kicad_sch_api/core/component_bounds.py +34 -12
  11. kicad_sch_api/core/components.py +146 -7
  12. kicad_sch_api/core/config.py +25 -12
  13. kicad_sch_api/core/connectivity.py +692 -0
  14. kicad_sch_api/core/exceptions.py +175 -0
  15. kicad_sch_api/core/factories/element_factory.py +3 -1
  16. kicad_sch_api/core/formatter.py +24 -7
  17. kicad_sch_api/core/geometry.py +94 -5
  18. kicad_sch_api/core/managers/__init__.py +4 -0
  19. kicad_sch_api/core/managers/base.py +76 -0
  20. kicad_sch_api/core/managers/file_io.py +3 -1
  21. kicad_sch_api/core/managers/format_sync.py +3 -2
  22. kicad_sch_api/core/managers/graphics.py +3 -2
  23. kicad_sch_api/core/managers/hierarchy.py +661 -0
  24. kicad_sch_api/core/managers/metadata.py +4 -2
  25. kicad_sch_api/core/managers/sheet.py +52 -14
  26. kicad_sch_api/core/managers/text_elements.py +3 -2
  27. kicad_sch_api/core/managers/validation.py +3 -2
  28. kicad_sch_api/core/managers/wire.py +112 -54
  29. kicad_sch_api/core/parsing_utils.py +63 -0
  30. kicad_sch_api/core/pin_utils.py +103 -9
  31. kicad_sch_api/core/schematic.py +343 -29
  32. kicad_sch_api/core/types.py +79 -7
  33. kicad_sch_api/exporters/__init__.py +10 -0
  34. kicad_sch_api/exporters/python_generator.py +610 -0
  35. kicad_sch_api/exporters/templates/default.py.jinja2 +65 -0
  36. kicad_sch_api/geometry/__init__.py +15 -3
  37. kicad_sch_api/geometry/routing.py +211 -0
  38. kicad_sch_api/parsers/elements/label_parser.py +30 -8
  39. kicad_sch_api/parsers/elements/symbol_parser.py +255 -83
  40. kicad_sch_api/utils/logging.py +555 -0
  41. kicad_sch_api/utils/logging_decorators.py +587 -0
  42. kicad_sch_api/utils/validation.py +16 -22
  43. kicad_sch_api/wrappers/__init__.py +14 -0
  44. kicad_sch_api/wrappers/base.py +89 -0
  45. kicad_sch_api/wrappers/wire.py +198 -0
  46. kicad_sch_api-0.5.1.dist-info/METADATA +540 -0
  47. kicad_sch_api-0.5.1.dist-info/RECORD +114 -0
  48. kicad_sch_api-0.5.1.dist-info/entry_points.txt +4 -0
  49. {kicad_sch_api-0.4.1.dist-info → kicad_sch_api-0.5.1.dist-info}/top_level.txt +1 -0
  50. mcp_server/__init__.py +34 -0
  51. mcp_server/example_logging_integration.py +506 -0
  52. mcp_server/models.py +252 -0
  53. mcp_server/server.py +357 -0
  54. mcp_server/tools/__init__.py +32 -0
  55. mcp_server/tools/component_tools.py +516 -0
  56. mcp_server/tools/connectivity_tools.py +532 -0
  57. mcp_server/tools/consolidated_tools.py +1216 -0
  58. mcp_server/tools/pin_discovery.py +333 -0
  59. mcp_server/utils/__init__.py +38 -0
  60. mcp_server/utils/logging.py +127 -0
  61. mcp_server/utils.py +36 -0
  62. kicad_sch_api-0.4.1.dist-info/METADATA +0 -491
  63. kicad_sch_api-0.4.1.dist-info/RECORD +0 -87
  64. kicad_sch_api-0.4.1.dist-info/entry_points.txt +0 -2
  65. {kicad_sch_api-0.4.1.dist-info → kicad_sch_api-0.5.1.dist-info}/WHEEL +0 -0
  66. {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.4.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 that eliminates code duplication
5
- across component, wire, and junction collections while providing consistent
6
- indexing, performance optimization, and management capabilities.
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 IndexedCollection
10
- from .components import ComponentCollection
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
- "IndexedCollection",
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
  ]