Skip to content

Python SDK User Guide

This guide is for Planet SDK for Python users who want to use Python code to search, order, customize, and deliver Planet imagery and data. If you’re new to Python, you may want to choose the no-code option of using the command-line interface (CLI). But if you’ve successfully followed the instructions to get started and you’re ready to try your hand at Python coding, this guide should be all you need to use this SDK to get Planet data.

We want to hear from you!

This is a beta release. We encourage you to test your workflows rigorously. Based on your feedback, we may roll out additional updates to improve your experience. Please share your feedback with us on our Planet Developers community channel.

This guide walks you through the steps:

  • Create a session—set up a context for calling on Planet servers and receiving data back.
  • Authenticate—pass your API key to Planet services to verify your permissions to data.
  • Create an orderbuild an orders client, send the request within the session context, and download it when it’s ready.
  • Collect and list data—handle the potentially large number of results from a search for imagery.
  • Query the data catalog—search the catalog based on a filter, activate the assets you want, and download and validate it when it’s ready.

Create a session

Communication with the Planet services is provided with the Session class. The recommended way to use a Session is as a context manager. This will provide for automatic clean up of connections when the context is left.

import asyncio
import os
from planet import Session

async def main():
    async with Session() as sess:
        # perform operations here
        pass

asyncio.run(main())

Alternatively, use await Session.aclose() to close a Session explicitly:

async def main():
    sess = Session()
    # perform operations here
    await sess.aclose()

asyncio.run(main())

Authenticate with Planet services

A Session requires authentication to communicate with Planet services. This authentication information is retrieved when a Session is created. By default, a Session obtains authorization from the following sources with order indicating priority:

  1. The environment variable PL_API_KEY
  2. The secret file

The SDK provides the auth.Auth class for managing authentication information. This module can be used to obtain authentication information from username and password with Auth.from_login(). Additionally, it can be created with the API key obtained directly from the Planet account site with Auth.from_key(<API_KEY>).

Once the authentication information is obtained, the most convenient way of managing it for local use is to write it to a secret file using Auth.write(). It can also be accessed, e.g. to store in an environment variable, as Auth.value.

For example, to obtain and store authentication information:

import getpass
from planet import Auth

pw = getpass.getpass()
auth = Auth.from_login('user', 'pw')
auth.store()

The default authentication behavior of the Session can be modified by specifying Auth explicitly using the methods Auth.from_file() and Auth.from_env(). While Auth.from_key() and Auth.from_login can be used, it is recommended that those functions be used in authentication initialization and the authentication information be stored using Auth.store().

The file and environment variable read from can be customized in the respective functions. For example, authentication can be read from a custom environment variable:

import asyncio
import os
from planet import Auth, Session

auth = Auth.from_env('ALTERNATE_VAR')
async def main():
    async with Session(auth=auth) as sess:
        # perform operations here
        pass

asyncio.run(main())

Create an order

The Orders Client mostly mirrors the Orders API, with the only difference being the addition of the ability to poll for when an order is completed and to download an entire order.

async def main():
    async with Session() as sess:
        client = sess.client('orders')
        # perform operations here

asyncio.run(main())

Your orders client

When creating an order, the order request details must be provided to the API as a JSON blob. This JSON blob can be built up manually or by using the build_request function.

An example of creating the request JSON with build_request:

from planet import order_request
products = [
    order_request.product(['20170614_113217_3163208_RapidEye-5'],
                          'analytic', 'REOrthoTile')
]

tools = [
    order_request.toar_tool(scale_factor=10000),
    order_request.reproject_tool(projection='WSG84', kernel='cubic'),
    order_request.tile_tool(1232, origin_x=-180, origin_y=-90,
              pixel_size=0.000027056277056,
              name_template='C1232_30_30_{tilex:04d}_{tiley:04d}')
]

request = order_request.build_request(
    'test_order', products=products, tools=tools)

The same thing, expressed as a JSON blob:

request = {
  "name": "test_order",
  "products": [
    {
      "item_ids": [
        "20170614_113217_3163208_RapidEye-5"
      ],
      "item_type": "REOrthoTile",
      "product_bundle": "analytic"
    }
  ],
  "tools": [
    {
      "toar": {
        "scale_factor": 10000
      }
    },
    {
      "reproject": {
        "projection": "WSG84",
        "kernel": "cubic"
      }
    },
    {
      "tile": {
        "tile_size": 1232,
        "origin_x": -180,
        "origin_y": -90,
        "pixel_size": 2.7056277056e-05,
        "name_template": "C1232_30_30_{tilex:04d}_{tiley:04d}"
      }
    }
  ]
}

Once the order request is built up, creating an order is done within the context of a Session with the OrdersClient:

async def main():
    async with Session() as sess:
        cl = sess.client('orders')
        order = await cl.create_order(request)

asyncio.run(main())

Waiting and downloading an order

Once an order is created, the Orders API takes some time to create the order and thus we must wait a while before downloading the order. We can use waiting to watch the order creation process and find out when the order is created successfully and ready to download.

With wait and download, it is often desired to track progress as these processes can take a long time. Therefore, in this example, we use a progress bar from the reporting module to report wait status. download_order has reporting built in.

from planet import reporting

async def create_wait_and_download():
    async with Session() as sess:
        cl = sess.client('orders')
        with reporting.StateBar(state='creating') as bar:
            # create order
            order = await cl.create_order(request)
            bar.update(state='created', order_id=order['id'])

            # poll
            await cl.wait(order['id'], callback=bar.update_state)

        # download
        await cl.download_order(order['id'])

asyncio.run(create_poll_and_download())

Validating checksums

Checksum validation provides for verification that the files in an order have been downloaded successfully and are not missing, corrupted, or changed. This functionality is included in the OrderClient, but does not require an instance of the class to be used.

To perform checksum validation:

from pathlib import Path

# path includes order id
order_path = Path('193e5bd1-dedc-4c65-a539-6bc70e55d928')
OrdersClient.validate_checksum(order_path, 'md5')

Collecting results

Some API calls, such as searching for imagery and listing orders, return a varying, and potentially large, number of results. These API responses are paged. The SDK manages paging internally and the associated client commands return an asynchronous iterator over the results. These results can be converted to a JSON blob using the collect command. When the results represent GeoJSON features, the JSON blob is a GeoJSON FeatureCollection. Otherwise, the JSON blob is a list of the individual results.

import asyncio
from planet import collect, Session

async def main():
    async with Session() as sess:
        client = sess.client('orders')
        orders_list = collect(client.list_orders())

asyncio.run(main())

Alternatively, these results can be converted to a list directly with

orders_list = [o async for o in client.list_orders()]

Query the data catalog

The Data Client mostly mirrors the Data API, with the only difference being the addition of functionality to activate an asset, poll for when activation is complete, and download the asset.

async def main():
    async with Session() as sess:
        client = sess.client('data')
        # perform operations here

asyncio.run(main())

Filter

When performing a quick search, creating or updating a saved search, or requesting stats, the data search filter must be provided to the API as a JSON blob. This JSON blob can be built up manually or by using the data_filter module.

An example of creating the request JSON with data_filter:

from datetime import datetime
from planet import data_filter
sfilter = data_filter.and_filter([
    data_filter.permission_filter(),
    data_filter.date_range_filter('acquired', gt=datetime(2022, 6, 1, 1))
])

The same thing, expressed as a JSON blob:

sfilter = {
    'type': 'AndFilter',
    'config': [
        {'type': 'PermissionFilter', 'config': ['assets:download']},
        {
            'type': 'DateRangeFilter',
            'field_name': 'acquired',
            'config': {'gt': '2022-06-01T01:00:00Z'}
        }
    ]
}

Once the filter is built up, performing a search is done within the context of a Session with the DataClient:

async def main():
    async with Session() as sess:
        cl = sess.client('data')
        items = [i async for i in cl.search(['PSScene'], sfilter)]

asyncio.run(main())

Downloading an asset

Downloading an asset is a multi-step process involving: activating the asset, waiting for the asset to be active, downloading the asset, and, optionally, validating the downloaded file.

With wait and download, it is often desired to track progress as these processes can take a long time. Therefore, in this example, we use a simple print command to report wait status. download_asset has reporting built in.

async def download_and_validate():
    async with Session() as sess:
        cl = sess.client('data')

        # get asset description
        item_type_id = 'PSScene'
        item_id = '20221003_002705_38_2461'
        asset_type_id = 'ortho_analytic_4b'
        asset = await cl.get_asset(item_type_id, item_id, asset_type_id)

        # activate asset
        await cl.activate_asset(asset)

        # wait for asset to become active
        asset = await cl.wait_asset(asset, callback=print)

        # download asset
        path = await cl.download_asset(asset)

        # validate download file
        cl.validate_checksum(asset, path)
Back to top