exstruct 0.4.2__tar.gz → 0.4.4__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.
Files changed (42) hide show
  1. {exstruct-0.4.2 → exstruct-0.4.4}/PKG-INFO +15 -4
  2. {exstruct-0.4.2 → exstruct-0.4.4}/README.md +12 -1
  3. {exstruct-0.4.2 → exstruct-0.4.4}/pyproject.toml +10 -3
  4. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/__init__.py +18 -2
  5. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/cli/main.py +6 -0
  6. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/engine.py +11 -2
  7. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/errors.py +2 -2
  8. exstruct-0.4.4/src/exstruct/mcp/__init__.py +125 -0
  9. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/mcp/chunk_reader.py +450 -413
  10. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/mcp/extract_runner.py +314 -309
  11. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/mcp/io.py +61 -61
  12. exstruct-0.4.4/src/exstruct/mcp/patch_runner.py +1315 -0
  13. exstruct-0.4.4/src/exstruct/mcp/server.py +574 -0
  14. exstruct-0.4.4/src/exstruct/mcp/sheet_reader.py +472 -0
  15. exstruct-0.4.4/src/exstruct/mcp/tools.py +483 -0
  16. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/mcp/validate_input.py +76 -76
  17. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/models/__init__.py +156 -1
  18. exstruct-0.4.2/src/exstruct/mcp/__init__.py +0 -59
  19. exstruct-0.4.2/src/exstruct/mcp/server.py +0 -312
  20. exstruct-0.4.2/src/exstruct/mcp/tools.py +0 -203
  21. {exstruct-0.4.2 → exstruct-0.4.4}/LICENSE +0 -0
  22. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/cli/availability.py +0 -0
  23. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/__init__.py +0 -0
  24. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/backends/__init__.py +0 -0
  25. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/backends/base.py +0 -0
  26. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/backends/com_backend.py +0 -0
  27. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/backends/openpyxl_backend.py +0 -0
  28. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/cells.py +0 -0
  29. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/charts.py +0 -0
  30. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/integrate.py +0 -0
  31. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/logging_utils.py +0 -0
  32. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/modeling.py +0 -0
  33. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/pipeline.py +0 -0
  34. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/ranges.py +0 -0
  35. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/shapes.py +0 -0
  36. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/core/workbook.py +0 -0
  37. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/io/__init__.py +0 -0
  38. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/io/serialize.py +0 -0
  39. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/models/maps.py +0 -0
  40. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/models/types.py +0 -0
  41. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/py.typed +0 -0
  42. {exstruct-0.4.2 → exstruct-0.4.4}/src/exstruct/render/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exstruct
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines
5
5
  Keywords: excel,structure,data,exstruct
6
6
  Author: harumiWeb
@@ -43,9 +43,9 @@ Requires-Dist: pyyaml>=6.0.3 ; extra == 'all'
43
43
  Requires-Dist: python-toon>=0.1.3 ; extra == 'all'
44
44
  Requires-Dist: pypdfium2>=5.1.0 ; extra == 'all'
45
45
  Requires-Dist: pillow>=12.0.0 ; extra == 'all'
46
- Requires-Dist: mcp>=1.6.0,<2.0.0 ; extra == 'all'
46
+ Requires-Dist: mcp>=1.25.0,<2.0.0 ; extra == 'all'
47
47
  Requires-Dist: httpx>=0.27,<1.0 ; extra == 'all'
48
- Requires-Dist: mcp>=1.6.0,<2.0.0 ; extra == 'mcp'
48
+ Requires-Dist: mcp>=1.25.0,<2.0.0 ; extra == 'mcp'
49
49
  Requires-Dist: httpx>=0.27,<1.0 ; extra == 'mcp'
50
50
  Requires-Dist: pypdfium2>=5.1.0 ; extra == 'render'
51
51
  Requires-Dist: pillow>=12.0.0 ; extra == 'render'
@@ -65,7 +65,7 @@ Description-Content-Type: text/markdown
65
65
 
66
66
  # ExStruct — Excel Structured Extraction Engine
67
67
 
