exstruct 0.5.1__tar.gz → 0.5.3__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 (63) hide show
  1. {exstruct-0.5.1 → exstruct-0.5.3}/PKG-INFO +14 -2
  2. {exstruct-0.5.1 → exstruct-0.5.3}/README.md +13 -1
  3. {exstruct-0.5.1 → exstruct-0.5.3}/pyproject.toml +1 -1
  4. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/__init__.py +14 -0
  5. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/op_schema.py +10 -3
  6. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/internal.py +641 -28
  7. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/models.py +71 -11
  8. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/service.py +27 -17
  9. exstruct-0.5.3/src/exstruct/mcp/render_runner.py +124 -0
  10. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/server.py +106 -0
  11. exstruct-0.5.3/src/exstruct/mcp/shared/__init__.py +39 -0
  12. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/shared/a1.py +167 -82
  13. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/shared/output_path.py +55 -1
  14. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/tools.py +87 -0
  15. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/render/__init__.py +1057 -636
  16. exstruct-0.5.3/src/exstruct/render/subprocess_worker.py +180 -0
  17. exstruct-0.5.1/src/exstruct/mcp/shared/__init__.py +0 -23
  18. {exstruct-0.5.1 → exstruct-0.5.3}/LICENSE +0 -0
  19. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/__init__.py +0 -0
  20. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/cli/availability.py +0 -0
  21. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/cli/main.py +0 -0
  22. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/__init__.py +0 -0
  23. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/backends/__init__.py +0 -0
  24. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/backends/base.py +0 -0
  25. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/backends/com_backend.py +0 -0
  26. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/backends/openpyxl_backend.py +0 -0
  27. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/cells.py +0 -0
  28. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/charts.py +0 -0
  29. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/integrate.py +0 -0
  30. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/logging_utils.py +0 -0
  31. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/modeling.py +0 -0
  32. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/pipeline.py +0 -0
  33. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/ranges.py +0 -0
  34. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/shapes.py +0 -0
  35. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/core/workbook.py +0 -0
  36. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/engine.py +0 -0
  37. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/errors.py +0 -0
  38. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/io/__init__.py +0 -0
  39. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/io/serialize.py +0 -0
  40. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/chunk_reader.py +0 -0
  41. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/extract_runner.py +0 -0
  42. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/io.py +0 -0
  43. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/__init__.py +0 -0
  44. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/chart_types.py +0 -0
  45. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/engine/__init__.py +0 -0
  46. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/engine/base.py +0 -0
  47. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/engine/openpyxl_engine.py +0 -0
  48. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/engine/xlwings_engine.py +0 -0
  49. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/normalize.py +0 -0
  50. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/ops/__init__.py +0 -0
  51. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/ops/common.py +0 -0
  52. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/ops/openpyxl_ops.py +0 -0
  53. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/ops/xlwings_ops.py +0 -0
  54. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/runtime.py +0 -0
  55. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/specs.py +0 -0
  56. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch/types.py +0 -0
  57. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/patch_runner.py +0 -0
  58. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/sheet_reader.py +0 -0
  59. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/mcp/validate_input.py +0 -0
  60. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/models/__init__.py +0 -0
  61. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/models/maps.py +0 -0
  62. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/models/types.py +0 -0
  63. {exstruct-0.5.1 → exstruct-0.5.3}/src/exstruct/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exstruct
3
- Version: 0.5.1
3
+ Version: 0.5.3
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
@@ -158,6 +158,7 @@ exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict re
158
158
  Available tools:
159
159
 
160
160
  - `exstruct_extract`
161
+ - `exstruct_capture_sheet_images`
161
162
  - `exstruct_make`
162
163
  - `exstruct_patch`
163
164
  - `exstruct_read_json_chunk`
@@ -169,6 +170,12 @@ Available tools:
169
170
  Notes:
170
171
 
171
172
  - 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.
173
+ - `exstruct_capture_sheet_images` is COM-only (Experimental) and supports optional `sheet` / `range` targeting (`A1:B2`, `Sheet1!A1:B2`, `'Sheet 1'!A1:B2`). When `out_dir` is omitted, it creates a unique `<workbook_stem>_images` directory under MCP `--root`.
174
+ - MCP server startup sets `EXSTRUCT_RENDER_SUBPROCESS=1` by default (`setdefault`). If you prefer in-process rendering, set `EXSTRUCT_RENDER_SUBPROCESS=0` before launching the server.
175
+ - Timeout tuning for `exstruct_capture_sheet_images`: `EXSTRUCT_MCP_CAPTURE_SHEET_IMAGES_TIMEOUT_SEC` (tool timeout), `EXSTRUCT_RENDER_SUBPROCESS_STARTUP_TIMEOUT_SEC` (worker startup), `EXSTRUCT_RENDER_SUBPROCESS_JOIN_TIMEOUT_SEC` (primary wait budget), `EXSTRUCT_RENDER_SUBPROCESS_RESULT_TIMEOUT_SEC` (post-exit grace).
176
+ - Subprocess errors are stage-aware (`stage=startup|join|result|worker`) so MCP clients can distinguish bootstrap failures vs timeout vs worker-side rendering errors.
177
+ - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=1`: subprocess startup/coordination overhead and dependency on worker-side module resolution.
178
+ - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=0`: less crash isolation and higher memory pressure risk in long-running processes.
172
179
  - Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
173
180
  - On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
174
181
  - `exstruct_patch` supports `backend` selection:
@@ -177,8 +184,13 @@ Notes:
177
184
  - `openpyxl`: force openpyxl (`.xls` is not supported)
178
185
  - `create_chart` is COM-only (`backend="openpyxl"` is not allowed for requests that include it), and it also rejects `dry_run` / `return_inverse_ops` / `preflight_formula_check`.
179
186
  - `create_chart` `chart_type` supports: `line`, `column`, `bar`, `area`, `pie`, `doughnut`, `scatter`, `radar` (aliases: `column_clustered`, `bar_clustered`, `xy_scatter`, `donut`).
180
- - `create_chart` and `apply_table_style` cannot be combined in one request (split into separate calls).
187
+ - `create_chart` `data_range` accepts either one range string or `list[str]` (multi-series), and `data_range` / `category_range` both support sheet-qualified ranges (`Sheet2!A1:B10`, `'Sales Data'!A1:B10`).
188
+ - `create_chart` supports optional explicit labels: `chart_title`, `x_axis_title`, `y_axis_title`.
189
+ - `create_chart` and `apply_table_style` can be combined in one request when the backend resolves to COM (`backend="com"` or `backend="auto"` with COM available).
190
+ - For stable `apply_table_style` COM runs on Windows, ensure desktop Excel is installed/runnable and the target `range` is a contiguous header-included A1 range.
191
+ - `exstruct_patch` error detail may include `error_code` / `failed_field` / `raw_com_message`; table-related codes include `table_style_invalid`, `list_object_add_failed`, and `com_api_missing`.
181
192
  - `exstruct_patch` response includes `engine` (`com` or `openpyxl`) to show the actual backend used. `restore_design_snapshot` remains openpyxl-only.
193
+ - Use `exstruct_make` for new workbook creation and `exstruct_patch` for editing existing workbooks.
182
194
  - `exstruct_make` creates a new workbook and applies `ops` in one call (`out_path` required, `ops` optional).
183
195
  - Supports `.xlsx` / `.xlsm` / `.xls`
184
196
  - Initial sheet is normalized to `Sheet1`
@@ -93,6 +93,7 @@ exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict re
93
93
  Available tools:
94
94
 
95
95
  - `exstruct_extract`
96
+ - `exstruct_capture_sheet_images`
96
97
  - `exstruct_make`
97
98
  - `exstruct_patch`
98
99
  - `exstruct_read_json_chunk`
@@ -104,6 +105,12 @@ Available tools:
104
105
  Notes:
105
106
 
106
107
  - 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.
108
+ - `exstruct_capture_sheet_images` is COM-only (Experimental) and supports optional `sheet` / `range` targeting (`A1:B2`, `Sheet1!A1:B2`, `'Sheet 1'!A1:B2`). When `out_dir` is omitted, it creates a unique `<workbook_stem>_images` directory under MCP `--root`.
109
+ - MCP server startup sets `EXSTRUCT_RENDER_SUBPROCESS=1` by default (`setdefault`). If you prefer in-process rendering, set `EXSTRUCT_RENDER_SUBPROCESS=0` before launching the server.
110
+ - Timeout tuning for `exstruct_capture_sheet_images`: `EXSTRUCT_MCP_CAPTURE_SHEET_IMAGES_TIMEOUT_SEC` (tool timeout), `EXSTRUCT_RENDER_SUBPROCESS_STARTUP_TIMEOUT_SEC` (worker startup), `EXSTRUCT_RENDER_SUBPROCESS_JOIN_TIMEOUT_SEC` (primary wait budget), `EXSTRUCT_RENDER_SUBPROCESS_RESULT_TIMEOUT_SEC` (post-exit grace).
111
+ - Subprocess errors are stage-aware (`stage=startup|join|result|worker`) so MCP clients can distinguish bootstrap failures vs timeout vs worker-side rendering errors.
112
+ - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=1`: subprocess startup/coordination overhead and dependency on worker-side module resolution.
113
+ - Trade-off of `EXSTRUCT_RENDER_SUBPROCESS=0`: less crash isolation and higher memory pressure risk in long-running processes.
107
114
  - Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
108
115
  - On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
109
116
  - `exstruct_patch` supports `backend` selection:
@@ -112,8 +119,13 @@ Notes:
112
119
  - `openpyxl`: force openpyxl (`.xls` is not supported)
113
120
  - `create_chart` is COM-only (`backend="openpyxl"` is not allowed for requests that include it), and it also rejects `dry_run` / `return_inverse_ops` / `preflight_formula_check`.
114
121
  - `create_chart` `chart_type` supports: `line`, `column`, `bar`, `area`, `pie`, `doughnut`, `scatter`, `radar` (aliases: `column_clustered`, `bar_clustered`, `xy_scatter`, `donut`).
115
- - `create_chart` and `apply_table_style` cannot be combined in one request (split into separate calls).
122
+ - `create_chart` `data_range` accepts either one range string or `list[str]` (multi-series), and `data_range` / `category_range` both support sheet-qualified ranges (`Sheet2!A1:B10`, `'Sales Data'!A1:B10`).
123
+ - `create_chart` supports optional explicit labels: `chart_title`, `x_axis_title`, `y_axis_title`.
124
+ - `create_chart` and `apply_table_style` can be combined in one request when the backend resolves to COM (`backend="com"` or `backend="auto"` with COM available).
125
+ - For stable `apply_table_style` COM runs on Windows, ensure desktop Excel is installed/runnable and the target `range` is a contiguous header-included A1 range.
126
+ - `exstruct_patch` error detail may include `error_code` / `failed_field` / `raw_com_message`; table-related codes include `table_style_invalid`, `list_object_add_failed`, and `com_api_missing`.
116
127
  - `exstruct_patch` response includes `engine` (`com` or `openpyxl`) to show the actual backend used. `restore_design_snapshot` remains openpyxl-only.
128
+ - Use `exstruct_make` for new workbook creation and `exstruct_patch` for editing existing workbooks.
117
129
  - `exstruct_make` creates a new workbook and applies `ops` in one call (`out_path` required, `ops` optional).
118
130
  - Supports `.xlsx` / `.xlsm` / `.xls`
119
131
  - Initial sheet is normalized to `Sheet1`
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "exstruct"
3
- version = "0.5.1"
3
+ version = "0.5.3"
4
4
  description = "Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -28,6 +28,11 @@ from .patch_runner import (
28
28
  run_make,
29
29
  run_patch,
30
30
  )
31
+ from .render_runner import (
32
+ CaptureSheetImagesRequest,
33
+ CaptureSheetImagesResult,
34
+ run_capture_sheet_images,
35
+ )
31
36
  from .sheet_reader import (
32
37
  CellReadItem,
33
38
  FormulaReadItem,
@@ -42,6 +47,8 @@ from .sheet_reader import (
42
47
  read_range,
43
48
  )
44
49
  from .tools import (
50
+ CaptureSheetImagesToolInput,
51
+ CaptureSheetImagesToolOutput,
45
52
  DescribeOpToolInput,
46
53
  DescribeOpToolOutput,
47
54
  ExtractToolInput,
@@ -61,6 +68,7 @@ from .tools import (
61
68
  ReadRangeToolOutput,
62
69
  ValidateInputToolInput,
63
70
  ValidateInputToolOutput,
71
+ run_capture_sheet_images_tool,
64
72
  run_describe_op_tool,
65
73
  run_extract_tool,
66
74
  run_list_ops_tool,
@@ -79,6 +87,10 @@ from .validate_input import (
79
87
  )
80
88
 
81
89
  __all__ = [
90
+ "CaptureSheetImagesRequest",
91
+ "CaptureSheetImagesResult",
92
+ "CaptureSheetImagesToolInput",
93
+ "CaptureSheetImagesToolOutput",
82
94
  "DescribeOpToolInput",
83
95
  "DescribeOpToolOutput",
84
96
  "ExtractRequest",
@@ -133,6 +145,8 @@ __all__ = [
133
145
  "run_make",
134
146
  "run_make_tool",
135
147
  "run_patch",
148
+ "run_capture_sheet_images",
149
+ "run_capture_sheet_images_tool",
136
150
  "run_patch_tool",
137
151
  "read_cells",
138
152
  "read_formulas",
@@ -380,7 +380,6 @@ _PATCH_OP_SCHEMA_BY_NAME: dict[str, PatchOpSchema] = {
380
380
  "range must include header row",
381
381
  "table name must be unique when provided",
382
382
  "range must not intersect existing table",
383
- "backend='com' falls back to openpyxl with warning",
384
383
  ],
385
384
  example={
386
385
  "op": "apply_table_style",
@@ -401,9 +400,14 @@ _PATCH_OP_SCHEMA_BY_NAME: dict[str, PatchOpSchema] = {
401
400
  "height",
402
401
  "titles_from_data",
403
402
  "series_from_rows",
403
+ "chart_title",
404
+ "x_axis_title",
405
+ "y_axis_title",
404
406
  ],
405
407
  constraints=[
406
408
  "chart_type in {'line','column','bar','area','pie','doughnut','scatter','radar'}",
409
+ "data_range accepts A1 range string or list[str] for multi-series input",
410
+ "data_range/category_range allow sheet-qualified ranges like 'Sheet2!A1:B10'",
407
411
  "width/height must be > 0 when provided",
408
412
  "chart_name must be unique in sheet when provided",
409
413
  "backend='openpyxl' is not supported",
@@ -412,14 +416,17 @@ _PATCH_OP_SCHEMA_BY_NAME: dict[str, PatchOpSchema] = {
412
416
  "op": "create_chart",
413
417
  "sheet": "Sheet1",
414
418
  "chart_type": "line",
415
- "data_range": "A1:C10",
416
- "category_range": "A2:A10",
419
+ "data_range": ["A2:A10", "C2:C10", "D2:D10"],
420
+ "category_range": "B2:B10",
417
421
  "anchor_cell": "E2",
418
422
  "chart_name": "SalesTrend",
419
423
  "width": 360,
420
424
  "height": 220,
421
425
  "titles_from_data": True,
422
426
  "series_from_rows": False,
427
+ "chart_title": "Sales trend",
428
+ "x_axis_title": "Month",
429
+ "y_axis_title": "Amount",
423
430
  },
424
431
  ),
425
432
  "restore_design_snapshot": PatchOpSchema(