Planet API Python Client

This tutorial is an introduction to Planet's Data API using the official Python client, the planet module.

Requirements

This tutorial assumes familiarity with the Python programming language throughout. Python modules used in this tutorial are:

You should also have an account on the Planet Platform and retrieve your API key from your account page.

This tutorial will cover the basic operations possible with the Python client, particularly those that interact with the Data API.

The basic workflow for interacting with the Data API is:

  1. search item types based on filters
  2. activate assets
  3. download assets

Set up

In order to interact with the Planet API using the client, we need to import planet.api.


In [1]:
from planet import api

We next need to create a ClientV1 object registered with our API key. The API key will be automatically read from the PL_API_KEY environment variable if it exists. If not it can be provided when creating the api object.


In [2]:
client = api.ClientV1()
# client = api.ClientV1(api_key="abcdef0123456789") <-- not a real key

# print client.auth.value

ClientV1 provides basic low-level access to Planet’s API. Only one ClientV1 should be in existence for an application. The client is thread safe and takes care to avoid API throttling and also retries any throttled requests. Any exceptional HTTP responses are handled by translation to one of the planet.api.exceptions classes.

We will also create a small helper function to print out JSON with proper indentation.


In [3]:
import json

def p(data):
    print(json.dumps(data, indent=2))

Let's also read in a GeoJSON geometry into a variable so we can use it during testing.


In [4]:
with open("data/san-francisco.json") as f:
    geom = json.loads(f.read())

Searching

We can search for items that are interesting by using the quick_search member function. Searches, however, always require a proper request that includes a filter that selects the specific items to return as seach results.

Filters

The Planet Python client also includes planet.api.filters to assist in the creation of search filters.


In [5]:
from planet.api import filters

The possible filters include and_filter, date_filter, range_filter and so on, mirroring the options supported by the Planet API.


In [6]:
from datetime import datetime
start_date = datetime(year=2017, month=1, day=1)

date_filter = filters.date_range('acquired', gte=start_date)
cloud_filter = filters.range_filter('cloud_cover', lte=0.1)

In [7]:
and_filter = filters.and_filter(date_filter, cloud_filter)

In [8]:
p(and_filter)


{
  "type": "AndFilter",
  "config": [
    {
      "field_name": "acquired",
      "type": "DateRangeFilter",
      "config": {
        "gte": "2017-01-01T00:00:00Z"
      }
    },
    {
      "field_name": "cloud_cover",
      "type": "RangeFilter",
      "config": {
        "lte": 0.1
      }
    }
  ]
}

In addition to the filter, a properly-constructed request also contains the list of item types that we want to select.


In [9]:
item_types = ["REOrthoTile", "PSOrthoTile"]
req = filters.build_search_request(and_filter, item_types)

In [10]:
p(req)


{
  "item_types": [
    "REOrthoTile",
    "PSOrthoTile"
  ],
  "filter": {
    "type": "AndFilter",
    "config": [
      {
        "field_name": "acquired",
        "type": "DateRangeFilter",
        "config": {
          "gte": "2017-01-01T00:00:00Z"
        }
      },
      {
        "field_name": "cloud_cover",
        "type": "RangeFilter",
        "config": {
          "lte": 0.1
        }
      }
    ]
  }
}

In [11]:
res = client.quick_search(req)

The results of quick_search can be handled in different ways, but most commonly the user will either iterating through the list of items (items_iter) or writing items to a GeoJSON file (json_encode).

In either case, the number of items must be specified.


In [13]:
for item in res.items_iter(4):
    print(item['id'], item['properties']['item_type'])


1727806_1357318_2018-09-22_100e PSOrthoTile
1727806_1354111_2018-09-22_100e PSOrthoTile
1727806_1466421_2018-09-22_100e PSOrthoTile
1727806_1465419_2018-09-22_100e PSOrthoTile

If the number of items requested is more than 250, the client will automatically fetch more pages of results in order to get the exact number requested.


In [14]:
with open('output/results.json','w') as f:
    res.json_encode(f,1000)

This GeoJSON file can be opened and viewed in any compatible application.

Assets and downloads

After a search returns results, the Python client can be used to check for assets and initiate downloads.

