Repository: planetlabs/planet-client-python

Issue:
Report invalid item-types with more human-readable list
With `planet data search` if I do an improper item-type I get a response like:

```
Error: Invalid value for 'ITEM_TYPES': ['psscend'] should be one of {'PSScene', 'MOD09GA', 'MYD09GA', 'MYD09GQ', 'SkySatCollect', 'REOrthoTile', 'REScene', 'MOD09GQ', 'PSScene4Band', 'Sentinel1', 'Sentinel2L1C', 'SkySatScene', 'Landsat8L1G', 'PSOrthoTile', 'PSScene3Band'}
```

The { and ' characters make it feel like a dump of a program. It'd be better to have it look like a more natural list. 

`planet orders request` does it in a more readable way, so likely can just copy theirs: 
```
Error: Invalid value: item_type - 'skysatcollectd' is not one of 'PSScene', 'Landsat8L1G', 'SkySatScene', 'SkySatCollect', 'PSOrthoTile', 'REOrthoTile', 'PSScene3Band', 'Sentinel2L1C'.
```

Comments:

Patch:
diff --git a/planet/cli/data.py b/planet/cli/data.py
index e45dbad..6ce15ee 100644
--- a/planet/cli/data.py
+++ b/planet/cli/data.py
@@ -21,7 +21,9 @@ from planet import data_filter, DataClient
 from planet.clients.data import (SEARCH_SORT,
                                  SEARCH_SORT_DEFAULT,
                                  STATS_INTERVAL)
-from planet.specs import get_item_types, SpecificationException
+from planet.specs import (get_item_types,
+                          validate_item_type,
+                          SpecificationException)
 
 from . import types
 from .cmds import coro, translate_exceptions
@@ -65,15 +67,14 @@ def assets_to_filter(ctx, param, assets: List[str]) -> Optional[dict]:
 
 
 def check_item_types(ctx, param, item_types) -> Optional[List[dict]]:
-    # Set difference between given item types and all item types
-    invalid_item_types = set([item.lower() for item in item_types]) - set(
-        [a.lower() for a in ALL_ITEM_TYPES])
-    if invalid_item_types:
-        raise SpecificationException(invalid_item_types,
-                                     ALL_ITEM_TYPES,
-                                     'item_type')
-    else:
+    '''Validates the item type by comparing the inputted item type to all
+    supported item types.'''
+    try:
+        for item_type in item_types:
+            validate_item_type(item_type)
         return item_types
+    except SpecificationException as e:
+        raise click.BadParameter(e)
 
 
 def date_range_to_filter(ctx, param, values) -> Optional[List[dict]]:


Test patch:
diff --git a/tests/integration/test_orders_cli.py b/tests/integration/test_orders_cli.py
index 3610ad9..59909c8 100644
--- a/tests/integration/test_orders_cli.py
+++ b/tests/integration/test_orders_cli.py
@@ -491,7 +491,8 @@ def test_cli_orders_request_item_type_invalid(invoke):
         '--id=4500474_2133707_2021-05-20_2419',
     ])
     assert result.exit_code == 2
-    assert "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" in result.output
+    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):
@@ -503,7 +504,8 @@ def test_cli_orders_request_product_bundle_invalid(invoke):
         '--id=4500474_2133707_2021-05-20_2419',
     ])
     assert result.exit_code == 2
-    assert "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" in result.output
+    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):
@@ -515,7 +517,8 @@ def test_cli_orders_request_product_bundle_incompatible(invoke):
         '--id=4500474_2133707_2021-05-20_2419',
     ])
     assert result.exit_code == 2
-    assert "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE" in result.output
+    error_msg = "Usage: main orders request [OPTIONS] ITEM_TYPE BUNDLE"
+    assert error_msg in result.output
 
 
 def test_cli_orders_request_id_empty(invoke):
diff --git a/tests/unit/test_data_callbacks.py b/tests/unit/test_data_callbacks.py
index a777609..41d7b78 100644
--- a/tests/unit/test_data_callbacks.py
+++ b/tests/unit/test_data_callbacks.py
@@ -13,7 +13,7 @@
 # limitations under the License.
 import logging
 import pytest
-from planet.specs import SpecificationException
+import click
 from planet.cli.data import check_item_types
 
 LOGGER = logging.getLogger(__name__)
@@ -51,5 +51,5 @@ def test_item_type_success(item_types):
 
 def test_item_type_fail():
     ctx = MockContext()
-    with pytest.raises(SpecificationException):
+    with pytest.raises(click.BadParameter):
         check_item_types(ctx, 'item_type', "bad_item_type")