diff --git a/CHANGELOG.md b/CHANGELOG.md index 88de335..e0e9992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v1.10.0-sdk.1 + +- Regenerated from the public API contract (525 to 529 operations). Adds the + **Airbnb Markets dataset** (4 endpoints): aggregate short-term-rental market + statistics -- listing supply, Superhost share, ratings, and nightly-price bands + -- rolled up by country, metro, and geo cell (search, item lookup, facets, and + nearby density). Aggregate-only: no individual listings or hosts. + ## v1.9.0-sdk.1 - Regenerated from the public API contract (499 to 525 operations). Adds four diff --git a/crawlora/client.py b/crawlora/client.py index 4385dac..bfa3002 100644 --- a/crawlora/client.py +++ b/crawlora/client.py @@ -20,7 +20,7 @@ from .operations import GROUPS, OPERATIONS DEFAULT_BASE_URL = "https://api.crawlora.net/api/v1" -VERSION = "1.9.0-sdk.1" +VERSION = "1.10.0-sdk.1" DEFAULT_USER_AGENT = f"crawlora-python-sdk/{VERSION}" DEFAULT_MAX_RETRY_DELAY = 30.0 DEFAULT_RETRY_STATUSES = (408, 409, 425, 429) diff --git a/crawlora/client.pyi b/crawlora/client.pyi index 284a605..f9181f0 100644 --- a/crawlora/client.pyi +++ b/crawlora/client.pyi @@ -2590,6 +2590,33 @@ ModelContactContactResponseDoc = TypedDict('ModelContactContactResponseDoc', { 'msg': NotRequired[str], }, total=False) +ModelDatasetsAirbnbMarketFacetResponse = TypedDict('ModelDatasetsAirbnbMarketFacetResponse', { + 'dataset': NotRequired[str], + 'facet': NotRequired[str], + 'items': NotRequired[list[ModelEsAirbnbMarketFacetItem]], +}, total=False) + +ModelDatasetsAirbnbMarketNearbyResponse = TypedDict('ModelDatasetsAirbnbMarketNearbyResponse', { + 'cells': NotRequired[list[ModelEsAirbnbDensityCell]], + 'dataset': NotRequired[str], + 'lat': NotRequired[float], + 'lon': NotRequired[float], + 'precision': NotRequired[int], + 'radius_m': NotRequired[int], + 'total': NotRequired[int], +}, total=False) + +ModelDatasetsAirbnbMarketSearchResponse = TypedDict('ModelDatasetsAirbnbMarketSearchResponse', { + 'dataset': NotRequired[str], + 'group_by': NotRequired[str], + 'items': NotRequired[list[ModelEsAirbnbMarketCell]], + 'min_listings': NotRequired[int], + 'page': NotRequired[int], + 'page_size': NotRequired[int], + 'sort': NotRequired[str], + 'total': NotRequired[int], +}, total=False) + ModelDatasetsAppsSearchResponse = TypedDict('ModelDatasetsAppsSearchResponse', { 'dataset': NotRequired[str], 'items': NotRequired[list[ModelEsAppRecord]], @@ -2668,6 +2695,30 @@ ModelDatasetsReviewsSearchResponse = TypedDict('ModelDatasetsReviewsSearchRespon 'total': NotRequired[int], }, total=False) +ModelDatasetsAirbnbMarketResponseDoc = TypedDict('ModelDatasetsAirbnbMarketResponseDoc', { + 'code': NotRequired[int], + 'data': NotRequired[ModelEsAirbnbMarketDetail], + 'msg': NotRequired[str], +}, total=False) + +ModelDatasetsAirbnbMarketsFacetResponseDoc = TypedDict('ModelDatasetsAirbnbMarketsFacetResponseDoc', { + 'code': NotRequired[int], + 'data': NotRequired[ModelDatasetsAirbnbMarketFacetResponse], + 'msg': NotRequired[str], +}, total=False) + +ModelDatasetsAirbnbMarketsNearbyResponseDoc = TypedDict('ModelDatasetsAirbnbMarketsNearbyResponseDoc', { + 'code': NotRequired[int], + 'data': NotRequired[ModelDatasetsAirbnbMarketNearbyResponse], + 'msg': NotRequired[str], +}, total=False) + +ModelDatasetsAirbnbMarketsSearchResponseDoc = TypedDict('ModelDatasetsAirbnbMarketsSearchResponseDoc', { + 'code': NotRequired[int], + 'data': NotRequired[ModelDatasetsAirbnbMarketSearchResponse], + 'msg': NotRequired[str], +}, total=False) + ModelDatasetsAppsSearchResponseDoc = TypedDict('ModelDatasetsAppsSearchResponseDoc', { 'code': NotRequired[int], 'data': NotRequired[ModelDatasetsAppsSearchResponse], @@ -2922,6 +2973,58 @@ ModelEbaySellerShopResponseDoc = TypedDict('ModelEbaySellerShopResponseDoc', { 'msg': NotRequired[Any], }, total=False) +ModelEsAirbnbDensityCell = TypedDict('ModelEsAirbnbDensityCell', { + 'geohash': NotRequired[str], + 'lat': NotRequired[float], + 'listings': NotRequired[int], + 'lon': NotRequired[float], + 'superhost_listings': NotRequired[int], + 'superhost_pct': NotRequired[float], +}, total=False) + +ModelEsAirbnbGeoBounds = TypedDict('ModelEsAirbnbGeoBounds', { + 'bottom_right': NotRequired[ModelEsGeoPoint], + 'top_left': NotRequired[ModelEsGeoPoint], +}, total=False) + +ModelEsAirbnbMarketCell = TypedDict('ModelEsAirbnbMarketCell', { + 'avg_rating': NotRequired[float], + 'avg_review_count': NotRequired[float], + 'key': NotRequired[str], + 'last_seen': NotRequired[str], + 'listings': NotRequired[int], + 'rated_listings': NotRequired[int], + 'superhost_listings': NotRequired[int], + 'superhost_pct': NotRequired[float], +}, total=False) + +ModelEsAirbnbMarketDetail = TypedDict('ModelEsAirbnbMarketDetail', { + 'avg_rating': NotRequired[float], + 'avg_review_count': NotRequired[float], + 'bounds': NotRequired[ModelEsAirbnbGeoBounds], + 'country': NotRequired[str], + 'currencies': NotRequired[list[ModelEsAirbnbPriceStats]], + 'last_seen': NotRequired[str], + 'listings': NotRequired[int], + 'metros': NotRequired[list[ModelEsAirbnbMarketCell]], + 'rated_listings': NotRequired[int], + 'superhost_listings': NotRequired[int], + 'superhost_pct': NotRequired[float], +}, total=False) + +ModelEsAirbnbMarketFacetItem = TypedDict('ModelEsAirbnbMarketFacetItem', { + 'count': NotRequired[int], + 'value': NotRequired[str], +}, total=False) + +ModelEsAirbnbPriceStats = TypedDict('ModelEsAirbnbPriceStats', { + 'currency': NotRequired[str], + 'listings': NotRequired[int], + 'p25': NotRequired[float], + 'p50': NotRequired[float], + 'p75': NotRequired[float], +}, total=False) + ModelEsAppRecord = TypedDict('ModelEsAppRecord', { 'android_max_installs': NotRequired[int], 'android_package': NotRequired[str], @@ -13149,6 +13252,64 @@ DatasetsListParams = TypedDict('DatasetsListParams', { '_headers': NotRequired[Mapping[str, str]], }, total=False) +DatasetsAirbnbMarketsFacetsResponse = ModelDatasetsAirbnbMarketsFacetResponseDoc +DatasetsAirbnbMarketsFacetsParams = TypedDict('DatasetsAirbnbMarketsFacetsParams', { + '_response_type': NotRequired[ResponseType], + '_timeout': NotRequired[float], + '_headers': NotRequired[Mapping[str, str]], + 'facet': Required[str], + 'group_by': NotRequired[str], + 'country': NotRequired[str], + 'market': NotRequired[str], + 'superhost': NotRequired[bool], + 'min_rating': NotRequired[float], + 'min_review_count': NotRequired[int], + 'active_since': NotRequired[str], + 'min_listings': NotRequired[int], +}, total=False) + +DatasetsAirbnbMarketsItemResponse = ModelDatasetsAirbnbMarketResponseDoc +DatasetsAirbnbMarketsItemParams = TypedDict('DatasetsAirbnbMarketsItemParams', { + '_response_type': NotRequired[ResponseType], + '_timeout': NotRequired[float], + '_headers': NotRequired[Mapping[str, str]], + 'country': Required[str], +}, total=False) + +DatasetsAirbnbMarketsNearbyResponse = ModelDatasetsAirbnbMarketsNearbyResponseDoc +DatasetsAirbnbMarketsNearbyParams = TypedDict('DatasetsAirbnbMarketsNearbyParams', { + '_response_type': NotRequired[ResponseType], + '_timeout': NotRequired[float], + '_headers': NotRequired[Mapping[str, str]], + 'lat': Required[float], + 'lon': Required[float], + 'radius_m': Required[int], + 'precision': NotRequired[int], + 'min_listings': NotRequired[int], + 'country': NotRequired[str], + 'superhost': NotRequired[bool], + 'min_rating': NotRequired[float], + 'active_since': NotRequired[str], +}, total=False) + +DatasetsAirbnbMarketsSearchResponse = ModelDatasetsAirbnbMarketsSearchResponseDoc +DatasetsAirbnbMarketsSearchParams = TypedDict('DatasetsAirbnbMarketsSearchParams', { + '_response_type': NotRequired[ResponseType], + '_timeout': NotRequired[float], + '_headers': NotRequired[Mapping[str, str]], + 'group_by': NotRequired[str], + 'country': NotRequired[str], + 'market': NotRequired[str], + 'superhost': NotRequired[bool], + 'min_rating': NotRequired[float], + 'min_review_count': NotRequired[int], + 'active_since': NotRequired[str], + 'min_listings': NotRequired[int], + 'sort': NotRequired[str], + 'page': NotRequired[int], + 'page_size': NotRequired[int], +}, total=False) + DatasetsAppsChartsSearchResponse = ModelDatasetsChartsSearchResponseDoc DatasetsAppsChartsSearchParams = TypedDict('DatasetsAppsChartsSearchParams', { '_response_type': NotRequired[ResponseType], @@ -17722,6 +17883,10 @@ class WebGroup: class DatasetsGroup: def list(self, **params: Unpack[DatasetsListParams]) -> DatasetsListResponse: ... + def airbnb_markets_facets(self, **params: Unpack[DatasetsAirbnbMarketsFacetsParams]) -> DatasetsAirbnbMarketsFacetsResponse: ... + def airbnb_markets_item(self, **params: Unpack[DatasetsAirbnbMarketsItemParams]) -> DatasetsAirbnbMarketsItemResponse: ... + def airbnb_markets_nearby(self, **params: Unpack[DatasetsAirbnbMarketsNearbyParams]) -> DatasetsAirbnbMarketsNearbyResponse: ... + def airbnb_markets_search(self, **params: Unpack[DatasetsAirbnbMarketsSearchParams]) -> DatasetsAirbnbMarketsSearchResponse: ... def apps_charts_search(self, **params: Unpack[DatasetsAppsChartsSearchParams]) -> DatasetsAppsChartsSearchResponse: ... def apps_reviews_search(self, **params: Unpack[DatasetsAppsReviewsSearchParams]) -> DatasetsAppsReviewsSearchResponse: ... def apps_search(self, **params: Unpack[DatasetsAppsSearchParams]) -> DatasetsAppsSearchResponse: ... @@ -18311,6 +18476,10 @@ OperationId = Literal[ 'coingecko-trending', 'contact', 'datasets-list', + 'datasets-airbnb-markets-facets', + 'datasets-airbnb-markets-item', + 'datasets-airbnb-markets-nearby', + 'datasets-airbnb-markets-search', 'datasets-apps-charts-search', 'datasets-apps-reviews-search', 'datasets-apps-search', @@ -19899,6 +20068,54 @@ class CrawloraClient: retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., ) -> DatasetsListResponse: ... @overload + def operation( + self, + operation_id: Literal['datasets-airbnb-markets-facets'], + params: DatasetsAirbnbMarketsFacetsParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsFacetsResponse: ... + @overload + def operation( + self, + operation_id: Literal['datasets-airbnb-markets-item'], + params: DatasetsAirbnbMarketsItemParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsItemResponse: ... + @overload + def operation( + self, + operation_id: Literal['datasets-airbnb-markets-nearby'], + params: DatasetsAirbnbMarketsNearbyParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsNearbyResponse: ... + @overload + def operation( + self, + operation_id: Literal['datasets-airbnb-markets-search'], + params: DatasetsAirbnbMarketsSearchParams = ..., + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsSearchResponse: ... + @overload def operation( self, operation_id: Literal['datasets-apps-charts-search'], @@ -26211,6 +26428,54 @@ class CrawloraClient: retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., ) -> DatasetsListResponse: ... @overload + def request( + self, + operation_id: Literal['datasets-airbnb-markets-facets'], + params: DatasetsAirbnbMarketsFacetsParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsFacetsResponse: ... + @overload + def request( + self, + operation_id: Literal['datasets-airbnb-markets-item'], + params: DatasetsAirbnbMarketsItemParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsItemResponse: ... + @overload + def request( + self, + operation_id: Literal['datasets-airbnb-markets-nearby'], + params: DatasetsAirbnbMarketsNearbyParams, + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsNearbyResponse: ... + @overload + def request( + self, + operation_id: Literal['datasets-airbnb-markets-search'], + params: DatasetsAirbnbMarketsSearchParams = ..., + *, + response_type: ResponseType = ..., + timeout: float | None = ..., + headers: Mapping[str, str] | None = ..., + retries: int | None = ..., + retry_predicate: Callable[[int, BaseException | None], bool] | None = ..., + ) -> DatasetsAirbnbMarketsSearchResponse: ... + @overload def request( self, operation_id: Literal['datasets-apps-charts-search'], diff --git a/crawlora/operations.py b/crawlora/operations.py index 5a05a64..4d262cf 100644 --- a/crawlora/operations.py +++ b/crawlora/operations.py @@ -2435,6 +2435,83 @@ 'produces': ['application/json'], 'queryParams': [], 'security': ['ApiKeyAuth']}, + 'datasets-airbnb-markets-facets': {'bodyParam': None, + 'bodyRequired': False, + 'consumes': ['application/json'], + 'formParams': [], + 'id': 'datasets-airbnb-markets-facets', + 'method': 'GET', + 'path': '/datasets/airbnb-markets/facets', + 'pathParams': [], + 'produces': ['application/json'], + 'queryParams': [{'in': 'query', + 'name': 'facet', + 'required': True, + 'type': 'string'}, + {'in': 'query', 'name': 'group_by', 'type': 'string'}, + {'in': 'query', 'name': 'country', 'type': 'string'}, + {'in': 'query', 'name': 'market', 'type': 'string'}, + {'in': 'query', 'name': 'superhost', 'type': 'boolean'}, + {'in': 'query', 'name': 'min_rating', 'type': 'number'}, + {'in': 'query', 'name': 'min_review_count', 'type': 'integer'}, + {'in': 'query', 'name': 'active_since', 'type': 'string'}, + {'in': 'query', 'name': 'min_listings', 'type': 'integer'}], + 'security': ['ApiKeyAuth']}, + 'datasets-airbnb-markets-item': {'bodyParam': None, + 'bodyRequired': False, + 'consumes': ['application/json'], + 'formParams': [], + 'id': 'datasets-airbnb-markets-item', + 'method': 'GET', + 'path': '/datasets/airbnb-markets/items/{country}', + 'pathParams': ['country'], + 'produces': ['application/json'], + 'queryParams': [], + 'security': ['ApiKeyAuth']}, + 'datasets-airbnb-markets-nearby': {'bodyParam': None, + 'bodyRequired': False, + 'consumes': ['application/json'], + 'formParams': [], + 'id': 'datasets-airbnb-markets-nearby', + 'method': 'GET', + 'path': '/datasets/airbnb-markets/nearby', + 'pathParams': [], + 'produces': ['application/json'], + 'queryParams': [{'in': 'query', 'name': 'lat', 'required': True, 'type': 'number'}, + {'in': 'query', 'name': 'lon', 'required': True, 'type': 'number'}, + {'in': 'query', + 'name': 'radius_m', + 'required': True, + 'type': 'integer'}, + {'in': 'query', 'name': 'precision', 'type': 'integer'}, + {'in': 'query', 'name': 'min_listings', 'type': 'integer'}, + {'in': 'query', 'name': 'country', 'type': 'string'}, + {'in': 'query', 'name': 'superhost', 'type': 'boolean'}, + {'in': 'query', 'name': 'min_rating', 'type': 'number'}, + {'in': 'query', 'name': 'active_since', 'type': 'string'}], + 'security': ['ApiKeyAuth']}, + 'datasets-airbnb-markets-search': {'bodyParam': None, + 'bodyRequired': False, + 'consumes': ['application/json'], + 'formParams': [], + 'id': 'datasets-airbnb-markets-search', + 'method': 'GET', + 'paginatable': True, + 'path': '/datasets/airbnb-markets/search', + 'pathParams': [], + 'produces': ['application/json'], + 'queryParams': [{'in': 'query', 'name': 'group_by', 'type': 'string'}, + {'in': 'query', 'name': 'country', 'type': 'string'}, + {'in': 'query', 'name': 'market', 'type': 'string'}, + {'in': 'query', 'name': 'superhost', 'type': 'boolean'}, + {'in': 'query', 'name': 'min_rating', 'type': 'number'}, + {'in': 'query', 'name': 'min_review_count', 'type': 'integer'}, + {'in': 'query', 'name': 'active_since', 'type': 'string'}, + {'in': 'query', 'name': 'min_listings', 'type': 'integer'}, + {'in': 'query', 'name': 'sort', 'type': 'string'}, + {'in': 'query', 'name': 'page', 'type': 'integer'}, + {'in': 'query', 'name': 'page_size', 'type': 'integer'}], + 'security': ['ApiKeyAuth']}, 'datasets-apps-charts-search': {'bodyParam': None, 'bodyRequired': False, 'consumes': ['application/json'], @@ -9094,7 +9171,11 @@ 'token_unlocks': 'coingecko-token-unlocks', 'treasuries': 'coingecko-treasuries', 'trending': 'coingecko-trending'}, - 'datasets': {'apps_charts_search': 'datasets-apps-charts-search', + 'datasets': {'airbnb_markets_facets': 'datasets-airbnb-markets-facets', + 'airbnb_markets_item': 'datasets-airbnb-markets-item', + 'airbnb_markets_nearby': 'datasets-airbnb-markets-nearby', + 'airbnb_markets_search': 'datasets-airbnb-markets-search', + 'apps_charts_search': 'datasets-apps-charts-search', 'apps_reviews_search': 'datasets-apps-reviews-search', 'apps_search': 'datasets-apps-search', 'creators_search': 'datasets-creators-search', @@ -9523,7 +9604,7 @@ 'video': 'youtube-video'}, 'zillow': {'autocomplete': 'zillow-autocomplete', 'property': 'zillow-property', 'search': 'zillow-search'}} -OPERATION_COUNT = 525 +OPERATION_COUNT = 529 class OperationId: AIRBNB_ROOM = 'airbnb-room' @@ -9609,6 +9690,10 @@ class OperationId: COIN_GECKO_TOKEN_UNLOCKS = 'coingecko-token-unlocks' COIN_GECKO_TREASURIES = 'coingecko-treasuries' COIN_GECKO_TRENDING = 'coingecko-trending' + DATASETS_AIRBNB_MARKETS_FACETS = 'datasets-airbnb-markets-facets' + DATASETS_AIRBNB_MARKETS_ITEM = 'datasets-airbnb-markets-item' + DATASETS_AIRBNB_MARKETS_NEARBY = 'datasets-airbnb-markets-nearby' + DATASETS_AIRBNB_MARKETS_SEARCH = 'datasets-airbnb-markets-search' DATASETS_APPS_CHARTS_SEARCH = 'datasets-apps-charts-search' DATASETS_APPS_REVIEWS_SEARCH = 'datasets-apps-reviews-search' DATASETS_APPS_SEARCH = 'datasets-apps-search' diff --git a/docs/operations.md b/docs/operations.md index 682fa35..7ca9714 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -2,7 +2,7 @@ Generated from `openapi/public.json`. Deprecated, admin, and internal operations are excluded from this SDK contract. -Total operations: `525` +Total operations: `529` | Group | SDK method | Operation ID | HTTP | Params | Auth | Response | Notes | | --- | --- | --- | --- | --- | --- | --- | --- | @@ -93,6 +93,10 @@ Total operations: `525` | web | `web.antibot_check` | `antibot-check` | `POST /diagnostics/antibot-check` | `request` (body str required) | `ApiKeyAuth` | `WebAntibotCheckResponse` | | | web | `web.scrape` | `web-scrape` | `POST /web/scrape` | `scrapeOption` (body str required) | `ApiKeyAuth` | `WebScrapeResponse` | | | datasets | `datasets.list` | `datasets-list` | `GET /datasets` | none | `ApiKeyAuth` | `DatasetsListResponse` | | +| datasets | `datasets.airbnb_markets_facets` | `datasets-airbnb-markets-facets` | `GET /datasets/airbnb-markets/facets` | `facet` (query str required)
`group_by` (query str)
`country` (query str)
`market` (query str)
`superhost` (query bool)
`min_rating` (query float)
`min_review_count` (query int)
`active_since` (query str)
`min_listings` (query int) | `ApiKeyAuth` | `DatasetsAirbnbMarketsFacetsResponse` | | +| datasets | `datasets.airbnb_markets_item` | `datasets-airbnb-markets-item` | `GET /datasets/airbnb-markets/items/{country}` | `country` (path str required) | `ApiKeyAuth` | `DatasetsAirbnbMarketsItemResponse` | | +| datasets | `datasets.airbnb_markets_nearby` | `datasets-airbnb-markets-nearby` | `GET /datasets/airbnb-markets/nearby` | `lat` (query float required)
`lon` (query float required)
`radius_m` (query int required)
`precision` (query int)
`min_listings` (query int)
`country` (query str)
`superhost` (query bool)
`min_rating` (query float)
`active_since` (query str) | `ApiKeyAuth` | `DatasetsAirbnbMarketsNearbyResponse` | | +| datasets | `datasets.airbnb_markets_search` | `datasets-airbnb-markets-search` | `GET /datasets/airbnb-markets/search` | `group_by` (query str)
`country` (query str)
`market` (query str)
`superhost` (query bool)
`min_rating` (query float)
`min_review_count` (query int)
`active_since` (query str)
`min_listings` (query int)
`sort` (query str)
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsAirbnbMarketsSearchResponse` | | | datasets | `datasets.apps_charts_search` | `datasets-apps-charts-search` | `GET /datasets/apps-charts/search` | `q` (query str)
`store` (query str)
`chart_type` (query str)
`collection` (query str)
`category` (query str)
`country` (query str)
`app_id` (query str)
`date` (query str)
`sort` (query str)
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsAppsChartsSearchResponse` | | | datasets | `datasets.apps_reviews_search` | `datasets-apps-reviews-search` | `GET /datasets/apps-reviews/search` | `q` (query str)
`store` (query str)
`app_id` (query str)
`country` (query str)
`min_score` (query int)
`sort` (query str)
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsAppsReviewsSearchResponse` | | | datasets | `datasets.apps_search` | `datasets-apps-search` | `GET /datasets/apps/search` | `q` (query str)
`store` (query str)
`category` (query str)
`country` (query str)
`developer` (query str)
`free` (query bool)
`min_rating` (query float)
`min_reviews` (query int)
`sort` (query str)
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsAppsSearchResponse` | | diff --git a/openapi/public.json b/openapi/public.json index 4ef2ec5..acda16d 100644 --- a/openapi/public.json +++ b/openapi/public.json @@ -8479,6 +8479,84 @@ }, "type": "object" }, + "datasets.AirbnbMarketFacetResponse": { + "properties": { + "dataset": { + "type": "string" + }, + "facet": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/definitions/es.AirbnbMarketFacetItem" + }, + "type": "array" + } + }, + "type": "object" + }, + "datasets.AirbnbMarketNearbyResponse": { + "properties": { + "cells": { + "items": { + "$ref": "#/definitions/es.AirbnbDensityCell" + }, + "type": "array" + }, + "dataset": { + "type": "string" + }, + "lat": { + "type": "number" + }, + "lon": { + "type": "number" + }, + "precision": { + "type": "integer" + }, + "radius_m": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" + }, + "datasets.AirbnbMarketSearchResponse": { + "properties": { + "dataset": { + "type": "string" + }, + "group_by": { + "type": "string" + }, + "items": { + "items": { + "$ref": "#/definitions/es.AirbnbMarketCell" + }, + "type": "array" + }, + "min_listings": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "sort": { + "type": "string" + }, + "total": { + "type": "integer" + } + }, + "type": "object" + }, "datasets.AppsSearchResponse": { "properties": { "dataset": { @@ -8703,6 +8781,70 @@ }, "type": "object" }, + "datasets.airbnbMarketResponseDoc": { + "properties": { + "code": { + "example": 200, + "type": "integer" + }, + "data": { + "$ref": "#/definitions/es.AirbnbMarketDetail" + }, + "msg": { + "example": "OK", + "type": "string" + } + }, + "type": "object" + }, + "datasets.airbnbMarketsFacetResponseDoc": { + "properties": { + "code": { + "example": 200, + "type": "integer" + }, + "data": { + "$ref": "#/definitions/datasets.AirbnbMarketFacetResponse" + }, + "msg": { + "example": "OK", + "type": "string" + } + }, + "type": "object" + }, + "datasets.airbnbMarketsNearbyResponseDoc": { + "properties": { + "code": { + "example": 200, + "type": "integer" + }, + "data": { + "$ref": "#/definitions/datasets.AirbnbMarketNearbyResponse" + }, + "msg": { + "example": "OK", + "type": "string" + } + }, + "type": "object" + }, + "datasets.airbnbMarketsSearchResponseDoc": { + "properties": { + "code": { + "example": 200, + "type": "integer" + }, + "data": { + "$ref": "#/definitions/datasets.AirbnbMarketSearchResponse" + }, + "msg": { + "example": "OK", + "type": "string" + } + }, + "type": "object" + }, "datasets.appsSearchResponseDoc": { "properties": { "code": { @@ -9538,6 +9680,144 @@ }, "type": "object" }, + "es.AirbnbDensityCell": { + "properties": { + "geohash": { + "type": "string" + }, + "lat": { + "type": "number" + }, + "listings": { + "type": "integer" + }, + "lon": { + "type": "number" + }, + "superhost_listings": { + "type": "integer" + }, + "superhost_pct": { + "type": "number" + } + }, + "type": "object" + }, + "es.AirbnbGeoBounds": { + "properties": { + "bottom_right": { + "$ref": "#/definitions/es.GeoPoint" + }, + "top_left": { + "$ref": "#/definitions/es.GeoPoint" + } + }, + "type": "object" + }, + "es.AirbnbMarketCell": { + "properties": { + "avg_rating": { + "type": "number" + }, + "avg_review_count": { + "type": "number" + }, + "key": { + "type": "string" + }, + "last_seen": { + "type": "string" + }, + "listings": { + "type": "integer" + }, + "rated_listings": { + "type": "integer" + }, + "superhost_listings": { + "type": "integer" + }, + "superhost_pct": { + "type": "number" + } + }, + "type": "object" + }, + "es.AirbnbMarketDetail": { + "properties": { + "avg_rating": { + "type": "number" + }, + "avg_review_count": { + "type": "number" + }, + "bounds": { + "$ref": "#/definitions/es.AirbnbGeoBounds" + }, + "country": { + "type": "string" + }, + "currencies": { + "items": { + "$ref": "#/definitions/es.AirbnbPriceStats" + }, + "type": "array" + }, + "last_seen": { + "type": "string" + }, + "listings": { + "type": "integer" + }, + "metros": { + "items": { + "$ref": "#/definitions/es.AirbnbMarketCell" + }, + "type": "array" + }, + "rated_listings": { + "type": "integer" + }, + "superhost_listings": { + "type": "integer" + }, + "superhost_pct": { + "type": "number" + } + }, + "type": "object" + }, + "es.AirbnbMarketFacetItem": { + "properties": { + "count": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "es.AirbnbPriceStats": { + "properties": { + "currency": { + "type": "string" + }, + "listings": { + "type": "integer" + }, + "p25": { + "type": "number" + }, + "p50": { + "type": "number" + }, + "p75": { + "type": "number" + } + }, + "type": "object" + }, "es.AppRecord": { "properties": { "android_max_installs": { @@ -48059,6 +48339,393 @@ ] } }, + "/datasets/airbnb-markets/facets": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns suppressed distribution counts over the Airbnb markets dataset, honoring the same filters as search. Facet enum: `country`, `market`, `currency`, `superhost`, `rating_band`, `review_band`. group_by enum: `country`, `market`.", + "operationId": "datasets-airbnb-markets-facets", + "parameters": [ + { + "description": "Facet enum: country, market, currency, superhost, rating_band, review_band", + "in": "query", + "name": "facet", + "required": true, + "type": "string" + }, + { + "description": "Aggregate cell dimension enum: country, market. Defaults to country", + "in": "query", + "name": "group_by", + "type": "string" + }, + { + "description": "Exact ISO-3166-1 alpha-2 country filter, e.g. FR", + "in": "query", + "name": "country", + "type": "string" + }, + { + "description": "Exact metro-market filter, max 128 characters", + "in": "query", + "name": "market", + "type": "string" + }, + { + "description": "Count only Superhost listings", + "in": "query", + "name": "superhost", + "type": "boolean" + }, + { + "description": "Minimum listing rating, from 0 through 5", + "in": "query", + "name": "min_rating", + "type": "number" + }, + { + "description": "Minimum listing review count, 0 or greater", + "in": "query", + "name": "min_review_count", + "type": "integer" + }, + { + "description": "Freshness filter, an ISO-8601 date (YYYY-MM-DD)", + "in": "query", + "name": "active_since", + "type": "string" + }, + { + "description": "Minimum listings per bucket; raises the small-cell suppression floor", + "in": "query", + "name": "min_listings", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/datasets.airbnbMarketsFacetResponseDoc" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "429": { + "description": "Too Many Requests", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Facet the Airbnb markets dataset", + "tags": [ + "Datasets" + ] + } + }, + "/datasets/airbnb-markets/items/{country}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns one country's full aggregate Airbnb market profile from dataset id enum value `airbnb-markets` — headline supply, Superhost share, ratings, its top metros, bounding box and per-currency nightly-price percentiles. Aggregate-only. Returns 404 for a country below the suppression floor.", + "operationId": "datasets-airbnb-markets-item", + "parameters": [ + { + "description": "ISO-3166-1 alpha-2 country code, e.g. FR", + "in": "path", + "name": "country", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/datasets.airbnbMarketResponseDoc" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "429": { + "description": "Too Many Requests", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Get an Airbnb market from the dataset", + "tags": [ + "Datasets" + ] + } + }, + "/datasets/airbnb-markets/nearby": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns an aggregate geohash-grid density map of Airbnb listings within a radius of a coordinate, from dataset id enum value `airbnb-markets`. Each cell reports a centroid, listing count and Superhost share; thin cells are suppressed. Aggregate-only.", + "operationId": "datasets-airbnb-markets-nearby", + "parameters": [ + { + "description": "Center latitude, from -90 through 90", + "in": "query", + "name": "lat", + "required": true, + "type": "number" + }, + { + "description": "Center longitude, from -180 through 180", + "in": "query", + "name": "lon", + "required": true, + "type": "number" + }, + { + "description": "Search radius in meters, from 1 through 50000", + "in": "query", + "name": "radius_m", + "required": true, + "type": "integer" + }, + { + "description": "Geohash precision, from 1 through 12; defaults to a value derived from the radius", + "in": "query", + "name": "precision", + "type": "integer" + }, + { + "description": "Minimum listings per cell; raises the small-cell suppression floor", + "in": "query", + "name": "min_listings", + "type": "integer" + }, + { + "description": "Exact ISO-3166-1 alpha-2 country filter, e.g. US", + "in": "query", + "name": "country", + "type": "string" + }, + { + "description": "Count only Superhost listings", + "in": "query", + "name": "superhost", + "type": "boolean" + }, + { + "description": "Minimum listing rating, from 0 through 5", + "in": "query", + "name": "min_rating", + "type": "number" + }, + { + "description": "Freshness filter, an ISO-8601 date (YYYY-MM-DD)", + "in": "query", + "name": "active_since", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/datasets.airbnbMarketsNearbyResponseDoc" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "429": { + "description": "Too Many Requests", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Airbnb market density near a coordinate", + "tags": [ + "Datasets" + ] + } + }, + "/datasets/airbnb-markets/search": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns aggregate Airbnb short-term-rental market rollups from the dataset id enum value `airbnb-markets`. Aggregate-only: each row is a market cell (a country or a metro), never an individual listing. Thin cells are suppressed. group_by enum: `country`, `market`. Sort enum: `listings_desc`, `superhost_pct_desc`, `rating_desc`, `key_asc`.", + "operationId": "datasets-airbnb-markets-search", + "parameters": [ + { + "description": "Aggregate cell dimension enum: country, market. Defaults to country", + "in": "query", + "name": "group_by", + "type": "string" + }, + { + "description": "Exact ISO-3166-1 alpha-2 country filter, e.g. FR", + "in": "query", + "name": "country", + "type": "string" + }, + { + "description": "Exact metro-market filter, e.g. Paris, max 128 characters", + "in": "query", + "name": "market", + "type": "string" + }, + { + "description": "Count only Superhost listings", + "in": "query", + "name": "superhost", + "type": "boolean" + }, + { + "description": "Minimum listing rating, from 0 through 5", + "in": "query", + "name": "min_rating", + "type": "number" + }, + { + "description": "Minimum listing review count, 0 or greater", + "in": "query", + "name": "min_review_count", + "type": "integer" + }, + { + "description": "Freshness filter, an ISO-8601 date (YYYY-MM-DD); only listings last seen on or after it are counted", + "in": "query", + "name": "active_since", + "type": "string" + }, + { + "description": "Minimum listings per cell; raises the small-cell suppression floor (never lowered below the built-in minimum)", + "in": "query", + "name": "min_listings", + "type": "integer" + }, + { + "description": "Sort enum: listings_desc, superhost_pct_desc, rating_desc, key_asc", + "in": "query", + "name": "sort", + "type": "string" + }, + { + "description": "Page number, defaults to 1", + "in": "query", + "name": "page", + "type": "integer" + }, + { + "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000", + "in": "query", + "name": "page_size", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/datasets.airbnbMarketsSearchResponseDoc" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "429": { + "description": "Too Many Requests", + "schema": { + "$ref": "#/definitions/app.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Search the Airbnb markets dataset", + "tags": [ + "Datasets" + ] + } + }, "/datasets/apps-charts/search": { "get": { "consumes": [ diff --git a/pyproject.toml b/pyproject.toml index 79b0828..61aac27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "crawlora" -version = "1.9.0.dev1" +version = "1.10.0.dev1" description = "Official Python SDK for the Crawlora web-scraping API: typed grouped and dynamic operation calls for every public endpoint, with retries, pagination, hooks, and an async client." readme = "README.md" requires-python = ">=3.10" diff --git a/tests/test_client.py b/tests/test_client.py index 58e9f27..9d8447f 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -267,7 +267,7 @@ def transport(_request, _timeout): self.assertIs(raised.exception.__cause__, cause) def test_operation_metadata_count(self): - self.assertEqual(OPERATION_COUNT, 525) + self.assertEqual(OPERATION_COUNT, 529) def test_deprecated_endpoints_are_not_generated(self): self.assertFalse(hasattr(CrawloraClient(api_key="api_test", base_url=self.base_url).google, "lens")) @@ -296,7 +296,7 @@ def test_docs_cover_operations_and_recipes(self): recipes_doc = root.joinpath("docs", "recipes.md").read_text() for expected in [ - "Total operations: `525`", + "Total operations: `529`", "`bing-search`", "`GET /bing/search`", "`bing.search`",