shelfshift 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 (87) hide show
  1. shelfshift-1.0.0/LICENSE +21 -0
  2. shelfshift-1.0.0/PKG-INFO +381 -0
  3. shelfshift-1.0.0/README.md +355 -0
  4. shelfshift-1.0.0/pyproject.toml +53 -0
  5. shelfshift-1.0.0/setup.cfg +4 -0
  6. shelfshift-1.0.0/shelfshift/__init__.py +48 -0
  7. shelfshift-1.0.0/shelfshift/cli/__init__.py +1 -0
  8. shelfshift-1.0.0/shelfshift/cli/main.py +190 -0
  9. shelfshift-1.0.0/shelfshift/config.py +72 -0
  10. shelfshift-1.0.0/shelfshift/core/__init__.py +79 -0
  11. shelfshift-1.0.0/shelfshift/core/api.py +227 -0
  12. shelfshift-1.0.0/shelfshift/core/canonical/__init__.py +60 -0
  13. shelfshift-1.0.0/shelfshift/core/canonical/entities.py +643 -0
  14. shelfshift-1.0.0/shelfshift/core/canonical/helpers.py +256 -0
  15. shelfshift-1.0.0/shelfshift/core/canonical/schemas.py +21 -0
  16. shelfshift-1.0.0/shelfshift/core/canonical/serialization.py +17 -0
  17. shelfshift-1.0.0/shelfshift/core/config.py +32 -0
  18. shelfshift-1.0.0/shelfshift/core/detect/__init__.py +4 -0
  19. shelfshift-1.0.0/shelfshift/core/detect/csv.py +5 -0
  20. shelfshift-1.0.0/shelfshift/core/detect/url.py +134 -0
  21. shelfshift-1.0.0/shelfshift/core/exporters/__init__.py +42 -0
  22. shelfshift-1.0.0/shelfshift/core/exporters/api.py +51 -0
  23. shelfshift-1.0.0/shelfshift/core/exporters/platforms/__init__.py +2 -0
  24. shelfshift-1.0.0/shelfshift/core/exporters/platforms/bigcommerce.py +486 -0
  25. shelfshift-1.0.0/shelfshift/core/exporters/platforms/shopify.py +216 -0
  26. shelfshift-1.0.0/shelfshift/core/exporters/platforms/squarespace.py +166 -0
  27. shelfshift-1.0.0/shelfshift/core/exporters/platforms/wix.py +310 -0
  28. shelfshift-1.0.0/shelfshift/core/exporters/platforms/woocommerce.py +332 -0
  29. shelfshift-1.0.0/shelfshift/core/exporters/shared/__init__.py +2 -0
  30. shelfshift-1.0.0/shelfshift/core/exporters/shared/batch.py +164 -0
  31. shelfshift-1.0.0/shelfshift/core/exporters/shared/utils.py +302 -0
  32. shelfshift-1.0.0/shelfshift/core/exporters/shared/weight_units.py +36 -0
  33. shelfshift-1.0.0/shelfshift/core/importers/__init__.py +10 -0
  34. shelfshift-1.0.0/shelfshift/core/importers/csv/__init__.py +58 -0
  35. shelfshift-1.0.0/shelfshift/core/importers/csv/batch.py +310 -0
  36. shelfshift-1.0.0/shelfshift/core/importers/csv/bigcommerce.py +226 -0
  37. shelfshift-1.0.0/shelfshift/core/importers/csv/common.py +348 -0
  38. shelfshift-1.0.0/shelfshift/core/importers/csv/detection.py +37 -0
  39. shelfshift-1.0.0/shelfshift/core/importers/csv/shopify.py +122 -0
  40. shelfshift-1.0.0/shelfshift/core/importers/csv/squarespace.py +113 -0
  41. shelfshift-1.0.0/shelfshift/core/importers/csv/wix.py +125 -0
  42. shelfshift-1.0.0/shelfshift/core/importers/csv/woocommerce.py +139 -0
  43. shelfshift-1.0.0/shelfshift/core/importers/url/__init__.py +105 -0
  44. shelfshift-1.0.0/shelfshift/core/importers/url/api.py +93 -0
  45. shelfshift-1.0.0/shelfshift/core/importers/url/common.py +303 -0
  46. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/__init__.py +20 -0
  47. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/aliexpress.py +404 -0
  48. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/amazon.py +308 -0
  49. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/shopify.py +391 -0
  50. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/squarespace.py +829 -0
  51. shelfshift-1.0.0/shelfshift/core/importers/url/platforms/woocommerce.py +694 -0
  52. shelfshift-1.0.0/shelfshift/core/registry.py +98 -0
  53. shelfshift-1.0.0/shelfshift/core/validate/__init__.py +4 -0
  54. shelfshift-1.0.0/shelfshift/core/validate/report.py +21 -0
  55. shelfshift-1.0.0/shelfshift/core/validate/rules.py +33 -0
  56. shelfshift-1.0.0/shelfshift/server/__init__.py +3 -0
  57. shelfshift-1.0.0/shelfshift/server/config.py +15 -0
  58. shelfshift-1.0.0/shelfshift/server/helpers/__init__.py +40 -0
  59. shelfshift-1.0.0/shelfshift/server/helpers/exporting.py +169 -0
  60. shelfshift-1.0.0/shelfshift/server/helpers/importing.py +150 -0
  61. shelfshift-1.0.0/shelfshift/server/helpers/payload.py +46 -0
  62. shelfshift-1.0.0/shelfshift/server/helpers/rendering.py +94 -0
  63. shelfshift-1.0.0/shelfshift/server/logging/__init__.py +3 -0
  64. shelfshift-1.0.0/shelfshift/server/logging/product_payloads.py +183 -0
  65. shelfshift-1.0.0/shelfshift/server/main.py +62 -0
  66. shelfshift-1.0.0/shelfshift/server/routers/__init__.py +3 -0
  67. shelfshift-1.0.0/shelfshift/server/routers/api.py +200 -0
  68. shelfshift-1.0.0/shelfshift/server/routers/web_csv.py +134 -0
  69. shelfshift-1.0.0/shelfshift/server/routers/web_url.py +314 -0
  70. shelfshift-1.0.0/shelfshift/server/schemas.py +81 -0
  71. shelfshift-1.0.0/shelfshift/server/web/static/app.js +904 -0
  72. shelfshift-1.0.0/shelfshift/server/web/static/favicon.ico +0 -0
  73. shelfshift-1.0.0/shelfshift/server/web/static/shelfshift_logo.png +0 -0
  74. shelfshift-1.0.0/shelfshift/server/web/static/styles.css +1077 -0
  75. shelfshift-1.0.0/shelfshift/server/web/templates/_export_form.html +59 -0
  76. shelfshift-1.0.0/shelfshift/server/web/templates/_product_editor.html +163 -0
  77. shelfshift-1.0.0/shelfshift/server/web/templates/_product_editor_batch.html +179 -0
  78. shelfshift-1.0.0/shelfshift/server/web/templates/base.html +78 -0
  79. shelfshift-1.0.0/shelfshift/server/web/templates/csv.html +85 -0
  80. shelfshift-1.0.0/shelfshift/server/web/templates/index.html +65 -0
  81. shelfshift-1.0.0/shelfshift/server/web/templates/url.html +78 -0
  82. shelfshift-1.0.0/shelfshift.egg-info/PKG-INFO +381 -0
  83. shelfshift-1.0.0/shelfshift.egg-info/SOURCES.txt +85 -0
  84. shelfshift-1.0.0/shelfshift.egg-info/dependency_links.txt +1 -0
  85. shelfshift-1.0.0/shelfshift.egg-info/entry_points.txt +3 -0
  86. shelfshift-1.0.0/shelfshift.egg-info/requires.txt +10 -0
  87. shelfshift-1.0.0/shelfshift.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Walid KINI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,381 @@
