# Supplier Feed Cleaner 1.0.0 Clean supplier CSV, JSON row arrays or ONIX 3.0 reference-tag XML into a product list and an exceptions report. No store access, cloud service, subscription, API key or model is required. Python 3.10+ is the only runtime dependency. No pip installation is needed. ## Local app Extract the whole ZIP into a folder. In a terminal in that folder, run: ```text python app.py ``` On Windows `py -3 app.py` also works; on some systems use `python3 app.py`. Open the complete local URL printed by the program. Click **Load sample** to try it, or select a file and click **Read columns**. Review the mapping, choose the price decimal format and supply a currency if your feed lacks one. Click **Clean and review**. Download the full JSON report, accepted CSV and exceptions CSV separately. Press Ctrl+C in the terminal to close the server. No outbound network calls are made. The local server listens only on loopback and checks a random session token. Do not expose it as a public API; hosted adapters require their own access controls and deployment verification. ## Command line ```text python cleaner.py examples/products.csv --format csv --currency USD --output results python cleaner.py examples/books.xml --format onix --output books-results ``` The output directory must not already exist. Source files are never overwritten. Exit codes: 0 = all rows accepted; 1 = report created with rejected rows; 2 = invalid file/options or output failure. `--help` lists explicit mappings, delimiter and decimal format. A mapping file is JSON such as `{"sku":"ItemNo","title":"Name","msrp":"Price"}`. The example products include one rejected row deliberately, so its exit code is 1. ## Supported profile - UTF-8 files, optionally with BOM; maximum 5 MiB, 10,000 rows, 100 columns, 20,000 characters per field. - CSV comma, semicolon or tab separator; quoted multiline fields; unique headers and consistent cell counts. - JSON array of flat objects. Identifiers must be strings so leading zeros survive. Duplicate keys and non-finite numbers are refused. - ONIXMessage release 3.0, reference tags with the standard namespace or no namespace. One unambiguous retail price per product. Short tags, ONIX 2.1/3.1 and DTD/entities are refused. - Required SKU, title, cost or retail price, and an explicit three-letter uppercase currency code. - Explicit point/comma price format; no symbols or negative prices; exact two-place decimal strings. - All rows sharing a duplicate SKU are rejected for review. ISBN/GTIN check digits are checked when supplied. - Image URLs are retained as text and never fetched. Currency code syntax is checked, not exchange rates or a currency registry. - JSON is the exact machine-readable output. CSV prefixes formula-like cells with an apostrophe for spreadsheet safety; import SKU columns as text to preserve zeros in spreadsheet apps. This edition does not read binary Excel files, repair bad identifiers, guess ambiguous prices, validate an entire ONIX schema, write to a store, calculate tax or guarantee marketplace acceptance. Export a spreadsheet as CSV to use it here. Every input row is accounted for as accepted or rejected. No other product is needed to complete the supported workflow. ## Tests ```text python -m unittest discover -s tests -v ``` Tests run in temporary directories and start a temporary loopback service. They do not contact external sites. The LICENSE covers personal and commercial use of this complete local utility.