From aa457b7116d33938fbe3af0f8df256380c21eb03 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 26 Mar 2024 16:34:50 -0400 Subject: [PATCH 01/17] hosting --- planet/cli/subscriptions.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index 70b7dad7..be16c724 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -11,6 +11,7 @@ from .session import CliSession from planet.clients.subscriptions import SubscriptionsClient from .. import subscription_request +from ..subscription_request import sentinel_hub from ..specs import get_item_types, validate_item_type, SpecificationException ALL_ITEM_TYPES = get_item_types() @@ -87,13 +88,23 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): echo_json(sub, pretty) -@subscriptions.command(name='create') # type: ignore -@click.argument('request', type=types.JSON()) +@subscriptions.command(name="create") # type: ignore +@click.argument("request", type=types.JSON()) +@click.option( + "--hosting", + default=None, + help='Hosting type. Currently, only "sentinel_hub" is supported.', +) +@click.option( + "--collection_id", + default=None, + help="Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", +) @pretty @click.pass_context @translate_exceptions @coro -async def create_subscription_cmd(ctx, request, pretty): +async def create_subscription_cmd(ctx, request, hosting, collection_id, pretty): """Create a subscription. Submits a subscription request for creation and prints the created @@ -102,6 +113,11 @@ async def create_subscription_cmd(ctx, request, pretty): REQUEST is the full description of the subscription to be created. It must be JSON and can be specified a json string, filename, or '-' for stdin. """ + + if hosting or hosting.lower() == "sentinel_hub": + hosting_info = sentinel_hub(collection_id) + request["hosting"] = hosting_info + async with subscriptions_client(ctx) as client: sub = await client.create_subscription(request) echo_json(sub, pretty) From e649d9d69acc7883c88ec8f3f3e835a6d3974530 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 26 Mar 2024 16:39:13 -0400 Subject: [PATCH 02/17] lower --- planet/cli/subscriptions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index be16c724..a9af0979 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -113,8 +113,8 @@ async def create_subscription_cmd(ctx, request, hosting, collection_id, pretty): REQUEST is the full description of the subscription to be created. It must be JSON and can be specified a json string, filename, or '-' for stdin. """ - - if hosting or hosting.lower() == "sentinel_hub": + + if hosting == "sentinel_hub": hosting_info = sentinel_hub(collection_id) request["hosting"] = hosting_info From d50299fd6c6fdd1803b64e2b52ebf8f1e759fde0 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 26 Mar 2024 16:43:09 -0400 Subject: [PATCH 03/17] format --- planet/cli/subscriptions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index a9af0979..33f1a1fe 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -98,13 +98,15 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.option( "--collection_id", default=None, - help="Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", + help= + "Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", ) @pretty @click.pass_context @translate_exceptions @coro -async def create_subscription_cmd(ctx, request, hosting, collection_id, pretty): +async def create_subscription_cmd(ctx, request, hosting, collection_id, + pretty): """Create a subscription. Submits a subscription request for creation and prints the created From 62f6a87bfb88bfa2836010a33b5d9c8402af71ba Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 26 Mar 2024 16:46:01 -0400 Subject: [PATCH 04/17] format --- planet/cli/subscriptions.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index 33f1a1fe..a9af0979 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -98,15 +98,13 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.option( "--collection_id", default=None, - help= - "Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", + help="Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", ) @pretty @click.pass_context @translate_exceptions @coro -async def create_subscription_cmd(ctx, request, hosting, collection_id, - pretty): +async def create_subscription_cmd(ctx, request, hosting, collection_id, pretty): """Create a subscription. Submits a subscription request for creation and prints the created From 86475860d418eebc56aff737445c1974432c757f Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Wed, 27 Mar 2024 11:16:26 -0400 Subject: [PATCH 05/17] format --- planet/cli/subscriptions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index a9af0979..e81286b1 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -98,13 +98,15 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.option( "--collection_id", default=None, - help="Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", + help= + "Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", ) @pretty @click.pass_context @translate_exceptions @coro -async def create_subscription_cmd(ctx, request, hosting, collection_id, pretty): +async def create_subscription_cmd(ctx, request, hosting, collection_id, + pretty): """Create a subscription. Submits a subscription request for creation and prints the created From 149b727b8b2be35520d9993eb6623e0789ded8bd Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Wed, 27 Mar 2024 11:44:53 -0400 Subject: [PATCH 06/17] changelog --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 6ba39c83..3ae26aa7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +2.5.0 (2024-03-27) +- Support Subscriptions API hosting block for Sentinel Hub in the CLI (#1029). + 2.4.0 (2024-03-19) Added: From fb046d3dce29b9f47320eb01b2a76c5906ac35c1 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Wed, 27 Mar 2024 11:45:23 -0400 Subject: [PATCH 07/17] wording --- CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 3ae26aa7..e87695e2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ 2.5.0 (2024-03-27) + +Added: - Support Subscriptions API hosting block for Sentinel Hub in the CLI (#1029). 2.4.0 (2024-03-19) From 98eec20e77c9a2a0aa9a3c8806be224439320678 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 2 Apr 2024 12:12:31 -0700 Subject: [PATCH 08/17] fix --- planet/cli/subscriptions.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index e81286b1..7567d52a 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -99,7 +99,7 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): "--collection_id", default=None, help= - "Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.", + 'Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.', ) @pretty @click.pass_context @@ -282,12 +282,13 @@ async def list_subscription_results_cmd(ctx, @click.option( '--hosting', type=types.JSON(), - help='Hosting JSON. Can be a string, a filename, or - for stdin.') + help='Hosting JSON. Can be a string, a filename, or - for stdin. Currently, only "sentinel_hub" is supported.') @click.option( '--clip-to-source', is_flag=True, default=False, help="Clip to the source geometry without specifying a clip tool.") +@click.option("--collection-id", default=None, help='Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.') @pretty def request(name, source, @@ -295,6 +296,7 @@ def request(name, notifications, tools, hosting, + collection_id, clip_to_source, pretty): """Generate a subscriptions request. @@ -304,12 +306,14 @@ def request(name, --clip-to-source option is a preview of the next API version's default behavior. """ + res = subscription_request.build_request(name, source, delivery, notifications=notifications, tools=tools, hosting=hosting, + collection_id=collection_id, clip_to_source=clip_to_source) echo_json(res, pretty) @@ -367,6 +371,7 @@ def request_catalog(item_types, time_range_type, pretty): """Generate a subscriptions request catalog source description.""" + res = subscription_request.catalog_source( item_types, asset_types, From d8c7d912e6211bc43d49ab3d9dadb1d1fbf2b48f Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 2 Apr 2024 16:03:57 -0700 Subject: [PATCH 09/17] tests etc --- planet/cli/subscriptions.py | 19 +++++------ planet/subscription_request.py | 14 ++++++-- tests/integration/test_subscriptions_cli.py | 36 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index 7567d52a..0c5d8e2b 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -95,12 +95,10 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): default=None, help='Hosting type. Currently, only "sentinel_hub" is supported.', ) -@click.option( - "--collection_id", - default=None, - help= - 'Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.', -) +@click.option("--collection-id", + default=None, + help='Collection ID for Sentinel Hub.' + 'If omitted, a new collection will be created.') @pretty @click.pass_context @translate_exceptions @@ -281,14 +279,17 @@ async def list_subscription_results_cmd(ctx, help='Toolchain JSON. Can be a string, filename, or - for stdin.') @click.option( '--hosting', - type=types.JSON(), - help='Hosting JSON. Can be a string, a filename, or - for stdin. Currently, only "sentinel_hub" is supported.') + default=None, + help='Hosting configuration. Can be JSON, "sentinel_hub", or omitted.') @click.option( '--clip-to-source', is_flag=True, default=False, help="Clip to the source geometry without specifying a clip tool.") -@click.option("--collection-id", default=None, help='Optional collection ID for Sentinel Hub. If omitted, a new collection will be created.') +@click.option("--collection-id", + default=None, + help='Collection ID for Sentinel Hub.' + 'If omitted, a new collection will be created.') @pretty def request(name, source, diff --git a/planet/subscription_request.py b/planet/subscription_request.py index 520e3411..3e72e749 100644 --- a/planet/subscription_request.py +++ b/planet/subscription_request.py @@ -52,7 +52,8 @@ def build_request(name: str, delivery: Optional[Mapping] = None, notifications: Optional[Mapping] = None, tools: Optional[List[Mapping]] = None, - hosting: Optional[Mapping] = None, + hosting: Optional[Union[Mapping, str]] = None, + collection_id: Optional[str] = None, clip_to_source: Optional[bool] = False) -> dict: """Construct a Subscriptions API request. @@ -150,8 +151,15 @@ def build_request(name: str, details['tools'] = tool_list - if hosting: - details['hosting'] = dict(hosting) + if hosting == "sentinel_hub": + hosting_info: Dict[str, Any] = { + "type": "sentinel_hub", "parameters": {} + } + if collection_id: + hosting_info["parameters"]["collection_id"] = collection_id + details['hosting'] = hosting_info + elif isinstance(hosting, dict): + details['hosting'] = hosting return details diff --git a/tests/integration/test_subscriptions_cli.py b/tests/integration/test_subscriptions_cli.py index 25b462dd..89690c44 100644 --- a/tests/integration/test_subscriptions_cli.py +++ b/tests/integration/test_subscriptions_cli.py @@ -435,3 +435,39 @@ def test_catalog_source_time_range_type(invoke, geom_geojson, time_range_type): assert result.exit_code == 0 # success. req = json.loads(result.output) assert req['parameters']['time_range_type'] == time_range_type + + +@pytest.mark.parametrize( + "hosting_option, collection_id_option, expected_success", + [ + ("--hosting=sentinel_hub", None, True), + ("--hosting=sentinel_hub", "--collection-id=7ff105c4-e0de-4910-96db-8345d86ab734", True), + ] +) +def test_request_base_hosting(invoke, geom_geojson, hosting_option, collection_id_option, expected_success): + """Test request command with various hosting and collection ID options.""" + source = json.dumps({ + "type": "catalog", + "parameters": { + "geometry": geom_geojson, + "start_time": "2021-03-01T00:00:00Z", + "end_time": "2023-11-01T00:00:00Z", + "rrule": "FREQ=MONTHLY;BYMONTH=3,4,5,6,7,8,9,10", + "item_types": ["PSScene"], + "asset_types": ["ortho_analytic_4b"] + } + }) + + cmd = [ + 'request', + '--name=test', + f'--source={source}', + hosting_option, + ] + + if collection_id_option: + cmd.append(collection_id_option) + + result = invoke(cmd) + + assert result.exit_code == 0, "Expected command to succeed." From 39ba7e3eea64db38bd01f0cc1037aa4bf90bc878 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 2 Apr 2024 16:06:41 -0700 Subject: [PATCH 10/17] whitespace --- tests/integration/test_subscriptions_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_subscriptions_cli.py b/tests/integration/test_subscriptions_cli.py index 89690c44..9a71e0c4 100644 --- a/tests/integration/test_subscriptions_cli.py +++ b/tests/integration/test_subscriptions_cli.py @@ -464,7 +464,7 @@ def test_request_base_hosting(invoke, geom_geojson, hosting_option, collection_i f'--source={source}', hosting_option, ] - + if collection_id_option: cmd.append(collection_id_option) From b535b04222b59a17e4c5700ac0e7e1c70e829dcb Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 2 Apr 2024 16:07:38 -0700 Subject: [PATCH 11/17] test --- tests/integration/test_subscriptions_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_subscriptions_cli.py b/tests/integration/test_subscriptions_cli.py index 9a71e0c4..1cef7b45 100644 --- a/tests/integration/test_subscriptions_cli.py +++ b/tests/integration/test_subscriptions_cli.py @@ -444,7 +444,7 @@ def test_catalog_source_time_range_type(invoke, geom_geojson, time_range_type): ("--hosting=sentinel_hub", "--collection-id=7ff105c4-e0de-4910-96db-8345d86ab734", True), ] ) -def test_request_base_hosting(invoke, geom_geojson, hosting_option, collection_id_option, expected_success): +def test_request_hosting(invoke, geom_geojson, hosting_option, collection_id_option, expected_success): """Test request command with various hosting and collection ID options.""" source = json.dumps({ "type": "catalog", From bc97c070ca59a3270f1a2df1e808b757b67e4bf4 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Tue, 2 Apr 2024 16:55:36 -0700 Subject: [PATCH 12/17] test --- tests/integration/test_subscriptions_cli.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/integration/test_subscriptions_cli.py b/tests/integration/test_subscriptions_cli.py index 1cef7b45..ded9d3dd 100644 --- a/tests/integration/test_subscriptions_cli.py +++ b/tests/integration/test_subscriptions_cli.py @@ -441,10 +441,15 @@ def test_catalog_source_time_range_type(invoke, geom_geojson, time_range_type): "hosting_option, collection_id_option, expected_success", [ ("--hosting=sentinel_hub", None, True), - ("--hosting=sentinel_hub", "--collection-id=7ff105c4-e0de-4910-96db-8345d86ab734", True), - ] -) -def test_request_hosting(invoke, geom_geojson, hosting_option, collection_id_option, expected_success): + ("--hosting=sentinel_hub", + "--collection-id=7ff105c4-e0de-4910-96db-8345d86ab734", + True), + ]) +def test_request_hosting(invoke, + geom_geojson, + hosting_option, + collection_id_option, + expected_success): """Test request command with various hosting and collection ID options.""" source = json.dumps({ "type": "catalog", From 12ce4d05a50f9a09836f014fa9129d4dd4306517 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Thu, 4 Apr 2024 10:02:39 -0700 Subject: [PATCH 13/17] kwargs --- planet/cli/subscriptions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index 0c5d8e2b..a71edf41 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -92,6 +92,7 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.argument("request", type=types.JSON()) @click.option( "--hosting", + type=click.Choice(["sentinel_hub",]), default=None, help='Hosting type. Currently, only "sentinel_hub" is supported.', ) @@ -103,8 +104,7 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.pass_context @translate_exceptions @coro -async def create_subscription_cmd(ctx, request, hosting, collection_id, - pretty): +async def create_subscription_cmd(ctx, request, pretty, **kwargs): """Create a subscription. Submits a subscription request for creation and prints the created @@ -114,6 +114,9 @@ async def create_subscription_cmd(ctx, request, hosting, collection_id, be JSON and can be specified a json string, filename, or '-' for stdin. """ + hosting = kwargs.get("hosting", None) + collection_id = kwargs.get("collection_id", None) + if hosting == "sentinel_hub": hosting_info = sentinel_hub(collection_id) request["hosting"] = hosting_info @@ -280,6 +283,7 @@ async def list_subscription_results_cmd(ctx, @click.option( '--hosting', default=None, + type=click.Choice(["sentinel_hub",]), help='Hosting configuration. Can be JSON, "sentinel_hub", or omitted.') @click.option( '--clip-to-source', From 7e851aeae0ff48d56af02aa8f80ce59365a45e25 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Thu, 4 Apr 2024 10:03:50 -0700 Subject: [PATCH 14/17] format --- planet/cli/subscriptions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index a71edf41..2892e823 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -92,7 +92,9 @@ async def list_subscriptions_cmd(ctx, status, limit, pretty): @click.argument("request", type=types.JSON()) @click.option( "--hosting", - type=click.Choice(["sentinel_hub",]), + type=click.Choice([ + "sentinel_hub", + ]), default=None, help='Hosting type. Currently, only "sentinel_hub" is supported.', ) @@ -283,7 +285,9 @@ async def list_subscription_results_cmd(ctx, @click.option( '--hosting', default=None, - type=click.Choice(["sentinel_hub",]), + type=click.Choice([ + "sentinel_hub", + ]), help='Hosting configuration. Can be JSON, "sentinel_hub", or omitted.') @click.option( '--clip-to-source', From b196e2237b988a470ce75b28f4cc8757a3b18195 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Thu, 4 Apr 2024 10:10:51 -0700 Subject: [PATCH 15/17] format --- planet/cli/subscriptions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/planet/cli/subscriptions.py b/planet/cli/subscriptions.py index 2892e823..cc12a5b5 100644 --- a/planet/cli/subscriptions.py +++ b/planet/cli/subscriptions.py @@ -114,6 +114,11 @@ async def create_subscription_cmd(ctx, request, pretty, **kwargs): REQUEST is the full description of the subscription to be created. It must be JSON and can be specified a json string, filename, or '-' for stdin. + + Other flag options are hosting and collection_id. The hosting flag + specifies the hosting type, and the collection_id flag specifies the + collection ID for Sentinel Hub. If the collection_id is omitted, a new + collection will be created. """ hosting = kwargs.get("hosting", None) From 0a7933531d8a8bda12a8bb02eb6920e1959a19a9 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Thu, 4 Apr 2024 11:32:10 -0700 Subject: [PATCH 16/17] date --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index e87695e2..cb731b55 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -2.5.0 (2024-03-27) +2.5.0 (2024-04-04) Added: - Support Subscriptions API hosting block for Sentinel Hub in the CLI (#1029). From 4e213231f3d4cb86456778dcd926700eb56d8d14 Mon Sep 17 00:00:00 2001 From: Emma Steuer Date: Thu, 4 Apr 2024 12:02:27 -0700 Subject: [PATCH 17/17] date --- CHANGES.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d7e80811..560b1d82 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,8 +3,7 @@ Added: - Support Subscriptions API hosting block for Sentinel Hub in the CLI (#1029). -Added: - - Support for field_boundaries_sentinel_2_p1m in Subscriptions API (#1026) +- Support for field_boundaries_sentinel_2_p1m in Subscriptions API (#1026) 2.4.0 (2024-03-19)