1
+ Metadata-Version: 2.4
2
+ Name: shelfshift
3
+ Version: 1.0.0
4
+ Summary: Developer toolkit for ecommerce catalog translation across URL/CSV sources and platform CSV targets.
5
+ License-Expression: MIT
6
+ Keywords: ecommerce,csv,catalog,shopify,woocommerce
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Topic :: Software Development :: Libraries
12
+ Requires-Python: >=3.13
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: babel<3.0.0,>=2.17.0
16
+ Requires-Dist: fastapi<1.0.0,>=0.116.0
17
+ Requires-Dist: httpx<1.0.0,>=0.28.0
18
+ Requires-Dist: jinja2<4.0.0,>=3.1.0
19
+ Requires-Dist: pandas<3.0.0,>=2.2.0
20
+ Requires-Dist: python-dotenv<2.0.0,>=1.1.0
21
+ Requires-Dist: python-multipart<1.0.0,>=0.0.20
22
+ Requires-Dist: python-slugify<9.0.0,>=8.0.0
23
+ Requires-Dist: requests<3.0.0,>=2.32.0
24
+ Requires-Dist: uvicorn[standard]<1.0.0,>=0.35.0
25
+ Dynamic: license-file
26
+
27
+ # Shelfshift
28
+
29
+ Shelfshift is a developer toolkit for ecommerce catalog translation.
30
+
31
+ Given a product source (URL or CSV), Shelfshift normalizes it into a canonical product model and exports platform-specific CSVs for:
32
+
33
+ - Shopify
34
+ - BigCommerce
35
+ - Wix
36
+ - Squarespace
37
+ - WooCommerce
38
+
39
+ This project is built for ecommerce developers and integration engineers who need reliable, automatable catalog pipelines.
40
+
41
+ ## Positioning
42
+
43
+ - `shelfshift.core`: the primary product (importable Python library)
44
+ - `shelfshift` CLI: automation and local workflows
45
+ - `shelfshift.server`: self-hosted FastAPI API surface
46
+ - Web UI: demo interface for core/server capabilities, not the primary target
47
+
48
+ ## Core Capabilities
49
+
50
+ - URL detection (`shopify`, `woocommerce`, `squarespace`, `amazon`, `aliexpress`)
51
+ - URL import to canonical product(s)
52
+ - CSV platform detection + CSV import to canonical product(s)
53
+ - Canonical product validation
54
+ - Canonical -> target-platform CSV export
55
+ - Single and batch export flows
56
+
57
+ ## Package Surfaces
58
+
59
+ - Library: `shelfshift.core`
60
+ - CLI: `shelfshift` (entrypoint from `pyproject.toml`)
61
+ - Server runner: `shelfshift-server`
62
+
63
+ ## Supported Inputs
64
+
65
+ ### URL import sources
66
+
67
+ - Shopify product URLs
68
+ - WooCommerce product/store API URLs
69
+ - Squarespace product URLs
70
+ - Amazon product URLs (requires `RAPIDAPI_KEY`)
71
+ - AliExpress product URLs (requires `RAPIDAPI_KEY`)
72
+
73
+ ### CSV import sources
74
+
75
+ - Shopify
76
+ - BigCommerce
77
+ - Wix
78
+ - Squarespace
79
+ - WooCommerce
80
+
81
+ ## Compatibility
82
+
83
+ - Python: `>=3.13`
84
+ - URL imports: `shopify`, `woocommerce`, `squarespace`, `amazon`, `aliexpress`
85
+ - CSV imports: `shopify`, `bigcommerce`, `wix`, `squarespace`, `woocommerce`
86
+ - CSV exports: `shopify`, `bigcommerce`, `wix`, `squarespace`, `woocommerce`
87
+
88
+ ## Installation
89
+
90
+ ### From PyPI (recommended for users)
91
+
92
+ ```bash
93
+ pip install shelfshift
94
+ ```
95
+
96
+ Or with `uv` in a project:
97
+
98
+ ```bash
99
+ uv add shelfshift
100
+ uv sync
101
+ ```
102
+
103
+ Quick smoke test:
104
+
105
+ ```bash
106
+ python -c "import shelfshift, shelfshift.core; print(shelfshift.__version__)"
107
+ shelfshift --help
108
+ ```
109
+
110
+ ## Running Commands
111
+
112
+ Use one of the following workflows for CLI and server commands:
113
+
114
+ 1. One-off invocation with `uv run`:
115
+
116
+ ```bash
117
+ uv run shelfshift detect ./source.csv
118
+ ```
119
+
120
+ 2. Activate `.venv` and run commands directly (recommended for repeated local development):
121
+
122
+ ```bash
123
+ source .venv/bin/activate
124
+ shelfshift detect ./source.csv
125
+ ```
126
+
127
+ When `.venv` is activated, you do not need `uv run` prefixes.
128
+
129
+ Optional local env file:
130
+
131
+ ```bash
132
+ cp .env.example .env
133
+ ```
134
+
135
+ ## Quick Start (Library)
136
+
137
+ ```python
138
+ from shelfshift.core import import_url, export_csv
139
+
140
+ # 1) Import canonical product from URL
141
+ result = import_url("https://example.myshopify.com/products/demo-item")
142
+ product = result.products[0]
143
+
144
+ # 2) Export to target platform CSV
145
+ exported = export_csv(product, target="shopify", options={"publish": False, "weight_unit": "g"})
146
+ with open("product.csv", "wb") as f:
147
+ f.write(exported.csv_bytes)
148
+ ```
149
+
150
+ Batch URL import:
151
+
152
+ ```python
153
+ from shelfshift.core import import_url
154
+
155
+ result = import_url([
156
+ "https://store-a.com/products/a",
157
+ "https://store-b.com/products/b",
158
+ ])
159
+
160
+ # result.products and result.errors support partial-success workflows
161
+ print(len(result.products), len(result.errors))
162
+ ```
163
+
164
+ Amazon/AliExpress import with explicit key (preferred over env fallback):
165
+
166
+ ```python
167
+ from shelfshift.core import import_url
168
+
169
+ result = import_url(
170
+ "https://www.amazon.com/dp/B0C1234567",
171
+ rapidapi_key="your-rapidapi-key",
172
+ )
173
+ ```
174
+
175
+ ## Quick Start (CLI)
176
+
177
+ Detect URL or CSV input:
178
+
179
+ ```bash
180
+ shelfshift detect "https://example.myshopify.com/products/demo-item"
181
+ shelfshift detect ./source.csv
182
+ ```
183
+
184
+ Import URL(s) to canonical JSON:
185
+
186
+ ```bash
187
+ shelfshift import-url "https://example.myshopify.com/products/demo-item"
188
+ shelfshift import-url "https://store-a.com/products/a" "https://store-b.com/products/b"
189
+ ```
190
+
191
+ For Amazon/AliExpress URLs, pass an explicit key (or set `RAPIDAPI_KEY` in env):
192
+
193
+ ```bash
194
+ shelfshift import-url "https://www.amazon.com/dp/B0C1234567" --rapidapi-key "your-rapidapi-key"
195
+ ```
196
+
197
+ Import source CSV to canonical JSON:
198
+
199
+ ```bash
200
+ shelfshift import-csv ./source.csv --source-platform shopify
201
+ ```
202
+
203
+ For `bigcommerce`, `wix`, and `squarespace` source CSVs, also pass `--source-weight-unit`:
204
+
205
+ ```bash
206
+ shelfshift import-csv ./source.csv --source-platform squarespace --source-weight-unit kg
207
+ ```
208
+
209
+ Convert source CSV directly to target CSV:
210
+
211
+ ```bash
212
+ shelfshift convert ./source.csv --to shopify --out ./converted.csv --report ./report.json
213
+ ```
214
+
215
+ If the source CSV platform is `bigcommerce`, `wix`, or `squarespace`, include `--source-weight-unit`:
216
+
217
+ ```bash
218
+ shelfshift convert ./source.csv --source squarespace --source-weight-unit kg --to shopify --out ./converted.csv
219
+ ```
220
+
221
+ Validate canonicalized products from CSV:
222
+
223
+ ```bash
224
+ shelfshift validate ./source.csv --platform shopify --report ./validate.json
225
+ ```
226
+
227
+ For `bigcommerce`, `wix`, and `squarespace` source CSVs, include `--source-weight-unit`:
228
+
229
+ ```bash
230
+ shelfshift validate ./source.csv --platform wix --source-weight-unit kg --report ./validate.json
231
+ ```
232
+
233
+ Export canonical JSON payload to target CSV:
234
+
235
+ ```bash
236
+ shelfshift export-csv ./canonical.json --to woocommerce --out ./woocommerce.csv
237
+ ```
238
+
239
+ ## Self-Hosted API (FastAPI)
240
+
241
+ Start server:
242
+
243
+ ```bash
244
+ shelfshift-server
245
+ ```
246
+
247
+ or:
248
+
249
+ ```bash
250
+ uvicorn shelfshift.server.main:app --reload
251
+ ```
252
+
253
+ Programmatic app creation with explicit settings:
254
+
255
+ ```python
256
+ from shelfshift.config import Settings
257
+ from shelfshift.server.main import create_app
258
+
259
+ app = create_app(
260
+ settings=Settings(
261
+ app_name="ShelfShift Internal",
262
+ app_tagline="Catalog bridge",
263
+ brand_primary="#18d9b6",
264
+ brand_secondary="#27c6f5",
265
+ brand_ink="#020b1a",
266
+ debug=True,
267
+ log_verbosity="high",
268
+ rapidapi_key="your-key",
269
+ cors_allow_origins=("https://admin.example.com",),
270
+ )
271
+ )
272
+ ```
273
+
274
+ Open:
275
+
276
+ - Swagger UI: `http://127.0.0.1:8000/docs`
277
+ - Landing page: `http://127.0.0.1:8000/`
278
+ - URL demo UI: `http://127.0.0.1:8000/url`
279
+ - CSV demo UI: `http://127.0.0.1:8000/csv`
280
+
281
+ ### API Routes
282
+
283
+ - `GET /health`
284
+ - `GET /api/v1/detect`
285
+ - `POST /api/v1/import`
286
+ - `POST /api/v1/detect/csv`
287
+ - `POST /api/v1/import/csv`
288
+ - `POST /api/v1/export/from-product.csv`
289
+ - `POST /api/v1/export/shopify.csv`
290
+ - `POST /api/v1/export/bigcommerce.csv`
291
+ - `POST /api/v1/export/wix.csv`
292
+ - `POST /api/v1/export/squarespace.csv`
293
+ - `POST /api/v1/export/woocommerce.csv`
294
+
295
+ ## API Examples
296
+
297
+ Detect URL:
298
+
299
+ ```bash
300
+ curl "http://127.0.0.1:8000/api/v1/detect?url=https://example.myshopify.com/products/demo-item"
301
+ ```
302
+
303
+ Import URL(s):
304
+
305
+ ```bash
306
+ curl -X POST "http://127.0.0.1:8000/api/v1/import" \
307
+ -H "Content-Type: application/json" \
308
+ -d '{"product_urls": ["https://example.myshopify.com/products/demo-item"]}'
309
+ ```
310
+
311
+ Import CSV:
312
+
313
+ ```bash
314
+ curl -X POST "http://127.0.0.1:8000/api/v1/import/csv" \
315
+ -F "source_platform=shopify" \
316
+ -F "file=@./source.csv"
317
+ ```
318
+
319
+ For `bigcommerce`, `wix`, and `squarespace` source CSVs, include `source_weight_unit` (`g|kg|lb|oz`):
320
+
321
+ ```bash
322
+ curl -X POST "http://127.0.0.1:8000/api/v1/import/csv" \
323
+ -F "source_platform=squarespace" \
324
+ -F "source_weight_unit=kg" \
325
+ -F "file=@./source.csv"
326
+ ```
327
+
328
+ Export from canonical payload:
329
+
330
+ ```bash
331
+ curl -X POST "http://127.0.0.1:8000/api/v1/export/from-product.csv" \
332
+ -H "Content-Type: application/json" \
333
+ -d '{"product": {"source": {"platform": "shopify"}, "title": "Demo"}, "target_platform": "shopify"}' \
334
+ -o out.csv
335
+ ```
336
+
337
+ ## Canonical Model
338
+
339
+ All importers normalize into the Shelfshift canonical entities under:
340
+
341
+ - `shelfshift.core.canonical.entities`
342
+ - `shelfshift.core.canonical.serialization`
343
+
344
+ This canonical layer is the contract between import and export stages.
345
+
346
+ ## Extensibility
347
+
348
+ Registry hooks are available via:
349
+
350
+ - `shelfshift.core.register_importer`
351
+ - `shelfshift.core.register_exporter`
352
+ - `shelfshift.core.list_importers`
353
+ - `shelfshift.core.list_exporters`
354
+
355
+ Use these for custom importer/exporter integration in internal tooling.
356
+
357
+ ## Runtime Configuration Precedence
358
+
359
+ Shelfshift resolves runtime settings in this order:
360
+
361
+ 1. Explicit runtime input (API args, CLI flags, `create_app(settings=...)`).
362
+ 2. Process environment (including values loaded from `.env`).
363
+ 3. Built-in defaults.
364
+
365
+ Configuration is resolved per core call or per server app instance (no request-level live reload).
366
+
367
+ ## Environment Variables
368
+
369
+ - `APP_NAME`: server/web title
370
+ - `APP_TAGLINE`: server/web subtitle
371
+ - `BRAND_PRIMARY`: UI primary color
372
+ - `BRAND_SECONDARY`: UI secondary color
373
+ - `BRAND_INK`: UI text color
374
+ - `DEBUG`: include/exclude `raw` in API import responses
375
+ - `LOG_VERBOSITY`: `low | medium | high | extrahigh`
376
+ - `RAPIDAPI_KEY`: required for Amazon/AliExpress URL imports
377
+ - `CORS_ALLOW_ORIGINS`: comma-separated CORS allowlist
378
+
379
+ ## License
380
+
381
+ This project is licensed under the MIT License. See `LICENSE`.