Add Catalog API SDK and CLI - #1223
Conversation
Onboard the Catalog API (https://docs.planet.com/develop/apis/catalog/), a STAC 1.0.0 implementation, as a thin wrapper following the existing client structure: an async client, a sync wrapper, and a CLI command group. Implements the nine operations in the OpenAPI specification: GET /catalog/v1 get_landing_page GET /catalog/v1/conformance get_conformance GET /catalog/v1/collections list_collections GET /catalog/v1/collections/{id} get_collection GET /catalog/v1/collections/{id}/queryables get_collection_queryables GET /catalog/v1/collections/{id}/items list_items GET /catalog/v1/collections/{id}/items/{featureId} get_item GET /catalog/v1/search simple_search POST /catalog/v1/search search Two details differ from the other clients: Unlike the rest of the Planet APIs, the Catalog API is not served from api.planet.com - it is hosted by Sentinel Hub and authenticates with an OAuth bearer token, so a plain Planet API key will not work. CatalogClient therefore takes its own default base URL instead of a suffix of PLANET_BASE_URL, and Planet(base_url=...) does not redirect it. Both regional deployment URLs are added to constants.py; the region is selected with a base_url override. Paging also works two ways. The GET endpoints return a STAC `links` entry with `rel: next`, while POST /search returns a `context.next` token that must be re-sent with the original query. Both pagers subclass planet.models.Paged so the limit semantics and page-cycle detection are shared. The iterating methods take `limit` as a total cap (0 for no maximum) and `page_size` as the per-request page size, consistent with the other clients. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
There are a couple of contract/UX mismatches (notably simple-search “single collection” semantics) and a CLI error-translation test that doesn’t assert the intended behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds first-class support for the Planet Catalog API (STAC) across the SDK: an async CatalogClient, a synchronous CatalogAPI wrapper exposed via Planet().catalog, and a new planet catalog CLI group, along with docs and integration tests.
Changes:
- Introduces
planet.clients.catalog.CatalogClientwith paging support for both STAClinks[rel=next]andcontext.nexttoken pagination. - Adds
planet syncand CLI surfaces for Catalog (new sync wrapper +planet catalog ...commands). - Updates documentation/nav and adds integration coverage for client + CLI behavior.
File summaries
| File | Description |
|---|---|
| tests/integration/test_catalog_cli.py | Adds integration tests for planet catalog command group behavior. |
| tests/integration/test_catalog_api.py | Adds integration tests for async client + sync wrapper, including paging semantics and base URL defaults. |
| planet/sync/client.py | Exposes Catalog API on the synchronous Planet facade as pl.catalog. |
| planet/sync/catalog.py | Adds synchronous wrapper around CatalogClient for iterator-friendly sync usage. |
| planet/http.py | Extends Session.client(...) typing/doc to include the new catalog client name (and other existing clients). |
| planet/constants.py | Adds Sentinel Hub base URL constants used for Catalog API defaults. |
| planet/clients/catalog.py | Implements async Catalog client and Catalog-specific pagers. |
| planet/clients/init.py | Exports/registers CatalogClient for Session.client('catalog') lookup. |
| planet/cli/cli.py | Registers the new catalog CLI group. |
| planet/cli/catalog.py | Implements planet catalog CLI group and subcommands. |
| planet/init.py | Re-exports CatalogClient at package top-level. |
| mkdocs.yml | Adds Catalog CLI tutorial page to docs nav. |
| docs/python/sdk-reference.md | Adds planet.CatalogClient to the generated SDK reference page. |
| docs/cli/cli-catalog.md | Adds Catalog CLI tutorial documentation. |
Review details
- Files reviewed: 14/14 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| --bbox 13,45,14,46 \\ | ||
| --distinct date | ||
| """ | ||
| async with catalog_client(ctx) as cl: |
| APIError: on an API server error. | ||
| ClientError: on a client error. | ||
| """ | ||
| params = self._query_params(collections=collections, |
| COLLECTION_ID | ||
| ]) | ||
|
|
||
| assert result.exit_code != 0 |
|
A few quick bits of feedback:
the tests seem like a funny mix of sync/async and one-of cases, e.g. |
Description
Adds support for the Planet Catalog API to the SDK. Includes an async client, sync client, and CLI built on the async client, following the same patterns used by the existing Planet APIs that are supported in the SDK.
Changes
CatalogClient(planet/clients/catalog.py) covering all Catalog API endpoints:get_landing_page,get_conformance,list_collections,get_collection,get_collection_queryables,list_items,get_item,simple_search,search.CatalogAPI(planet/sync/catalog.py) synchronous wrapper, exposed onplanetaspl.catalog.planet catalogCLI group (planet/cli/catalog.py) withcollections,conformance,items,landing-page,search, andsimple-searchsubcommands.constants.py.linksentry withrel: next, while POST /search returns acontext.nexttoken that must be re-sent with the original query. Both pagers subclassplanet.models.Pagedso the limit semantics and page-cycle detection are shared.