ExcelAlchemy 2.2.8__tar.gz → 2.4.0__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.
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/PKG-INFO +65 -4
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/README-pypi.md +64 -3
- excelalchemy-2.4.0/src/excelalchemy/README.md +477 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/__init__.py +13 -2
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/boolean.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/date.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/date_range.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/multi_checkbox.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/number.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/organization.py +6 -1
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/radio.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/staff.py +8 -1
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/string.py +1 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/tree.py +6 -1
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/abstract.py +13 -3
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/alchemy.py +34 -4
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/import_session.py +125 -49
- excelalchemy-2.4.0/src/excelalchemy/core/preflight.py +97 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/storage_minio.py +6 -2
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/exceptions.py +7 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/i18n/messages.py +3 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/metadata.py +27 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/results.py +301 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/LICENSE +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/pyproject.toml +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/constants.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/deprecation.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/diagnostics.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/header_models.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/identity.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/_primitives/payloads.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/artifacts.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/base.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/email.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/money.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/number_range.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/phone_number.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/codecs/url.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/config.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/const.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/executor.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/headers.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/rendering.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/rows.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/schema.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/storage.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/storage_protocol.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/table.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/core/writer.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/exc.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/header_models.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/helper/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/helper/pydantic.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/i18n/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/identity.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/py.typed +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/abstract.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/alchemy.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/field.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/header.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/identity.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/result.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/boolean.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/date.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/date_range.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/email.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/money.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/multi_checkbox.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/number.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/number_range.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/organization.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/phone_number.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/radio.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/staff.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/string.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/tree.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/types/value/url.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/util/__init__.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/util/converter.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/util/convertor.py +0 -0
- {excelalchemy-2.2.8 → excelalchemy-2.4.0}/src/excelalchemy/util/file.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ExcelAlchemy
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Schema-driven Python library for typed Excel import/export workflows with Pydantic and locale-aware workbooks.
|
|
5
5
|
Keywords: excel,openpyxl,pydantic,minio,schema
|
|
6
6
|
Author: Ray
|
|
@@ -49,9 +49,20 @@ ExcelAlchemy turns Pydantic models into typed workbook contracts:
|
|
|
49
49
|
- render workbook-facing output in `zh-CN` or `en`
|
|
50
50
|
- keep storage pluggable through `ExcelStorage`
|
|
51
51
|
|
|
52
|
-
The current stable release is `2.
|
|
52
|
+
The current stable release is `2.4.0`, which continues the 2.x line with a
|
|
53
|
+
more complete import workflow: clearer template guidance before upload,
|
|
54
|
+
lightweight structural preflight before execution, synchronous lifecycle
|
|
55
|
+
visibility during import, and remediation-oriented payloads after failures.
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
At the top level, that import workflow is:
|
|
58
|
+
|
|
59
|
+
- template authoring
|
|
60
|
+
- preflight gate
|
|
61
|
+
- import runtime
|
|
62
|
+
- result intelligence
|
|
63
|
+
- artifact and delivery
|
|
64
|
+
|
|
65
|
+
[GitHub Repository](https://github.com/RayCarterLab/ExcelAlchemy) · [Full README](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/README.md) · [Getting Started](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/getting-started.md) · [Integration Roadmap](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-roadmap.md) · [Platform Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md) · [Runtime Model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md) · [Integration Blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md) · [Result Objects](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/result-objects.md) · [API Response Cookbook](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/api-response-cookbook.md) · [Examples Showcase](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/examples-showcase.md) · [Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/architecture.md) · [Migration Notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/MIGRATIONS.md)
|
|
55
66
|
|
|
56
67
|
## Screenshots
|
|
57
68
|
|
|
@@ -108,7 +119,12 @@ class Importer(BaseModel):
|
|
|
108
119
|
email: Annotated[
|
|
109
120
|
Email,
|
|
110
121
|
Field(min_length=10),
|
|
111
|
-
ExcelMeta(
|
|
122
|
+
ExcelMeta(
|
|
123
|
+
label='Email',
|
|
124
|
+
order=1,
|
|
125
|
+
hint='Use your work email',
|
|
126
|
+
example_value='alice@company.com',
|
|
127
|
+
),
|
|
112
128
|
]
|
|
113
129
|
|
|
114
130
|
|
|
@@ -116,6 +132,48 @@ alchemy = ExcelAlchemy(ImporterConfig(Importer, locale='en'))
|
|
|
116
132
|
template = alchemy.download_template_artifact(filename='people-template.xlsx')
|
|
117
133
|
```
|
|
118
134
|
|
|
135
|
+
This template metadata is additive: it leaves the worksheet layout alone and
|
|
136
|
+
improves the generated header comment with both guidance text and a concrete
|
|
137
|
+
example value.
|
|
138
|
+
|
|
139
|
+
## Import Workflow Overview
|
|
140
|
+
|
|
141
|
+
The shortest path through the import workflow is:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
template -> preflight -> import -> remediation -> delivery
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Minimal example:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from excelalchemy.results import build_frontend_remediation_payload
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
events: list[dict[str, object]] = []
|
|
154
|
+
|
|
155
|
+
preflight = alchemy.preflight_import('employees.xlsx')
|
|
156
|
+
if preflight.is_valid:
|
|
157
|
+
result = await alchemy.import_data(
|
|
158
|
+
'employees.xlsx',
|
|
159
|
+
'employees-result.xlsx',
|
|
160
|
+
on_event=events.append,
|
|
161
|
+
)
|
|
162
|
+
payload = build_frontend_remediation_payload(
|
|
163
|
+
result=result,
|
|
164
|
+
cell_error_map=alchemy.cell_error_map,
|
|
165
|
+
row_error_map=alchemy.row_error_map,
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
See also:
|
|
170
|
+
|
|
171
|
+
- [Platform Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md)
|
|
172
|
+
- [Runtime Model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md)
|
|
173
|
+
- [Integration Blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md)
|
|
174
|
+
- [Result Objects](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/result-objects.md)
|
|
175
|
+
- [API Response Cookbook](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/api-response-cookbook.md)
|
|
176
|
+
|
|
119
177
|
## Example Outputs
|
|
120
178
|
|
|
121
179
|
These fixed outputs are generated from the repository examples by
|
|
@@ -193,6 +251,9 @@ for configured selection fields.
|
|
|
193
251
|
## Learn More
|
|
194
252
|
|
|
195
253
|
- [Full project README](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/README.md)
|
|
254
|
+
- [Platform architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md)
|
|
255
|
+
- [Runtime model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md)
|
|
256
|
+
- [Integration blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md)
|
|
196
257
|
- [Architecture notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/architecture.md)
|
|
197
258
|
- [Locale policy](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/locale.md)
|
|
198
259
|
- [Migration notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/MIGRATIONS.md)
|
|
@@ -10,9 +10,20 @@ ExcelAlchemy turns Pydantic models into typed workbook contracts:
|
|
|
10
10
|
- render workbook-facing output in `zh-CN` or `en`
|
|
11
11
|
- keep storage pluggable through `ExcelStorage`
|
|
12
12
|
|
|
13
|
-
The current stable release is `2.
|
|
13
|
+
The current stable release is `2.4.0`, which continues the 2.x line with a
|
|
14
|
+
more complete import workflow: clearer template guidance before upload,
|
|
15
|
+
lightweight structural preflight before execution, synchronous lifecycle
|
|
16
|
+
visibility during import, and remediation-oriented payloads after failures.
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
At the top level, that import workflow is:
|
|
19
|
+
|
|
20
|
+
- template authoring
|
|
21
|
+
- preflight gate
|
|
22
|
+
- import runtime
|
|
23
|
+
- result intelligence
|
|
24
|
+
- artifact and delivery
|
|
25
|
+
|
|
26
|
+
[GitHub Repository](https://github.com/RayCarterLab/ExcelAlchemy) · [Full README](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/README.md) · [Getting Started](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/getting-started.md) · [Integration Roadmap](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-roadmap.md) · [Platform Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md) · [Runtime Model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md) · [Integration Blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md) · [Result Objects](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/result-objects.md) · [API Response Cookbook](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/api-response-cookbook.md) · [Examples Showcase](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/examples-showcase.md) · [Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/architecture.md) · [Migration Notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/MIGRATIONS.md)
|
|
16
27
|
|
|
17
28
|
## Screenshots
|
|
18
29
|
|
|
@@ -69,7 +80,12 @@ class Importer(BaseModel):
|
|
|
69
80
|
email: Annotated[
|
|
70
81
|
Email,
|
|
71
82
|
Field(min_length=10),
|
|
72
|
-
ExcelMeta(
|
|
83
|
+
ExcelMeta(
|
|
84
|
+
label='Email',
|
|
85
|
+
order=1,
|
|
86
|
+
hint='Use your work email',
|
|
87
|
+
example_value='alice@company.com',
|
|
88
|
+
),
|
|
73
89
|
]
|
|
74
90
|
|
|
75
91
|
|
|
@@ -77,6 +93,48 @@ alchemy = ExcelAlchemy(ImporterConfig(Importer, locale='en'))
|
|
|
77
93
|
template = alchemy.download_template_artifact(filename='people-template.xlsx')
|
|
78
94
|
```
|
|
79
95
|
|
|
96
|
+
This template metadata is additive: it leaves the worksheet layout alone and
|
|
97
|
+
improves the generated header comment with both guidance text and a concrete
|
|
98
|
+
example value.
|
|
99
|
+
|
|
100
|
+
## Import Workflow Overview
|
|
101
|
+
|
|
102
|
+
The shortest path through the import workflow is:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
template -> preflight -> import -> remediation -> delivery
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Minimal example:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from excelalchemy.results import build_frontend_remediation_payload
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
events: list[dict[str, object]] = []
|
|
115
|
+
|
|
116
|
+
preflight = alchemy.preflight_import('employees.xlsx')
|
|
117
|
+
if preflight.is_valid:
|
|
118
|
+
result = await alchemy.import_data(
|
|
119
|
+
'employees.xlsx',
|
|
120
|
+
'employees-result.xlsx',
|
|
121
|
+
on_event=events.append,
|
|
122
|
+
)
|
|
123
|
+
payload = build_frontend_remediation_payload(
|
|
124
|
+
result=result,
|
|
125
|
+
cell_error_map=alchemy.cell_error_map,
|
|
126
|
+
row_error_map=alchemy.row_error_map,
|
|
127
|
+
)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
See also:
|
|
131
|
+
|
|
132
|
+
- [Platform Architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md)
|
|
133
|
+
- [Runtime Model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md)
|
|
134
|
+
- [Integration Blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md)
|
|
135
|
+
- [Result Objects](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/result-objects.md)
|
|
136
|
+
- [API Response Cookbook](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/api-response-cookbook.md)
|
|
137
|
+
|
|
80
138
|
## Example Outputs
|
|
81
139
|
|
|
82
140
|
These fixed outputs are generated from the repository examples by
|
|
@@ -154,6 +212,9 @@ for configured selection fields.
|
|
|
154
212
|
## Learn More
|
|
155
213
|
|
|
156
214
|
- [Full project README](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/README.md)
|
|
215
|
+
- [Platform architecture](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/platform-architecture.md)
|
|
216
|
+
- [Runtime model](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/runtime-model.md)
|
|
217
|
+
- [Integration blueprints](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/integration-blueprints.md)
|
|
157
218
|
- [Architecture notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/architecture.md)
|
|
158
219
|
- [Locale policy](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/docs/locale.md)
|
|
159
220
|
- [Migration notes](https://github.com/RayCarterLab/ExcelAlchemy/blob/main/MIGRATIONS.md)
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# `src/excelalchemy/` Package Guide
|
|
2
|
+
|
|
3
|
+
This file explains the internal structure of the main package directory.
|
|
4
|
+
It is meant for developers and AI agents who need to change implementation details without confusing public API, compatibility layers, and internal collaborators.
|
|
5
|
+
|
|
6
|
+
## Related docs
|
|
7
|
+
|
|
8
|
+
- [../../README.md](../../README.md) for the public-facing overview.
|
|
9
|
+
- [../../AGENTS.md](../../AGENTS.md) for repository-local editing guidance.
|
|
10
|
+
- [../../docs/repo-map.md](../../docs/repo-map.md) for top-level repository navigation.
|
|
11
|
+
- [../../docs/domain-model.md](../../docs/domain-model.md) for the main concepts implemented here.
|
|
12
|
+
- [../../docs/invariants.md](../../docs/invariants.md) for important behavioral constraints.
|
|
13
|
+
- [../../tests/README.md](../../tests/README.md) for where this package's behavior is protected.
|
|
14
|
+
|
|
15
|
+
## Role of This Package
|
|
16
|
+
|
|
17
|
+
- `src/excelalchemy/` is the main library package.
|
|
18
|
+
- It contains:
|
|
19
|
+
- the stable public surface used by application code
|
|
20
|
+
- the internal orchestration that implements import, export, template generation, rendering, and storage integration
|
|
21
|
+
- compatibility modules retained for the 2.x line
|
|
22
|
+
- The package is organized around a small public facade and a set of focused internal collaborators.
|
|
23
|
+
- In the v2.4 docs, those collaborators are also described through a higher-level
|
|
24
|
+
import platform model:
|
|
25
|
+
- template authoring
|
|
26
|
+
- preflight gate
|
|
27
|
+
- import runtime
|
|
28
|
+
- result intelligence
|
|
29
|
+
- artifact and delivery
|
|
30
|
+
|
|
31
|
+
## High-Level Package Structure
|
|
32
|
+
|
|
33
|
+
- `__init__.py`
|
|
34
|
+
- Main public re-export surface.
|
|
35
|
+
- If application-facing imports change, start here.
|
|
36
|
+
- `config.py`
|
|
37
|
+
- Public workflow configuration types.
|
|
38
|
+
- `metadata.py`
|
|
39
|
+
- Public metadata declarations plus the internal layered field-metadata model.
|
|
40
|
+
- `results.py`
|
|
41
|
+
- Public result models and API-friendly error maps.
|
|
42
|
+
- `exceptions.py`
|
|
43
|
+
- Public exception types.
|
|
44
|
+
- `artifacts.py`
|
|
45
|
+
- Public workbook artifact wrapper.
|
|
46
|
+
- `codecs/`
|
|
47
|
+
- Public field codecs and codec base classes.
|
|
48
|
+
- `core/`
|
|
49
|
+
- Internal workflow orchestration and execution.
|
|
50
|
+
- `helper/`
|
|
51
|
+
- Internal adapter layer, currently centered on Pydantic integration.
|
|
52
|
+
- `i18n/`
|
|
53
|
+
- Internal message and locale handling.
|
|
54
|
+
- `_primitives/`
|
|
55
|
+
- Internal low-level types, constants, payload aliases, diagnostics, and deprecation helpers.
|
|
56
|
+
- `types/`, `exc.py`, `identity.py`, `header_models.py`, `const.py`, `util/convertor.py`
|
|
57
|
+
- Compatibility-oriented modules retained in the 2.x line.
|
|
58
|
+
|
|
59
|
+
## Public Surface vs Internal Implementation
|
|
60
|
+
|
|
61
|
+
### Public surface
|
|
62
|
+
|
|
63
|
+
These modules are the stable public entry points documented in `docs/public-api.md`:
|
|
64
|
+
|
|
65
|
+
- `src/excelalchemy/__init__.py`
|
|
66
|
+
- `src/excelalchemy/config.py`
|
|
67
|
+
- `src/excelalchemy/metadata.py`
|
|
68
|
+
- `src/excelalchemy/results.py`
|
|
69
|
+
- `src/excelalchemy/exceptions.py`
|
|
70
|
+
- `src/excelalchemy/codecs/`
|
|
71
|
+
- `src/excelalchemy/artifacts.py`
|
|
72
|
+
|
|
73
|
+
### Internal implementation
|
|
74
|
+
|
|
75
|
+
These modules implement behavior but are not the recommended import paths for application code:
|
|
76
|
+
|
|
77
|
+
- `src/excelalchemy/core/`
|
|
78
|
+
- `src/excelalchemy/helper/`
|
|
79
|
+
- `src/excelalchemy/i18n/`
|
|
80
|
+
- `src/excelalchemy/_primitives/`
|
|
81
|
+
|
|
82
|
+
### Compatibility-only surface
|
|
83
|
+
|
|
84
|
+
These exist to support the 2.x line and should not be treated as preferred implementation entry points for new work:
|
|
85
|
+
|
|
86
|
+
- `src/excelalchemy/types/`
|
|
87
|
+
- `src/excelalchemy/exc.py`
|
|
88
|
+
- `src/excelalchemy/identity.py`
|
|
89
|
+
- `src/excelalchemy/header_models.py`
|
|
90
|
+
- `src/excelalchemy/const.py`
|
|
91
|
+
- `src/excelalchemy/util/convertor.py`
|
|
92
|
+
|
|
93
|
+
## Major Modules and Responsibilities
|
|
94
|
+
|
|
95
|
+
### Public-facing root modules
|
|
96
|
+
|
|
97
|
+
- `src/excelalchemy/__init__.py`
|
|
98
|
+
- Re-exports `ExcelAlchemy`, configs, codecs, result types, exception types, and common identity/value types.
|
|
99
|
+
- Changes here affect top-level user imports directly.
|
|
100
|
+
|
|
101
|
+
- `src/excelalchemy/config.py`
|
|
102
|
+
- Defines:
|
|
103
|
+
- `ExcelMode`
|
|
104
|
+
- `ImportMode`
|
|
105
|
+
- `ImporterConfig`
|
|
106
|
+
- `ExporterConfig`
|
|
107
|
+
- normalized schema/behavior/storage option groupings
|
|
108
|
+
- Also contains legacy Minio compatibility handling and deprecation warnings.
|
|
109
|
+
|
|
110
|
+
- `src/excelalchemy/metadata.py`
|
|
111
|
+
- Defines public declaration helpers:
|
|
112
|
+
- `FieldMeta(...)`
|
|
113
|
+
- `ExcelMeta(...)`
|
|
114
|
+
- Also defines the internal metadata layers behind `FieldMetaInfo`:
|
|
115
|
+
- `DeclaredFieldMeta`
|
|
116
|
+
- `RuntimeFieldBinding`
|
|
117
|
+
- `WorkbookPresentationMeta`
|
|
118
|
+
- `ImportConstraints`
|
|
119
|
+
- This file is central when changing field declaration behavior, workbook comments, formatting hints, or constraint overlay rules.
|
|
120
|
+
|
|
121
|
+
- `src/excelalchemy/results.py`
|
|
122
|
+
- Defines public result objects:
|
|
123
|
+
- `ImportResult`
|
|
124
|
+
- `ValidateHeaderResult`
|
|
125
|
+
- `ValidateResult`
|
|
126
|
+
- `ValidateRowResult`
|
|
127
|
+
- `CellErrorMap`
|
|
128
|
+
- `RowIssueMap`
|
|
129
|
+
- This is the main file for API payload shape and structured error access.
|
|
130
|
+
|
|
131
|
+
- `src/excelalchemy/exceptions.py`
|
|
132
|
+
- Defines the public exception model:
|
|
133
|
+
- `ExcelAlchemyError`
|
|
134
|
+
- `ExcelCellError`
|
|
135
|
+
- `ExcelRowError`
|
|
136
|
+
- `ProgrammaticError`
|
|
137
|
+
- `ConfigError`
|
|
138
|
+
|
|
139
|
+
- `src/excelalchemy/artifacts.py`
|
|
140
|
+
- Defines `ExcelArtifact`, which wraps rendered workbook content as bytes, base64, or a data URL.
|
|
141
|
+
|
|
142
|
+
### `core/` internal orchestration
|
|
143
|
+
|
|
144
|
+
- `src/excelalchemy/core/alchemy.py`
|
|
145
|
+
- Main facade implementation.
|
|
146
|
+
- Builds layout and storage, exposes the top-level workflow methods, and surfaces inspection properties like `worksheet_table` and `cell_error_map`.
|
|
147
|
+
- This is the first internal file to inspect when changing how the facade behaves.
|
|
148
|
+
|
|
149
|
+
- `src/excelalchemy/core/import_session.py`
|
|
150
|
+
- Owns one import run’s runtime state.
|
|
151
|
+
- Tracks:
|
|
152
|
+
- workbook load state
|
|
153
|
+
- header table
|
|
154
|
+
- worksheet table
|
|
155
|
+
- issue maps
|
|
156
|
+
- execution counts
|
|
157
|
+
- result rendering state
|
|
158
|
+
- `ImportSessionSnapshot`
|
|
159
|
+
- This is the main import lifecycle owner.
|
|
160
|
+
|
|
161
|
+
- `src/excelalchemy/core/schema.py`
|
|
162
|
+
- Converts extracted field metadata into `ExcelSchemaLayout`.
|
|
163
|
+
- Responsible for:
|
|
164
|
+
- layout ordering
|
|
165
|
+
- unique label/key indexing
|
|
166
|
+
- composite field expansion
|
|
167
|
+
- merged-header detection for selected output keys
|
|
168
|
+
|
|
169
|
+
- `src/excelalchemy/core/headers.py`
|
|
170
|
+
- Header parsing and header validation.
|
|
171
|
+
- Responsible for:
|
|
172
|
+
- detecting simple vs merged headers
|
|
173
|
+
- normalizing parsed headers into `ExcelHeader` objects
|
|
174
|
+
- comparing workbook headers against schema layout
|
|
175
|
+
|
|
176
|
+
- `src/excelalchemy/core/rows.py`
|
|
177
|
+
- Row reconstruction and issue tracking.
|
|
178
|
+
- `RowAggregator` groups flattened worksheet data back into model-shaped payloads.
|
|
179
|
+
- `ImportIssueTracker` maps row/cell failures back to workbook coordinates and prepends result columns.
|
|
180
|
+
|
|
181
|
+
- `src/excelalchemy/core/executor.py`
|
|
182
|
+
- Dispatches the actual import execution path.
|
|
183
|
+
- Responsible for:
|
|
184
|
+
- choosing create/update/create-or-update behavior
|
|
185
|
+
- validating reconstructed payloads
|
|
186
|
+
- invoking configured callbacks
|
|
187
|
+
- mapping failures into row/cell issues
|
|
188
|
+
|
|
189
|
+
- `src/excelalchemy/core/rendering.py`
|
|
190
|
+
- High-level rendering entry points for templates, exports, and import result workbooks.
|
|
191
|
+
|
|
192
|
+
- `src/excelalchemy/core/writer.py`
|
|
193
|
+
- Lower-level workbook writing details:
|
|
194
|
+
- comments
|
|
195
|
+
- fills/colors
|
|
196
|
+
- workbook rows/cells
|
|
197
|
+
- result/reason columns
|
|
198
|
+
|
|
199
|
+
- `src/excelalchemy/core/storage_protocol.py`
|
|
200
|
+
- Defines the `ExcelStorage` protocol.
|
|
201
|
+
- This is the main storage extension boundary.
|
|
202
|
+
|
|
203
|
+
- `src/excelalchemy/core/storage.py`
|
|
204
|
+
- Resolves configured storage into a concrete gateway.
|
|
205
|
+
- Also defines the missing-storage fallback path.
|
|
206
|
+
|
|
207
|
+
- `src/excelalchemy/core/storage_minio.py`
|
|
208
|
+
- Built-in Minio-backed storage implementation.
|
|
209
|
+
|
|
210
|
+
- `src/excelalchemy/core/table.py`
|
|
211
|
+
- Defines `WorksheetTable`, `WorksheetRow`, and related helpers.
|
|
212
|
+
- This is the internal table abstraction used instead of pandas.
|
|
213
|
+
|
|
214
|
+
### `codecs/` field behavior
|
|
215
|
+
|
|
216
|
+
- `src/excelalchemy/codecs/base.py`
|
|
217
|
+
- Defines:
|
|
218
|
+
- `ExcelFieldCodec`
|
|
219
|
+
- `CompositeExcelFieldCodec`
|
|
220
|
+
- fallback logging helpers
|
|
221
|
+
- Start here when changing the codec contract itself.
|
|
222
|
+
|
|
223
|
+
- `src/excelalchemy/codecs/*.py`
|
|
224
|
+
- Built-in concrete field codecs such as:
|
|
225
|
+
- `string.py`
|
|
226
|
+
- `number.py`
|
|
227
|
+
- `date.py`
|
|
228
|
+
- `date_range.py`
|
|
229
|
+
- `email.py`
|
|
230
|
+
- `phone_number.py`
|
|
231
|
+
- `money.py`
|
|
232
|
+
- `radio.py`
|
|
233
|
+
- `multi_checkbox.py`
|
|
234
|
+
- `organization.py`
|
|
235
|
+
- `staff.py`
|
|
236
|
+
- `tree.py`
|
|
237
|
+
- `url.py`
|
|
238
|
+
|
|
239
|
+
### Adapter, i18n, and primitive helpers
|
|
240
|
+
|
|
241
|
+
- `src/excelalchemy/helper/pydantic.py`
|
|
242
|
+
- Isolates the Pydantic boundary.
|
|
243
|
+
- Responsible for:
|
|
244
|
+
- extracting model metadata
|
|
245
|
+
- resolving codec types
|
|
246
|
+
- normalizing validation messages
|
|
247
|
+
- mapping Pydantic validation output to `ExcelCellError` and `ExcelRowError`
|
|
248
|
+
|
|
249
|
+
- `src/excelalchemy/i18n/messages.py`
|
|
250
|
+
- Central message lookup and locale handling.
|
|
251
|
+
- Important when changing workbook-facing text, runtime error text, or locale policy.
|
|
252
|
+
|
|
253
|
+
- `src/excelalchemy/_primitives/constants.py`
|
|
254
|
+
- Internal constants and enum-like definitions used across the package.
|
|
255
|
+
|
|
256
|
+
- `src/excelalchemy/_primitives/identity.py`
|
|
257
|
+
- Internal typed wrappers for labels, keys, row indexes, column indexes, URLs, and related string-like identifiers.
|
|
258
|
+
|
|
259
|
+
- `src/excelalchemy/_primitives/payloads.py`
|
|
260
|
+
- Shared payload type aliases for import/export/data-converter/callback paths.
|
|
261
|
+
|
|
262
|
+
- `src/excelalchemy/_primitives/diagnostics.py`
|
|
263
|
+
- Developer-facing diagnostic logging helpers.
|
|
264
|
+
|
|
265
|
+
- `src/excelalchemy/_primitives/deprecation.py`
|
|
266
|
+
- Deprecation warning helpers used by compatibility modules.
|
|
267
|
+
|
|
268
|
+
- `src/excelalchemy/_primitives/header_models.py`
|
|
269
|
+
- Internal parsed-header model objects.
|
|
270
|
+
|
|
271
|
+
## Major Internal Flows
|
|
272
|
+
|
|
273
|
+
The package guide keeps the internal ownership view.
|
|
274
|
+
If you want the capability-oriented platform view above these flows, start with:
|
|
275
|
+
|
|
276
|
+
- [`../../docs/platform-architecture.md`](../../docs/platform-architecture.md)
|
|
277
|
+
- [`../../docs/runtime-model.md`](../../docs/runtime-model.md)
|
|
278
|
+
- [`../../docs/platform-code-mapping.md`](../../docs/platform-code-mapping.md)
|
|
279
|
+
|
|
280
|
+
### Import validation flow
|
|
281
|
+
|
|
282
|
+
The import path is implemented roughly in this order:
|
|
283
|
+
|
|
284
|
+
1. `src/excelalchemy/core/alchemy.py`
|
|
285
|
+
- `ExcelAlchemy.import_data(...)` creates a new import session.
|
|
286
|
+
2. `src/excelalchemy/core/import_session.py`
|
|
287
|
+
- loads workbook data through storage
|
|
288
|
+
- builds header and worksheet state
|
|
289
|
+
3. `src/excelalchemy/core/headers.py`
|
|
290
|
+
- parses headers
|
|
291
|
+
- validates headers against the schema layout
|
|
292
|
+
4. `src/excelalchemy/core/rows.py`
|
|
293
|
+
- reconstructs model-shaped row payloads
|
|
294
|
+
5. `src/excelalchemy/core/executor.py`
|
|
295
|
+
- validates and dispatches create/update/upsert logic
|
|
296
|
+
6. `src/excelalchemy/helper/pydantic.py`
|
|
297
|
+
- adapts Pydantic validation into ExcelAlchemy issues
|
|
298
|
+
7. `src/excelalchemy/core/rows.py`
|
|
299
|
+
- records row/cell failures in workbook coordinates
|
|
300
|
+
8. `src/excelalchemy/core/rendering.py` and `src/excelalchemy/core/writer.py`
|
|
301
|
+
- render the import result workbook when rows fail
|
|
302
|
+
9. `src/excelalchemy/results.py`
|
|
303
|
+
- exposes the final result through `ImportResult`, `CellErrorMap`, and `RowIssueMap`
|
|
304
|
+
|
|
305
|
+
### Template generation flow
|
|
306
|
+
|
|
307
|
+
The template path is implemented roughly in this order:
|
|
308
|
+
|
|
309
|
+
1. `src/excelalchemy/core/alchemy.py`
|
|
310
|
+
- selects output keys and header shape
|
|
311
|
+
2. `src/excelalchemy/core/schema.py`
|
|
312
|
+
- provides ordered layout and merged-header decisions
|
|
313
|
+
3. `src/excelalchemy/codecs/`
|
|
314
|
+
- provide comments, display formatting, and field-specific workbook semantics
|
|
315
|
+
4. `src/excelalchemy/core/rendering.py`
|
|
316
|
+
5. `src/excelalchemy/core/writer.py`
|
|
317
|
+
- produce the workbook output
|
|
318
|
+
6. `src/excelalchemy/artifacts.py`
|
|
319
|
+
- wraps the output when the artifact API is used
|
|
320
|
+
|
|
321
|
+
### Export flow
|
|
322
|
+
|
|
323
|
+
The export path is implemented roughly in this order:
|
|
324
|
+
|
|
325
|
+
1. `src/excelalchemy/core/alchemy.py`
|
|
326
|
+
- accepts export rows and selected keys
|
|
327
|
+
2. `src/excelalchemy/core/schema.py`
|
|
328
|
+
- resolves output layout and merged-header needs
|
|
329
|
+
3. `src/excelalchemy/codecs/`
|
|
330
|
+
- format workbook-facing values
|
|
331
|
+
4. `src/excelalchemy/core/rendering.py`
|
|
332
|
+
5. `src/excelalchemy/core/writer.py`
|
|
333
|
+
6. `src/excelalchemy/core/storage_protocol.py` and `src/excelalchemy/core/storage.py`
|
|
334
|
+
- are used only when the upload path is chosen
|
|
335
|
+
|
|
336
|
+
### Storage integration flow
|
|
337
|
+
|
|
338
|
+
Storage-related behavior is split into three concerns:
|
|
339
|
+
|
|
340
|
+
- contract:
|
|
341
|
+
- `src/excelalchemy/core/storage_protocol.py`
|
|
342
|
+
- resolution:
|
|
343
|
+
- `src/excelalchemy/core/storage.py`
|
|
344
|
+
- built-in Minio backend:
|
|
345
|
+
- `src/excelalchemy/core/storage_minio.py`
|
|
346
|
+
|
|
347
|
+
The recommended 2.x design is:
|
|
348
|
+
|
|
349
|
+
- config holds `storage=...`
|
|
350
|
+
- `build_storage_gateway(...)` resolves it
|
|
351
|
+
- import reads workbook data as `WorksheetTable`
|
|
352
|
+
- export/import-result uploads return a URL through the storage implementation
|
|
353
|
+
- custom storage readers currently use `src/excelalchemy/core/table.py` for that `WorksheetTable` contract
|
|
354
|
+
|
|
355
|
+
## Where To Look When Changing Specific Behavior
|
|
356
|
+
|
|
357
|
+
### Changing public API behavior
|
|
358
|
+
|
|
359
|
+
Start here:
|
|
360
|
+
|
|
361
|
+
- `src/excelalchemy/__init__.py`
|
|
362
|
+
- `src/excelalchemy/config.py`
|
|
363
|
+
- `src/excelalchemy/metadata.py`
|
|
364
|
+
- `src/excelalchemy/results.py`
|
|
365
|
+
- `src/excelalchemy/exceptions.py`
|
|
366
|
+
- `docs/public-api.md`
|
|
367
|
+
- `MIGRATIONS.md`
|
|
368
|
+
- `tests/contracts/`
|
|
369
|
+
|
|
370
|
+
Use extra caution when changing:
|
|
371
|
+
|
|
372
|
+
- exported names
|
|
373
|
+
- config constructor behavior
|
|
374
|
+
- result payload shape
|
|
375
|
+
- exception wording or exception type mapping
|
|
376
|
+
- compatibility aliases
|
|
377
|
+
|
|
378
|
+
### Changing import validation behavior
|
|
379
|
+
|
|
380
|
+
Start here:
|
|
381
|
+
|
|
382
|
+
- `src/excelalchemy/core/import_session.py`
|
|
383
|
+
- `src/excelalchemy/core/headers.py`
|
|
384
|
+
- `src/excelalchemy/core/rows.py`
|
|
385
|
+
- `src/excelalchemy/core/executor.py`
|
|
386
|
+
- `src/excelalchemy/helper/pydantic.py`
|
|
387
|
+
- `src/excelalchemy/results.py`
|
|
388
|
+
- `tests/contracts/test_import_contract.py`
|
|
389
|
+
- `tests/contracts/test_core_components_contract.py`
|
|
390
|
+
- `tests/contracts/test_pydantic_contract.py`
|
|
391
|
+
|
|
392
|
+
Typical examples:
|
|
393
|
+
|
|
394
|
+
- header validation rules
|
|
395
|
+
- row reconstruction
|
|
396
|
+
- Pydantic error mapping
|
|
397
|
+
- create/update/upsert behavior
|
|
398
|
+
- result-workbook error placement
|
|
399
|
+
|
|
400
|
+
### Changing export or template generation behavior
|
|
401
|
+
|
|
402
|
+
Start here:
|
|
403
|
+
|
|
404
|
+
- `src/excelalchemy/core/alchemy.py`
|
|
405
|
+
- `src/excelalchemy/core/schema.py`
|
|
406
|
+
- `src/excelalchemy/core/rendering.py`
|
|
407
|
+
- `src/excelalchemy/core/writer.py`
|
|
408
|
+
- `src/excelalchemy/codecs/`
|
|
409
|
+
- `tests/contracts/test_template_contract.py`
|
|
410
|
+
- `tests/contracts/test_export_contract.py`
|
|
411
|
+
|
|
412
|
+
Typical examples:
|
|
413
|
+
|
|
414
|
+
- workbook comments
|
|
415
|
+
- merged headers
|
|
416
|
+
- selected output keys
|
|
417
|
+
- workbook-facing display formatting
|
|
418
|
+
- artifact generation
|
|
419
|
+
|
|
420
|
+
### Changing storage integration behavior
|
|
421
|
+
|
|
422
|
+
Start here:
|
|
423
|
+
|
|
424
|
+
- `src/excelalchemy/core/storage_protocol.py`
|
|
425
|
+
- `src/excelalchemy/core/storage.py`
|
|
426
|
+
- `src/excelalchemy/core/storage_minio.py`
|
|
427
|
+
- `src/excelalchemy/config.py`
|
|
428
|
+
- `examples/custom_storage.py`
|
|
429
|
+
- `tests/contracts/test_storage_contract.py`
|
|
430
|
+
- `tests/unit/test_config_options.py`
|
|
431
|
+
|
|
432
|
+
Typical examples:
|
|
433
|
+
|
|
434
|
+
- storage contract shape
|
|
435
|
+
- default gateway selection
|
|
436
|
+
- missing-storage behavior
|
|
437
|
+
- Minio compatibility behavior
|
|
438
|
+
- upload payload expectations
|
|
439
|
+
|
|
440
|
+
### Changing locale-aware output behavior
|
|
441
|
+
|
|
442
|
+
Start here:
|
|
443
|
+
|
|
444
|
+
- `src/excelalchemy/i18n/messages.py`
|
|
445
|
+
- `src/excelalchemy/metadata.py`
|
|
446
|
+
- `src/excelalchemy/core/alchemy.py`
|
|
447
|
+
- `src/excelalchemy/core/writer.py`
|
|
448
|
+
- `docs/locale.md`
|
|
449
|
+
- `tests/contracts/test_template_contract.py`
|
|
450
|
+
- `tests/contracts/test_import_contract.py`
|
|
451
|
+
|
|
452
|
+
Typical examples:
|
|
453
|
+
|
|
454
|
+
- workbook instruction text
|
|
455
|
+
- header comments
|
|
456
|
+
- result/reason column labels
|
|
457
|
+
- row status text
|
|
458
|
+
- fallback locale behavior
|
|
459
|
+
|
|
460
|
+
## Implementation Cautions
|
|
461
|
+
|
|
462
|
+
- Do not treat compatibility modules under `src/excelalchemy/types/` and the root compatibility shims as preferred edit points for new behavior.
|
|
463
|
+
- Do not reintroduce pandas-style assumptions into the runtime path; this package now uses `WorksheetTable`.
|
|
464
|
+
- Do not hard-wire Minio into core workflow logic; storage is intentionally abstracted behind `ExcelStorage`.
|
|
465
|
+
- Treat `src/excelalchemy/core/table.py` as a narrow extension seam for current 2.x storage integrations, not as a general application import surface.
|
|
466
|
+
- If you change result payload shape, inspect:
|
|
467
|
+
- `src/excelalchemy/results.py`
|
|
468
|
+
- `docs/result-objects.md`
|
|
469
|
+
- `docs/api-response-cookbook.md`
|
|
470
|
+
- `scripts/smoke_api_payload_snapshot.py`
|
|
471
|
+
- `files/example-outputs/import-failure-api-payload.json`
|
|
472
|
+
- If you change docs-visible example behavior, inspect:
|
|
473
|
+
- `examples/`
|
|
474
|
+
- `files/example-outputs/`
|
|
475
|
+
- `scripts/generate_example_output_assets.py`
|
|
476
|
+
- `scripts/smoke_examples.py`
|
|
477
|
+
- `scripts/smoke_docs_assets.py`
|