The list of assets for an item can be retrieved with get_assets or get_assets_by_id.


In [15]:
print(item['id'])


1727806_1465419_2018-09-22_100e

In [16]:
assets = client.get_assets(item).get()

In [17]:
for asset in sorted(assets.keys()):
    print(asset)


analytic
analytic_dn
analytic_dn_xml
analytic_xml
udm
visual
visual_xml

In [18]:
activation = client.activate(assets['analytic'])
activation.response.status_code


Out[18]:
202

A response of 202 means that the request has been accepted and the activation will begin shortly. A 204 code indicates that the asset is already active and no further action is needed. A 401 code means the user does not have permissions to download this file.

Below, we are polling the API until the item is done activation. This may take awhile.


In [19]:
import time

asset_activated = False

while asset_activated == False:
    
    # Get asset and its activation status
    assets = client.get_assets(item).get()
    asset = assets.get('analytic')
    asset_status = asset["status"]
    
    # If asset is already active, we are done
    if asset_status == 'active':
        asset_activated = True
        print("Asset is active and ready to download")
   
    # Still activating. Wait and check again.
    else:
        print("...Still waiting for asset activation...")
        time.sleep(3)


...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
...Still waiting for asset activation...
Asset is active and ready to download

In [20]:
callback = api.write_to_file(directory='output/')
body = client.download(assets['analytic_xml'], callback=callback)
body.await()


Out[20]:
<planet.api.models.Body at 0x7f6f0e06d668>

Saved Searches

The Python API client can also help in managing saved searches on the Planet Platform.


In [21]:
searches = client.get_searches()

In [22]:
for search in searches.items_iter(100):
    print(search['id'], search['name'])


3b67071ddf0a4f2c9cd032d269992dae San Francisco
06b6392f4076460b9514e5c6a11d8577 Viet smaller AOI
fa1622c65a4644e58bd5cc3e51fe41ce Vietnam Label-Maker
378c4e84629a48688fac99c917214c76 San Francisco
7d793c34ee074cdebdb4c85b56b65e18 Medianía Alta

In [23]:
item_types = ["PSScene3Band"]
san_francisco_filter = filters.geom_filter(geom)
req = filters.build_search_request(san_francisco_filter, item_types, name="San Francisco")

In [24]:
p(req)


{
  "item_types": [
    "PSScene3Band"
  ],
  "filter": {
    "field_name": "geometry",
    "type": "GeometryFilter",
    "config": {
      "type": "Polygon",
      "coordinates": [
        [
          [
            -122.47455596923828,
            37.810326435534755
          ],
          [
            -122.49172210693358,
            37.795406713958236
          ],
          [
            -122.52056121826172,
            37.784282779035216
          ],
          [
            -122.51953124999999,
            37.6971326434885
          ],
          [
            -122.38941192626953,
            37.69441603823106
          ],
          [
            -122.38872528076173,
            37.705010235842614
          ],
          [
            -122.36228942871092,
            37.70935613533687
          ],
          [
            -122.34992980957031,
            37.727280276860036
          ],
          [
            -122.37773895263672,
            37.76230130281876
          ],
          [
            -122.38494873046875,
            37.794592824285104
          ],
          [
            -122.40554809570311,
            37.813310018173155
          ],
          [
            -122.46150970458983,
            37.805715207044685
          ],
          [
            -122.47455596923828,
            37.810326435534755
          ]
        ]
      ]
    }
  },
  "name": "San Francisco"
}

In [25]:
res = client.create_search(req)

In [26]:
search = res.get()
print(search["id"], search["name"])


f1d47dd8eb00453da94cf5f0d690bb10 San Francisco

In [27]:
res = client.saved_search(search["id"])

In [28]:
for item in res.items_iter(20):
    print(item["id"], item["properties"]["view_angle"])


20180926_181023_0f40 0
20180926_181022_0f40 0
20180926_181024_0f40 0
20180926_182749_1018 0.5
20180926_182750_1018 0.5
20180926_182747_1018 0.5
20180925_181112_100d 0.2
20180925_181113_100d 0.2
20180925_181115_100d 0.2
20180925_213151_0f02 0
20180925_213153_0f02 0
20180925_181114_100d 0.1
20180925_213152_0f02 0
20180925_182742_0f34 1.3
20180925_182741_0f34 1.3
20180925_182743_0f34 1.2
20180924_182734_101e 0.1
20180924_182736_101e 0.1
20180924_182735_101e 0.1
20180923_213329_0f4c 0

Statistics

The Python API client can also help report statistical summaries of the amount of data in the Planet API.


In [29]:
item_types = ["PSScene3Band"]
san_francisco_filter = filters.geom_filter(geom)
req = filters.build_search_request(san_francisco_filter, item_types, interval="year")

In [30]:
stats = client.stats(req).get()

In [31]:
p(stats)


{
  "utc_offset": "+0h",
  "interval": "year",
  "buckets": [
    {
      "count": 3,
      "start_time": "2014-01-01T00:00:00.000000Z"
    },
    {
      "count": 54,
      "start_time": "2015-01-01T00:00:00.000000Z"
    },
    {
      "count": 204,
      "start_time": "2016-01-01T00:00:00.000000Z"
    },
    {
      "count": 1083,
      "start_time": "2017-01-01T00:00:00.000000Z"
    },
    {
      "count": 1207,
      "start_time": "2018-01-01T00:00:00.000000Z"
    }
  ]
}

In [32]:
assets = client.get_assets(item)

In [33]:
assets.last_modified()

In [34]:
assets.get()


Out[34]:
{'analytic': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWMiLCAiY3QiOiAiaXRlbS10eXBlIn0',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWMiLCAiY3QiOiAiaXRlbS10eXBlIn0/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/analytic'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'analytic'},
 'analytic_dn': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfZG4iLCAiY3QiOiAiaXRlbS10eXBlIn0',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfZG4iLCAiY3QiOiAiaXRlbS10eXBlIn0/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/analytic_dn'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'analytic_dn'},
 'analytic_dn_xml': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfZG5feG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfZG5feG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/analytic_dn_xml'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'analytic_dn_xml'},
 'analytic_xml': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfeG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYW5hbHl0aWNfeG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/analytic_xml'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'analytic_xml'},
 'basic_analytic': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWMiLCAiY3QiOiAiaXRlbS10eXBlIn0',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWMiLCAiY3QiOiAiaXRlbS10eXBlIn0/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic'},
 'basic_analytic_dn': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG4iLCAiY3QiOiAiaXRlbS10eXBlIn0',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG4iLCAiY3QiOiAiaXRlbS10eXBlIn0/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic_dn'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic_dn'},
 'basic_analytic_dn_rpc': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG5fcnBjIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG5fcnBjIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic_dn_rpc'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic_dn_rpc'},
 'basic_analytic_dn_xml': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG5feG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfZG5feG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic_dn_xml'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic_dn_xml'},
 'basic_analytic_rpc': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfcnBjIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfcnBjIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic_rpc'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic_rpc'},
 'basic_analytic_xml': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfeG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfYW5hbHl0aWNfeG1sIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_analytic_xml'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_analytic_xml'},
 'basic_udm': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfdWRtIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAiYmFzaWNfdWRtIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/basic_udm'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'basic_udm'},
 'udm': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidWRtIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidWRtIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/udm'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'udm'},
 'visual': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidmlzdWFsIiwgImN0IjogIml0ZW0tdHlwZSJ9',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidmlzdWFsIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/visual'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'visual'},
 'visual_xml': {'_links': {'_self': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidmlzdWFsX3htbCIsICJjdCI6ICJpdGVtLXR5cGUifQ',
   'activate': 'https://api.planet.com/data/v1/assets/eyJpIjogIjIwMTgwOTIzXzIxMzMyOV8wZjRjIiwgImMiOiAiUFNTY2VuZTNCYW5kIiwgInQiOiAidmlzdWFsX3htbCIsICJjdCI6ICJpdGVtLXR5cGUifQ/activate',
   'type': 'https://api.planet.com/data/v1/asset-types/visual_xml'},
  '_permissions': ['download'],
  'md5_digest': None,
  'status': 'inactive',
  'type': 'visual_xml'}}

In [ ]: