excel2api 1.0.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.
Files changed (44) hide show
  1. excel2api-1.0.0/.github/workflows/ci.yml +32 -0
  2. excel2api-1.0.0/.github/workflows/release.yml +66 -0
  3. excel2api-1.0.0/.github/workflows/testpypi.yml +51 -0
  4. excel2api-1.0.0/.gitignore +9 -0
  5. excel2api-1.0.0/LICENSE +16 -0
  6. excel2api-1.0.0/PKG-INFO +398 -0
  7. excel2api-1.0.0/README.md +380 -0
  8. excel2api-1.0.0/examples/dependency-demo.xlsx +0 -0
  9. excel2api-1.0.0/examples/dependency-demo.yaml +26 -0
  10. excel2api-1.0.0/examples/doctor-dependency.yaml +13 -0
  11. excel2api-1.0.0/examples/doctor.yaml +17 -0
  12. excel2api-1.0.0/examples/excel2api.yaml +39 -0
  13. excel2api-1.0.0/examples/multi-sheet.xlsx +0 -0
  14. excel2api-1.0.0/examples/multi-sheet.yaml +32 -0
  15. excel2api-1.0.0/examples/patient-crud.yaml +54 -0
  16. excel2api-1.0.0/examples/patient-dependency.yaml +13 -0
  17. excel2api-1.0.0/examples/patient-response.yaml +42 -0
  18. excel2api-1.0.0/examples/patient.yaml +37 -0
  19. excel2api-1.0.0/examples/patients-crud.xlsx +0 -0
  20. excel2api-1.0.0/examples/patients.xlsx +0 -0
  21. excel2api-1.0.0/pyproject.toml +34 -0
  22. excel2api-1.0.0/src/excel2api/__init__.py +1 -0
  23. excel2api-1.0.0/src/excel2api/__main__.py +4 -0
  24. excel2api-1.0.0/src/excel2api/api.py +98 -0
  25. excel2api-1.0.0/src/excel2api/cli.py +255 -0
  26. excel2api-1.0.0/src/excel2api/config.py +30 -0
  27. excel2api-1.0.0/src/excel2api/converter.py +18 -0
  28. excel2api-1.0.0/src/excel2api/dependencies.py +120 -0
  29. excel2api-1.0.0/src/excel2api/doctor.py +79 -0
  30. excel2api-1.0.0/src/excel2api/errors.py +17 -0
  31. excel2api-1.0.0/src/excel2api/reader.py +36 -0
  32. excel2api-1.0.0/src/excel2api/report.py +45 -0
  33. excel2api-1.0.0/src/excel2api/schema.py +69 -0
  34. excel2api-1.0.0/src/excel2api/sync.py +154 -0
  35. excel2api-1.0.0/src/excel2api/validator.py +160 -0
  36. excel2api-1.0.0/tests/test_api.py +38 -0
  37. excel2api-1.0.0/tests/test_config.py +9 -0
  38. excel2api-1.0.0/tests/test_dependencies.py +16 -0
  39. excel2api-1.0.0/tests/test_doctor.py +27 -0
  40. excel2api-1.0.0/tests/test_endpoints.py +22 -0
  41. excel2api-1.0.0/tests/test_multisheet.py +29 -0
  42. excel2api-1.0.0/tests/test_reader.py +7 -0
  43. excel2api-1.0.0/tests/test_report.py +20 -0
  44. excel2api-1.0.0/tests/test_validator.py +22 -0
@@ -0,0 +1,32 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ cache: pip
24
+
25
+ - name: Install package and test dependencies
26
+ run: python -m pip install -e ".[dev]"
27
+
28
+ - name: Run tests
29
+ run: python -m pytest -q
30
+
31
+ - name: Run Ruff
32
+ run: ruff check src tests
@@ -0,0 +1,66 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.x"
19
+
20
+ - name: Install build tools
21
+ run: python -m pip install --upgrade build
22
+
23
+ - name: Verify tag matches package version
24
+ shell: bash
25
+ run: |
26
+ PACKAGE_VERSION=$(python - <<'PY'
27
+ import tomllib
28
+ with open("pyproject.toml", "rb") as f:
29
+ print(tomllib.load(f)["project"]["version"])
30
+ PY
31
+ )
32
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
33
+ if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
34
+ echo "Version mismatch: pyproject.toml=$PACKAGE_VERSION, tag=$TAG_VERSION"
35
+ exit 1
36
+ fi
37
+
38
+ - name: Build distributions
39
+ run: python -m build
40
+
41
+ - name: Check distributions
42
+ run: python -m pip install --upgrade twine && python -m twine check dist/*
43
+
44
+ - name: Upload distributions
45
+ uses: actions/upload-artifact@v4
46
+ with:
47
+ name: python-package-distributions
48
+ path: dist/
49
+
50
+ publish:
51
+ needs: build
52
+ runs-on: ubuntu-latest
53
+ environment:
54
+ name: pypi
55
+ url: https://pypi.org/p/excel2api
56
+ permissions:
57
+ id-token: write
58
+ steps:
59
+ - name: Download distributions
60
+ uses: actions/download-artifact@v5
61
+ with:
62
+ name: python-package-distributions
63
+ path: dist/
64
+
65
+ - name: Publish to PyPI
66
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ name: Publish to TestPyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - name: Checkout
11
+ uses: actions/checkout@v4
12
+
13
+ - name: Set up Python
14
+ uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.x"
17
+
18
+ - name: Install build tools
19
+ run: python -m pip install --upgrade build
20
+
21
+ - name: Build distributions
22
+ run: python -m build
23
+
24
+ - name: Check distributions
25
+ run: python -m pip install --upgrade twine && python -m twine check dist/*
26
+
27
+ - name: Upload distributions
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: python-package-distributions
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment:
37
+ name: testpypi
38
+ url: https://test.pypi.org/p/excel2api
39
+ permissions:
40
+ id-token: write
41
+ steps:
42
+ - name: Download distributions
43
+ uses: actions/download-artifact@v5
44
+ with:
45
+ name: python-package-distributions
46
+ path: dist/
47
+
48
+ - name: Publish to TestPyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
50
+ with:
51
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ *.json
@@ -0,0 +1,16 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Maneesh Nandan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files, to deal in the Software
7
+ without restriction, including without limitation the rights to use, copy,
8
+ modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9
+ subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -0,0 +1,398 @@
1
+ Metadata-Version: 2.5
2
+ Name: excel2api
3
+ Version: 1.0.0
4
+ Summary: Convert Excel and CSV data into validated, API-ready JSON
5
+ Author: Maneesh Nandan
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: openpyxl>=3.1
10
+ Requires-Dist: pandas>=2.0
11
+ Requires-Dist: pyyaml>=6.0
12
+ Requires-Dist: requests>=2.31
13
+ Requires-Dist: typer>=0.12
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=8.0; extra == 'dev'
16
+ Requires-Dist: ruff>=0.6; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # Excel2API
20
+
21
+ Schema-driven Excel/CSV validation, transformation and API synchronization.
22
+
23
+ Excel2API turns spreadsheet rows into validated JSON and can optionally execute REST API operations such as CREATE, UPDATE, PATCH and DELETE.
24
+
25
+ ## Features
26
+
27
+ - Excel and CSV input
28
+ - Multi-sheet input
29
+ - YAML-driven field mapping
30
+ - Type conversion and validation
31
+ - Required, nullable, default, length, numeric, regex, email and phone constraints
32
+ - Transformations (`strip`, `uppercase`, `lowercase`)
33
+ - JSON generation
34
+ - REST API CREATE / UPDATE / PATCH / DELETE
35
+ - Configurable endpoint templates
36
+ - Dry-run mode
37
+ - Bearer-token and custom-header authentication
38
+ - Configurable request timeout
39
+ - Retry with exponential backoff for transient HTTP failures
40
+ - Optional retry for CREATE requests
41
+ - Rate limiting
42
+ - Batch processing
43
+ - Resumable synchronization with checkpoints
44
+ - Stop-on-error control
45
+ - JSON and Excel sync reports
46
+ - Validation error Excel reports
47
+ - API response field mapping
48
+ - Dependency-aware multi-sheet synchronization
49
+ - Cross-sheet ID/reference resolution
50
+ - Circular dependency detection
51
+ - Control fields such as ID and Operation can stay in the spreadsheet without being sent to the API
52
+ - Configuration-file driven jobs
53
+ - `doctor` command for configuration validation
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install excel2api
59
+ ```
60
+
61
+ For development:
62
+
63
+ ```bash
64
+ pip install -e ".[dev]"
65
+ ```
66
+
67
+ ## Validate
68
+
69
+ ```bash
70
+ excel2api validate examples/patients.xlsx --schema examples/patient.yaml
71
+ ```
72
+
73
+ ## Convert
74
+
75
+ ```bash
76
+ excel2api convert examples/patients.xlsx \
77
+ --schema examples/patient.yaml \
78
+ --output patients.json
79
+ ```
80
+
81
+ ## CRUD / API sync
82
+
83
+ The Excel file can contain `ID` and `Operation` columns:
84
+
85
+ ```text
86
+ ID | Operation | Patient Name | ...
87
+ 101 | UPDATE | John Doe
88
+ 102 | DELETE | Jane Smith
89
+ | CREATE | Rahul Kumar
90
+ 103 | PATCH | Anita Thomas
91
+ ```
92
+
93
+ `ID` and `Operation` are control fields in the CRUD schema, so they are used to decide what API call to make but are not included in the JSON payload sent to the API.
94
+
95
+ ### Dry run
96
+
97
+ Always test a spreadsheet with dry-run before making changes to a real API:
98
+
99
+ ```bash
100
+ excel2api sync examples/patients-crud.xlsx \
101
+ --schema examples/patient-crud.yaml \
102
+ --api https://example.com/api/patients \
103
+ --dry-run
104
+ ```
105
+
106
+ ### Execute
107
+
108
+ ```bash
109
+ excel2api sync examples/patients-crud.xlsx \
110
+ --schema examples/patient-crud.yaml \
111
+ --api https://example.com/api/patients \
112
+ --token "$API_TOKEN"
113
+ ```
114
+
115
+ ### Timeout, retries and report
116
+
117
+ ```bash
118
+ excel2api sync examples/patients-crud.xlsx \
119
+ --schema examples/patient-crud.yaml \
120
+ --api https://example.com/api/patients \
121
+ --timeout 30 \
122
+ --retries 3 \
123
+ --report sync-report.json
124
+ ```
125
+
126
+ By default, retries apply to idempotent operations (`PUT`, `PATCH`, `DELETE`) and transient responses such as `408`, `429`, `500`, `502`, `503` and `504`. CREATE (`POST`) is not retried by default because repeating a POST can create duplicate resources.
127
+
128
+ If the target API supports idempotent POSTs, CREATE retries can be explicitly enabled:
129
+
130
+ ```bash
131
+ excel2api sync examples/patients-crud.xlsx \
132
+ --schema examples/patient-crud.yaml \
133
+ --api https://example.com/api/patients \
134
+ --retries 3 \
135
+ --retry-create
136
+ ```
137
+
138
+ ## Schema
139
+
140
+ A normal field is mapped and included in the API payload:
141
+
142
+ ```yaml
143
+ patient_name:
144
+ column: Patient Name
145
+ type: string
146
+ required: true
147
+ min_length: 3
148
+ transform: [strip]
149
+ ```
150
+
151
+ A control field can be excluded from the generated API payload:
152
+
153
+ ```yaml
154
+ id:
155
+ column: ID
156
+ type: integer
157
+ nullable: true
158
+ include: false
159
+ ```
160
+
161
+ ## Supported operations
162
+
163
+ - CREATE → POST `/resource`
164
+ - UPDATE → PUT `/resource/{id}`
165
+ - PATCH → PATCH `/resource/{id}`
166
+ - DELETE → DELETE `/resource/{id}`
167
+
168
+ ## Architecture
169
+
170
+ ```text
171
+ Excel / CSV
172
+
173
+ Reader
174
+
175
+ Schema Mapping
176
+
177
+ Validation + Type Conversion
178
+
179
+ Validated Records
180
+
181
+ JSON Output REST API Sync
182
+
183
+ API Client
184
+
185
+ Result / Report
186
+ ```
187
+
188
+ CRUD execution is intentionally separate from validation/conversion so the same core engine can be used for safe JSON generation without modifying remote data.
189
+
190
+ ## Multi-sheet dependencies
191
+
192
+ Sheets can depend on other sheets. A successful API response can provide a value such as a newly created database ID to a dependent sheet.
193
+
194
+ ```yaml
195
+ sheets:
196
+ Doctors:
197
+ schema: examples/doctor-dependency.yaml
198
+ endpoint: /doctors
199
+ response:
200
+ mapping:
201
+ api_id: id
202
+
203
+ Patients:
204
+ schema: examples/patient-dependency.yaml
205
+ endpoint: /patients
206
+ references:
207
+ - target_field: doctor_id
208
+ source_sheet: Doctors
209
+ source_key: doctor_code
210
+ target_key: doctor_code
211
+ source_value: api_id
212
+ ```
213
+
214
+ Excel2API executes `Doctors` first, indexes successful API IDs by `doctor_code`, and injects the matching ID into `Patients.doctor_id` before validation and API execution. Circular dependencies are rejected.
215
+
216
+ ## Resumable synchronization
217
+
218
+ Large imports can be resumed without repeating successful rows:
219
+
220
+ ```bash
221
+ excel2api sync patients.xlsx \
222
+ --schema patient.yaml \
223
+ --api https://example.com/api/patients \
224
+ --checkpoint sync.checkpoint.json \
225
+ --batch-size 50
226
+ ```
227
+
228
+ Resume after an interruption:
229
+
230
+ ```bash
231
+ excel2api sync patients.xlsx \
232
+ --schema patient.yaml \
233
+ --api https://example.com/api/patients \
234
+ --checkpoint sync.checkpoint.json \
235
+ --resume
236
+ ```
237
+
238
+ ## Custom API headers
239
+
240
+ ```bash
241
+ excel2api sync patients.xlsx \
242
+ --schema patient.yaml \
243
+ --api https://example.com/api/patients \
244
+ --header "X-API-Key=YOUR_KEY"
245
+ ```
246
+
247
+ Multiple headers can be supplied. Bearer tokens can also be provided through `EXCEL2API_TOKEN` or another environment variable configured in YAML.
248
+
249
+ ## Rate limiting and stop-on-error
250
+
251
+ ```bash
252
+ excel2api sync patients.xlsx \
253
+ --schema patient.yaml \
254
+ --api https://example.com/api/patients \
255
+ --rate-limit 0.2 \
256
+ --batch-size 100 \
257
+ --stop-on-error
258
+ ```
259
+
260
+ ## API response mapping
261
+
262
+ A schema can define response fields to extract into the sync report:
263
+
264
+ ```yaml
265
+ response:
266
+ mapping:
267
+ api_id: id
268
+ api_status: status
269
+ api_message: message
270
+ ```
271
+
272
+ Generate an Excel sync report:
273
+
274
+ ```bash
275
+ excel2api sync examples/patients-crud.xlsx \
276
+ --schema examples/patient-response.yaml \
277
+ --api https://example.com/api/patients \
278
+ --excel-report sync-results.xlsx
279
+ ```
280
+
281
+ Validation failures can also be exported:
282
+
283
+ ```bash
284
+ excel2api sync patients.xlsx \
285
+ --schema patient.yaml \
286
+ --api https://example.com/api/patients \
287
+ --error-report validation-errors.xlsx
288
+ ```
289
+
290
+ ## Configuration file
291
+
292
+ For repeatable jobs, API settings and sync behavior can be stored in YAML:
293
+
294
+ ```yaml
295
+ input: examples/patients-crud.xlsx
296
+ schema: examples/patient-response.yaml
297
+
298
+ api:
299
+ base_url: https://example.com/api/patients
300
+ auth:
301
+ type: bearer
302
+ token_env: PATIENT_API_TOKEN
303
+ timeout: 30
304
+ retries: 3
305
+ rate_limit: 0.2
306
+ headers:
307
+ X-Client: excel2api
308
+
309
+ sync:
310
+ operation_field: operation
311
+ identifier_field: id
312
+ batch_size: 100
313
+ checkpoint: sync.checkpoint.json
314
+ dry_run: true
315
+ report: sync-report.json
316
+ excel_report: sync-results.xlsx
317
+ ```
318
+
319
+ Run the complete job with:
320
+
321
+ ```bash
322
+ excel2api sync --config examples/excel2api.yaml
323
+ ```
324
+
325
+ CLI options override values from the configuration file. Keep secrets out of YAML whenever possible; use `token_env` to read bearer tokens from environment variables.
326
+
327
+ ## Endpoint templates
328
+
329
+ Use configurable endpoint templates when your API does not follow the default REST paths:
330
+
331
+ ```yaml
332
+ api:
333
+ base_url: https://example.com/api
334
+ endpoints:
335
+ CREATE:
336
+ method: POST
337
+ path: /patients
338
+ UPDATE:
339
+ method: PUT
340
+ path: /patients/{id}
341
+ PATCH:
342
+ method: PATCH
343
+ path: /patients/{id}
344
+ DELETE:
345
+ method: DELETE
346
+ path: /patients/{id}
347
+ ```
348
+
349
+ Endpoint paths may use `{id}`, `{identifier}`, or fields from the API payload, such as `{department}`.
350
+
351
+ ## CLI commands
352
+
353
+ ```text
354
+ excel2api convert
355
+ excel2api validate
356
+ excel2api sync
357
+ excel2api doctor
358
+ ```
359
+
360
+ Check the installed version:
361
+
362
+ ```bash
363
+ excel2api --version
364
+ ```
365
+
366
+ ## Development
367
+
368
+ Run tests from the repository root:
369
+
370
+ ```bash
371
+ PYTHONPATH=src python -m pytest -q
372
+ ```
373
+
374
+ Run linting:
375
+
376
+ ```bash
377
+ ruff check src tests
378
+ ```
379
+
380
+ Build the package:
381
+
382
+ ```bash
383
+ python -m pip install build
384
+ python -m build
385
+ ```
386
+
387
+ ## Release
388
+
389
+ Excel2API uses GitHub Actions for CI and PyPI publishing. Releases are published from version tags such as `v1.0.0` after configuring PyPI Trusted Publishing for the repository.
390
+
391
+ ## Roadmap
392
+
393
+ - UPSERT with explicit existence checking and POST/PUT selection
394
+ - API-key authentication as a first-class schema option
395
+ - Idempotency-key support
396
+ - Local mock API for end-to-end testing
397
+ - Additional authentication mechanisms
398
+ - Improved mapping expressions for nested API responses