Spaces:
Sleeping
Sleeping
| from flask import Flask, jsonify, request, render_template | |
| import requests | |
| from flask_cors import CORS | |
| import os | |
| app = Flask(__name__) | |
| CORS(app) | |
| def search_products(search_term, sku): | |
| headers = { | |
| "accept": "*/*", | |
| "accept-language": "en-US,en;q=0.9,gu;q=0.8,ru;q=0.7,hi;q=0.6", | |
| "Authorization": "Bearer " + os.environ.get('APIKEY'), | |
| "cache-control": "no-cache", | |
| "content-type": "application/json", | |
| "origin": "https://bestbeauty1.retail.lightspeed.app", | |
| "pragma": "no-cache", | |
| "priority": "u=1, i", | |
| "referer": "https://bestbeauty1.retail.lightspeed.app", | |
| "sec-ch-ua": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"', | |
| "sec-ch-ua-mobile": "?0", | |
| "sec-ch-ua-platform": '"Windows"', | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "same-origin", | |
| "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36", | |
| } | |
| json_data = [ | |
| { | |
| "operationName": "Products", | |
| "variables": { | |
| "filter": { | |
| "excludeChildren": True, | |
| "include": {}, | |
| "exclude": {}, | |
| "includeGiftCard": True, | |
| "searchTerm": search_term, | |
| "customMode": "RETURN_ROOT_ONLY", | |
| }, | |
| "first": 25, | |
| "orderBy": { | |
| "direction": "ASC", | |
| "field": "NAME", | |
| }, | |
| }, | |
| "query": "fragment Badge on Product {\n isActive\n sku\n name\n handle\n hasVariants\n variantParentID\n variantName\n isComposite\n variantCount\n imageThumbnailURL\n skuImageThumbnailURL\n __typename\n}\nfragment ProductSummary on Product {\n id\n ...Badge\n __typename\n}\nfragment ProductData on Product {\n ...ProductSummary\n __typename\n}\nquery Products($after: String, $filter: ProductFilter, $first: Int, $orderBy: ProductOrder!) {\n products(after: $after, filter: $filter, first: $first, orderBy: $orderBy) {\n products {\n ...ProductData\n __typename\n }\n __typename\n }\n}", | |
| } | |
| ] | |
| try: | |
| response = requests.post( | |
| "https://bestbeauty1.retail.lightspeed.app/api/graphql", | |
| headers=headers, | |
| json=json_data, | |
| ) | |
| products = response.json()[0]["data"]["products"]["products"] | |
| if len(products) == 1: | |
| return products[0] | |
| else: | |
| finalProduct = "" | |
| for product in products: | |
| # if product["handle"].replace("--","-").replace("--","-").replace("--","-") == search_term: | |
| # finalProduct = product | |
| # break | |
| if product["sku"] == sku: | |
| finalProduct = product | |
| break | |
| if finalProduct == "": | |
| finalProduct = products[0] if products else {} | |
| return finalProduct | |
| except Exception as e: | |
| return {"error": str(e)} | |
| def get_product_variants(product_id): | |
| headers = { | |
| "accept": "*/*", | |
| "accept-language": "en-US,en;q=0.9,gu;q=0.8,ru;q=0.7,hi;q=0.6", | |
| "Authorization": "Bearer " + os.environ.get('APIKEY'), | |
| "cache-control": "no-cache", | |
| "content-type": "application/json", | |
| "origin": "https://bestbeauty1.retail.lightspeed.app", | |
| "pragma": "no-cache", | |
| "priority": "u=1, i", | |
| "referer": "https://bestbeauty1.retail.lightspeed.app", | |
| "sec-ch-ua": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"', | |
| "sec-ch-ua-mobile": "?0", | |
| "sec-ch-ua-platform": '"Windows"', | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "same-origin", | |
| "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36", | |
| } | |
| json_data = [ | |
| { | |
| "operationName": "Variants", | |
| "variables": {"variantParentID": product_id}, | |
| "query": "fragment Badge on Product {\n isActive\n sku\n name\n hasVariants\n variantParentID\n variantName\n isComposite\n variantCount\n imageThumbnailURL\n skuImageThumbnailURL\n __typename\n}\nfragment InventoryLevels on Product {\n inventoryLevels {\n locationID\n quantity\n inboundLevels {\n hasInboundOrders\n __typename\n }\n __typename\n }\n __typename\n}\nquery Variants($variantParentID: String!) {\n products(\n filter: {include: {variantParentIDs: [$variantParentID]}}\n orderBy: {direction: ASC, field: BUTTON_ORDER}\n ) {\n products {\n id\n ...Badge\n ...InventoryLevels\n __typename\n }\n __typename\n }\n}", | |
| } | |
| ] | |
| try: | |
| response = requests.post( | |
| "https://bestbeauty1.retail.lightspeed.app/api/graphql", | |
| headers=headers, | |
| json=json_data, | |
| ) | |
| return response.json()[0]["data"]["products"]["products"] | |
| except Exception as e: | |
| return {"error": str(e)} | |
| def search(): | |
| search_term = request.args.get("q", "") | |
| sku = request.args.get("sku", "") | |
| if not search_term: | |
| return jsonify({"error": "Search term is required"}), 400 | |
| product = search_products(search_term, sku) | |
| if product["variantCount"] > 0: | |
| variants = get_product_variants(product["id"]) if "id" in product else {} | |
| product["variants"] = variants | |
| else: | |
| product["variants"] = [] | |
| return jsonify(product) | |
| def get_product_list(after=None, before=None): | |
| base_url = "https://bestbeauty1.retail.lightspeed.app/api/2.0/products" | |
| params = {"deleted": "false"} | |
| if after: | |
| params["after"] = after | |
| if before: | |
| params["before"] = before | |
| headers = { | |
| "accept": "application/json", | |
| "authorization": "Bearer " + os.environ.get('APIKEY'), | |
| } | |
| try: | |
| response = requests.get(base_url, headers=headers, params=params) | |
| return response.json() | |
| except Exception as e: | |
| return {"error": str(e)} | |
| def list_products(): | |
| after = request.args.get("after", None) | |
| before = request.args.get("before", None) | |
| products_data = get_product_list(after, before) | |
| # Filter out products without images | |
| products = [p for p in products_data.get("data", []) | |
| if p.get("image_url") and | |
| not p["image_url"].endswith("no-image-white-standard.png")] | |
| version_info = products_data.get("version", {}) | |
| return render_template( | |
| "index.html", | |
| products=products, | |
| pagination={ | |
| "next_page": version_info.get("max"), | |
| "prev_page": version_info.get("min") | |
| } | |
| ) | |
| if __name__ == "__main__": | |
| app.run(debug=True, host="0.0.0.0", port=7860) | |