Skip to content

lexgbr/api-upload

Repository files navigation

eMAG Marketplace Utility Scripts

Python helpers for interacting with the eMAG Marketplace API: sending offers, bulk uploads, and exporting category metadata. All scripts rely on Basic Auth credentials provided by eMAG.

  • send_payload.py – Send a JSON payload with one or more offers.
  • send_payload_json_strict.py – Minimal example that posts a single offer.
  • upload_products.py – Convert a CSV sheet into offer requests with validation, retries, and response logging.
  • list_category_ids.py – Read marketplace categories (ID + name) and optionally export to XLSX/JSON.

Requirements

  • Python 3.9+ (tested with 3.13).
  • pip install requests python-dotenv for all scripts.
  • pip install openpyxl when using list_category_ids.py --xlsx.
  • Network access to https://marketplace-api.emag.ro from a whitelisted IP.
  • .env file or environment variables:
    • EMAG_API_USER
    • EMAG_API_KEY
    • Optional: EMAG_API_HOST (defaults to https://marketplace-api.emag.ro)
    • Optional: EMAG_DEFAULT_HANDLING_TIME (defaults to 10 if missing)
    • Optional: EMAG_DEFAULT_SUPPLIER_LEAD_TIME (defaults to 14 if missing)

Create .env in the project root:

EMAG_API_USER=your-user
EMAG_API_KEY=your-key
EMAG_API_HOST=https://marketplace-api.emag.ro

Local Web UI

A lightweight Flask UI is included for local automation. It wraps the existing helpers so you can trigger uploads, inspect logs, and track how many products were updated without leaving the browser.

Setup

python -m venv .venv
.venv\Scripts\activate  # PowerShell: .\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

Ensure the .env file contains your EMAG_API_USER, EMAG_API_KEY, and optional EMAG_API_HOST just like the CLI scripts.

Run the UI

python app.py

By default the application listens on http://127.0.0.1:5000/.

Features

  • Send JSON payloads directly to product_offer/save and see the parsed response.
  • Upload CSV files produced from bulk_products_template.csv; validation is identical to upload_products.py.
  • Dry-run mode for CSV uploads to validate rows without sending API requests.
  • Automatic defaults for handling_time (10) and supplier_lead_time (14) unless you override them in the CSV/JSON payload or via environment variables.
  • Background uploads that keep running even if you leave the page, with a resumable progress bar and live row counters.
  • Supplier & inventory hub backed by SQLite: manage suppliers, import full product batches, refresh stock from CSV, and push only the delta to eMAG once you approve it.
  • Activity logs pulled from results_product_offer_save.csv (and enhanced copies in ui_actions.jsonl).
  • Live counters showing total rows processed and how many products were successfully updated (OK status).

Existing log files (responses_product_offer_save.jsonl and results_product_offer_save.csv) are reused, so the UI stays in sync with the CLI tooling.


Database Workflow

The UI now ships with an integrated SQLite database (emag.db by default, override via EMAG_DB_PATH). Use it to stage offers per supplier before touching the API:

  1. Manage suppliers – add new supplier codes (the field supplier_tng) or reuse existing ones from the Suppliers card.
  2. Import products – upload the full eMAG template under Import Products into Database while selecting a supplier (or creating a new one on the fly). All required offer fields, images, and stock are stored locally.
  3. Refresh stock – drop a stock-only CSV in Import Supplier Stock. The database captures the new figures without pinging eMAG.
  4. Review changes – the Pending Stock Changes table lists products whose stock differs from what was last synced to eMAG. Filter by supplier to focus on a single feed.
  5. Push updates – click Update Stock on eMAG to send a minimal payload per product (stock + mandatory offer fields). Successful updates automatically reset the pending list.

This workflow lets you merge multiple stock files, eyeball deltas, and only hit the API once you're confident in the data.


Common Notes

  • All requests use Basic Authorization; credentials must have API rights.
  • eMAG enforces rate limits: typically 3 requests/sec for non-order endpoints.
  • Save API responses and monitor isError in every reply.
  • When the API responds with HTTP 401/403, verify IP whitelisting and credentials.

send_payload.py

Utility for sending a ready-made payload (list of offers) to product_offer/save. Includes an auth sanity check (vat/read) and retries on HTTP 429.

python send_payload.py payload.json

Arguments

  • payload.json – Required path to a JSON file. Accepts:
    • Array of offer objects.
    • Object with key products containing the array (legacy format).

Behavior

  • Verifies EMAG_API_USER/EMAG_API_KEY.
  • Performs a test request to /api-3/vat/read to confirm access.
  • Sends the payload to /api-3/product_offer/save with 6 exponential backoff retries on HTTP 429.
  • Prints the parsed JSON response; exits with an error code if isError is true or JSON parsing fails.

Example

python send_payload.py payload.json

Use when you have already constructed a request body and need a quick sender.


send_payload_json_strict.py

Minimal script that posts a hard-coded sample offer (feel free to edit the product dict). Useful for testing credentials or inspecting the raw API response.

python send_payload_json_strict.py

Behavior:

  • Loads credentials from .env.
  • Posts the product payload (list with one element) to /api-3/product_offer/save.
  • Prints HTTP status code and JSON response (falls back to raw text if JSON parsing fails).

Edit the product dictionary before running to match your data.


upload_products.py

Bulk uploader driven by a CSV template (bulk_products_template.csv). Handles field normalization, validation, automatic id_keyid mapping, optional dry-runs, retries, and response logging.

python upload_products.py --csv bulk_products_template.csv [options]

Key Features

  • Converts CSV rows into product_offer/save payloads.
  • Validates required fields, price range, stock, and main image presence.
  • Retries up to 6 times on HTTP 429 with exponential backoff.
  • Writes JSON responses to responses_product_offer_save.jsonl.
  • Generates a CSV report (results_product_offer_save.csv) summarizing each row.

Arguments

  • --csv PATH (required) – Input CSV (UTF-8). Empty lines are skipped.
  • --host URL – Override API host (default EMAG_API_HOST).
  • --user USER / --key KEY – Override credentials (otherwise use env).
  • --verbose – Print debug logging for each row.
  • --dry-run – Skip HTTP calls; still validate/write report.
  • --out PATH – Response log file (default responses_product_offer_save.jsonl).
  • --report PATH – Report CSV path (default results_product_offer_save.csv).

CSV Column Tips

  • Core fields: id, category_id, name, brand, part_number, description, vat_id, status, sale_price, min_sale_price, max_sale_price.
  • ean[0], ean[1], … for multiple barcodes.
  • images[0].url, images[0].display_type (1 = main), etc.
  • stock[0].warehouse_id, stock[0].value, …
  • id_key auto-fills id if id column is empty.

list_category_ids.py

Fetch every active marketplace category with optional localization and export formats. Paginates category/read until completion and enforces the documented itemsPerPage ≤ 100.

python list_category_ids.py [options]

Arguments

  • --language CODE – Return category names in a specific language (EN, RO, HU, BG, PL, GR, DE).
  • --items-per-page N – Page size (1–100, default 100).
  • --timeout SECONDS – HTTP request timeout (default 30).
  • --json – Print the full response objects instead of id,name.
  • --xlsx PATH – Write results to an Excel file (Category ID, Category Name); requires openpyxl.
  • --no-stdout – Suppress CSV output (useful with --json or --xlsx).

Usage Examples

Export CSV to terminal:

python list_category_ids.py --language EN

Save to Excel only:

python list_category_ids.py --language RO --xlsx data/categories.xlsx --no-stdout

Retrieve raw JSON with custom timeout:

python list_category_ids.py --json --timeout 120 > categories.json

Errors (e.g., HTTP 401, isError: true) are reported on stderr. Increase --timeout or reduce --items-per-page if the API is slow.


Troubleshooting

  • 401 Unauthorized – Check credentials, IP whitelisting, or account API rights.
  • 429 Too Many Requests – Respect rate limits; scripts already retry.
  • UnicodeEncodeError on Windowslist_category_ids.py forces UTF-8 output; redirect to a UTF-8 capable console or file.
  • SSL / connection issues – Ensure the host is reachable and TLS interception is not blocking requests.

License

Internal use only (no explicit license provided). Update this section if you plan to distribute the scripts externally.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published