mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-20 23:21:06 +02:00
feat(amazon): add scrape capability schema, executor, definition
This commit is contained in:
parent
b5b700c853
commit
3e0caa2027
5 changed files with 150 additions and 0 deletions
59
surfsense_backend/app/capabilities/amazon/scrape/executor.py
Normal file
59
surfsense_backend/app/capabilities/amazon/scrape/executor.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"""Executor for the ``amazon.scrape`` capability."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
from app.capabilities.amazon.scrape.schemas import (
|
||||
MAX_AMAZON_RESULTS,
|
||||
ScrapeInput,
|
||||
ScrapeOutput,
|
||||
)
|
||||
from app.capabilities.core import Executor
|
||||
from app.capabilities.core.progress import emit_progress
|
||||
from app.proprietary.platforms.amazon import AmazonScrapeInput, scrape_products
|
||||
|
||||
ScrapeFn = Callable[..., Awaitable[list[dict]]]
|
||||
|
||||
|
||||
def build_scrape_executor(scrape_fn: ScrapeFn | None = None) -> Executor:
|
||||
"""Bind the capability input mapping to a replaceable scraper function."""
|
||||
scrape_fn = scrape_fn or scrape_products
|
||||
|
||||
async def execute(payload: ScrapeInput) -> ScrapeOutput:
|
||||
search_urls = [
|
||||
f"https://{payload.domain}/s?k={quote_plus(term)}"
|
||||
for term in payload.search_terms
|
||||
]
|
||||
input_model = AmazonScrapeInput(
|
||||
categoryOrProductUrls=[
|
||||
{"url": url} for url in [*payload.urls, *search_urls]
|
||||
],
|
||||
maxItemsPerStartUrl=payload.max_items,
|
||||
language=payload.language,
|
||||
countryCode=payload.country_code,
|
||||
zipCode=payload.zip_code,
|
||||
scrapeProductDetails=payload.include_details,
|
||||
maxOffers=payload.max_offers,
|
||||
scrapeSellers=payload.include_sellers,
|
||||
maxProductVariantsAsSeparateResults=payload.max_variants,
|
||||
scrapeProductVariantPrices=payload.include_variant_prices,
|
||||
)
|
||||
emit_progress(
|
||||
"starting",
|
||||
"Scraping Amazon products",
|
||||
total=payload.estimated_units,
|
||||
unit="product",
|
||||
)
|
||||
items = await scrape_fn(input_model, limit=MAX_AMAZON_RESULTS)
|
||||
emit_progress(
|
||||
"done",
|
||||
f"Scraped {sum('error' not in item for item in items)} product(s)",
|
||||
current=len(items),
|
||||
total=payload.estimated_units,
|
||||
unit="product",
|
||||
)
|
||||
return ScrapeOutput(items=items)
|
||||
|
||||
return execute
|
||||
Loading…
Add table
Add a link
Reference in a new issue