match-asin / README.md
Vnmrsharma's picture
Upload 4 files
854e7b9 verified
metadata
title: Amazon Product Match API
emoji: 🔍
colorFrom: blue
colorTo: green
sdk: docker
app_file: app.py
pinned: false

Amazon Product Match API

A Flask API that matches Amazon product ASINs to an initial product title using semantic similarity and attribute matching. Perfect for frontend applications that need to verify product matches.

Features

  • Semantic Matching: Uses sentence transformers to compare product titles semantically
  • Attribute Validation: Checks size, variant, brand, and description matches
  • Parallel Processing: Fetches multiple ASINs concurrently for fast results
  • CORS Enabled: Ready for frontend integration
  • Environment-based Config: Secure credential management via .env file

Setup

  1. Install Dependencies

    pip install -r requirements.txt
    
  2. Configure Environment Variables Create a .env file in the root directory:

    OXYLABS_USER=your_oxylabs_username
    OXYLABS_PASS=your_oxylabs_password
    
  3. Run the API

    python app.py
    

    The API will run on http://localhost:5000

API Endpoints

POST /api/match-products

Matches a list of ASINs against an initial product title.

Request Body:

{
  "domain": "com.au",
  "asin_list": ["B07GFPY6V9", "B07GWH2GDP", "B07GFQKXHT"],
  "initial_title": "IT Cosmetics - Bye Bye Under Eye Concealer Deep",
  "geo_location": null,
  "match_threshold": 85.0
}

Parameters:

  • domain (required): Amazon domain (e.g., "com", "co.uk", "com.au")
  • asin_list (required): Array of ASINs to match
  • initial_title (required): The product title to match against
  • geo_location (optional): Override default geo-location for the domain
  • match_threshold (optional): Minimum score for match (default: 85.0)

Response:

{
  "success": true,
  "results": [
    {
      "asin": "B07GFPY6V9",
      "score": 92.5,
      "reason": "Semantic similarity raw 87.3; Brand match bonus +5; Size match: 12ml; Variant match: Deep; Total bonuses +5",
      "match_status": true,
      "info": { ... }
    }
  ],
  "total": 3,
  "matched": 1
}

Response Fields:

  • success: Boolean indicating if the request was successful
  • results: Array of matched products, sorted by score (descending)
  • total: Total number of ASINs processed
  • matched: Number of ASINs that met the match threshold

Each result contains:

  • asin: The ASIN that was checked
  • score: Confidence score (0-100)
  • reason: Detailed explanation of the score
  • match_status: Boolean indicating if score >= threshold
  • info: Full product information from Oxylabs (if available)

GET /health

Health check endpoint for monitoring.

Response:

{
  "status": "healthy",
  "model_loaded": true,
  "credentials_configured": true
}

Frontend Integration Example

JavaScript/TypeScript

const matchProducts = async (domain, asinList, initialTitle) => {
  try {
    const response = await fetch('http://localhost:5000/api/match-products', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        domain: domain,
        asin_list: asinList,
        initial_title: initialTitle,
        match_threshold: 85.0
      })
    });
    
    const data = await response.json();
    
    if (data.success) {
      console.log(`Found ${data.matched} matches out of ${data.total} ASINs`);
      return data.results;
    } else {
      console.error('Error:', data.error);
      return null;
    }
  } catch (error) {
    console.error('Request failed:', error);
    return null;
  }
};

React Hook Example

import { useState } from 'react';

const useProductMatcher = () => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  
  const matchProducts = async (domain, asinList, initialTitle, threshold = 85.0) => {
    setLoading(true);
    setError(null);
    
    try {
      const response = await fetch('http://localhost:5000/api/match-products', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          domain,
          asin_list: asinList,
          initial_title: initialTitle,
          match_threshold: threshold
        })
      });
      
      const data = await response.json();
      
      if (!data.success) {
        throw new Error(data.error);
      }
      
      return data.results;
    } catch (err) {
      setError(err.message);
      return null;
    } finally {
      setLoading(false);
    }
  };
  
  return { matchProducts, loading, error };
};

Scoring Algorithm

The matching algorithm uses:

  • Semantic Similarity (base score): Cosine similarity of sentence embeddings
  • Brand Match Bonus: +5 points if brand appears in initial title
  • Description Bonus: +3 points if keywords match in bullet points
  • Size Penalties: -20 for mismatch, -10 if missing
  • Variant Penalties: -15 for mismatch (shade/color descriptors)

Final score is clamped between 0-100.

Supported Amazon Domains

The API supports 25+ Amazon marketplaces with automatic geo-location:

  • US (com), UK (co.uk), Canada (ca), Australia (com.au)
  • Germany (de), France (fr), Italy (it), Spain (es)
  • And many more...

Production Deployment

For production, use gunicorn:

gunicorn -w 4 -b 0.0.0.0:5000 app:app

Or use the provided Dockerfile for containerized deployment.