diff options
Diffstat (limited to 'octopart/bom_quote.py')
-rw-r--r-- | octopart/bom_quote.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/octopart/bom_quote.py b/octopart/bom_quote.py new file mode 100644 index 0000000..9c7e087 --- /dev/null +++ b/octopart/bom_quote.py @@ -0,0 +1,85 @@ +# Section 1 +# Convert csv file into line items and queries +# This code assumes a file format similar to the one on the +# Arduino BOM +import csv + + +csv_file = open("arduino_bom.csv", "r") +csv_reader = csv.DictReader(csv_file) +line_items = [] +queries = [] +for line_item in csv_reader: + # Skip line items without part numbers and manufacturers + if not line_item['Part Number'] or not line_item['Manufacturer']: + continue + line_items.append(line_item) + queries.append({'mpn': line_item['Part Number'], + 'brand': line_item['Manufacturer'], + 'reference': len(line_items) - 1}) + + +# Section 2 +# Send queries to REST API for part matching. +import json +import urllib + + +results = [] +for i in range(0, len(queries), 20): + # Batch queries in groups of 20, query limit of + # parts match endpoint + batched_queries = queries[i: i + 20] + + url = 'http://octopart.com/api/v3/parts/match?queries=%s' \ + % urllib.quote(json.dumps(batched_queries)) + url += '&apikey=e3d61a07' + data = urllib.urlopen(url).read() + response = json.loads(data) + print response + + # Record results for analysis + results.extend(response['results']) + + +# Section 3 +# Analyze results sent back by Octopart API +from decimal import Decimal + + +print "Found %s line items in BOM." % len(line_items) +# Price BOM +hits = 0 +total_avg_price = 0 +for result in results: + line_item = line_items[result['reference']] + if len(result['items']) == 0: + print "Did not find match on line item %s" % line_item + continue + + # Get pricing from the first item for desired quantity + quantity = Decimal(line_items[result['reference']]['Qty']) + prices = [] + for offer in result['items'][0]['offers']: + if 'USD' not in offer['prices'].keys(): + continue + price = None + for price_tuple in offer['prices']['USD']: + # Find correct price break + if price_tuple[0] > quantity: + break + # Cast pricing string to Decimal for precision + # calculations + price = Decimal(price_tuple[1]) + if price is not None: + prices.append(price) + + if len(prices) == 0: + print "Did not find pricing on line item %s" % line_item + continue + avg_price = quantity * sum(prices) / len(prices) + total_avg_price += avg_price + hits += 1 + +print "Matched on %.2f of BOM, total average price is USD %.2f" % ( \ + hits / float(len(line_items)), total_avg_price) |