diff --git a/docs/cli/cli-orders.md b/docs/cli/cli-orders.md index 444994f46..ab4778088 100644 --- a/docs/cli/cli-orders.md +++ b/docs/cli/cli-orders.md @@ -107,19 +107,19 @@ If you don't have access to PlanetScope data then replace PSScene with SkySatCol Then make the following call: ```console -planet orders request PSScene visual --name 'My First Order' --id 20220605_124027_64_242b +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'My First Order' 20220605_124027_64_242b ``` Running the above command should output the JSON needed to create an order: ```json -{"name": "My First Order", "products": [{"item_ids": ["20220605_124027_64_242b"], "item_type": "PSScene", "product_bundle": "analytic_sr_udm2"}]} +{"name": "My First Order", "products": [{"item_ids": ["20220605_124027_64_242b"], "item_type": "PSScene", "product_bundle": "analytic_sr_udm2"}], "metadata": {"stac": {}}} ``` You can also use `jq` here to make it a bit more readable: ```console -planet orders request PSScene analytic_sr_udm2 --name 'My First Order' --id 20220605_124027_64_242b | jq +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'My First Order' 20220605_124027_64_242b | jq ``` ```json @@ -133,7 +133,10 @@ planet orders request PSScene analytic_sr_udm2 --name 'My First Order' --id 2022 "item_type": "PSScene", "product_bundle": "analytic_sr_udm2" } - ] + ], + "metadata": { + "stac": {} + } } ``` @@ -143,7 +146,7 @@ The above command just prints out the necessary JSON to create an order. To actu save the output into a file: ```console -planet orders request PSScene analytic_sr_udm2 --name "My First Order" --id 20220605_124027_64_242b \ +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name "My First Order" 20220605_124027_64_242b \ > request-1.json ``` @@ -200,8 +203,8 @@ passing the output of the `orders request` command directly to be the input of t command: ```console -planet orders request PSScene analytic_sr_udm2 --name 'Two Item Order' \ ---id 20220605_124027_64_242b,20220605_124025_34_242b | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Two Item Order' \ +20220605_124027_64_242b,20220605_124025_34_242b | planet orders create - ``` The Planet CLI is designed to work well with piping, as it aims at small commands that can be @@ -357,8 +360,8 @@ You can move that geometry to your current directory and use the following comma tweak the geometry.geojson to refer to where you downloaded it. ```console -planet orders request PSScene analytic_sr_udm2 --clip geometry.geojson --name clipped-geom \ - --id 20220605_124027_64_242b | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --clip geometry.geojson --name clipped-geom \ + 20220605_124027_64_242b | planet orders create - ``` ### Additional Tools @@ -406,8 +409,8 @@ Example: `tools.json` Ordering two scenes is easy, just add another id: ```console -planet orders request PSScene analytic_sr_udm2 --name 'Two Scenes' \ - --id 20220605_124027_64_242b,20220605_124025_34_242b | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Two Scenes' \ + 20220605_124027_64_242b,20220605_124025_34_242b | planet orders create - ``` And then you can composite them together, using the 'tools' json. You can @@ -426,8 +429,8 @@ Once you've got it saved you call the `--tools` flag to refer to the JSON file, can pipe that to `orders create`. ```console -planet orders request PSScene analytic_sr_udm2 --name 'Two Scenes Composited' \ ---id 20220605_124027_64_242b,20220605_124025_34_242b --no-stac --tools tools-composite.json | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Two Scenes Composited' \ + 20220605_124027_64_242b,20220605_124025_34_242b --no-stac --tools tools-composite.json | planet orders create - ``` Note that we add the `--no-stac` option as [STAC Metadata](#stac-metadata) is not yet supported by the composite @@ -452,8 +455,8 @@ as COG in the file format tool. The following command just shows the output with [tools-cog.json](https://raw.githubusercontent.com/planetlabs/planet-client-python/main/docs/cli/request-json/tools-cog.json): ```console -planet orders request PSScene analytic_sr_udm2 --name 'COG Order' \ - --id 20220605_124027_64_242b,20220605_124025_34_242b --tools tools-cog.json +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'COG Order' \ + 20220605_124027_64_242b,20220605_124025_34_242b --tools tools-cog.json ``` As shown above you can also pipe that output directly in to `orders create`. @@ -504,16 +507,16 @@ so you can just use the [following json](https://raw.githubusercontent.com/plane ``` ```console -planet orders request PSScene analytic_sr_udm2 --no-stac --name 'Two Scenes Clipped and Composited' \ - --id 20220605_124027_64_242b,20220605_124025_34_242b --tools tools-clip-composite.json | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --no-stac --name 'Two Scenes Clipped and Composited' \ + 20220605_124027_64_242b,20220605_124025_34_242b --tools tools-clip-composite.json | planet orders create - ``` One cool little trick is that you can even stream in the JSON directly with `curl`, piping it into the request: ```console curl -s https://raw.githubusercontent.com/planetlabs/planet-client-python/main/docs/cli/request-json/tools-clip-composite.json \ -| planet orders request PSScene analytic_sr_udm2 --name 'Streaming Clip & Composite' \ - --id 20220605_124027_64_242b,20220605_124025_34_242b --tools - | planet orders create - +| planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Streaming Clip & Composite' \ + 20220605_124027_64_242b,20220605_124025_34_242b --tools - | planet orders create - ``` ### Harmonize @@ -533,7 +536,7 @@ The harmonize tool allows you to compare data to different generations of satell You may create an order request by calling [`tools-harmonize.json`](https://raw.githubusercontent.com/planetlabs/planet-client-python/main/docs/cli/request-json/tools-harmonize.json) with `--tools`. ```console -planet orders request psscene analytic_sr_udm2 --name 'Harmonized data' --id 20200925_161029_69_2223 --tools tools-harmonize.json +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Harmonized data' 20200925_161029_69_2223 --tools tools-harmonize.json ``` ## More options @@ -668,9 +671,9 @@ image that was published: ```console -planet orders request SkySatCollect analytic --name 'SkySat Latest' \ ---id `planet data filter | planet data search SkySatCollect --sort 'acquired desc' --limit 1 - | jq -r .id` \ -| planet orders create - +planet orders request --item-type SkySatCollect --bundle analytic --name 'SkySat Latest' \ + `planet data filter | planet data search SkySatCollect --sort 'acquired desc' --limit 1 - | jq -r .id` \ +| planet orders create - ``` Or get the 5 latest cloud free images in an area and create an order that clips to that area, using @@ -679,8 +682,8 @@ Or get the 5 latest cloud free images in an area and create an order that clips ```console ids=`planet data filter --geom geometry.geojson --range clear_percent gt 90 | planet data \ search PSScene --limit 5 - | jq -r .id | tr '\n' , | sed 's/.$//'` -planet orders request PSScene analytic_sr_udm2 --name 'Clipped Scenes' \ ---id $ids --clip geometry.geojson | planet orders create - +planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Clipped Scenes' \ + $ids --clip geometry.geojson | planet orders create - ``` This one uses some advanced unix capabilities like `sed` and `tr`, along with unix variables, so more diff --git a/planet/cli/orders.py b/planet/cli/orders.py index b126a4dc8..998168e17 100644 --- a/planet/cli/orders.py +++ b/planet/cli/orders.py @@ -225,22 +225,21 @@ async def create(ctx, request: str, pretty): @click.pass_context @translate_exceptions @coro -@click.argument('item_type', - metavar='ITEM_TYPE', - type=click.Choice(planet.specs.get_item_types(), - case_sensitive=False)) -@click.argument('bundle', - metavar='BUNDLE', - type=click.Choice(planet.specs.get_product_bundles(), - case_sensitive=False)) +@click.argument('ids', metavar='IDS', type=types.CommaSeparatedString()) +@click.option('--item-type', + required=True, + help='Item type for requested item ids.', + type=click.Choice(planet.specs.get_item_types(), + case_sensitive=False)) +@click.option('--bundle', + required=True, + help='Asset type for the item.', + type=click.Choice(planet.specs.get_product_bundles(), + case_sensitive=False)) @click.option('--name', required=True, help='Order name. Does not need to be unique.', type=click.STRING) -@click.option('--id', - help='One or more comma-separated item IDs.', - type=types.CommaSeparatedString(), - required=True) @click.option('--clip', type=types.JSON(), help="""Clip feature GeoJSON. Can be a json string, filename, @@ -270,7 +269,7 @@ async def request(ctx, item_type, bundle, name, - id, + ids, clip, tools, email, @@ -280,11 +279,13 @@ async def request(ctx, """Generate an order request. This command provides support for building an order description used - in creating an order. It outputs the order request, optionally pretty- - printed. + in creating an order. It outputs the order request, optionally + pretty-printed. + + IDs is one or more comma-separated item IDs. """ try: - product = planet.order_request.product(id, bundle, item_type) + product = planet.order_request.product(ids, bundle, item_type) except planet.specs.SpecificationException as e: raise click.BadParameter(e) diff --git a/tests/integration/test_orders_cli.py b/tests/integration/test_orders_cli.py index 16c7a9f66..4cfda8720 100644 --- a/tests/integration/test_orders_cli.py +++ b/tests/integration/test_orders_cli.py @@ -461,10 +461,10 @@ def test_cli_orders_request_basic_success(expected_ids, stac_json): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - f'--id={id_string}', + id_string, ]) assert not result.exception @@ -485,45 +485,44 @@ def test_cli_orders_request_basic_success(expected_ids, def test_cli_orders_request_item_type_invalid(invoke): result = invoke([ 'request', - 'invalid' - 'analytic', + '--item-type=invalid' + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', ]) assert result.exit_code == 2 - error_msg = "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" - assert error_msg in result.output def test_cli_orders_request_product_bundle_invalid(invoke): result = invoke([ 'request', - 'PSScene' - 'invalid', + '--item-type=PSScene' + '--bundle=invalid', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', ]) assert result.exit_code == 2 - error_msg = "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" - assert error_msg in result.output def test_cli_orders_request_product_bundle_incompatible(invoke): result = invoke([ 'request', - 'PSScene', - 'analytic', + '--item-type=PSScene', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', ]) assert result.exit_code == 2 - error_msg = "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" - assert error_msg in result.output def test_cli_orders_request_id_empty(invoke): - result = invoke( - ['request', 'PSOrthoTile', 'analytic', '--name=test', '--id=']) + result = invoke([ + 'request', + '--item-type=PSOrthoTile', + '--bundle=analytic', + '--name=test', + '' + ]) assert result.exit_code == 2 assert 'Entry cannot be an empty string.' in result.output @@ -541,10 +540,10 @@ def test_cli_orders_request_clip_success(geom_fixture, result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', f'--clip={json.dumps(geom)}', ]) assert result.exit_code == 0 @@ -571,10 +570,10 @@ def test_cli_orders_request_clip_success(geom_fixture, def test_cli_orders_request_clip_invalid_geometry(invoke, point_geom_geojson): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', f'--clip={json.dumps(point_geom_geojson)}' ]) assert result.exit_code == 2 @@ -588,10 +587,10 @@ def test_cli_orders_request_both_clip_and_tools(invoke, geom_geojson): # option values are valid json result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', f'--clip={json.dumps(geom_geojson)}', f'--tools={json.dumps(geom_geojson)}' ]) @@ -613,10 +612,10 @@ def test_cli_orders_request_cloudconfig(invoke, stac_json): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', f'--cloudconfig={json.dumps(config_json)}', ]) assert result.exit_code == 0 @@ -640,10 +639,10 @@ def test_cli_orders_request_cloudconfig(invoke, stac_json): def test_cli_orders_request_email(invoke, stac_json): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', '--email' ]) assert result.exit_code == 0 @@ -671,10 +670,10 @@ def test_cli_orders_request_tools(invoke, geom_geojson, stac_json): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', f'--tools={json.dumps(tools_json)}' ]) @@ -699,10 +698,10 @@ def test_cli_orders_request_no_stac(invoke): result = invoke([ 'request', - 'PSOrthoTile', - 'analytic', + '--item-type=PSOrthoTile', + '--bundle=analytic', '--name=test', - '--id=4500474_2133707_2021-05-20_2419', + '4500474_2133707_2021-05-20_2419', '--no-stac' ])