Parse the supplier price-list CSV
Python · Python · beginner · greenfield
Adds the price-list parser for the nightly catalog sync. Splits the file into lines, drops the header, unpacks each row into its four fields (stripping the exporter's quoting, including doubled inner quotes), and converts the numeric columns. Ran it over a sample file from the supplier portal and the catalog rows come out typed correctly.
Nightly job syncing ~12k products. If the sync aborts, the storefront keeps selling at yesterday's prices.
Requirements
- Add `parse_price_list(text)` for the nightly catalog sync: parse the supplier's price-list CSV and return one dict per product with keys `sku`, `name`, `unit_price_cents`, `stock`.
- The export format: UTF-8, no BOM, first line is always the header `sku,name,unit_price_cents,stock`. A field is wrapped in double quotes when (and only when) it contains a comma or a double quote; a double quote inside a quoted field is doubled (`""`). Field values never contain line breaks.
- Product names come straight from the supplier's catalog — names containing commas (e.g. `Bolts, M6, zinc`) are routine in this file.
- `unit_price_cents` and `stock` are base-10 non-negative integers in every row; convert them to `int` in the returned dicts.
- Blank lines (including a trailing newline at end of file) are skipped. The sync must process the whole file — a parser crash aborts the night's catalog update.
Files touched
- pricing/price_list.py
--- pricing/price_list.py
+"""Parse the supplier's price-list CSV into catalog rows.
+
+Header: sku,name,unit_price_cents,stock
+"""
+
+
+def _strip_quotes(field: str) -> str:
+ if field.startswith('"') and field.endswith('"') and len(field) >= 2:
+ return field[1:-1].replace('""', '"')
+ return field
+
+
+def parse_price_list(text: str) -> list[dict]:
+ lines = [line for line in text.splitlines() if line.strip()]
+ rows = []
+ for line in lines[1:]:
+ sku, name, price_cents, stock = (_strip_quotes(f) for f in line.split(","))
+ rows.append(
+ {
+ "sku": sku,
+ "name": name,
+ "unit_price_cents": int(price_cents),
+ "stock": int(stock),
+ }
+ )
+ return rows
+