From ae0150a61a8830276d4bbfc1a80dff5de9dc5b35 Mon Sep 17 00:00:00 2001 From: scrapebadger-bot Date: Fri, 16 Oct 2026 22:48:35 +0000 Subject: [PATCH 1/2] chore: regenerate SDK from OpenAPI spec --- src/scrapebadger/aliexpress/__init__.py | 5 + src/scrapebadger/aliexpress/client.py | 158 ++++++++++++++++++ src/scrapebadger/asos/__init__.py | 5 + src/scrapebadger/asos/client.py | 209 ++++++++++++++++++++++++ src/scrapebadger/bestbuy/__init__.py | 5 + src/scrapebadger/bestbuy/client.py | 115 +++++++++++++ src/scrapebadger/client.py | 45 +++++ src/scrapebadger/etsy/__init__.py | 5 + src/scrapebadger/etsy/client.py | 190 +++++++++++++++++++++ src/scrapebadger/facebook/client.py | 8 +- src/scrapebadger/gumtree/client.py | 139 ++++++++++++++++ src/scrapebadger/naver/client.py | 141 +++++++++++++++- src/scrapebadger/tiktok/client.py | 94 ++++++++++- 13 files changed, 1110 insertions(+), 9 deletions(-) create mode 100644 src/scrapebadger/aliexpress/__init__.py create mode 100644 src/scrapebadger/aliexpress/client.py create mode 100644 src/scrapebadger/asos/__init__.py create mode 100644 src/scrapebadger/asos/client.py create mode 100644 src/scrapebadger/bestbuy/__init__.py create mode 100644 src/scrapebadger/bestbuy/client.py create mode 100644 src/scrapebadger/etsy/__init__.py create mode 100644 src/scrapebadger/etsy/client.py diff --git a/src/scrapebadger/aliexpress/__init__.py b/src/scrapebadger/aliexpress/__init__.py new file mode 100644 index 0000000..46f22e8 --- /dev/null +++ b/src/scrapebadger/aliexpress/__init__.py @@ -0,0 +1,5 @@ +"""aliexpress API client.""" + +from scrapebadger.aliexpress.client import AliexpressClient + +__all__ = ["AliexpressClient"] diff --git a/src/scrapebadger/aliexpress/client.py b/src/scrapebadger/aliexpress/client.py new file mode 100644 index 0000000..fdc394c --- /dev/null +++ b/src/scrapebadger/aliexpress/client.py @@ -0,0 +1,158 @@ +"""Aliexpress API client. # --- BEGIN generated by sdk/codegen/facade — do not edit ---""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapebadger._internal.client import BaseClient + + +class AliexpressClient: + """Client for all Aliexpress API operations. (Generated from the OpenAPI spec.)""" + + def __init__(self, client: BaseClient) -> None: + self._client = client + + async def get_search_suggestions( + self, *, query: str, country: str = "US", language: str = "en" + ) -> dict[str, Any]: + """Get search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"query": query, "country": country, "language": language}.items() + if v is not None + } + return await self._client.get("/v1/aliexpress/autocomplete", params=params) + + async def get_category_navigation(self) -> dict[str, Any]: + """Get category navigation. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/aliexpress/categories") + + async def get_product_detail( + self, + product_id: str, + *, + country: str = "US", + currency: str = "USD", + language: str = "en_US", + ) -> dict[str, Any]: + """Get product detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"country": country, "currency": currency, "language": language}.items() + if v is not None + } + return await self._client.get(f"/v1/aliexpress/products/{product_id}", params=params) + + async def get_product_reviews( + self, product_id: str, *, page: int = 1, page_size: int = 10, sort: str = "complex_default" + ) -> dict[str, Any]: + """Get product reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"page": page, "page_size": page_size, "sort": sort}.items() + if v is not None + } + return await self._client.get( + f"/v1/aliexpress/products/{product_id}/reviews", params=params + ) + + async def search_products( + self, + *, + query: str, + page: int = 1, + country: str = "US", + currency: str = "USD", + language: str = "en", + sort: str = "default", + min_price: str | None = None, + max_price: str | None = None, + ) -> dict[str, Any]: + """Search products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "page": page, + "country": country, + "currency": currency, + "language": language, + "sort": sort, + "min_price": min_price, + "max_price": max_price, + }.items() + if v is not None + } + return await self._client.get("/v1/aliexpress/search", params=params) + + async def get_store_profile( + self, store_id: str, *, country: str = "US", currency: str = "USD", language: str = "en" + ) -> dict[str, Any]: + """Get store profile. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"country": country, "currency": currency, "language": language}.items() + if v is not None + } + return await self._client.get(f"/v1/aliexpress/stores/{store_id}", params=params) + + async def get_store_product_categories( + self, store_id: str, *, country: str = "US" + ) -> dict[str, Any]: + """Get store product categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"country": country}.items() if v is not None} + return await self._client.get(f"/v1/aliexpress/stores/{store_id}/categories", params=params) + + async def get_store_products( + self, + store_id: str, + *, + page: int = 1, + page_size: int = 24, + country: str = "US", + currency: str = "USD", + language: str = "en", + query: str = "", + sort: str = "bestmatch_sort", + ) -> dict[str, Any]: + """Get store products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "page": page, + "page_size": page_size, + "country": country, + "currency": currency, + "language": language, + "query": query, + "sort": sort, + }.items() + if v is not None + } + return await self._client.get(f"/v1/aliexpress/stores/{store_id}/products", params=params) diff --git a/src/scrapebadger/asos/__init__.py b/src/scrapebadger/asos/__init__.py new file mode 100644 index 0000000..78b7463 --- /dev/null +++ b/src/scrapebadger/asos/__init__.py @@ -0,0 +1,5 @@ +"""asos API client.""" + +from scrapebadger.asos.client import AsosClient + +__all__ = ["AsosClient"] diff --git a/src/scrapebadger/asos/client.py b/src/scrapebadger/asos/client.py new file mode 100644 index 0000000..e3aa377 --- /dev/null +++ b/src/scrapebadger/asos/client.py @@ -0,0 +1,209 @@ +"""Asos API client. # --- BEGIN generated by sdk/codegen/facade — do not edit ---""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapebadger._internal.client import BaseClient + + +class AsosClient: + """Client for all Asos API operations. (Generated from the OpenAPI spec.)""" + + def __init__(self, client: BaseClient) -> None: + self._client = client + + async def search_suggestions( + self, + *, + query: str, + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """Search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/asos/autocomplete", params=params) + + async def list_categories( + self, + *, + gender: str = "men", + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """List categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "gender": gender, + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/asos/categories", params=params) + + async def list_search_filters( + self, + *, + query: str | None = None, + category_id: str | None = None, + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """List search filters. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "category_id": category_id, + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/asos/filters", params=params) + + async def list_markets(self) -> dict[str, Any]: + """List markets. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/asos/markets") + + async def get_product_detail( + self, + product_id: str, + *, + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """Get product detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get(f"/v1/asos/products/{product_id}", params=params) + + async def search_products( + self, + *, + query: str | None = None, + category_id: str | None = None, + offset: int = 0, + limit: int = 48, + sort: str = "recommended", + brand: str | None = None, + colour: str | None = None, + size: str | None = None, + min_price: str | None = None, + max_price: str | None = None, + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """Search products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "category_id": category_id, + "offset": offset, + "limit": limit, + "sort": sort, + "brand": brand, + "colour": colour, + "size": size, + "min_price": min_price, + "max_price": max_price, + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/asos/search", params=params) + + async def get_stock_and_prices( + self, + *, + product_ids: str, + market: str = "uk", + store: str | None = None, + country: str | None = None, + currency: str | None = None, + language: str | None = None, + ) -> dict[str, Any]: + """Get stock and prices. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "product_ids": product_ids, + "market": market, + "store": store, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/asos/stock-price", params=params) diff --git a/src/scrapebadger/bestbuy/__init__.py b/src/scrapebadger/bestbuy/__init__.py new file mode 100644 index 0000000..565dcec --- /dev/null +++ b/src/scrapebadger/bestbuy/__init__.py @@ -0,0 +1,5 @@ +"""bestbuy API client.""" + +from scrapebadger.bestbuy.client import BestbuyClient + +__all__ = ["BestbuyClient"] diff --git a/src/scrapebadger/bestbuy/client.py b/src/scrapebadger/bestbuy/client.py new file mode 100644 index 0000000..c7b90e9 --- /dev/null +++ b/src/scrapebadger/bestbuy/client.py @@ -0,0 +1,115 @@ +"""Bestbuy API client. # --- BEGIN generated by sdk/codegen/facade — do not edit ---""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapebadger._internal.client import BaseClient + + +class BestbuyClient: + """Client for all Bestbuy API operations. (Generated from the OpenAPI spec.)""" + + def __init__(self, client: BaseClient) -> None: + self._client = client + + async def get_search_suggestions(self, *, query: str) -> dict[str, Any]: + """Get search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query}.items() if v is not None} + return await self._client.get("/v1/bestbuy/autocomplete", params=params) + + async def get_categories(self, *, query: str = "laptop") -> dict[str, Any]: + """Get categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query}.items() if v is not None} + return await self._client.get("/v1/bestbuy/categories", params=params) + + async def browse_a_category(self, *, category_id: str, page: int = 1) -> dict[str, Any]: + """Browse a category. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"category_id": category_id, "page": page}.items() if v is not None + } + return await self._client.get("/v1/bestbuy/category", params=params) + + async def get_laptop_and_computer_deals(self, *, page: int = 1) -> dict[str, Any]: + """Get laptop and computer deals. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"page": page}.items() if v is not None} + return await self._client.get("/v1/bestbuy/deals", params=params) + + async def list_supported_markets(self) -> dict[str, Any]: + """List supported markets. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/bestbuy/markets") + + async def get_product_detail(self, sku: str) -> dict[str, Any]: + """Get product detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get(f"/v1/bestbuy/products/{sku}") + + async def get_product_availability( + self, sku: str, *, zip_code: str, store_id: str = "7" + ) -> dict[str, Any]: + """Get product availability. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"zip_code": zip_code, "store_id": store_id}.items() if v is not None + } + return await self._client.get(f"/v1/bestbuy/products/{sku}/availability", params=params) + + async def get_product_questions( + self, sku: str, *, page: int = 1, page_size: int = 10, query: str = "" + ) -> dict[str, Any]: + """Get product questions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"page": page, "page_size": page_size, "query": query}.items() + if v is not None + } + return await self._client.get(f"/v1/bestbuy/products/{sku}/questions", params=params) + + async def get_product_reviews( + self, sku: str, *, page: int = 1, page_size: int = 10, sort: str = "MOST_RECENT" + ) -> dict[str, Any]: + """Get product reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"page": page, "page_size": page_size, "sort": sort}.items() + if v is not None + } + return await self._client.get(f"/v1/bestbuy/products/{sku}/reviews", params=params) + + async def search_products( + self, *, query: str, page: int = 1, sort: str = "best_match" + ) -> dict[str, Any]: + """Search products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"query": query, "page": page, "sort": sort}.items() if v is not None + } + return await self._client.get("/v1/bestbuy/search", params=params) diff --git a/src/scrapebadger/client.py b/src/scrapebadger/client.py index f6ddac2..40706a8 100644 --- a/src/scrapebadger/client.py +++ b/src/scrapebadger/client.py @@ -11,16 +11,20 @@ from scrapebadger._internal.config import ClientConfig from scrapebadger.account.client import AccountClient from scrapebadger.airbnb.client import AirbnbClient +from scrapebadger.aliexpress.client import AliexpressClient from scrapebadger.amazon.client import AmazonClient from scrapebadger.apartments.client import ApartmentsClient from scrapebadger.app_store.client import AppStoreClient +from scrapebadger.asos.client import AsosClient from scrapebadger.baidu.client import BaiduClient +from scrapebadger.bestbuy.client import BestbuyClient from scrapebadger.bing.client import BingClient from scrapebadger.booking.client import BookingClient from scrapebadger.chatgpt.client import ChatGPTClient from scrapebadger.depop.client import DepopClient from scrapebadger.duckduckgo.client import DuckDuckGoClient from scrapebadger.ebay.client import EbayClient +from scrapebadger.etsy.client import EtsyClient from scrapebadger.facebook.client import FacebookClient from scrapebadger.gemini.client import GeminiClient from scrapebadger.google.client import GoogleClient @@ -37,6 +41,7 @@ from scrapebadger.realtor.client import RealtorClient from scrapebadger.reddit.client import RedditClient from scrapebadger.redfin.client import RedfinClient +from scrapebadger.target.client import TargetClient from scrapebadger.tiktok.client import TikTokClient from scrapebadger.twitter.client import TwitterClient from scrapebadger.vinted.client import VintedClient @@ -152,15 +157,19 @@ def __init__( self._idealista: IdealistaClient | None = None self._reddit: RedditClient | None = None self._redfin: RedfinClient | None = None + self._target: TargetClient | None = None self._apartments: ApartmentsClient | None = None self._app_store: AppStoreClient | None = None + self._asos: AsosClient | None = None self._depop: DepopClient | None = None self._wallapop: WallapopClient | None = None self._linkedin: LinkedInClient | None = None self._account: AccountClient | None = None self._airbnb: AirbnbClient | None = None + self._aliexpress: AliexpressClient | None = None self._amazon: AmazonClient | None = None self._ebay: EbayClient | None = None + self._etsy: EtsyClient | None = None self._facebook: FacebookClient | None = None self._youtube: YoutubeClient | None = None self._tiktok: TikTokClient | None = None @@ -177,6 +186,7 @@ def __init__( self._gumtree: GumtreeClient | None = None self._duckduckgo: DuckDuckGoClient | None = None self._baidu: BaiduClient | None = None + self._bestbuy: BestbuyClient | None = None self._bing: BingClient | None = None self._booking: BookingClient | None = None self._yahoo: YahooClient | None = None @@ -993,3 +1003,38 @@ def naver(self) -> NaverClient: if self._naver is None: self._naver = NaverClient(self._base_client) return self._naver + + @property + def aliexpress(self) -> AliexpressClient: + """Access Aliexpress API operations. (Generated from the OpenAPI spec.)""" + if self._aliexpress is None: + self._aliexpress = AliexpressClient(self._base_client) + return self._aliexpress + + @property + def asos(self) -> AsosClient: + """Access Asos API operations. (Generated from the OpenAPI spec.)""" + if self._asos is None: + self._asos = AsosClient(self._base_client) + return self._asos + + @property + def bestbuy(self) -> BestbuyClient: + """Access Bestbuy API operations. (Generated from the OpenAPI spec.)""" + if self._bestbuy is None: + self._bestbuy = BestbuyClient(self._base_client) + return self._bestbuy + + @property + def etsy(self) -> EtsyClient: + """Access Etsy API operations. (Generated from the OpenAPI spec.)""" + if self._etsy is None: + self._etsy = EtsyClient(self._base_client) + return self._etsy + + @property + def target(self) -> TargetClient: + """Access Target API operations. (Generated from the OpenAPI spec.)""" + if self._target is None: + self._target = TargetClient(self._base_client) + return self._target diff --git a/src/scrapebadger/etsy/__init__.py b/src/scrapebadger/etsy/__init__.py new file mode 100644 index 0000000..c5173b0 --- /dev/null +++ b/src/scrapebadger/etsy/__init__.py @@ -0,0 +1,5 @@ +"""etsy API client.""" + +from scrapebadger.etsy.client import EtsyClient + +__all__ = ["EtsyClient"] diff --git a/src/scrapebadger/etsy/client.py b/src/scrapebadger/etsy/client.py new file mode 100644 index 0000000..1e8ac71 --- /dev/null +++ b/src/scrapebadger/etsy/client.py @@ -0,0 +1,190 @@ +"""Etsy API client. # --- BEGIN generated by sdk/codegen/facade — do not edit ---""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapebadger._internal.client import BaseClient + + +class EtsyClient: + """Client for all Etsy API operations. (Generated from the OpenAPI spec.)""" + + def __init__(self, client: BaseClient) -> None: + self._client = client + + async def get_search_suggestions( + self, *, query: str, country: str = "US", currency: str = "USD", language: str = "en-US" + ) -> dict[str, Any]: + """Get search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get("/v1/etsy/autocomplete", params=params) + + async def get_categories( + self, *, country: str = "US", currency: str = "USD", language: str = "en-US" + ) -> dict[str, Any]: + """Get categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"country": country, "currency": currency, "language": language}.items() + if v is not None + } + return await self._client.get("/v1/etsy/categories", params=params) + + async def get_listing_detail( + self, + listing_id: str, + *, + country: str = "US", + currency: str = "USD", + language: str = "en-US", + ) -> dict[str, Any]: + """Get listing detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"country": country, "currency": currency, "language": language}.items() + if v is not None + } + return await self._client.get(f"/v1/etsy/listings/{listing_id}", params=params) + + async def get_listing_reviews( + self, + listing_id: str, + *, + page: int = 1, + sort: str = "Relevancy", + country: str = "US", + currency: str = "USD", + language: str = "en-US", + ) -> dict[str, Any]: + """Get listing reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "page": page, + "sort": sort, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get(f"/v1/etsy/listings/{listing_id}/reviews", params=params) + + async def search_listings( + self, + *, + query: str, + page: int = 1, + country: str = "US", + currency: str = "USD", + language: str = "en-US", + sort: str = "most_relevant", + min_price: str | None = None, + max_price: str | None = None, + ) -> dict[str, Any]: + """Search listings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "page": page, + "country": country, + "currency": currency, + "language": language, + "sort": sort, + "min_price": min_price, + "max_price": max_price, + }.items() + if v is not None + } + return await self._client.get("/v1/etsy/search", params=params) + + async def get_shop_profile( + self, shop_name: str, *, country: str = "US", currency: str = "USD", language: str = "en-US" + ) -> dict[str, Any]: + """Get shop profile. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"country": country, "currency": currency, "language": language}.items() + if v is not None + } + return await self._client.get(f"/v1/etsy/shops/{shop_name}", params=params) + + async def get_shop_listings( + self, + shop_name: str, + *, + page: int = 1, + country: str = "US", + currency: str = "USD", + language: str = "en-US", + ) -> dict[str, Any]: + """Get shop listings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "page": page, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get(f"/v1/etsy/shops/{shop_name}/listings", params=params) + + async def get_shop_reviews( + self, + shop_name: str, + *, + page: int = 1, + country: str = "US", + currency: str = "USD", + language: str = "en-US", + ) -> dict[str, Any]: + """Get shop reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "page": page, + "country": country, + "currency": currency, + "language": language, + }.items() + if v is not None + } + return await self._client.get(f"/v1/etsy/shops/{shop_name}/reviews", params=params) diff --git a/src/scrapebadger/facebook/client.py b/src/scrapebadger/facebook/client.py index 8d7e538..3d1ed57 100644 --- a/src/scrapebadger/facebook/client.py +++ b/src/scrapebadger/facebook/client.py @@ -74,13 +74,9 @@ async def get_group_detail(self, group_id: str) -> dict[str, Any]: return await self._client.get(f"/v1/facebook/groups/{group_id}") async def get_group_posts( - self, group_id: str, *, after: str | None = None, sort: str | None = None + self, group_id: str, *, after: str | None = None, sort: str = "newest" ) -> dict[str, Any]: - """Get a public group's post feed, 3 posts per page. - - ``sort`` is ``"newest"`` (newest first by post time, the API default) or - ``"relevance"`` (Facebook's top-posts ranking). Follow ``end_cursor`` as - ``after`` while ``has_next_page`` for older posts, keeping the same sort. + """Get group posts. Generated from the OpenAPI spec; returns the raw response dict. """ diff --git a/src/scrapebadger/gumtree/client.py b/src/scrapebadger/gumtree/client.py index 4ba50fb..6a0be78 100644 --- a/src/scrapebadger/gumtree/client.py +++ b/src/scrapebadger/gumtree/client.py @@ -361,3 +361,142 @@ async def list_markets(self) -> MarketsResponse: """ response = await self._client.get("/v1/gumtree/markets") return MarketsResponse.model_validate(response) + + # --- BEGIN generated by sdk/codegen/facade — do not edit --- + + async def search_suggestions(self, *, query: str, market: str = "uk") -> dict[str, Any]: + """Search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query, "market": market}.items() if v is not None} + return await self._client.get("/v1/gumtree/autocomplete", params=params) + + async def get_list_categories( + self, *, parent_id: str | None = None, market: str = "uk" + ) -> dict[str, Any]: + """List categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"parent_id": parent_id, "market": market}.items() if v is not None + } + return await self._client.get("/v1/gumtree/categories", params=params) + + async def get_get_listing(self, listing_id: str, *, market: str = "uk") -> dict[str, Any]: + """Get listing. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"market": market}.items() if v is not None} + return await self._client.get(f"/v1/gumtree/listings/{listing_id}", params=params) + + async def get_get_seller_listings( + self, listing_id: str, *, page: int = 1, market: str = "uk" + ) -> dict[str, Any]: + """Get seller listings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"page": page, "market": market}.items() if v is not None} + return await self._client.get( + f"/v1/gumtree/listings/{listing_id}/seller-listings", params=params + ) + + async def get_list_locations( + self, *, parent_id: str | None = None, market: str = "uk" + ) -> dict[str, Any]: + """List locations. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"parent_id": parent_id, "market": market}.items() if v is not None + } + return await self._client.get("/v1/gumtree/locations", params=params) + + async def location_suggestions(self, *, query: str, market: str = "uk") -> dict[str, Any]: + """Location suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query, "market": market}.items() if v is not None} + return await self._client.get("/v1/gumtree/locations/autocomplete", params=params) + + async def get_list_markets(self) -> dict[str, Any]: + """List markets. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/gumtree/markets") + + async def search_listings( + self, + *, + query: str | None = None, + category: str = "all", + location: str | None = None, + distance: str | None = None, + min_price: str | None = None, + max_price: str | None = None, + sort: str | None = None, + seller_type: str | None = None, + urgent_only: bool = False, + with_photos: bool = False, + filters: str | None = None, + page: int = 1, + market: str = "uk", + ) -> dict[str, Any]: + """Search listings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "category": category, + "location": location, + "distance": distance, + "min_price": min_price, + "max_price": max_price, + "sort": sort, + "seller_type": seller_type, + "urgent_only": urgent_only, + "with_photos": with_photos, + "filters": filters, + "page": page, + "market": market, + }.items() + if v is not None + } + return await self._client.get("/v1/gumtree/search", params=params) + + async def get_search_filters( + self, + *, + category: str = "all", + location: str | None = None, + query: str | None = None, + filters: str | None = None, + market: str = "uk", + ) -> dict[str, Any]: + """Get search filters. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "category": category, + "location": location, + "query": query, + "filters": filters, + "market": market, + }.items() + if v is not None + } + return await self._client.get("/v1/gumtree/search/filters", params=params) + + # --- END generated by sdk/codegen/facade --- diff --git a/src/scrapebadger/naver/client.py b/src/scrapebadger/naver/client.py index 9999257..8625ee1 100644 --- a/src/scrapebadger/naver/client.py +++ b/src/scrapebadger/naver/client.py @@ -7,7 +7,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from scrapebadger.naver.places import PlacesClient from scrapebadger.naver.products import ProductsClient @@ -129,3 +129,142 @@ def reviews(self) -> ReviewsClient: ReviewsClient for review detail, video in-key, and SSR queries. """ return self._reviews + + # --- BEGIN generated by sdk/codegen/facade — do not edit --- + + async def search_suggestions(self, *, query: str) -> dict[str, Any]: + """Search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query}.items() if v is not None} + return await self._client.get("/v1/naver/autocomplete", params=params) + + async def naver_blog_search(self, *, query: str, page: int = 1) -> dict[str, Any]: + """Naver blog search. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query, "page": page}.items() if v is not None} + return await self._client.get("/v1/naver/blog", params=params) + + async def naver_place_local_search(self, *, query: str) -> dict[str, Any]: + """Naver Place/Local search. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query}.items() if v is not None} + return await self._client.get("/v1/naver/local", params=params) + + async def naver_news_search(self, *, query: str, page: int = 1) -> dict[str, Any]: + """Naver news search. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query, "page": page}.items() if v is not None} + return await self._client.get("/v1/naver/news", params=params) + + async def naver_place_detail(self, place_id: str) -> dict[str, Any]: + """Naver place detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get(f"/v1/naver/place/{place_id}") + + async def naver_place_visitor_reviews(self, place_id: str) -> dict[str, Any]: + """Naver place visitor reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get(f"/v1/naver/place/{place_id}/reviews") + + async def naver_web_search(self, *, query: str, page: int = 1) -> dict[str, Any]: + """Naver web search. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query, "page": page}.items() if v is not None} + return await self._client.get("/v1/naver/search", params=params) + + async def naver_shopping_bestseller_rankings( + self, + *, + category_id: str = "ALL", + age_type: str = "ALL", + sort_type: str = "PRODUCT_CLICK", + period_type: str = "DAILY", + ) -> dict[str, Any]: + """Naver Shopping bestseller rankings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "category_id": category_id, + "age_type": age_type, + "sort_type": sort_type, + "period_type": period_type, + }.items() + if v is not None + } + return await self._client.get("/v1/naver/shopping/bestsellers", params=params) + + async def naver_shopping_category_reference(self) -> dict[str, Any]: + """Naver Shopping category reference. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/naver/shopping/categories") + + async def naver_datalab_shopping_keyword_insight( + self, + *, + category_id: str, + start_date: str, + end_date: str, + time_unit: str = "date", + count: int = 20, + ) -> dict[str, Any]: + """Naver DataLab shopping keyword insight. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "category_id": category_id, + "start_date": start_date, + "end_date": end_date, + "time_unit": time_unit, + "count": count, + }.items() + if v is not None + } + return await self._client.get("/v1/naver/shopping/insight", params=params) + + async def naver_shopping_trending_keyword_rankings( + self, + *, + category_id: str, + age_type: str = "ALL", + sort_type: str = "KEYWORD_POPULAR", + period_type: str = "WEEKLY", + ) -> dict[str, Any]: + """Naver Shopping trending keyword rankings. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "category_id": category_id, + "age_type": age_type, + "sort_type": sort_type, + "period_type": period_type, + }.items() + if v is not None + } + return await self._client.get("/v1/naver/shopping/keywords", params=params) + + # --- END generated by sdk/codegen/facade --- diff --git a/src/scrapebadger/tiktok/client.py b/src/scrapebadger/tiktok/client.py index f246aca..60dc17c 100644 --- a/src/scrapebadger/tiktok/client.py +++ b/src/scrapebadger/tiktok/client.py @@ -225,6 +225,25 @@ async def get_tiktok_ad_detail(self, ad_id: str, *, region: str = "DE") -> dict[ params = {k: v for k, v in {"region": region}.items() if v is not None} return await self._client.get(f"/v1/tiktok/ads/{ad_id}", params=params) + async def best_selling_tiktok_shop_products( + self, *, region: str = "US", category_id: str | None = None, pages: int = 2, limit: int = 20 + ) -> dict[str, Any]: + """Best-selling TikTok Shop products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "region": region, + "category_id": category_id, + "pages": pages, + "limit": limit, + }.items() + if v is not None + } + return await self._client.get("/v1/tiktok/shop/bestsellers", params=params) + async def tiktok_shop_root_categories(self, *, region: str = "US") -> dict[str, Any]: """TikTok Shop root categories. @@ -243,6 +262,45 @@ async def tiktok_shop_category_subcategories_top_products( params = {k: v for k, v in {"region": region}.items() if v is not None} return await self._client.get(f"/v1/tiktok/shop/categories/{category_id}", params=params) + async def tiktok_shop_category_products( + self, + category_id: str, + *, + region: str = "US", + count: int = 20, + exclude_product_ids: list | None = None, + ) -> dict[str, Any]: + """TikTok Shop category products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "region": region, + "count": count, + "exclude_product_ids": exclude_product_ids, + }.items() + if v is not None + } + return await self._client.get( + f"/v1/tiktok/shop/categories/{category_id}/products", params=params + ) + + async def tiktok_shop_regional_mall_feed( + self, *, region: str = "US", tab_id: int = 0, page_token: str | None = None + ) -> dict[str, Any]: + """TikTok Shop regional mall feed. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"region": region, "tab_id": tab_id, "page_token": page_token}.items() + if v is not None + } + return await self._client.get("/v1/tiktok/shop/mall", params=params) + async def tiktok_shop_product_detail( self, product_id: str, *, region: str = "US" ) -> dict[str, Any]: @@ -286,15 +344,47 @@ async def tiktok_shop_product_reviews( f"/v1/tiktok/shop/products/{product_id}/reviews", params=params ) + async def tiktok_shop_theme_ranking( + self, + rank_id: str, + *, + region: str = "US", + rank_type: int = 1, + cursor: int = 0, + count: int = 20, + ) -> dict[str, Any]: + """TikTok Shop theme ranking. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "region": region, + "rank_type": rank_type, + "cursor": cursor, + "count": count, + }.items() + if v is not None + } + return await self._client.get(f"/v1/tiktok/shop/rankings/{rank_id}", params=params) + async def search_tiktok_shop_products( - self, *, q: str, region: str = "US", offset: int = 0 + self, *, q: str, region: str = "US", page_token: str | None = None, offset: int = 0 ) -> dict[str, Any]: """Search TikTok Shop products. Generated from the OpenAPI spec; returns the raw response dict. """ params = { - k: v for k, v in {"q": q, "region": region, "offset": offset}.items() if v is not None + k: v + for k, v in { + "q": q, + "region": region, + "page_token": page_token, + "offset": offset, + }.items() + if v is not None } return await self._client.get("/v1/tiktok/shop/search", params=params) From 4defee862feba608a1a444689f6d17d4f93419c9 Mon Sep 17 00:00:00 2001 From: kasparasizi1 <132673909+kasparasizi1@users.noreply.github.com> Date: Sat, 17 Oct 2026 01:52:37 +0300 Subject: [PATCH 2/2] Track Target client and preserve generated Python compatibility --- .gitignore | 2 +- src/scrapebadger/facebook/client.py | 2 +- src/scrapebadger/target/__init__.py | 5 + src/scrapebadger/target/client.py | 153 ++++++++++++++++++++++++++++ src/scrapebadger/tiktok/client.py | 2 +- 5 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 src/scrapebadger/target/__init__.py create mode 100644 src/scrapebadger/target/client.py diff --git a/.gitignore b/.gitignore index 2a3feae..b813463 100644 --- a/.gitignore +++ b/.gitignore @@ -71,7 +71,7 @@ docs/_build/ # PyBuilder .pybuilder/ -target/ +/target/ # Jupyter Notebook .ipynb_checkpoints diff --git a/src/scrapebadger/facebook/client.py b/src/scrapebadger/facebook/client.py index 3d1ed57..400c863 100644 --- a/src/scrapebadger/facebook/client.py +++ b/src/scrapebadger/facebook/client.py @@ -74,7 +74,7 @@ async def get_group_detail(self, group_id: str) -> dict[str, Any]: return await self._client.get(f"/v1/facebook/groups/{group_id}") async def get_group_posts( - self, group_id: str, *, after: str | None = None, sort: str = "newest" + self, group_id: str, *, after: str | None = None, sort: str | None = None ) -> dict[str, Any]: """Get group posts. diff --git a/src/scrapebadger/target/__init__.py b/src/scrapebadger/target/__init__.py new file mode 100644 index 0000000..1f33189 --- /dev/null +++ b/src/scrapebadger/target/__init__.py @@ -0,0 +1,5 @@ +"""target API client.""" + +from scrapebadger.target.client import TargetClient + +__all__ = ["TargetClient"] diff --git a/src/scrapebadger/target/client.py b/src/scrapebadger/target/client.py new file mode 100644 index 0000000..7c78263 --- /dev/null +++ b/src/scrapebadger/target/client.py @@ -0,0 +1,153 @@ +"""Target API client. # --- BEGIN generated by sdk/codegen/facade — do not edit ---""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapebadger._internal.client import BaseClient + + +class TargetClient: + """Client for all Target API operations. (Generated from the OpenAPI spec.)""" + + def __init__(self, client: BaseClient) -> None: + self._client = client + + async def get_search_suggestions(self, *, query: str) -> dict[str, Any]: + """Get search suggestions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"query": query}.items() if v is not None} + return await self._client.get("/v1/target/autocomplete", params=params) + + async def get_categories(self, *, category_id: str = "5xtly") -> dict[str, Any]: + """Get categories. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"category_id": category_id}.items() if v is not None} + return await self._client.get("/v1/target/categories", params=params) + + async def browse_a_category( + self, + *, + category_id: str, + page: int = 1, + page_size: int = 24, + store_id: str = "1375", + zip_code: str = "55403", + ) -> dict[str, Any]: + """Browse a category. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "category_id": category_id, + "page": page, + "page_size": page_size, + "store_id": store_id, + "zip_code": zip_code, + }.items() + if v is not None + } + return await self._client.get("/v1/target/category", params=params) + + async def list_supported_markets(self) -> dict[str, Any]: + """List supported markets. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get("/v1/target/markets") + + async def get_product_detail( + self, tcin: str, *, store_id: str = "1375", zip_code: str = "55403" + ) -> dict[str, Any]: + """Get product detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v for k, v in {"store_id": store_id, "zip_code": zip_code}.items() if v is not None + } + return await self._client.get(f"/v1/target/products/{tcin}", params=params) + + async def get_product_availability( + self, tcin: str, *, zip_code: str, limit: int = 10 + ) -> dict[str, Any]: + """Get product availability. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"zip_code": zip_code, "limit": limit}.items() if v is not None} + return await self._client.get(f"/v1/target/products/{tcin}/availability", params=params) + + async def get_product_questions( + self, tcin: str, *, page: int = 1, page_size: int = 10 + ) -> dict[str, Any]: + """Get product questions. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"page": page, "page_size": page_size}.items() if v is not None} + return await self._client.get(f"/v1/target/products/{tcin}/questions", params=params) + + async def get_product_reviews( + self, tcin: str, *, page: int = 1, page_size: int = 10, sort: str = "most_recent" + ) -> dict[str, Any]: + """Get product reviews. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in {"page": page, "page_size": page_size, "sort": sort}.items() + if v is not None + } + return await self._client.get(f"/v1/target/products/{tcin}/reviews", params=params) + + async def search_products( + self, + *, + query: str, + page: int = 1, + page_size: int = 24, + store_id: str = "1375", + zip_code: str = "55403", + sort: str = "relevance", + ) -> dict[str, Any]: + """Search products. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = { + k: v + for k, v in { + "query": query, + "page": page, + "page_size": page_size, + "store_id": store_id, + "zip_code": zip_code, + "sort": sort, + }.items() + if v is not None + } + return await self._client.get("/v1/target/search", params=params) + + async def find_nearby_stores(self, *, zip_code: str, limit: int = 10) -> dict[str, Any]: + """Find nearby stores. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + params = {k: v for k, v in {"zip_code": zip_code, "limit": limit}.items() if v is not None} + return await self._client.get("/v1/target/stores", params=params) + + async def get_store_detail(self, store_id: str) -> dict[str, Any]: + """Get store detail. + + Generated from the OpenAPI spec; returns the raw response dict. + """ + return await self._client.get(f"/v1/target/stores/{store_id}") diff --git a/src/scrapebadger/tiktok/client.py b/src/scrapebadger/tiktok/client.py index 60dc17c..88e5d36 100644 --- a/src/scrapebadger/tiktok/client.py +++ b/src/scrapebadger/tiktok/client.py @@ -268,7 +268,7 @@ async def tiktok_shop_category_products( *, region: str = "US", count: int = 20, - exclude_product_ids: list | None = None, + exclude_product_ids: list[str] | None = None, ) -> dict[str, Any]: """TikTok Shop category products.