← Back to examples
Agent skill

Screen a portfolio of AOIs

Subscribe a chosen Cecil dataset to a portfolio of plots in one batch and return a tidy table mapping each input to its AOI id and subscription id. The foundation for any multi-site analysis (TNFD, CSRD, EUDR, supply chain).

Use this skill when the user has more than one site/plot/property and wants the same dataset subscribed against all of them. Most regulatory and supply-chain workflows start here.

Prerequisites

Steps

  1. Inputs. A list of plots, each with:

    • plot_id — a stable identifier (supplier code, asset id, etc.).
    • geometry — GeoJSON Polygon or Point.

    Plus a single dataset_id (the dataset to subscribe to all plots).

  2. Look up existing AOIs to keep runs idempotent. Re-running a screen shouldn't create duplicate AOIs. Use external_ref=plot_id.

    existing = {a.external_ref: a for a in client.list_aois() if a.external_ref}
  3. Create AOIs and subscriptions per plot.

    records = []
    for plot in plots:
        aoi = existing.get(plot["plot_id"]) or client.create_aoi(
            geometry=plot["geometry"],
            external_ref=plot["plot_id"],
        )
        subscription = client.create_subscription(
            aoi_id=aoi.id,
            dataset_id=dataset_id,
            external_ref=plot["plot_id"],
        )
        records.append({
            "plot_id": plot["plot_id"],
            "aoi_id": aoi.id,
            "aoi_hectares": aoi.hectares,
            "subscription_id": subscription.id,
        })
  4. Wait for staging. Subscriptions process asynchronously. Poll each one (or all of them in parallel) using the subscribe-and-load polling pattern. For large portfolios, fan out with concurrent.futures.ThreadPoolExecutor so plots stage in parallel.

  5. Return the result table as a pandas.DataFrame. Downstream skills (e.g. land-cover-baseline-and-change) take this table as input.

Important constraints

  • Dataset constraints. Some datasets enforce min/max AOI hectares or vertex counts — see client.get_dataset(dataset_id).constraints. Validate inputs against these before bulk-creating subscriptions, otherwise individual plots will fail mid-batch.
  • Cost. Every subscription is potentially billable. Check client.get_dataset(dataset_id).pricing before running across a large portfolio.
  • Cleanup. For exploratory runs, archive aggressively: client.archive_subscription(s.id) and client.archive_aoi(a.id).

References