Skip to content

Commit d19ebfb

Browse files
committed
Adding notebooks for Tasking Monitoring orders and locked-in orders
1 parent ed8c299 commit d19ebfb

File tree

4 files changed

+754
-11
lines changed

4 files changed

+754
-11
lines changed

jupyter-notebooks/tasking-api/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
These guides are to provide working examples of how to use and interact with Planet's [Tasking API](https://developers.planet.com/docs/tasking/). The Planet Tasking API provides the ability to create and manage tasking orders that will provide tasks for Planets satellites which will return beautiful high-resolution imagery. Currently these notebooks will focus on working directly with the API REST endpoints, but never fear, a Python client is on its way.
44

5-
These guides will show how to create a Tasking Order, explaining the various tasking order types available and the differences between them, how to edit or even cancel tasking orders that have been created and the restrictions that apply, as well as monitoring orders and how to download the images generated by a
6-
tasking order request.
5+
These guides will show how to create a Tasking Order, explaining the various tasking order types available and the differences between them, how to edit or even cancel tasking orders that have been created and the restrictions that apply, as well as monitoring orders and how to download the images generated by a tasking order request.
76

87
### The Notebooks
98
* [Create/Monitor/Download assest of a basic tasking order](planet_tasking_api_order_creation.ipynb)
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
{
2+
"metadata": {
3+
"language_info": {
4+
"codemirror_mode": {
5+
"name": "ipython",
6+
"version": 3
7+
},
8+
"file_extension": ".py",
9+
"mimetype": "text/x-python",
10+
"name": "python",
11+
"nbconvert_exporter": "python",
12+
"pygments_lexer": "ipython3",
13+
"version": 3
14+
},
15+
"orig_nbformat": 2
16+
},
17+
"nbformat": 4,
18+
"nbformat_minor": 2,
19+
"cells": [
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
24+
"# Planet Tasking API Monitoring Tasking Orders\n",
25+
"\n",
26+
"---"
27+
]
28+
},
29+
{
30+
"cell_type": "markdown",
31+
"metadata": {},
32+
"source": [
33+
"## Introduction\n",
34+
"\n",
35+
"---\n",
36+
"\n",
37+
"This tutorial is an introduction on how to create monitoring tasking orders using [Planet](https://www.planet.com)'s Tasking API. It provides code samples on how to write simple Python code to do this.\n",
38+
"\n",
39+
"The API reference documentation can be found at https://developers.planet.com/docs/tasking"
40+
]
41+
},
42+
{
43+
"cell_type": "markdown",
44+
"metadata": {},
45+
"source": [
46+
"### Requirements\n",
47+
"\n",
48+
"---\n",
49+
"\n",
50+
"#### Software & Modules\n",
51+
"\n",
52+
"This tutorial assumes familiarity with the [Python](https://python.org) programming language throughout. Familiarity with basic REST API concepts and usage is also assumed.\n",
53+
"\n",
54+
"We'll be using a **\"Jupyter Notebook\"** (aka Python Notebook) to run through the examples.\n",
55+
"To learn more about and get started with using Jupyter, visit: [Jupyter](https://jupyter.org/) and [IPython](https://ipython.org/). \n",
56+
"\n",
57+
"For the best experience, download this notebook and run it on your system, and make sure to install the modules listed below first. You can also copy the examples' code to a separate Python files an run them directly with Python on your system if you prefer.\n",
58+
"\n",
59+
"#### Planet API Key\n",
60+
"\n",
61+
"You should have an account on the Planet Platform to access the Tasking API. You may retrieve your API key from your [account page](https://www.planet.com/account/), or from the \"API Tab\" in [Planet Explorer](https://www.planet.com/explorer)."
62+
]
63+
},
64+
{
65+
"cell_type": "markdown",
66+
"metadata": {},
67+
"source": [
68+
"## Overview\n",
69+
"\n",
70+
"---\n",
71+
"\n",
72+
"### The basic workflow\n",
73+
"\n",
74+
"1. Create a monitoring tasking order\n",
75+
"1. Check the status of the tasking order"
76+
]
77+
},
78+
{
79+
"cell_type": "markdown",
80+
"metadata": {},
81+
"source": [
82+
"### API Endpoints\n",
83+
"\n",
84+
"This tutorial will cover the following API ***endpoint***:\n",
85+
"\n",
86+
"* [`/order`](https://api.planet.com/tasking/v2/order/)"
87+
]
88+
},
89+
{
90+
"cell_type": "markdown",
91+
"metadata": {},
92+
"source": [
93+
"## Basic Setup\n",
94+
"\n",
95+
"---\n",
96+
"\n",
97+
"Before interacting with the Planet Tasking API using Python, we will set up our environment with some useful modules and helper functions.\n",
98+
"\n",
99+
"* We'll configure *authentication* to the Planet Tasking API\n",
100+
"* We'll use the `requests` Python module to make HTTP communication easier. \n",
101+
"* We'll use the `json` Python module to help us work with JSON responses from the API.\n",
102+
"* We'll use the `pytz` Python module to define the time frame for the order that we will be creating.\n",
103+
"* We'll create a function called `p` that will print Python dictionaries nicely.\n",
104+
"\n",
105+
"Then we'll be ready to make our first call to the Planet Tasking API by hitting the base endpoint at `https://api.planet.com/tasking/v2`. \n",
106+
"\n",
107+
"Let's start by configuring authentication:"
108+
]
109+
},
110+
{
111+
"cell_type": "markdown",
112+
"metadata": {},
113+
"source": [
114+
"### Authentication\n",
115+
"\n",
116+
"Authentication with the Planet Tasking API can be achieved using a valid Planet **API key**.\n",
117+
"\n",
118+
"You can *export* your API Key as an environment variable on your system:\n",
119+
"\n",
120+
"`export PL_API_KEY=\"YOUR API KEY HERE\"`\n",
121+
"\n",
122+
"Or add the variable to your path, etc.\n",
123+
"\n",
124+
"To start our Python code, we'll setup an API Key variable from an environment variable to use with our requests:"
125+
]
126+
},
127+
{
128+
"cell_type": "code",
129+
"execution_count": null,
130+
"metadata": {},
131+
"outputs": [],
132+
"source": [
133+
"# Import the os module in order to access environment variables\n",
134+
"import os\n",
135+
"\n",
136+
"#If you are running this notebook outside of the docker environment that comes with the repo, you can uncomment the next line to provide your API key\n",
137+
"#os.environ['PL_API_KEY']=input('Please provide your API Key')\n",
138+
"\n",
139+
"# Setup the API Key from the `PL_API_KEY` environment variable\n",
140+
"PLANET_API_KEY = os.getenv('PL_API_KEY')"
141+
]
142+
},
143+
{
144+
"cell_type": "markdown",
145+
"metadata": {},
146+
"source": [
147+
"### Helper Modules and Functions"
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {},
154+
"outputs": [],
155+
"source": [
156+
"# Import helper modules\n",
157+
"import json\n",
158+
"import requests\n",
159+
"import pytz\n",
160+
"from time import sleep\n",
161+
"from datetime import datetime, timedelta"
162+
]
163+
},
164+
{
165+
"cell_type": "code",
166+
"execution_count": null,
167+
"metadata": {},
168+
"outputs": [],
169+
"source": [
170+
"# Helper function to printformatted JSON using the json module\n",
171+
"def p(data):\n",
172+
" print(json.dumps(data, indent=2))"
173+
]
174+
},
175+
{
176+
"cell_type": "code",
177+
"execution_count": null,
178+
"metadata": {},
179+
"outputs": [],
180+
"source": [
181+
"# Setup Planet Tasking PLANET_API_HOST\n",
182+
"TASKING_API_URL = \"https://api.planet.com/tasking/v2\"\n",
183+
"\n",
184+
"# Setup the session\n",
185+
"session = requests.Session()\n",
186+
"\n",
187+
"# Authenticate\n",
188+
"session.headers.update({\n",
189+
" 'Authorization': f'api-key {PLANET_API_KEY}',\n",
190+
" 'Content-Type': 'application/json'\n",
191+
"})"
192+
]
193+
},
194+
{
195+
"cell_type": "markdown",
196+
"metadata": {},
197+
"source": [
198+
"## 1 | Compose the monitoring tasking order\n",
199+
"\n",
200+
"We want to create a monitoring tasking order that can be set up to take images of the same location at a defined cadence, in this example once per week. To keep things simple we are going to create a Point order, which takes a single latitude/longitude coordinate pair. Since this is your monitoring order, you need to provide the details of what the tasing order is called, the coordinates, the time period over which the order should be active and the cadence.\n",
201+
"\n",
202+
"To make things easier, we will default the start and end time to start tomorrow and end 28 days from now, with the aim of taking four images if we stick to the weekly cadence. Of course, feel free to change this to suit your needs, but if you do, take note that all times should be in UTC format. Unlike a standard flexible tasking order, a monitoring tasking order requires the end time to be defined."
203+
]
204+
},
205+
{
206+
"cell_type": "code",
207+
"execution_count": null,
208+
"metadata": {},
209+
"outputs": [],
210+
"source": [
211+
"# Define the name and coordinates for the order\n",
212+
"name=input(\"Give the order a name\")\n",
213+
"latitude=float(input(\"Provide the latitude\"))\n",
214+
"longitude=float(input(\"Provide the longitude\"))\n",
215+
"\n",
216+
"# Because the geometry is GeoJSON, the coordinates must be longitude,latitude\n",
217+
"order = {\n",
218+
" 'name': name,\n",
219+
" 'geometry': {\n",
220+
" 'type': 'Point',\n",
221+
" 'coordinates': [\n",
222+
" longitude,\n",
223+
" latitude\n",
224+
" ]\n",
225+
" }\n",
226+
"}\n",
227+
"\n",
228+
"# Set a start and end time, giving the order a month to complete\n",
229+
"tomorrow = datetime.now(pytz.utc) + timedelta(days=1)\n",
230+
"twenty_eight_days_later = tomorrow + timedelta(days=28)\n",
231+
"\n",
232+
"# define the cadence\n",
233+
"cadence=7\n",
234+
"\n",
235+
"monitoring_parameters = {\n",
236+
" 'start_time': tomorrow.isoformat(),\n",
237+
" 'end_time': twenty_eight_days_later.isoformat(),\n",
238+
" 'monitoring_cadence': cadence\n",
239+
"}\n",
240+
"\n",
241+
"# Add the monitoring parameters\n",
242+
"order.update(monitoring_parameters)"
243+
]
244+
},
245+
{
246+
"cell_type": "code",
247+
"execution_count": null,
248+
"metadata": {},
249+
"outputs": [],
250+
"source": [
251+
"#View the payload before posting\n",
252+
"p(order)"
253+
]
254+
},
255+
{
256+
"cell_type": "code",
257+
"execution_count": null,
258+
"metadata": {},
259+
"outputs": [],
260+
"source": [
261+
"# The creation of an order is a POST request to the /orders endpoint\n",
262+
"res = session.request('POST', TASKING_API_URL + '/orders/', json=order)\n",
263+
"\n",
264+
"if res.status_code == 403:\n",
265+
" print('Your PLANET_API_KEY is valid, but you are not authorized.')\n",
266+
"elif res.status_code == 401:\n",
267+
" print('Your PLANET_API_KEY is incorrect')\n",
268+
"elif res.status_code == 201:\n",
269+
" print('Your order was created successfully')\n",
270+
"else:\n",
271+
" print(f'Received status code {res.status_code} from the API. Please contact support.')\n",
272+
"\n",
273+
"# View the response\n",
274+
"p(res.json())"
275+
]
276+
},
277+
{
278+
"cell_type": "markdown",
279+
"metadata": {},
280+
"source": [
281+
"**Congratulations!** You just created a monitoring tasking order using the Planet Tasking API. Depending on the parameters that you provided, a satellite will be attempting to take an image over your given coordinates in the near future."
282+
]
283+
},
284+
{
285+
"cell_type": "markdown",
286+
"metadata": {},
287+
"source": [
288+
"## 2 | Check the status of the monitoring order\n",
289+
"\n",
290+
"To see the status of the new monitoring tasking order, the tasking order id is required. Depending on the tasking order, it can take some time for the status of the tasking order to change, and so you may need to come back to this section once some time has elapsed before changes to the tasking order can be seen. It is recommended to run the next part of this notebook to extract the ID of the newly created order and save that for later use."
291+
]
292+
},
293+
{
294+
"cell_type": "code",
295+
"execution_count": null,
296+
"metadata": {},
297+
"outputs": [],
298+
"source": [
299+
"# Get the response JSON and extract the ID of the order\n",
300+
"response = res.json()\n",
301+
"new_order_id = response[\"id\"]\n",
302+
"p(new_order_id)"
303+
]
304+
},
305+
{
306+
"cell_type": "code",
307+
"execution_count": null,
308+
"metadata": {},
309+
"outputs": [],
310+
"source": [
311+
"def check_order_status(order_id):\n",
312+
" # Make a GET request with the order_id concatenated to the end of the /orders url; e.g. https://api.planet.com/tasking/v2/orders/<ORDER_ID>\n",
313+
" res = session.request('GET', TASKING_API_URL + '/orders/' + order_id)\n",
314+
"\n",
315+
" if res.status_code == 403:\n",
316+
" print('Your PLANET_API_KEYPLANET_API_KEY is valid, but you are not authorized to view this order.')\n",
317+
" elif res.status_code == 401:\n",
318+
" print('Your PLANET_API_KEYPLANET_API_KEY is incorrect')\n",
319+
" elif res.status_code == 404:\n",
320+
" print(f'Your order ({order_id}) does not exist')\n",
321+
" elif res.status_code != 200:\n",
322+
" print(f'Received status code {res.status_code} from the API. Please contact support.')\n",
323+
" else:\n",
324+
" order = res.json()\n",
325+
" p(res.json())\n",
326+
" print(f'Your order is {order[\"status\"]} with {order[\"capture_status_published_count\"]} published captures '\n",
327+
" f'and {order[\"capture_assessment_success_count\"]} successful captures')"
328+
]
329+
},
330+
{
331+
"cell_type": "code",
332+
"execution_count": null,
333+
"metadata": {},
334+
"outputs": [],
335+
"source": [
336+
"check_order_status(new_order_id)"
337+
]
338+
}
339+
]
340+
}

0 commit comments

Comments
 (0)