The most comprehensive Python SDK for e-commerce product data and pricing intelligence.
Access real-time product information, pricing data, and historical trends across thousands of retailers and millions of products with the official ShopSavvy Data API.
pip install shopsavvy-sdk- 🌟 Visit shopsavvy.com/data
- 📝 Sign up for a free account
- 🔑 Get your API key from the dashboard
fromshopsavvyimportcreate_client# Initialize the clientapi=create_client("ss_live_your_api_key_here")
# Look up any product by barcode, ASIN, or URLproduct=api.get_product_details("012345678901")
print(f"📦 {product.data.name} by {product.data.brand}")
# Get current prices from all retailersoffers=api.get_current_offers("012345678901")
cheapest=min(offers.data, key=lambdax: x.price)
print(f"💰 Best price: ${cheapest.price} at {cheapest.retailer}")
# Set up price monitoringapi.schedule_product_monitoring("012345678901", "daily")
print("🔔 Price alerts activated!")| Feature | Description | Use Cases |
|---|---|---|
| 🔍 Universal Product Lookup | Search by barcode, ASIN, URL, model number | Product catalogs, inventory management |
| 💲 Real-Time Pricing | Current prices across major retailers | Price comparison, competitive analysis |
| 📈 Historical Data | Price trends and availability over time | Market research, pricing strategy |
| 🔔 Smart Monitoring | Automated price tracking and alerts | Price drops, stock notifications |
| 🏪 Multi-Retailer Support | Amazon, Walmart, Target, Best Buy + more | Comprehensive market coverage |
| ⚡ Batch Operations | Process multiple products efficiently | Bulk analysis, data processing |
| 🛡️ Type Safety | Full Pydantic models with validation | Reliable data structures |
| 📊 Multiple Formats | JSON and CSV response options | Easy data integration |
pip install shopsavvy-sdkgit clone https://github.com/shopsavvy/sdk-python
cd sdk-python
pip install -e ".[dev]"# Optional: Store your API key securelyexport SHOPSAVVY_API_KEY="ss_live_your_api_key_here"fromshopsavvyimportcreate_client# Basic setupapi=create_client("ss_live_your_api_key_here")
# With custom timeout and base URLapi=create_client(
api_key="ss_live_your_api_key_here",
timeout=60.0,
base_url="https://api.shopsavvy.com/v1"
)fromshopsavvyimportShopSavvyDataAPI, ShopSavvyConfigconfig=ShopSavvyConfig(
api_key="ss_live_your_api_key_here",
timeout=45.0
)
api=ShopSavvyDataAPI(config)# Automatically closes connections when donewithcreate_client("ss_live_your_api_key_here") asapi:
product=api.get_product_details("012345678901")
print(product.data.name)
# Connection automatically closed here# Search by barcode (UPC/EAN)product=api.get_product_details("012345678901")
# Search by Amazon ASINamazon_product=api.get_product_details("B08N5WRWNW")
# Search by product URLurl_product=api.get_product_details("https://www.amazon.com/dp/B08N5WRWNW")
# Search by model numbermodel_product=api.get_product_details("MQ023LL/A") # iPhone model number# Access product informationprint(f"📦 Product: {product.data.name}")
print(f"🏷️ Brand: {product.data.brand}")
print(f"📂 Category: {product.data.category}")
print(f"🔢 Product ID: {product.data.product_id}")
print(f"📷 Image: {product.data.image_url}")# Look up multiple products at onceidentifiers= [
"012345678901", # Barcode"B08N5WRWNW", # Amazon ASIN"https://www.target.com/p/example", # URL"MODEL-ABC123"# Model number
]
products=api.get_product_details_batch(identifiers)
forproductinproducts.data:
print(f"✅ Found: {product.name} by {product.brand}")
print(f" ID: {product.product_id}")
print(f" Category: {product.category}")
print("---")# Get product data in CSV format for easy processingproduct_csv=api.get_product_details("012345678901", format="csv")
# Process with pandasimportpandasaspdimportiodf=pd.read_csv(io.StringIO(product_csv.data))
print(df.head())# Get prices from all retailersoffers=api.get_current_offers("012345678901")
print(f"Found {len(offers.data)} offers:")
forofferinoffers.data:
print(f"🏪 {offer.retailer}: ${offer.price}")
print(f" 📦 Condition: {offer.condition}")
print(f" ✅ Available: {offer.availability}")
print(f" 🔗 Buy: {offer.url}")
ifoffer.shipping:
print(f" 🚚 Shipping: ${offer.shipping}")
print("---")# Get offers from specific retailersamazon_offers=api.get_current_offers("012345678901", retailer="amazon")
walmart_offers=api.get_current_offers("012345678901", retailer="walmart")
target_offers=api.get_current_offers("012345678901", retailer="target")
print("Amazon prices:")
forofferinamazon_offers.data:
print(f" ${offer.price} - {offer.condition}")# Get current offers for multiple productsproducts= ["012345678901", "B08N5WRWNW", "045496596439"]
batch_offers=api.get_current_offers_batch(products)
foridentifier, offersinbatch_offers.data.items():
best_price=min(offers, key=lambdax: x.price) ifofferselseNoneifbest_price:
print(f"{identifier}: Best price ${best_price.price} at {best_price.retailer}")
else:
print(f"{identifier}: No offers found")fromdatetimeimportdatetime, timedelta# Get 30 days of price historyend_date=datetime.now().strftime("%Y-%m-%d")
start_date= (datetime.now() -timedelta(days=30)).strftime("%Y-%m-%d")
history=api.get_price_history("012345678901", start_date, end_date)
forofferinhistory.data:
print(f"🏪 {offer.retailer}:")
print(f" 💰 Current price: ${offer.price}")
print(f" 📊 Historical points: {len(offer.price_history)}")
ifoffer.price_history:
prices= [point.priceforpointinoffer.price_history]
print(f" 📉 Lowest: ${min(prices)}")
print(f" 📈 Highest: ${max(prices)}")
print(f" 📊 Average: ${sum(prices) /len(prices):.2f}")
print("---")# Get price history from Amazon onlyamazon_history=api.get_price_history(
"012345678901", "2024-01-01", "2024-01-31",
retailer="amazon"
)
forofferinamazon_history.data:
print(f"Amazon price trends for {offer.retailer}:")
forpointinoffer.price_history[-10:]: # Last 10 data pointsprint(f" {point.date}: ${point.price} ({point.availability})")# Monitor daily across all retailersresult=api.schedule_product_monitoring("012345678901", "daily")
ifresult.data.get("scheduled"):
print("✅ Daily monitoring activated!")
# Monitor hourly at specific retailerresult=api.schedule_product_monitoring(
"012345678901", "hourly", retailer="amazon"
)
print(f"Amazon monitoring: {result.data}")# Schedule multiple products for monitoringproducts_to_monitor= [
"012345678901",
"B08N5WRWNW", "045496596439"
]
batch_result=api.schedule_product_monitoring_batch(products_to_monitor, "daily")
foriteminbatch_result.data:
ifitem.get('scheduled'):
print(f"✅ Monitoring activated for {item['identifier']}")
else:
print(f"❌ Failed to monitor {item['identifier']}")# View all monitored productsscheduled=api.get_scheduled_products()
print(f"📊 Currently monitoring {len(scheduled.data)} products:")
forproductinscheduled.data:
print(f"🔔 {product.identifier}")
print(f" 📅 Frequency: {product.frequency}")
print(f" 🏪 Retailer: {product.retaileror'All retailers'}")
print(f" 📅 Created: {product.created_at}")
ifproduct.last_refreshed:
print(f" 🔄 Last refresh: {product.last_refreshed}")
print("---")
# Remove products from monitoringapi.remove_product_from_schedule("012345678901")
print("🗑️ Removed from monitoring")
# Remove multiple productsapi.remove_products_from_schedule(["012345678901", "B08N5WRWNW"])
print("🗑️ Batch removal complete")# Check your API usageusage=api.get_usage()
print("📊 API Usage Summary:")
print(f"💳 Plan: {usage.data.plan_name}")
print(f"✅ Credits used: {usage.data.credits_used:,}")
print(f"🔋 Credits remaining: {usage.data.credits_remaining:,}")
print(f"📊 Total credits: {usage.data.credits_total:,}")
print(f"📅 Billing period: {usage.data.billing_period_start} to {usage.data.billing_period_end}")
# Calculate usage percentageusage_percent= (usage.data.credits_used/usage.data.credits_total) *100print(f"📈 Usage: {usage_percent:.1f}%")deffind_best_deals(identifier: str, max_results: int=5):
"""Find the best deals for a product across all retailers"""try:
# Get product infoproduct=api.get_product_details(identifier)
print(f"🔍 Searching deals for: {product.data.name}")
print(f"📦 Brand: {product.data.brand}")
print("="*50)
# Get all current offersoffers=api.get_current_offers(identifier)
ifnotoffers.data:
print("❌ No offers found")
return# Filter and sort offersavailable_offers= [
offerforofferinoffers.dataifoffer.availability=="in_stock"
]
ifnotavailable_offers:
print("❌ No in-stock offers found")
return# Sort by total cost (price + shipping)deftotal_cost(offer):
returnoffer.price+ (offer.shippingor0)
sorted_offers=sorted(available_offers, key=total_cost)[:max_results]
print(f"🏆 Top {len(sorted_offers)} Deals:")
fori, offerinenumerate(sorted_offers, 1):
total=total_cost(offer)
print(f"{i}. 🏪 {offer.retailer}")
print(f" 💰 Price: ${offer.price}")
ifoffer.shipping:
print(f" 🚚 Shipping: ${offer.shipping}")
print(f" 💳 Total: ${total}")
print(f" 📦 Condition: {offer.condition}")
print(f" 🔗 Buy now: {offer.url}")
print("---")
# Calculate savingsiflen(sorted_offers) >1:
cheapest=total_cost(sorted_offers[0])
most_expensive=total_cost(sorted_offers[-1])
savings=most_expensive-cheapestprint(f"💰 Potential savings: ${savings:.2f}")
exceptExceptionase:
print(f"❌ Error: {e}")
# Usagefind_best_deals("012345678901")importtimefromdatetimeimportdatetimeclassPriceAlertBot:
def__init__(self, api_client):
self.api=api_clientself.alerts= {} # identifier -> target_pricedefadd_alert(self, identifier: str, target_price: float):
"""Add a price alert for a product"""self.alerts[identifier] =target_price# Schedule monitoringself.api.schedule_product_monitoring(identifier, "daily")
print(f"🔔 Alert set: {identifier} @ ${target_price}")
defcheck_alerts(self):
"""Check all price alerts"""print(f"🔍 Checking {len(self.alerts)} price alerts...")
foridentifier, target_priceinself.alerts.items():
try:
offers=self.api.get_current_offers(identifier)
ifnotoffers.data:
continue# Find best available offerbest_offer=min(
[oforoinoffers.dataifo.availability=="in_stock"],
key=lambdax: x.price,
default=None
)
ifbest_offerandbest_offer.price<=target_price:
self.trigger_alert(identifier, best_offer, target_price)
exceptExceptionase:
print(f"❌ Error checking {identifier}: {e}")
deftrigger_alert(self, identifier: str, offer, target_price: float):
"""Trigger price alert notification"""product=self.api.get_product_details(identifier)
print("🚨"*10)
print("💰 PRICE ALERT TRIGGERED!")
print(f"📦 Product: {product.data.name}")
print(f"🎯 Target: ${target_price}")
print(f"💸 Current: ${offer.price} at {offer.retailer}")
print(f"✅ Savings: ${target_price-offer.price:.2f}")
print(f"🔗 Buy now: {offer.url}")
print("🚨"*10)
# Remove alert after triggeringdelself.alerts[identifier]
# Usagealert_bot=PriceAlertBot(api)
alert_bot.add_alert("012345678901", 199.99)
alert_bot.add_alert("B08N5WRWNW", 299.99)
# Run periodic checksalert_bot.check_alerts()importstatisticsfromcollectionsimportdefaultdictdefanalyze_market_trends(identifiers: list, days: int=30):
"""Comprehensive market analysis for multiple products"""fromdatetimeimportdatetime, timedeltaend_date=datetime.now().strftime("%Y-%m-%d")
start_date= (datetime.now() -timedelta(days=days)).strftime("%Y-%m-%d")
print(f"📊 Market Analysis Report ({days} days)")
print("="*50)
foridentifierinidentifiers:
try:
# Get product infoproduct=api.get_product_details(identifier)
print(f"\\n📦 {product.data.name}")
print(f"🏷️ {product.data.brand} | {product.data.category}")
print("-"*40)
# Get price historyhistory=api.get_price_history(identifier, start_date, end_date)
retailer_stats= {}
forofferinhistory.data:
ifnotoffer.price_history:
continueprices= [point.priceforpointinoffer.price_history]
retailer_stats[offer.retailer] = {
'current_price': offer.price,
'avg_price': statistics.mean(prices),
'min_price': min(prices),
'max_price': max(prices),
'volatility': statistics.stdev(prices) iflen(prices) >1else0,
'data_points': len(prices),
'trend': calculate_trend(prices)
}
# Display resultsifretailer_stats:
print("🏪 Retailer Analysis:")
forretailer, statsinsorted(retailer_stats.items()):
print(f" {retailer}:")
print(f" 💰 Current: ${stats['current_price']}")
print(f" 📊 Average: ${stats['avg_price']:.2f}")
print(f" 📉 Min: ${stats['min_price']} | 📈 Max: ${stats['max_price']}")
print(f" 📈 Trend: {stats['trend']}")
print(f" 📊 Data points: {stats['data_points']}")
# Find best valuebest_retailer=min(retailer_stats.items(), key=lambdax: x[1]['current_price'])
print(f"\\n🏆 Best Price: {best_retailer[0]} @ ${best_retailer[1]['current_price']}")
else:
print("❌ No price history available")
exceptExceptionase:
print(f"❌ Error analyzing {identifier}: {e}")
defcalculate_trend(prices: list) ->str:
"""Calculate price trend direction"""iflen(prices) <2:
return"Unknown"recent=prices[-7:] # Last weekolder=prices[:-7] # Everything elseifnotolder:
return"New"recent_avg=statistics.mean(recent)
older_avg=statistics.mean(older)
ifrecent_avg>older_avg*1.05: # 5% thresholdreturn"📈 Rising"elifrecent_avg<older_avg*0.95:
return"📉 Falling"else:
return"➡️ Stable"# Usageproducts_to_analyze= [
"012345678901",
"B08N5WRWNW",
"045496596439"
]
analyze_market_trends(products_to_analyze, days=60)defbulk_product_manager(csv_file_path: str):
"""Manage products from CSV file"""importcsvprint("📂 Loading products from CSV...")
products= []
withopen(csv_file_path, 'r') asfile:
reader=csv.DictReader(file)
forrowinreader:
products.append({
'identifier': row['identifier'],
'target_price': float(row.get('target_price', 0)),
'monitor': row.get('monitor', 'true').lower() =='true'
})
print(f"📊 Processing {len(products)} products...")
# Batch lookupidentifiers= [p['identifier'] forpinproducts]
try:
product_details=api.get_product_details_batch(identifiers)
current_offers=api.get_current_offers_batch(identifiers)
results= []
forproduct, detailsinzip(products, product_details.data):
offers=current_offers.data.get(product['identifier'], [])
best_price=min([o.priceforoinoffersifo.availability=="in_stock"], default=None)
result= {
'identifier': product['identifier'],
'name': details.name,
'brand': details.brand,
'target_price': product['target_price'],
'current_best_price': best_price,
'price_alert': best_price<=product['target_price'] ifbest_priceelseFalse,
'offers_count': len(offers)
}
results.append(result)
# Setup monitoring if requestedifproduct['monitor']:
api.schedule_product_monitoring(product['identifier'], "daily")
# Generate reportprint("\\n📊 Bulk Analysis Report:")
print("="*80)
forresultinresults:
status="🚨 ALERT"ifresult['price_alert'] else"📊 TRACKING"print(f"{status} | {result['name']} by {result['brand']}")
print(f" 🎯 Target: ${result['target_price']} | 💰 Current: ${result['current_best_price'] or'N/A'}")
print(f" 🏪 Offers: {result['offers_count']}")
print()
exceptExceptionase:
print(f"❌ Error processing bulk products: {e}")
# Usage# bulk_product_manager("my_products.csv")defexport_product_data(identifiers: list, format: str="json"):
"""Export product data in various formats"""importjsonimportcsvfromdatetimeimportdatetimetimestamp=datetime.now().strftime("%Y%m%d_%H%M%S")
ifformat.lower() =="json":
# Export as JSONproducts=api.get_product_details_batch(identifiers)
offers=api.get_current_offers_batch(identifiers)
export_data= {
"exported_at": datetime.now().isoformat(),
"products": []
}
forproductinproducts.data:
product_offers=offers.data.get(product.product_id, [])
export_data["products"].append({
"product": product.dict(),
"offers": [offer.dict() forofferinproduct_offers]
})
filename=f"shopsavvy_export_{timestamp}.json"withopen(filename, 'w') asf:
json.dump(export_data, f, indent=2)
print(f"✅ Exported {len(products.data)} products to {filename}")
elifformat.lower() =="csv":
# Export as CSVfilename=f"shopsavvy_export_{timestamp}.csv"withopen(filename, 'w', newline='') ascsvfile:
fieldnames= ['product_id', 'name', 'brand', 'category', 'barcode', 'retailer', 'price', 'availability', 'condition', 'url']
writer=csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
foridentifierinidentifiers:
try:
product=api.get_product_details(identifier)
offers=api.get_current_offers(identifier)
forofferinoffers.data:
writer.writerow({
'product_id': product.data.product_id,
'name': product.data.name,
'brand': product.data.brand,
'category': product.data.category,
'barcode': product.data.barcode,
'retailer': offer.retailer,
'price': offer.price,
'availability': offer.availability,
'condition': offer.condition,
'url': offer.url
})
exceptExceptionase:
print(f"❌ Error exporting {identifier}: {e}")
print(f"✅ Exported data to {filename}")
# Usageexport_product_data(["012345678901", "B08N5WRWNW"], format="json")
export_product_data(["012345678901", "B08N5WRWNW"], format="csv")fromshopsavvyimport (
APIError, AuthenticationError, RateLimitError, NotFoundError,
ValidationError,
TimeoutError,
NetworkError
)
defrobust_product_lookup(identifier: str):
"""Example of robust error handling"""try:
product=api.get_product_details(identifier)
offers=api.get_current_offers(identifier)
print(f"✅ Success: {product.data.name}")
print(f"💰 Found {len(offers.data)} offers")
returnproduct, offersexceptAuthenticationError:
print("❌ Authentication failed - check your API key")
print("🔑 Get your key at: https://shopsavvy.com/data/dashboard")
exceptNotFoundError:
print(f"❌ Product not found: {identifier}")
print("💡 Try a different identifier (barcode, ASIN, URL)")
exceptRateLimitError:
print("⏳ Rate limit exceeded - please slow down")
print("💡 Consider upgrading your plan for higher limits")
time.sleep(60) # Wait before retryingexceptValidationErrorase:
print(f"❌ Invalid request: {e}")
print("💡 Check your parameters and try again")
exceptTimeoutError:
print("⏱️ Request timeout - API might be slow")
print("💡 Try increasing timeout or retry later")
exceptNetworkErrorase:
print(f"🌐 Network error: {e}")
print("💡 Check your internet connection")
exceptAPIErrorase:
print(f"🚨 API Error: {e}")
print("💡 This might be a temporary issue")
returnNone, None# Usage with retry logicdeflookup_with_retry(identifier: str, max_retries: int=3):
"""Lookup with automatic retry on failures"""forattemptinrange(max_retries):
try:
returnapi.get_product_details(identifier)
except (TimeoutError, NetworkError) ase:
ifattempt<max_retries-1:
wait_time=2**attempt# Exponential backoffprint(f"⏳ Retry {attempt+1}/{max_retries} in {wait_time}s...")
time.sleep(wait_time)
else:
raiseeimporttimefromfunctoolsimportwrapsdefrate_limit(calls_per_second: float=10):
"""Decorator to rate limit function calls"""min_interval=1.0/calls_per_secondlast_called= [0.0]
defdecorator(func):
@wraps(func)defwrapper(*args, **kwargs):
elapsed=time.time() -last_called[0]
left_to_wait=min_interval-elapsedifleft_to_wait>0:
time.sleep(left_to_wait)
ret=func(*args, **kwargs)
last_called[0] =time.time()
returnretreturnwrapperreturndecorator# Rate-limited API calls@rate_limit(calls_per_second=5) # Max 5 calls per seconddefsafe_get_offers(identifier: str):
returnapi.get_current_offers(identifier)
# Batch processing with rate limitingdefprocess_products_safely(identifiers: list):
"""Process products with automatic rate limiting"""results= []
total=len(identifiers)
fori, identifierinenumerate(identifiers, 1):
print(f"🔄 Processing {i}/{total}: {identifier}")
try:
offers=safe_get_offers(identifier)
results.append((identifier, offers))
print(f" ✅ Found {len(offers.data)} offers")
exceptExceptionase:
print(f" ❌ Error: {e}")
results.append((identifier, None))
returnresultsimportosfromdataclassesimportdataclass@dataclassclassShopSavvySettings:
"""Application settings"""api_key: strtimeout: float=30.0max_retries: int=3rate_limit: float=10.0# calls per second@classmethoddeffrom_env(cls):
"""Load settings from environment variables"""api_key=os.getenv("SHOPSAVVY_API_KEY")
ifnotapi_key:
raiseValueError("SHOPSAVVY_API_KEY environment variable required")
returncls(
api_key=api_key,
timeout=float(os.getenv("SHOPSAVVY_TIMEOUT", "30.0")),
max_retries=int(os.getenv("SHOPSAVVY_MAX_RETRIES", "3")),
rate_limit=float(os.getenv("SHOPSAVVY_RATE_LIMIT", "10.0"))
)
# Usagesettings=ShopSavvySettings.from_env()
api=create_client(settings.api_key, timeout=settings.timeout)# Install development dependencies
pip install -e ".[dev]"# Run all tests
pytest
# Run with coverage
pytest --cov=shopsavvy
# Run specific test file
pytest tests/test_client.py
# Run with verbose output
pytest -v# Format code
black src tests
# Sort imports
isort src tests
# Type checking
mypy src
# Linting
flake8 src testsimportpytestfromunittest.mockimportMock, patchfromshopsavvyimportcreate_client, AuthenticationErrordeftest_client_creation():
"""Test client creation with valid API key"""api=create_client("ss_test_valid_key")
assertapiisnotNonedeftest_invalid_api_key():
"""Test invalid API key handling"""withpytest.raises(ValueError):
create_client("invalid_key_format")
@patch('shopsavvy.client.httpx.Client.request')deftest_product_lookup(mock_request):
"""Test product lookup with mocked response"""# Mock successful responsemock_response=Mock()
mock_response.status_code=200mock_response.is_success=Truemock_response.json.return_value= {
"success": True,
"data": {
"product_id": "12345",
"name": "Test Product",
"brand": "Test Brand"
}
}
mock_request.return_value=mock_response# Test the clientapi=create_client("ss_test_valid_key")
product=api.get_product_details("012345678901")
assertproduct.successisTrueassertproduct.data.name=="Test Product"FROM python:3.11-slim
WORKDIR /app
# Install dependenciesCOPY requirements.txt .
RUN pip install -r requirements.txt
# Copy applicationCOPY . .
# Set environment variablesENV SHOPSAVVY_API_KEY="your_api_key_here"ENV SHOPSAVVY_TIMEOUT="30.0"# Run applicationCMD ["python", "app.py"]importjsonimportosfromshopsavvyimportcreate_client# Initialize client outside handler for connection reuseapi=create_client(os.environ['SHOPSAVVY_API_KEY'])
deflambda_handler(event, context):
"""AWS Lambda handler for product lookup"""try:
identifier=event.get('identifier')
ifnotidentifier:
return {
'statusCode': 400,
'body': json.dumps({'error': 'identifier required'})
}
# Get product dataproduct=api.get_product_details(identifier)
offers=api.get_current_offers(identifier)
# Find best pricebest_offer=min(offers.data, key=lambdax: x.price) ifoffers.dataelseNoneresponse= {
'product': {
'name': product.data.name,
'brand': product.data.brand,
'category': product.data.category
},
'best_price': {
'price': best_offer.price,
'retailer': best_offer.retailer,
'url': best_offer.url
} ifbest_offerelseNone,
'total_offers': len(offers.data)
}
return {
'statusCode': 200,
'body': json.dumps(response)
}
exceptExceptionase:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}# Requiredexport SHOPSAVVY_API_KEY="ss_live_your_api_key_here"# Optionalexport SHOPSAVVY_TIMEOUT="30.0"export SHOPSAVVY_BASE_URL="https://api.shopsavvy.com/v1"export SHOPSAVVY_MAX_RETRIES="3"classEcommerceIntegration:
"""Integration with e-commerce platforms"""def__init__(self, api_key: str):
self.api=create_client(api_key)
defenrich_product_catalog(self, product_skus: list):
"""Enrich existing product catalog with market data"""enriched_products= []
forskuinproduct_skus:
try:
# Get competitive pricingoffers=self.api.get_current_offers(sku)
competitor_prices= [
offer.priceforofferinoffers.dataifoffer.retailer!="your-store"
]
enrichment= {
'sku': sku,
'competitor_count': len(competitor_prices),
'min_competitor_price': min(competitor_prices) ifcompetitor_priceselseNone,
'avg_competitor_price': sum(competitor_prices) /len(competitor_prices) ifcompetitor_priceselseNone,
'price_position': self.calculate_price_position(sku, competitor_prices)
}
enriched_products.append(enrichment)
exceptExceptionase:
print(f"❌ Error enriching {sku}: {e}")
returnenriched_productsdefcalculate_price_position(self, sku: str, competitor_prices: list) ->str:
"""Calculate where your price stands vs competitors"""ifnotcompetitor_prices:
return"no_competition"your_price=self.get_your_price(sku) # Your implementationifnotyour_price:
return"unknown"cheaper_count=sum(1forpriceincompetitor_pricesifprice<your_price)
total_competitors=len(competitor_prices)
ifcheaper_count==0:
return"most_expensive"elifcheaper_count==total_competitors:
return"cheapest"elifcheaper_count<total_competitors/3:
return"premium"elifcheaper_count>total_competitors*2/3:
return"budget"else:
return"competitive"classBusinessIntelligenceDashboard:
"""BI dashboard for retail insights"""def__init__(self, api_key: str):
self.api=create_client(api_key)
defgenerate_market_report(self, category: str, time_period: int=30):
"""Generate comprehensive market report"""fromdatetimeimportdatetime, timedelta# Get category products (you'd have your own product database)category_products=self.get_category_products(category)
report= {
'category': category,
'analysis_date': datetime.now().isoformat(),
'time_period_days': time_period,
'products_analyzed': len(category_products),
'insights': {}
}
# Analyze each productprice_trends= []
retailer_coverage=defaultdict(int)
availability_stats=defaultdict(int)
forproduct_idincategory_products:
try:
# Get current market stateoffers=self.api.get_current_offers(product_id)
forofferinoffers.data:
retailer_coverage[offer.retailer] +=1availability_stats[offer.availability] +=1# Get price trendsstart_date= (datetime.now() -timedelta(days=time_period)).strftime("%Y-%m-%d")
end_date=datetime.now().strftime("%Y-%m-%d")
history=self.api.get_price_history(product_id, start_date, end_date)
foroffer_historyinhistory.data:
ifoffer_history.price_history:
prices= [p.priceforpinoffer_history.price_history]
trend=self.calculate_trend_percentage(prices)
price_trends.append(trend)
exceptExceptionase:
print(f"❌ Error analyzing {product_id}: {e}")
# Compile insightsreport['insights'] = {
'avg_price_trend': sum(price_trends) /len(price_trends) ifprice_trendselse0,
'top_retailers': dict(sorted(retailer_coverage.items(), key=lambdax: x[1], reverse=True)[:10]),
'availability_breakdown': dict(availability_stats),
'market_volatility': statistics.stdev(price_trends) iflen(price_trends) >1else0
}
returnreportfromflaskimportFlask, jsonify, requestfromshopsavvyimportcreate_clientapp=Flask(__name__)
api=create_client(os.environ['SHOPSAVVY_API_KEY'])
@app.route('/api/product/scan', methods=['POST'])defscan_product():
"""Handle barcode scans from mobile app"""data=request.get_json()
barcode=data.get('barcode')
ifnotbarcode:
returnjsonify({'error': 'Barcode required'}), 400try:
# Get product detailsproduct=api.get_product_details(barcode)
# Get current offersoffers=api.get_current_offers(barcode)
# Find best dealsavailable_offers= [oforoinoffers.dataifo.availability=="in_stock"]
best_offer=min(available_offers, key=lambdax: x.price) ifavailable_offerselseNoneresponse= {
'product': {
'name': product.data.name,
'brand': product.data.brand,
'image_url': product.data.image_url,
'category': product.data.category
},
'pricing': {
'best_price': best_offer.priceifbest_offerelseNone,
'best_retailer': best_offer.retailerifbest_offerelseNone,
'buy_url': best_offer.urlifbest_offerelseNone,
'total_offers': len(available_offers),
'all_offers': [
{
'retailer': offer.retailer,
'price': offer.price,
'availability': offer.availability,
'condition': offer.condition,
'url': offer.url
}
forofferinavailable_offers[:5] # Top 5 offers
]
}
}
returnjsonify(response)
exceptExceptionase:
returnjsonify({'error': str(e)}), 500@app.route('/api/product/alerts', methods=['POST'])defcreate_price_alert():
"""Create price alert for mobile users"""data=request.get_json()
product_id=data.get('product_id')
target_price=data.get('target_price')
user_id=data.get('user_id') # Your user systemtry:
# Schedule monitoringresult=api.schedule_product_monitoring(product_id, "daily")
# Store alert in your database# store_price_alert(user_id, product_id, target_price)returnjsonify({
'success': True,
'message': 'Price alert created successfully',
'monitoring_active': result.data.get('scheduled', False)
})
exceptExceptionase:
returnjsonify({'error': str(e)}), 500if__name__=='__main__':
app.run(debug=True)We welcome contributions! See CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes with tests
- Run the test suite:
pytest - Submit a pull request
| Resource | Link | Description |
|---|---|---|
| 🌐 API Documentation | shopsavvy.com/data/documentation | Complete API reference |
| 📊 Dashboard | shopsavvy.com/data/dashboard | Manage your API keys and usage |
| 💬 Support | business@shopsavvy.com | Get help from our team |
| 🐛 Issues | GitHub Issues | Report bugs and request features |
| 📦 PyPI | pypi.org/project/shopsavvy-sdk | Python package repository |
| 📖 Changelog | GitHub Releases | Version history and updates |
This project is licensed under the MIT License - see the LICENSE file for details.
ShopSavvy has been helping shoppers save money since 2008. With over 40 million downloads and millions of active users, we're the most trusted name in price comparison and shopping intelligence.
Our Data API provides the same powerful product data and pricing intelligence that powers our consumer app, now available to developers and businesses worldwide.
- ✅ 13+ Years of e-commerce data expertise
- ✅ Millions of Products across thousands of retailers
- ✅ Real-Time Data updated continuously
- ✅ Enterprise Scale trusted by major brands
- ✅ Developer Friendly with comprehensive tools and support
🚀 Ready to get started?Get your API key and start building amazing e-commerce applications today!
💬 Need help? Contact us at business@shopsavvy.com or visit shopsavvy.com/data for more information.