|
| 1 | +import os |
1 | 2 | import re
|
2 | 3 | import warnings
|
3 | 4 | from functools import lru_cache
|
@@ -335,6 +336,52 @@ def _warn_about_fallback(self, *args: str) -> None:
|
335 | 336 | warnings.warn(DoesNotConformTo(*args), stacklevel=2)
|
336 | 337 | warnings.warn(FallbackToPystac(), stacklevel=2)
|
337 | 338 |
|
| 339 | + def get_queryables(self, *collections: Optional[str]) -> Dict[str, Any]: |
| 340 | + """Return all queryables, or limit to those of specified collections. |
| 341 | +
|
| 342 | + Queryables from multiple collections are unioned together, except in the case |
| 343 | + when the same queryable key has a different definition, in which case that key |
| 344 | + is dropped. |
| 345 | +
|
| 346 | + Output is a dictionary that can be used in ``jsonshema.validate`` |
| 347 | + Args: |
| 348 | + *collections: The IDs of the items to include. |
| 349 | +
|
| 350 | + Return: |
| 351 | + Dict[str, Any]: Dictionary containing queryable fields |
| 352 | + """ |
| 353 | + if not collections: |
| 354 | + return super().get_queryables() |
| 355 | + |
| 356 | + col = self.get_collection(collections[0]) |
| 357 | + assert isinstance(col, CollectionClient) |
| 358 | + response = col.get_queryables() |
| 359 | + addProps = response.get("additionalProperties", None) |
| 360 | + for collection in collections[1:]: |
| 361 | + col = self.get_collection(collection) |
| 362 | + assert isinstance(col, CollectionClient) |
| 363 | + col_resp = col.get_queryables() |
| 364 | + # Ensure schema consistency |
| 365 | + assert response["$schema"] == col_resp["$schema"], ( |
| 366 | + f"$schema inconsistency between {os.path.basename(response['$id'])} " |
| 367 | + f"and {os.path.basename(col_resp['$id'])}. '{response['$schema']}' " |
| 368 | + f"!= '{col_resp['$schema']}'" |
| 369 | + ) |
| 370 | + assert addProps == col_resp.get( |
| 371 | + "additionalProperties", None |
| 372 | + ), "'additionalProperties' varies across collections specified" |
| 373 | + |
| 374 | + # drop queryables if their keys match, but the descriptions differ |
| 375 | + for k in set(col_resp["properties"].keys()).intersection( |
| 376 | + response["properties"].keys() |
| 377 | + ): |
| 378 | + if col_resp["properties"][k] != response["properties"][k]: |
| 379 | + col_resp["properties"].pop(k) |
| 380 | + response["properties"].pop(k) |
| 381 | + response["properties"].update(col_resp["properties"]) |
| 382 | + |
| 383 | + return response |
| 384 | + |
338 | 385 | @lru_cache()
|
339 | 386 | def get_collection(self, collection_id: str) -> Union[Collection, CollectionClient]:
|
340 | 387 | """Get a single collection from this Catalog/API
|
|
0 commit comments