Repository: planetlabs/planet-client-python
Pull request #676 (2022-08-11 19:33:19)

Add STAC output orders request
As the title reads, I've added STAC output to the Orders CLIs and APIs `request` function.

`planet.cli.orders.py`
- Added `--stac` as a `click.option` as a flag (i.e., boolean)
    - @cholmes, I've set the default to be **_false_**, but I could be convinced that it should be set to true

`planet.orders_request.py`
- Added `stac` as an input to `build_request()`

`tests.integration.test_orders_cli.py`
- Added an integration test for the Orders CLI for a STAC output

`tests.unit.test_orders_request.py`
- Added a unit test for the Orders API (`build_request()`) for a STAC output

Below is an example of the STAC metadata at work:
```
> planet orders request \                          
--name Bangladesh_2018_visual \
--id 20180418_043113_1053,20180418_043112_1053 \
--item-type PSScene \
--bundle visual \
--stac

{"name": "Bangladesh_2018_visual", "products": [{"item_ids": ["20180418_043113_1053", "20180418_043112_1053"], "item_type": "PSScene", "product_bundle": "visual"}], "metadata": {"stac": {}}}
```

**FYI:** @cholmes @sgillies @jreiberkyle @mkshah605 

Closing #597 


Patch:
diff --git a/planet/cli/orders.py b/planet/cli/orders.py
index 12b642e..73138d5 100644
--- a/planet/cli/orders.py
+++ b/planet/cli/orders.py
@@ -263,6 +263,12 @@ async def create(ctx, request: str, pretty):
     type=types.JSON(),
     help="""Credentials for cloud storage provider to enable cloud delivery of
     data. Can be a json string, filename, or '-' for stdin.""")