68
- [![PyPI version](https://badge.fury.io/py/exstruct.svg)](https://pypi.org/project/exstruct/) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/exstruct?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/exstruct) ![Licence: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue?style=flat-square) [![pytest](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml/badge.svg)](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e081cb4f634e4175b259eb7c34f54f60)](https://app.codacy.com/gh/harumiWeb/exstruct/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![codecov](https://codecov.io/gh/harumiWeb/exstruct/graph/badge.svg?token=2XI1O8TTA9)](https://codecov.io/gh/harumiWeb/exstruct)
68
+ [![PyPI version](https://badge.fury.io/py/exstruct.svg)](https://pypi.org/project/exstruct/) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/exstruct?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/exstruct) ![Licence: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue?style=flat-square) [![pytest](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml/badge.svg)](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e081cb4f634e4175b259eb7c34f54f60)](https://app.codacy.com/gh/harumiWeb/exstruct/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![codecov](https://codecov.io/gh/harumiWeb/exstruct/graph/badge.svg?token=2XI1O8TTA9)](https://codecov.io/gh/harumiWeb/exstruct) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/harumiWeb/exstruct)
69
69
 
70
70
  ![ExStruct Image](docs/assets/icon.webp)
71
71
 
@@ -84,6 +84,15 @@ ExStruct reads Excel workbooks and outputs structured data (cells, table candida
84
84
  - **CLI rendering** (Excel required): optional PDF and per-sheet PNGs.
85
85
  - **Graceful fallback**: if Excel COM is unavailable, extraction falls back to cells + table candidates without crashing.
86
86
 
87
+ ## Benchmark
88
+
89
+ ![Benchmark Chart](benchmark/public/plots/markdown_quality.png)
90
+
91
+ This repository includes benchmark reports focused on RAG/LLM preprocessing of Excel documents.
92
+ We track two perspectives: (1) core extraction accuracy and (2) reconstruction utility for downstream structure queries (RUB).
93
+ See `benchmark/REPORT.md` for the working summary and `benchmark/public/REPORT.md` for the public bundle.
94
+ Current results are based on n=12 cases and will be expanded.
95
+
87
96
  ## Installation
88
97
 
89
98
  ```bash
@@ -129,11 +138,13 @@ exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict re
129
138
  Available tools:
130
139
 
131
140
  - `exstruct_extract`
141
+ - `exstruct_patch`
132
142
  - `exstruct_read_json_chunk`
133
143
  - `exstruct_validate_input`
134
144
 
135
145
  Notes:
136
146
 
147
+ - In MCP, `exstruct_extract` defaults to `options.alpha_col=true` (column keys: `A`, `B`, ...). Set `options.alpha_col=false` for legacy 0-based numeric string keys.
137
148
  - Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
138
149
  - On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
139
150
 
@@ -1,6 +1,6 @@
1
1
  # ExStruct — Excel Structured Extraction Engine
2
2
 
3
- [![PyPI version](https://badge.fury.io/py/exstruct.svg)](https://pypi.org/project/exstruct/) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/exstruct?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/exstruct) ![Licence: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue?style=flat-square) [![pytest](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml/badge.svg)](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e081cb4f634e4175b259eb7c34f54f60)](https://app.codacy.com/gh/harumiWeb/exstruct/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![codecov](https://codecov.io/gh/harumiWeb/exstruct/graph/badge.svg?token=2XI1O8TTA9)](https://codecov.io/gh/harumiWeb/exstruct)
3
+ [![PyPI version](https://badge.fury.io/py/exstruct.svg)](https://pypi.org/project/exstruct/) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/exstruct?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/exstruct) ![Licence: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue?style=flat-square) [![pytest](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml/badge.svg)](https://github.com/harumiWeb/exstruct/actions/workflows/pytest.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e081cb4f634e4175b259eb7c34f54f60)](https://app.codacy.com/gh/harumiWeb/exstruct/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![codecov](https://codecov.io/gh/harumiWeb/exstruct/graph/badge.svg?token=2XI1O8TTA9)](https://codecov.io/gh/harumiWeb/exstruct) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/harumiWeb/exstruct)
4
4
 
5
5
  ![ExStruct Image](docs/assets/icon.webp)
6
6
 
@@ -19,6 +19,15 @@ ExStruct reads Excel workbooks and outputs structured data (cells, table candida
19
19
  - **CLI rendering** (Excel required): optional PDF and per-sheet PNGs.
20
20
  - **Graceful fallback**: if Excel COM is unavailable, extraction falls back to cells + table candidates without crashing.
21
21
 
22
+ ## Benchmark
23
+
24
+ ![Benchmark Chart](benchmark/public/plots/markdown_quality.png)
25
+
26
+ This repository includes benchmark reports focused on RAG/LLM preprocessing of Excel documents.
27
+ We track two perspectives: (1) core extraction accuracy and (2) reconstruction utility for downstream structure queries (RUB).
28
+ See `benchmark/REPORT.md` for the working summary and `benchmark/public/REPORT.md` for the public bundle.
29
+ Current results are based on n=12 cases and will be expanded.
30
+
22
31
  ## Installation
23
32
 
24
33
  ```bash
@@ -64,11 +73,13 @@ exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict re
64
73
  Available tools:
65
74
 
66
75
  - `exstruct_extract`
76
+ - `exstruct_patch`
67
77
  - `exstruct_read_json_chunk`
68
78
  - `exstruct_validate_input`
69
79
 
70
80
  Notes:
71
81
 
82
+ - In MCP, `exstruct_extract` defaults to `options.alpha_col=true` (column keys: `A`, `B`, ...). Set `options.alpha_col=false` for legacy 0-based numeric string keys.
72
83
  - Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
73
84
  - On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
74
85
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "exstruct"
3
- version = "0.4.2"
3
+ version = "0.4.4"
4
4
  description = "Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -42,14 +42,14 @@ all = [
42
42
  "python-toon>=0.1.3",
43
43
  "pypdfium2>=5.1.0",
44
44
  "Pillow>=12.0.0",
45
- "mcp>=1.6.0,<2.0.0",
45
+ "mcp>=1.25.0,<2.0.0",
46
46
  "httpx>=0.27,<1.0",
47
47
  ]
48
48
  yaml = ["pyyaml>=6.0.3"]
49
49
  toon = ["python-toon>=0.1.3"]
50
50
  render = ["pypdfium2>=5.1.0", "Pillow>=12.0.0"]
51
51
  mcp = [
52
- "mcp>=1.6.0,<2.0.0",
52
+ "mcp>=1.25.0,<2.0.0",
53
53
  "httpx>=0.27,<1.0",
54
54
  ]
55
55
 
@@ -74,6 +74,7 @@ omit = [
74
74
  target-version = "py311"
75
75
  src = ["exstruct"]
76
76
  fix = true
77
+ exclude = ["benchmark/**"]
77
78
 
78
79
  # 静的解析ルール
79
80
  [tool.ruff.lint]
@@ -113,6 +114,7 @@ max-complexity = 12
113
114
  [tool.mypy]
114
115
  packages = ["exstruct"]
115
116
  python_version = "3.11"
117
+ exclude = "benchmark/.*"
116
118
 
117
119
  # 外部ライブラリの型情報がない場合は無視
118
120
  ignore_missing_imports = true
@@ -141,3 +143,8 @@ codecov-unit = "codecov-cli upload-process -f coverage.xml -F unit -C %CODECOV_S
141
143
  codecov-com = "codecov-cli upload-process -f coverage.xml -F com -C %CODECOV_SHA% -t %CODECOV_TOKEN%"
142
144
  docs = "mkdocs serve"
143
145
  build-docs = "mkdocs build && python scripts/gen_json_schema.py && python scripts/gen_model_docs.py"
146
+
147
+ [tool.uv.workspace]
148
+ members = [
149
+ "benchmark",
150
+ ]
@@ -41,6 +41,10 @@ from .models import (
41
41
  Shape,
42
42
  SheetData,
43
43
  WorkbookData,
44
+ col_index_to_alpha,
45
+ convert_row_keys_to_alpha,
46
+ convert_sheet_keys_to_alpha,
47
+ convert_workbook_keys_to_alpha,
44
48
  )
45
49
  from .render import export_pdf, export_sheet_images
46
50
 
@@ -82,19 +86,26 @@ __all__ = [
82
86
  "ColorsOptions",
83
87
  "serialize_workbook",
84
88
  "export_auto_page_breaks",
89
+ "col_index_to_alpha",
90
+ "convert_row_keys_to_alpha",
91
+ "convert_sheet_keys_to_alpha",
92
+ "convert_workbook_keys_to_alpha",
85
93
  ]
86
94
 
87
95
 
88
96
  ExtractionMode = Literal["light", "standard", "verbose"]
89
97
 
90
98
 
91
- def extract(file_path: str | Path, mode: ExtractionMode = "standard") -> WorkbookData:
99
+ def extract(
100
+ file_path: str | Path, mode: ExtractionMode = "standard", *, alpha_col: bool = False
101
+ ) -> WorkbookData:
92
102
  """
93
103
  Extracts an Excel workbook into a WorkbookData structure.
94
104
 
95
105
  Parameters:
96
106
  file_path (str | Path): Path to the workbook file (.xlsx, .xlsm, .xls).
97
107
  mode (ExtractionMode): Extraction detail level. "light" includes cells and table detection only (no COM, shapes/charts empty; print areas via openpyxl). "standard" includes texted shapes, arrows, charts (COM if available) and print areas. "verbose" also includes shape/chart sizes, cell link map, colors map, and formulas map.
108
+ alpha_col: When True, convert CellRow column keys to Excel-style ABC names (A, B, ..., Z, AA, ...) instead of 0-based numeric strings.
98
109
 
99
110
  Returns:
100
111
  WorkbookData: Parsed workbook representation containing sheets, rows, shapes, charts, and print areas.
@@ -108,6 +119,7 @@ def extract(file_path: str | Path, mode: ExtractionMode = "standard") -> Workboo
108
119
  include_cell_links=include_links,
109
120
  include_colors_map=include_colors_map,
110
121
  include_formulas_map=include_formulas_map,
122
+ alpha_col=alpha_col,
111
123
  )
112
124
  )
113
125
  return engine.extract(file_path, mode=mode)
@@ -317,6 +329,8 @@ def process_excel(
317
329
  print_areas_dir: str | Path | None = None,
318
330
  auto_page_breaks_dir: str | Path | None = None,
319
331
  stream: TextIO | None = None,
332
+ *,
333
+ alpha_col: bool = False,
320
334
  ) -> None:
321
335
  """
322
336
  Convenience wrapper: extract -> serialize (file or stdout) -> optional PDF/PNG.
@@ -335,6 +349,8 @@ def process_excel(
335
349
  print_areas_dir: Directory to write per-print-area files (string or Path).
336
350
  auto_page_breaks_dir: Directory to write per-auto-page-break files (COM only).
337
351
  stream: IO override when output_path is None.
352
+ alpha_col: When True, convert CellRow column keys to Excel-style
353
+ ABC names (A, B, ...) instead of 0-based numeric strings.
338
354
 
339
355
  Raises:
340
356
  ValueError: If an unsupported format or mode is given.
@@ -353,7 +369,7 @@ def process_excel(
353
369
  >>> process_excel(Path("input.xlsx"), output_path=Path("out.json"), pdf=True) # doctest: +SKIP
354
370
  """
355
371
  engine = ExStructEngine(
356
- options=StructOptions(mode=mode),
372
+ options=StructOptions(mode=mode, alpha_col=alpha_col),
357
373
  output=OutputOptions(
358
374
  format=FormatOptions(fmt=out_fmt, pretty=pretty, indent=indent),
359
375
  filters=FilterOptions(
@@ -109,6 +109,11 @@ def build_parser(
109
109
  availability if availability is not None else get_com_availability()
110
110
  )
111
111
  _add_auto_page_breaks_argument(parser, resolved_availability)
112
+ parser.add_argument(
113
+ "--alpha-col",
114
+ action="store_true",
115
+ help="Output column keys as Excel-style ABC names (A, B, ..., Z, AA, ...) instead of 0-based indices.",
116
+ )
112
117
  return parser
113
118
 
114
119
 
@@ -143,6 +148,7 @@ def main(argv: list[str] | None = None) -> int:
143
148
  sheets_dir=args.sheets_dir,
144
149
  print_areas_dir=args.print_areas_dir,
145
150
  auto_page_breaks_dir=getattr(args, "auto_page_breaks_dir", None),
151
+ alpha_col=args.alpha_col,
146
152
  )
147
153
  return 0
148
154
  except Exception as e:
@@ -17,7 +17,7 @@ from .io import (
17
17
  save_sheets,
18
18
  serialize_workbook,
19
19
  )
20
- from .models import SheetData, WorkbookData
20
+ from .models import SheetData, WorkbookData, convert_workbook_keys_to_alpha
21
21
  from .render import export_pdf, export_sheet_images
22
22
 
23
23
  ExtractionMode = Literal["light", "standard", "verbose"]
@@ -76,6 +76,8 @@ class StructOptions:
76
76
  include_merged_cells: Whether to extract merged cell ranges.
77
77
  include_merged_values_in_rows: Whether to keep merged values in rows.
78
78
  colors: Color extraction options.
79
+ alpha_col: When True, convert CellRow column keys to Excel-style
80
+ ABC names (A, B, ..., Z, AA, ...) instead of 0-based numeric strings.
79
81
  """
80
82
 
81
83
  mode: ExtractionMode = "standard"
@@ -88,6 +90,7 @@ class StructOptions:
88
90
  include_merged_cells: bool | None = None # None -> auto: light=False, others=True
89
91
  include_merged_values_in_rows: bool = True
90
92
  colors: ColorsOptions = field(default_factory=ColorsOptions)
93
+ alpha_col: bool = False
91
94
 
92
95
 
93
96
  class FormatOptions(BaseModel):
@@ -314,6 +317,9 @@ class ExStructEngine:
314
317
  merged_cells=sheet.merged_cells
315
318
  if self.output.filters.include_merged_cells
316
319
  else None,
320
+ merged_ranges=sheet.merged_ranges
321
+ if self.output.filters.include_merged_cells
322
+ else [],
317
323
  )
318
324
 
319
325
  def _filter_workbook(
@@ -383,7 +389,7 @@ class ExStructEngine:
383
389
  )
384
390
  normalized_file_path = self._ensure_path(file_path)
385
391
  with self._table_params_scope():
386
- return extract_workbook(
392
+ workbook = extract_workbook(
387
393
  normalized_file_path,
388
394
  mode=chosen_mode,
389
395
  include_cell_links=self.options.include_cell_links,
@@ -396,6 +402,9 @@ class ExStructEngine:
396
402
  include_merged_cells=self.options.include_merged_cells,
397
403
  include_merged_values_in_rows=self.options.include_merged_values_in_rows,
398
404
  )
405
+ if self.options.alpha_col:
406
+ workbook = convert_workbook_keys_to_alpha(workbook)
407
+ return workbook
399
408
 
400
409
  def serialize(
401
410
  self,
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from enum import Enum
5
+ from enum import StrEnum
6
6
 
7
7
 
8
8
  class ExstructError(Exception):
@@ -37,7 +37,7 @@ class PrintAreaError(ExstructError, ValueError):
37
37
  """Raised when print-area specific processing fails (also a ValueError for compatibility)."""
38
38
 
39
39
 
40
- class FallbackReason(str, Enum):
40
+ class FallbackReason(StrEnum):
41
41
  """Reason codes for extraction fallbacks."""
42
42
 
43
43
  LIGHT_MODE = "light_mode"
@@ -0,0 +1,125 @@
1
+ """MCP server integration for ExStruct."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .chunk_reader import (
6
+ ReadJsonChunkFilter,
7
+ ReadJsonChunkRequest,
8
+ ReadJsonChunkResult,
9
+ read_json_chunk,
10
+ )
11
+ from .extract_runner import (
12
+ ExtractOptions,
13
+ ExtractRequest,
14
+ ExtractResult,
15
+ WorkbookMeta,
16
+ run_extract,
17
+ )
18
+ from .io import PathPolicy
19
+ from .patch_runner import (
20
+ FormulaIssue,
21
+ PatchDiffItem,
22
+ PatchErrorDetail,
23
+ PatchOp,
24
+ PatchRequest,
25
+ PatchResult,
26
+ PatchValue,
27
+ run_patch,
28
+ )
29
+ from .sheet_reader import (
30
+ CellReadItem,
31
+ FormulaReadItem,
32
+ ReadCellsRequest,
33
+ ReadCellsResult,
34
+ ReadFormulasRequest,
35
+ ReadFormulasResult,
36
+ ReadRangeRequest,
37
+ ReadRangeResult,
38
+ read_cells,
39
+ read_formulas,
40
+ read_range,
41
+ )
42
+ from .tools import (
43
+ ExtractToolInput,
44
+ ExtractToolOutput,
45
+ PatchToolInput,
46
+ PatchToolOutput,
47
+ ReadCellsToolInput,
48
+ ReadCellsToolOutput,
49
+ ReadFormulasToolInput,
50
+ ReadFormulasToolOutput,
51
+ ReadJsonChunkToolInput,
52
+ ReadJsonChunkToolOutput,
53
+ ReadRangeToolInput,
54
+ ReadRangeToolOutput,
55
+ ValidateInputToolInput,
56
+ ValidateInputToolOutput,
57
+ run_extract_tool,
58
+ run_patch_tool,
59
+ run_read_cells_tool,
60
+ run_read_formulas_tool,
61
+ run_read_json_chunk_tool,
62
+ run_read_range_tool,
63
+ run_validate_input_tool,
64
+ )
65
+ from .validate_input import (
66
+ ValidateInputRequest,
67
+ ValidateInputResult,
68
+ validate_input,
69
+ )
70
+
71
+ __all__ = [
72
+ "ExtractRequest",
73
+ "ExtractResult",
74
+ "ExtractOptions",
75
+ "ExtractToolInput",
76
+ "ExtractToolOutput",
77
+ "FormulaIssue",
78
+ "FormulaReadItem",
79
+ "PatchDiffItem",
80
+ "PatchErrorDetail",
81
+ "PatchOp",
82
+ "PatchRequest",
83
+ "PatchResult",
84
+ "PatchToolInput",
85
+ "PatchToolOutput",
86
+ "PatchValue",
87
+ "PathPolicy",
88
+ "ReadCellsRequest",
89
+ "ReadCellsResult",
90
+ "ReadCellsToolInput",
91
+ "ReadCellsToolOutput",
92
+ "ReadFormulasRequest",
93
+ "ReadFormulasResult",
94
+ "ReadFormulasToolInput",
95
+ "ReadFormulasToolOutput",
96
+ "ReadJsonChunkFilter",
97
+ "ReadJsonChunkRequest",
98
+ "ReadJsonChunkResult",
99
+ "ReadJsonChunkToolInput",
100
+ "ReadJsonChunkToolOutput",
101
+ "ReadRangeRequest",
102
+ "ReadRangeResult",
103
+ "ReadRangeToolInput",
104
+ "ReadRangeToolOutput",
105
+ "CellReadItem",
106
+ "ValidateInputRequest",
107
+ "ValidateInputResult",
108
+ "ValidateInputToolInput",
109
+ "ValidateInputToolOutput",
110
+ "WorkbookMeta",
111
+ "read_json_chunk",
112
+ "validate_input",
113
+ "run_extract",
114
+ "run_extract_tool",
115
+ "run_patch",
116
+ "run_patch_tool",
117
+ "read_cells",
118
+ "read_formulas",
119
+ "run_read_json_chunk_tool",
120
+ "read_range",
121
+ "run_read_cells_tool",
122
+ "run_read_formulas_tool",
123
+ "run_read_range_tool",
124
+ "run_validate_input_tool",
125
+ ]