Skip to content

Move v2 orders client over to async #240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b82e55c
move to py3.7+, implement async create and cancel order and download …
jreiberkyle Jan 26, 2021
8fffc3c
download order, optional progresss bar for downloads
jreiberkyle Jan 27, 2021
fca5990
cleanup
jreiberkyle Jan 27, 2021
fbfb824
implement async cancel orders
jreiberkyle Jan 27, 2021
377c3b1
implement list orders
jreiberkyle Jan 30, 2021
1daab03
fix list orders so it does not retrieve more pages if limit is reached
jreiberkyle Feb 3, 2021
8cd4828
move Paged to models and add unit tests
jreiberkyle Feb 3, 2021
27590fe
move orders and orderspaged to models
jreiberkyle Feb 4, 2021
51fe020
cleaning up tests, orders
jreiberkyle Feb 4, 2021
3092019
implement aggregated_order_stats
jreiberkyle Feb 4, 2021
ee0c418
full test coverage for AOrdersClient
jreiberkyle Feb 5, 2021
670ca5c
add lost test data file
jreiberkyle Feb 5, 2021
0e45064
workaround for respx issue that still allows running test
jreiberkyle Feb 17, 2021
e0db54b
update function level documentation
jreiberkyle Feb 17, 2021
ccac3f0
get tox up and running again
jreiberkyle Feb 17, 2021
b59b328
sophisticated order details handling, allow creating order details fr…
jreiberkyle Mar 2, 2021
534f184
update readme with python library examples
jreiberkyle Mar 3, 2021
75c8208
add verbose flag to poll
jreiberkyle Mar 3, 2021
8f93139
remove requests dependency
jreiberkyle Mar 3, 2021
f87e393
update Python req in README
jreiberkyle Mar 3, 2021
866ca40
fix doctest and flake8 issues, remove utils and move functionality in…
jreiberkyle Mar 3, 2021
710c49f
remove mock dependency
jreiberkyle Mar 3, 2021
79b799d
fix small test error
jreiberkyle Mar 3, 2021
7abfad6
Apply suggestions from code review
jreiberkyle Mar 10, 2021
410aee8
update authentication information
jreiberkyle Mar 10, 2021
88fb4e5
test/fix code examples
jreiberkyle Mar 10, 2021
35d2ddd
small doc fixes
jreiberkyle Mar 10, 2021
4fd89a7
fill in a bit more about sync and add reference to sync need ticket
jreiberkyle Mar 10, 2021
a33ac22
move to top-level imports
jreiberkyle Mar 11, 2021
69dfa26
rename APlanetSession -> Session, AOrdersClient -> OrdersClient
jreiberkyle Mar 11, 2021
e934584
add documentation on waiting for httpx retry
jreiberkyle Mar 11, 2021
37df69e
remove unused scripts
jreiberkyle Mar 16, 2021
61d38ad
more helpful intro to async programming
jreiberkyle Mar 16, 2021
018d38a
APlanetSession -> Session, match test names to modules
jreiberkyle Mar 16, 2021
8307e74
throw more specific exception, add test
jreiberkyle Mar 18, 2021
3f117b2
use HTTPStatus instead of integers for status codes
jreiberkyle Mar 18, 2021
ba19a61
remove elevated module imports at planet.api level
jreiberkyle Mar 18, 2021
e476019
remove references to CLI
jreiberkyle Mar 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: python
python:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
cache:
directories:
- $HOME/.cache/pip
Expand Down
169 changes: 139 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Build Status](https://travis-ci.org/planetlabs/planet-client-python.svg?branch=master)](https://travis-ci.org/planetlabs/planet-client-python)

Python client library and CLI for Planet's public APIs.
Python client library for Planet's APIs.

The client provides access to the following Planet APIs:
* [analytics](https://developers.planet.com/docs/analytics/)
Expand All @@ -14,7 +14,7 @@ The client provides access to the following Planet APIs:

### Prerequisites

* Python version 3.6+
* Python version 3.7+

### Install package

Expand All @@ -28,49 +28,158 @@ flag is highly recommended for those new to [pip](https://pip.pypa.io).
A PEX executable (Windows not supported) and source releases are
[here](https://github.com/planetlabs/planet-client-python/releases/latest).

## Documentation
## Authentication

Online documentation:
https://planetlabs.github.io/planet-client-python/index.html
Planet's APIs require an account for use.
[Sign up here](https://www.planet.com/explorer/?signup).

Documentation is also provided for download
[here](https://github.com/planetlabs/planet-client-python/releases/latest).

## Quick Start

## Development
The client modules within the Python library are asynchronous, which greatly
speeds up many interactions with Planet's APIs. Support for asynchronous
development is native to Python 3.6+ via the
[`asyncio` module](https://docs.python.org/3/library/asyncio.html). A great
resource for getting started with asynchronous programming in Python is
https://project-awesome.org/timofurrer/awesome-asyncio. The Writings and Talks
sections are particularly helpful in getting oriented.

To contribute or develop with this library, see
[CONTRIBUTING](https://github.com/planetlabs/planet-client-python/CONTRIBUTING.md)
```python
import asyncio
import os

import planet

## API Key
API_KEY = os.getenv('PL_API_KEY')

The API requires an account for use. [Signup here](https://www.planet.com/explorer/?signup).
image_ids = ['3949357_1454705_2020-12-01_241c']
order_details = planet.OrderDetails(
'test_order',
[planet.Product(image_ids, 'analytic', 'psorthotile')]
)

This can be provided via the environment variable `PL_API_KEY` or the flag `-k` or `--api-key`.
async def create_order(order_details):
async with planet.Session(auth=(API_KEY, '')) as ps:
client = planet.OrdersClient(ps)
return await client.create_order(order_details)

Using `planet init` your account credentials (login/password) can be used to obtain the api key.
oid = asyncio.run(create_order(order_details))
print(oid)
```

Not into async? No problem. Just wrap the library and async operations together
and call from your synchronous code.

# Example CLI Usage
```python
def sync_create_order(order_details):
return asyncio.run(create_order(order_details))

**Hint:** autocompletion can be enabled in some shells using:
```console
$ eval "$(_PLANET_COMPLETE=source planet)"
oid = sync_create_order(order_details)
print(oid)
```

Basics and help:

```console
$ planet --help
When using `asyncio.run` to develop synchronous code with the async library,
keep in mind this excerpt from the
[asyncio.run](https://docs.python.org/3/library/asyncio-task.html#asyncio.run)
documentation:

"*This function always creates a new event loop and closes it at the end. It
should be used as a main entry point for asyncio programs, and should ideally
only be called once.*"

Do you have a use case where native synchronous support is essential? If so,
please contribute to
[Determine need for synchronous support](https://github.com/planetlabs/planet-client-python/issues/251)


Why async? Because things get *really cool* when you want to work with multiple
orders. Here's an example of submitting two orders, waiting for them to
complete, and downloading them. The orders each clip a set of images to a
specific area of interest (AOI), so they cannot be combined into one order.
(hint: [Planet Explorer](https://www.planet.com/explorer/) was used to define
the AOIs and get the image ids.)


```python
import asyncio
import os

import planet

API_KEY = os.getenv('PL_API_KEY')

iowa_aoi = {
"type": "Polygon",
"coordinates": [[
[-91.198465, 42.893071],
[-91.121931, 42.893071],
[-91.121931, 42.946205],
[-91.198465, 42.946205],
[-91.198465, 42.893071]]]
}

iowa_images = [
'20200925_161029_69_2223',
'20200925_161027_48_2223'
]
iowa_order = planet.OrderDetails(
'iowa_order',
[planet.Product(iowa_images, 'analytic', 'PSScene4Band')],
tools=[planet.Tool('clip', {'aoi': iowa_aoi})]
)

oregon_aoi = {
"type": "Polygon",
"coordinates": [[
[-117.558734, 45.229745],
[-117.452447, 45.229745],
[-117.452447, 45.301865],
[-117.558734, 45.301865],
[-117.558734, 45.229745]]]
}

oregon_images = [
'20200909_182525_1014',
'20200909_182524_1014'
]
oregon_order = planet.OrderDetails(
'oregon_order',
[planet.Product(oregon_images, 'analytic', 'PSScene4Band')],
tools=[planet.Tool('clip', {'aoi': oregon_aoi})]
)


async def create_and_download(order_detail, client):
oid = await client.create_order(order_detail)
print(oid)
state = await client.poll(oid, verbose=True)
print(state)
filenames = await client.download_order(oid, progress_bar=True)
print(f'downloaded {oid}, {len(filenames)} files downloaded.')


async def main():
async with planet.Session(auth=(API_KEY, '')) as ps:
client = planet.OrdersClient(ps)
await asyncio.gather(
create_and_download(iowa_order, client),
create_and_download(oregon_order, client)
)

asyncio.run(main())
```
[Example output](example_output.md)

Specific API client usage:
```console
$ planet data
```

Specific command help:
```console
$ planet data download --help
```
## Documentation

Online documentation:
https://planetlabs.github.io/planet-client-python/index.html

Documentation is also provided for download
[here](https://github.com/planetlabs/planet-client-python/releases/latest).

## Development

To contribute or develop with this library, see
[CONTRIBUTING](https://github.com/planetlabs/planet-client-python/CONTRIBUTING.md)
66 changes: 66 additions & 0 deletions example_output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
```
a27c63c9-a076-4db2-a2e3-c1ff35655cbd
5d5892b5-3ec0-4df7-9852-a27a40baf0c1
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: queued
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: queued
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: running
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
order a27c63c9-a076-4db2-a2e3-c1ff35655cbd state: success
success
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: running
./20200909_182525_1014_3B_AnalyticMS_clip.tif: 100%|███████████████████████████████████████████████████████████████████████████████████| 35.8k/35.8k [00:03<00:00, 9.97MB/s]
./20200909_182525_1014_metadata.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 4.08MB/s]
./20200909_182525_1014_3B_AnalyticMS_metadata_clip.xml: 100%|██████████████████████████████████████████████████████████████████████████| 0.01k/0.01k [00:00<00:00, 7.12MB/s]
./20200909_182525_1014_3B_AnalyticMS_DN_udm_clip.tif: 100%|████████████████████████████████████████████████████████████████████████████| 0.06k/0.06k [00:00<00:00, 1.81MB/s]
./20200909_182524_1014_3B_AnalyticMS_clip.tif: 100%|███████████████████████████████████████████████████████████████████████████████████| 33.6k/33.6k [00:02<00:00, 12.2MB/s]
./20200909_182524_1014_3B_AnalyticMS_DN_udm_clip.tif: 100%|████████████████████████████████████████████████████████████████████████████| 0.08k/0.08k [00:00<00:00, 1.78MB/s]
order 5d5892b5-3ec0-4df7-9852-a27a40baf0c1 state: success
success
./20200909_182524_1014_3B_AnalyticMS_metadata_clip.xml: 100%|██████████████████████████████████████████████████████████████████████████| 0.01k/0.01k [00:00<00:00, 9.77MB/s]
./20200909_182524_1014_metadata.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 3.12MB/s]
./manifest.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 8.29MB/s]
downloaded a27c63c9-a076-4db2-a2e3-c1ff35655cbd, 9 files downloaded.
./20200925_161029_69_2223_3B_AnalyticMS_metadata_clip.xml: 100%|███████████████████████████████████████████████████████████████████████| 0.01k/0.01k [00:00<00:00, 8.93MB/s]
./20200925_161029_69_2223_3B_AnalyticMS_clip.tif: 100%|████████████████████████████████████████████████████████████████████████████████| 21.3k/21.3k [00:01<00:00, 12.0MB/s]
./20200925_161029_69_2223_3B_AnalyticMS_DN_udm_clip.tif: 100%|█████████████████████████████████████████████████████████████████████████| 0.07k/0.07k [00:00<00:00, 1.99MB/s]
./20200925_161029_69_2223_metadata.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 1.78MB/s]
./20200925_161027_48_2223_metadata.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 2.24MB/s]
./20200925_161027_48_2223_3B_AnalyticMS_clip.tif: 100%|████████████████████████████████████████████████████████████████████████████████| 33.9k/33.9k [00:02<00:00, 11.9MB/s]
./20200925_161027_48_2223_3B_AnalyticMS_DN_udm_clip.tif: 100%|█████████████████████████████████████████████████████████████████████████| 0.08k/0.08k [00:00<00:00, 1.85MB/s]
./20200925_161027_48_2223_3B_AnalyticMS_metadata_clip.xml: 100%|███████████████████████████████████████████████████████████████████████| 0.01k/0.01k [00:00<00:00, 11.7MB/s]
./manifest.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 0.00k/0.00k [00:00<00:00, 8.52MB/s]
downloaded 5d5892b5-3ec0-4df7-9852-a27a40baf0c1, 9 files downloaded.
```

23 changes: 23 additions & 0 deletions planet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,26 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .api.http import Session
from .api.models import Order
from .api.orders import OrdersClient
from .api.order_details import (
OrderDetails, Product, Notifications, Delivery, AmazonS3Delivery,
AzureBlobStorageDelivery, GoogleCloudStorageDelivery,
GoogleEarthEngineDelivery, Tool)
from .api.__version__ import __version__ # NOQA
Copy link
Contributor

Choose a reason for hiding this comment

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

This import appears unused and can be removed.


__all__ = [
Session,
OrdersClient,
Order,
OrderDetails,
Product,
Notifications,
Delivery,
AmazonS3Delivery,
AzureBlobStorageDelivery,
GoogleCloudStorageDelivery,
GoogleEarthEngineDelivery,
Tool
]
7 changes: 0 additions & 7 deletions planet/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from .orders import OrdersClient
from .__version__ import __version__ # NOQA

__all__ = [
OrdersClient
]
58 changes: 0 additions & 58 deletions planet/api/auth.py

This file was deleted.

Loading