+@click.option(
+    '--stac/--no-stac',
+    default=True,
+    is_flag=True,
+    help="""Do not request metadata to be in SpatioTemporal Asset Catalog
+    (STAC) format.""")
 @pretty
 async def request(ctx,
                   name,
@@ -273,6 +279,7 @@ async def request(ctx,
                   item_type,
                   email,
                   cloudconfig,
+                  stac,
                   pretty):
     """Generate an order request.
 
@@ -305,10 +312,16 @@ async def request(ctx,
     else:
         delivery = None
 
+    if stac:
+        stac_json = {'stac': {}}
+    else:
+        stac_json = {}
+
     request = planet.order_request.build_request(name,
                                                  products=[product],
                                                  delivery=delivery,
                                                  notifications=notifications,
-                                                 tools=tools)
+                                                 tools=tools,
+                                                 stac=stac_json)
 
     echo_json(request, pretty)
diff --git a/planet/order_request.py b/planet/order_request.py
index 104b028..911927b 100644
--- a/planet/order_request.py
+++ b/planet/order_request.py
@@ -28,7 +28,8 @@ def build_request(name: str,
                   delivery: dict = None,
                   notifications: dict = None,
                   order_type: str = None,
-                  tools: List[dict] = None) -> dict:
+                  tools: List[dict] = None,
+                  stac: dict = None) -> dict:
     '''Prepare an order request.
 
     ```python
@@ -86,6 +87,9 @@ def build_request(name: str,
     if tools:
         details['tools'] = tools
 
+    if stac:
+        details['metadata'] = stac
+
     return details
 
 


Test patch:
diff --git a/tests/integration/test_orders_cli.py b/tests/integration/test_orders_cli.py
index 11eb711..f47c6bb 100644
--- a/tests/integration/test_orders_cli.py
+++ b/tests/integration/test_orders_cli.py
@@ -44,6 +44,11 @@ def invoke():
     return _invoke
 
 
+@pytest.fixture
+def stac_json():
+    return {'stac': {}}
+
+
 @respx.mock
 def test_cli_orders_list_basic(invoke, order_descriptions):
     next_page_url = TEST_ORDERS_URL + '/blob/?page_marker=IAmATest'
@@ -451,7 +456,10 @@ def test_cli_orders_create_basic_success(expected_ids,
     [('4500474_2133707_2021-05-20_2419', ['4500474_2133707_2021-05-20_2419']),
      ('4500474_2133707_2021-05-20_2419,4500474_2133707_2021-05-20_2420',
       ['4500474_2133707_2021-05-20_2419', '4500474_2133707_2021-05-20_2420'])])
-def test_cli_orders_request_basic_success(expected_ids, id_string, invoke):
+def test_cli_orders_request_basic_success(expected_ids,
+                                          id_string,
+                                          invoke,
+                                          stac_json):
     result = invoke([
         'request',
         '--name=test',
@@ -469,6 +477,8 @@ def test_cli_orders_request_basic_success(expected_ids, id_string, invoke):
             "item_type": "PSOrthoTile",
             "product_bundle": "analytic"
         }],
+        "metadata":
+        stac_json
     }
     assert order_request == json.loads(result.output)
 
@@ -503,7 +513,8 @@ def test_cli_orders_request_id_empty(invoke):
 def test_cli_orders_request_clip_success(geom_fixture,
                                          request,
                                          invoke,
-                                         geom_geojson):
+                                         geom_geojson,
+                                         stac_json):
 
     geom = request.getfixturevalue(geom_fixture)
 
@@ -529,7 +540,9 @@ def test_cli_orders_request_clip_success(geom_fixture,
             'clip': {
                 'aoi': geom_geojson
             }
-        }]
+        }],
+        "metadata":
+        stac_json
     }
     assert order_request == json.loads(result.output)
 
@@ -566,7 +579,7 @@ def test_cli_orders_request_both_clip_and_tools(invoke, geom_geojson):
     assert "Specify only one of '--clip' or '--tools'" in result.output
 
 
-def test_cli_orders_request_cloudconfig(invoke):
+def test_cli_orders_request_cloudconfig(invoke, stac_json):
     config_json = {
         'amazon_s3': {
             'aws_access_key_id': 'aws_access_key_id',
@@ -596,12 +609,14 @@ def test_cli_orders_request_cloudconfig(invoke):
             "product_bundle": "analytic",
         }],
         "delivery":
-        config_json
+        config_json,
+        "metadata":
+        stac_json
     }
     assert order_request == json.loads(result.output)
 
 
-def test_cli_orders_request_email(invoke):
+def test_cli_orders_request_email(invoke, stac_json):
     result = invoke([
         'request',
         '--name=test',
@@ -621,14 +636,16 @@ def test_cli_orders_request_email(invoke):
             "product_bundle": "analytic",
         }],
         "notifications": {
-            "email": True
-        }
+            "email": True,
+        },
+        "metadata":
+        stac_json
     }
     assert order_request == json.loads(result.output)
 
 
 @respx.mock
-def test_cli_orders_request_tools(invoke, geom_geojson):
+def test_cli_orders_request_tools(invoke, geom_geojson, stac_json):
     tools_json = [{'clip': {'aoi': geom_geojson}}, {'composite': {}}]
 
     result = invoke([
@@ -649,6 +666,32 @@ def test_cli_orders_request_tools(invoke, geom_geojson):
             "product_bundle": "analytic",
         }],
         "tools":
-        tools_json
+        tools_json,
+        "metadata":
+        stac_json
+    }
+    assert order_request == json.loads(result.output)
+
+
+@respx.mock
+def test_cli_orders_request_no_stac(invoke):
+
+    result = invoke([
+        'request',
+        '--name=test',
+        '--id=4500474_2133707_2021-05-20_2419',
+        '--bundle=analytic',
+        '--item-type=PSOrthoTile',
+        '--no-stac'
+    ])
+
+    order_request = {
+        "name":
+        "test",
+        "products": [{
+            "item_ids": ["4500474_2133707_2021-05-20_2419"],
+            "item_type": "PSOrthoTile",
+            "product_bundle": "analytic",
+        }]
     }
     assert order_request == json.loads(result.output)
diff --git a/tests/unit/test_order_request.py b/tests/unit/test_order_request.py
index 0953e4e..0163357 100644
--- a/tests/unit/test_order_request.py
+++ b/tests/unit/test_order_request.py
@@ -52,13 +52,15 @@ def test_build_request():
     }
     order_type = 'partial'
     tool = {'band_math': 'jsonstring'}
+    stac_json = {'stac': {}}
 
     request = order_request.build_request('test_name', [product],
                                           subscription_id=subscription_id,
                                           delivery=delivery,
                                           notifications=notifications,
                                           order_type=order_type,
-                                          tools=[tool])
+                                          tools=[tool],
+                                          stac=stac_json)
     expected = {
         'name': 'test_name',
         'products': [product],
@@ -66,7 +68,8 @@ def test_build_request():
         'delivery': delivery,
         'notifications': notifications,
         'order_type': order_type,
-        'tools': [tool]
+        'tools': [tool],
+        'metadata': stac_json
     }
     assert request == expected
 
@@ -77,7 +80,8 @@ def test_build_request():
                                         delivery=delivery,
                                         notifications=notifications,
                                         order_type=order_type,
-                                        tools=[tool])
+                                        tools=[tool],
+                                        stac=stac_json)
 
 
 def test_product():