Skip to content

Add Catalog API SDK and CLI - #1223

Open
asonnenschein wants to merge 1 commit into
mainfrom
adrians/add-catalog-api
Open

Add Catalog API SDK and CLI#1223
asonnenschein wants to merge 1 commit into
mainfrom
adrians/add-catalog-api

Conversation

@asonnenschein

Copy link
Copy Markdown
Contributor

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

  • Add 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.
  • Add CatalogAPI (planet/sync/catalog.py) synchronous wrapper, exposed on planet as pl.catalog.
  • Add planet catalog CLI group (planet/cli/catalog.py) with collections, conformance, items, landing-page, search, and simple-search subcommands.
  • Defaults to legacy base URL and authenticates with an OAuth bearer token. Both regional legacy URLs are added to constants.py.
  • Paging 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.

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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.CatalogClient with paging support for both STAC links[rel=next] and context.next token pagination.
  • Adds planet sync and 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.

Comment thread planet/cli/catalog.py
--bbox 13,45,14,46 \\
--distinct date
"""
async with catalog_client(ctx) as cl:
Comment thread planet/clients/catalog.py
APIError: on an API server error.
ClientError: on a client error.
"""
params = self._query_params(collections=collections,
COLLECTION_ID
])

assert result.exit_code != 0
@ischneider

Copy link
Copy Markdown
Member

A few quick bits of feedback:

  • as copilot noted, there are numerous places where client validation is missing, both CLI flags (required=True) and in the client, e.g. if required_thing is None: raise ClientException('required_thing ...')
  • the try/except/raise pattern in the client should go away - adds nothing as the client methods and the request method both note the types of exception that can be raised
  • i think compliance, landing-page, queryables, etc. are not interesting to CLI or client users and can be removed - instead these allow powering a generic STAC client via discovery...

the tests seem like a funny mix of sync/async and one-of cases, e.g. test_list_items_omits_unset_params ... there is real fragility in our sync wrappers omitting or mixing up a parameter but I think we can test this using permutations and some python test magic (e.g. loop over client and make sure at a code level, each function has the same params?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants