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`",