Google Shopping search tool (#317)
This commit is contained in:
parent
f6765bed67
commit
c9ed5ce123
4 changed files with 285 additions and 0 deletions
|
|
@ -37,3 +37,13 @@ DEFAULT_GOOGLE_MAPS_TRAVEL_MODE = GoogleMapsTravelMode(
|
|||
YOUTUBE_MAX_DESCRIPTION_LENGTH = 500
|
||||
DEFAULT_YOUTUBE_SEARCH_LANGUAGE = os.getenv("ARCADE_YOUTUBE_SEARCH_LANGUAGE")
|
||||
DEFAULT_YOUTUBE_SEARCH_COUNTRY = os.getenv("ARCADE_YOUTUBE_SEARCH_COUNTRY")
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# Google Shopping default constants
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
DEFAULT_GOOGLE_SHOPPING_LANGUAGE = os.getenv(
|
||||
"ARCADE_GOOGLE_SHOPPING_LANGUAGE", DEFAULT_GOOGLE_LANGUAGE
|
||||
)
|
||||
DEFAULT_GOOGLE_SHOPPING_COUNTRY = os.getenv(
|
||||
"ARCADE_GOOGLE_SHOPPING_COUNTRY", DEFAULT_GOOGLE_COUNTRY
|
||||
)
|
||||
|
|
|
|||
|
|
@ -279,3 +279,191 @@ LANGUAGE_CODES = {
|
|||
"zh-cn": "Chinese (Simplified)",
|
||||
"zh-tw": "Chinese (Traditional)",
|
||||
}
|
||||
|
||||
|
||||
GOOGLE_DOMAIN_BY_COUNTRY_CODE = {
|
||||
"ad": "google.ad",
|
||||
"ae": "google.ae",
|
||||
"al": "google.al",
|
||||
"am": "google.am",
|
||||
"as": "google.as",
|
||||
"at": "google.at",
|
||||
"az": "google.az",
|
||||
"ba": "google.ba",
|
||||
"be": "google.be",
|
||||
"bf": "google.bf",
|
||||
"bg": "google.bg",
|
||||
"bi": "google.bi",
|
||||
"bj": "google.bj",
|
||||
"bs": "google.bs",
|
||||
"bt": "google.bt",
|
||||
"by": "google.by",
|
||||
"ca": "google.ca",
|
||||
"cg": "google.cg",
|
||||
"cf": "google.cf",
|
||||
"ch": "google.ch",
|
||||
"ci": "google.ci",
|
||||
"cl": "google.cl",
|
||||
"cm": "google.cm",
|
||||
"ao": "google.co.ao",
|
||||
"bw": "google.co.bw",
|
||||
"ck": "google.co.ck",
|
||||
"cr": "google.co.cr",
|
||||
"id": "google.co.id",
|
||||
"il": "google.co.il",
|
||||
"in": "google.co.in",
|
||||
"jp": "google.co.jp",
|
||||
"ke": "google.co.ke",
|
||||
"kr": "google.co.kr",
|
||||
"ls": "google.co.ls",
|
||||
"ma": "google.co.ma",
|
||||
"mz": "google.co.mz",
|
||||
"nz": "google.co.nz",
|
||||
"th": "google.co.th",
|
||||
"tz": "google.co.tz",
|
||||
"ug": "google.co.ug",
|
||||
"uk": "google.co.uk",
|
||||
"uz": "google.co.uz",
|
||||
"ve": "google.co.ve",
|
||||
"vi": "google.co.vi",
|
||||
"za": "google.co.za",
|
||||
"zm": "google.co.zm",
|
||||
"zw": "google.co.zw",
|
||||
"us": "google.com",
|
||||
"af": "google.com.af",
|
||||
"ag": "google.com.ag",
|
||||
"ai": "google.com.ai",
|
||||
"ar": "google.com.ar",
|
||||
"au": "google.com.au",
|
||||
"bd": "google.com.bd",
|
||||
"bh": "google.com.bh",
|
||||
"bn": "google.com.bn",
|
||||
"bo": "google.com.bo",
|
||||
"br": "google.com.br",
|
||||
"bz": "google.com.bz",
|
||||
"co": "google.com.co",
|
||||
"cu": "google.com.cu",
|
||||
"cy": "google.com.cy",
|
||||
"do": "google.com.do",
|
||||
"ec": "google.com.ec",
|
||||
"eg": "google.com.eg",
|
||||
"et": "google.com.et",
|
||||
"fj": "google.com.fj",
|
||||
"gh": "google.com.gh",
|
||||
"gi": "google.com.gi",
|
||||
"gt": "google.com.gt",
|
||||
"hk": "google.com.hk",
|
||||
"jm": "google.com.jm",
|
||||
"kh": "google.com.kh",
|
||||
"kw": "google.com.kw",
|
||||
"lb": "google.com.lb",
|
||||
"ly": "google.com.ly",
|
||||
"mm": "google.com.mm",
|
||||
"mt": "google.com.mt",
|
||||
"mx": "google.com.mx",
|
||||
"my": "google.com.my",
|
||||
"na": "google.com.na",
|
||||
"ng": "google.com.ng",
|
||||
"ni": "google.com.ni",
|
||||
"np": "google.com.np",
|
||||
"om": "google.com.om",
|
||||
"pa": "google.com.pa",
|
||||
"pe": "google.com.pe",
|
||||
"pg": "google.com.pg",
|
||||
"ph": "google.com.ph",
|
||||
"pk": "google.com.pk",
|
||||
"pr": "google.com.pr",
|
||||
"py": "google.com.py",
|
||||
"qa": "google.com.qa",
|
||||
"sa": "google.com.sa",
|
||||
"sb": "google.com.sb",
|
||||
"sg": "google.com.sg",
|
||||
"sl": "google.com.sl",
|
||||
"sv": "google.com.sv",
|
||||
"tj": "google.com.tj",
|
||||
"tr": "google.com.tr",
|
||||
"tw": "google.com.tw",
|
||||
"ua": "google.com.ua",
|
||||
"uy": "google.com.uy",
|
||||
"vc": "google.com.vc",
|
||||
"vn": "google.com.vn",
|
||||
"cv": "google.cv",
|
||||
"cz": "google.cz",
|
||||
"de": "google.de",
|
||||
"dj": "google.dj",
|
||||
"dk": "google.dk",
|
||||
"dm": "google.dm",
|
||||
"dz": "google.dz",
|
||||
"ee": "google.ee",
|
||||
"es": "google.es",
|
||||
"fi": "google.fi",
|
||||
"fm": "google.fm",
|
||||
"fr": "google.fr",
|
||||
"ga": "google.ga",
|
||||
"ge": "google.ge",
|
||||
"gl": "google.gl",
|
||||
"gm": "google.gm",
|
||||
"gp": "google.gp",
|
||||
"gr": "google.gr",
|
||||
"gy": "google.gy",
|
||||
"hn": "google.hn",
|
||||
"hr": "google.hr",
|
||||
"ht": "google.ht",
|
||||
"hu": "google.hu",
|
||||
"ie": "google.ie",
|
||||
"iq": "google.iq",
|
||||
"is": "google.is",
|
||||
"it": "google.it",
|
||||
"je": "google.je",
|
||||
"jo": "google.jo",
|
||||
"kg": "google.kg",
|
||||
"ki": "google.ki",
|
||||
"kz": "google.kz",
|
||||
"la": "google.la",
|
||||
"li": "google.li",
|
||||
"lk": "google.lk",
|
||||
"lt": "google.lt",
|
||||
"lu": "google.lu",
|
||||
"lv": "google.lv",
|
||||
"md": "google.md",
|
||||
"mg": "google.mg",
|
||||
"mk": "google.mk",
|
||||
"ml": "google.ml",
|
||||
"mn": "google.mn",
|
||||
"ms": "google.ms",
|
||||
"mu": "google.mu",
|
||||
"mv": "google.mv",
|
||||
"mw": "google.mw",
|
||||
"ne": "google.ne",
|
||||
"nl": "google.nl",
|
||||
"no": "google.no",
|
||||
"nr": "google.nr",
|
||||
"nu": "google.nu",
|
||||
"pl": "google.pl",
|
||||
"ps": "google.ps",
|
||||
"pt": "google.pt",
|
||||
"ro": "google.ro",
|
||||
"rs": "google.rs",
|
||||
"ru": "google.ru",
|
||||
"rw": "google.rw",
|
||||
"sc": "google.sc",
|
||||
"se": "google.se",
|
||||
"sh": "google.sh",
|
||||
"si": "google.si",
|
||||
"sk": "google.sk",
|
||||
"sm": "google.sm",
|
||||
"sn": "google.sn",
|
||||
"so": "google.so",
|
||||
"sr": "google.sr",
|
||||
"td": "google.td",
|
||||
"tg": "google.tg",
|
||||
"tk": "google.tk",
|
||||
"tl": "google.tl",
|
||||
"tm": "google.tm",
|
||||
"tn": "google.tn",
|
||||
"to": "google.to",
|
||||
"tt": "google.tt",
|
||||
"vg": "google.vg",
|
||||
"vu": "google.vu",
|
||||
"ws": "google.ws",
|
||||
}
|
||||
|
|
|
|||
66
toolkits/search/arcade_search/tools/google_shopping.py
Normal file
66
toolkits/search/arcade_search/tools/google_shopping.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
from typing import Annotated, Any, Optional
|
||||
|
||||
from arcade.sdk import ToolContext, tool
|
||||
from arcade.sdk.errors import ToolExecutionError
|
||||
|
||||
from arcade_search.constants import (
|
||||
DEFAULT_GOOGLE_SHOPPING_COUNTRY,
|
||||
DEFAULT_GOOGLE_SHOPPING_LANGUAGE,
|
||||
)
|
||||
from arcade_search.google_data import GOOGLE_DOMAIN_BY_COUNTRY_CODE
|
||||
from arcade_search.utils import (
|
||||
call_serpapi,
|
||||
extract_shopping_results,
|
||||
prepare_params,
|
||||
resolve_country_code,
|
||||
resolve_language_code,
|
||||
)
|
||||
|
||||
|
||||
@tool(requires_secrets=["SERP_API_KEY"])
|
||||
async def search_shopping_products(
|
||||
context: ToolContext,
|
||||
keywords: Annotated[
|
||||
str,
|
||||
"Keywords to search for products in Google Shopping. E.g. 'Apple iPhone'.",
|
||||
],
|
||||
country_code: Annotated[
|
||||
Optional[str],
|
||||
"2-character country code to search for products in Google Shopping. "
|
||||
f"E.g. 'us' (United States). Defaults to '{DEFAULT_GOOGLE_SHOPPING_COUNTRY or 'us'}'.",
|
||||
] = DEFAULT_GOOGLE_SHOPPING_COUNTRY,
|
||||
language_code: Annotated[
|
||||
Optional[str],
|
||||
"2-character language code to search for products on Google Shopping. E.g. 'en' (English). "
|
||||
f"Defaults to '{DEFAULT_GOOGLE_SHOPPING_LANGUAGE or 'en'}'.",
|
||||
] = DEFAULT_GOOGLE_SHOPPING_LANGUAGE,
|
||||
) -> Annotated[dict[str, list[dict[str, Any]]], "Products on Google Shopping."]:
|
||||
"""Search for products on Google Shopping related to a given query."""
|
||||
country_code = resolve_country_code(country_code, DEFAULT_GOOGLE_SHOPPING_COUNTRY)
|
||||
language_code = resolve_language_code(language_code, DEFAULT_GOOGLE_SHOPPING_LANGUAGE)
|
||||
|
||||
if not isinstance(country_code, str):
|
||||
country_code = "us"
|
||||
|
||||
if not isinstance(language_code, str):
|
||||
language_code = "en"
|
||||
|
||||
google_domain = GOOGLE_DOMAIN_BY_COUNTRY_CODE.get(country_code, "google.com")
|
||||
|
||||
params = prepare_params(
|
||||
"google_shopping",
|
||||
q=keywords,
|
||||
gl=country_code,
|
||||
hl=language_code,
|
||||
google_domain=google_domain,
|
||||
)
|
||||
|
||||
response = call_serpapi(context, params)
|
||||
|
||||
if response.get("error"):
|
||||
error_msg = response.get("error") or "Unknown Google Shopping Error"
|
||||
raise ToolExecutionError(error_msg)
|
||||
|
||||
return {
|
||||
"products": extract_shopping_results(response.get("shopping_results", [])),
|
||||
}
|
||||
|
|
@ -276,6 +276,27 @@ def extract_news_results(
|
|||
return news_results
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# Google Shopping utils
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
def extract_shopping_results(results: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
"title": result.get("title"),
|
||||
"direct_link": result.get("link"),
|
||||
"google_link": result.get("product_link"),
|
||||
"source": result.get("source"),
|
||||
"price": result.get("price"),
|
||||
"product_rating": result.get("rating"),
|
||||
"product_reviews": result.get("reviews"),
|
||||
"store_rating": result.get("store_rating"),
|
||||
"store_reviews": result.get("store_reviews"),
|
||||
"delivery": result.get("delivery"),
|
||||
}
|
||||
for result in results
|
||||
]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# Walmart utils
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue