Skip to content

Commit b31ef7d

Browse files
committed
add std quality filter to planet data filter default
1 parent 376c05c commit b31ef7d

File tree

4 files changed

+98
-30
lines changed

4 files changed

+98
-30
lines changed

planet/cli/data.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,13 @@ def _func(obj):
294294
@click.option('--permission',
295295
type=bool,
296296
default=True,
297+
show_default=True,
297298
help='Filter to assets with download permissions.')
299+
@click.option('--std-quality',
300+
type=bool,
301+
default=True,
302+
show_default=True,
303+
help='Filter to standard quality.')
298304
def filter(ctx,
299305
asset,
300306
date_range,
@@ -304,7 +310,8 @@ def filter(ctx,
304310
string_in,
305311
update,
306312
permission,
307-
pretty):
313+
pretty,
314+
std_quality):
308315
"""Create a structured item search filter.
309316
310317
This command provides basic functionality for specifying a filter by
@@ -314,6 +321,7 @@ def filter(ctx,
314321
the Python API.
315322
"""
316323
permission = data_filter.permission_filter() if permission else None
324+
std_quality = data_filter.std_quality_filter() if std_quality else None
317325

318326
filter_options = (asset,
319327
date_range,
@@ -322,7 +330,8 @@ def filter(ctx,
322330
nrange,
323331
string_in,
324332
update,
325-
permission)
333+
permission,
334+
std_quality)
326335

327336
# options allowing multiples are broken up so one filter is created for
328337
# each time the option is specified

planet/data_filter.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,12 @@ def permission_filter() -> dict:
300300
download.
301301
"""
302302
return {'type': 'PermissionFilter', 'config': ['assets:download']}
303+
304+
305+
def std_quality_filter() -> dict:
306+
"""Create a filter for standard-quality items.
307+
308+
This is a custom filter which filters to items that are categorized as
309+
standard quality.
310+
"""
311+
return string_in_filter('quality_category', ['standard'])

tests/integration/test_data_cli.py

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""Tests of the Data CLI."""
1515
from http import HTTPStatus
1616
import json
17+
import logging
1718

1819
import httpx
1920
import respx
@@ -23,6 +24,8 @@
2324

2425
from planet.cli import cli
2526

27+
LOGGER = logging.getLogger(__name__)
28+
2629
TEST_URL = 'https://api.planet.com/data/v1'
2730
TEST_QUICKSEARCH_URL = f'{TEST_URL}/quick-search'
2831
TEST_SEARCHES_URL = f'{TEST_URL}/searches'
@@ -51,22 +54,17 @@ def test_data_command_registered(invoke):
5154
# Add other sub-commands here.
5255

5356

54-
permission_filter = {"type": "PermissionFilter", "config": ["assets:download"]}
57+
PERMISSION_FILTER = {"type": "PermissionFilter", "config": ["assets:download"]}
58+
STD_QUALITY_FILTER = {
59+
"type": "StringInFilter",
60+
"field_name": "quality_category",
61+
"config": ["standard"]
62+
}
5563

5664

57-
@respx.mock
58-
@pytest.mark.asyncio
59-
@pytest.mark.parametrize("permission, expected",
60-
[(False, ''),
61-
(True, json.dumps(permission_filter) + '\n')])
62-
def test_data_filter_permission(invoke, permission, expected):
63-
"""Test that the proper filter is created when zero and one subfilters
64-
are specified."""
65-
runner = CliRunner()
66-
result = invoke(["filter", f'--permission={permission}'], runner=runner)
67-
68-
assert result.exit_code == 0
69-
assert result.output == expected
65+
@pytest.fixture()
66+
def default_filters():
67+
return [PERMISSION_FILTER, STD_QUALITY_FILTER]
7068

7169

7270
@pytest.fixture
@@ -84,6 +82,37 @@ def _func(filter1, filter2):
8482
return _func
8583

8684

85+
@respx.mock
86+
@pytest.mark.asyncio
87+
@pytest.mark.parametrize("permission, p_remove",
88+
[(None, None),
89+
('--permission=False', PERMISSION_FILTER)])
90+
@pytest.mark.parametrize("std_quality, s_remove",
91+
[(None, None),
92+
('--std-quality=False', STD_QUALITY_FILTER)])
93+
def test_data_filter_defaults(permission,
94+
p_remove,
95+
std_quality,
96+
s_remove,
97+
invoke,
98+
default_filters,
99+
assert_and_filters_equal):
100+
runner = CliRunner()
101+
102+
args = [arg for arg in [permission, std_quality] if arg]
103+
result = invoke(["filter", *args], runner=runner)
104+
assert result.exit_code == 0
105+
106+
[default_filters.remove(rem) for rem in [p_remove, s_remove] if rem]
107+
if len(default_filters) > 1:
108+
expected_filt = {"type": "AndFilter", "config": default_filters}
109+
assert_and_filters_equal(json.loads(result.output), expected_filt)
110+
elif len(default_filters) == 1:
111+
assert json.loads(result.output) == default_filters[0]
112+
else:
113+
assert result.output == ''
114+
115+
87116
@respx.mock
88117
@pytest.mark.asyncio
89118
@pytest.mark.parametrize("asset, expected",
@@ -92,22 +121,28 @@ def _func(filter1, filter2):
92121
['ortho_analytic_8b_sr', 'ortho_analytic_4b_sr']),
93122
('ortho_analytic_8b_sr , ortho_analytic_4b_sr',
94123
['ortho_analytic_8b_sr', 'ortho_analytic_4b_sr'])])
95-
def test_data_filter_asset(asset, expected, invoke, assert_and_filters_equal):
124+
def test_data_filter_asset(asset,
125+
expected,
126+
invoke,
127+
default_filters,
128+
assert_and_filters_equal):
96129
runner = CliRunner()
97130

98131
result = invoke(["filter", f'--asset={asset}'], runner=runner)
99132
assert result.exit_code == 0
100133

101134
asset_filter = {"type": "AssetFilter", "config": expected}
102135
expected_filt = {
103-
"type": "AndFilter", "config": [asset_filter, permission_filter]
136+
"type": "AndFilter", "config": default_filters + [asset_filter]
104137
}
105138
assert_and_filters_equal(json.loads(result.output), expected_filt)
106139

107140

108141
@respx.mock
109142
@pytest.mark.asyncio
110-
def test_data_filter_date_range(invoke, assert_and_filters_equal):
143+
def test_data_filter_date_range(invoke,
144+
assert_and_filters_equal,
145+
default_filters):
111146
"""Check filter is created correctly and that multiple options results in
112147
multiple filters"""
113148
runner = CliRunner()
@@ -134,7 +169,7 @@ def test_data_filter_date_range(invoke, assert_and_filters_equal):
134169

135170
expected_filt = {
136171
"type": "AndFilter",
137-
"config": [permission_filter, date_range_filter1, date_range_filter2]
172+
"config": default_filters + [date_range_filter1, date_range_filter2]
138173
}
139174

140175
assert_and_filters_equal(json.loads(result.output), expected_filt)
@@ -149,7 +184,8 @@ def test_data_filter_geom(geom_fixture,
149184
request,
150185
invoke,
151186
geom_geojson,
152-
assert_and_filters_equal):
187+
assert_and_filters_equal,
188+
default_filters):
153189
"""Ensure that all GeoJSON forms of describing a geometry are handled
154190
and all result in the same, valid GeometryFilter being created"""
155191
runner = CliRunner()
@@ -166,15 +202,17 @@ def test_data_filter_geom(geom_fixture,
166202
}
167203

168204
expected_filt = {
169-
"type": "AndFilter", "config": [permission_filter, geom_filter]
205+
"type": "AndFilter", "config": default_filters + [geom_filter]
170206
}
171207

172208
assert_and_filters_equal(json.loads(result.output), expected_filt)
173209

174210

175211
@respx.mock
176212
@pytest.mark.asyncio
177-
def test_data_filter_number_in(invoke, assert_and_filters_equal):
213+
def test_data_filter_number_in(invoke,
214+
assert_and_filters_equal,
215+
default_filters):
178216
runner = CliRunner()
179217

180218
result = invoke(["filter"] + '--number-in field 1'.split() +
@@ -191,15 +229,15 @@ def test_data_filter_number_in(invoke, assert_and_filters_equal):
191229

192230
expected_filt = {
193231
"type": "AndFilter",
194-
"config": [permission_filter, number_in_filter1, number_in_filter2]
232+
"config": default_filters + [number_in_filter1, number_in_filter2]
195233
}
196234

197235
assert_and_filters_equal(json.loads(result.output), expected_filt)
198236

199237

200238
@respx.mock
201239
@pytest.mark.asyncio
202-
def test_data_filter_range(invoke, assert_and_filters_equal):
240+
def test_data_filter_range(invoke, assert_and_filters_equal, default_filters):
203241
"""Check filter is created correctly, that multiple options results in
204242
multiple filters, and that floats are processed correctly."""
205243
runner = CliRunner()
@@ -224,15 +262,17 @@ def test_data_filter_range(invoke, assert_and_filters_equal):
224262

225263
expected_filt = {
226264
"type": "AndFilter",
227-
"config": [permission_filter, range_filter1, range_filter2]
265+
"config": default_filters + [range_filter1, range_filter2]
228266
}
229267

230268
assert_and_filters_equal(json.loads(result.output), expected_filt)
231269

232270

233271
@respx.mock
234272
@pytest.mark.asyncio
235-
def test_data_filter_string_in(invoke, assert_and_filters_equal):
273+
def test_data_filter_string_in(invoke,
274+
assert_and_filters_equal,
275+
default_filters):
236276
runner = CliRunner()
237277

238278
result = invoke(["filter"] + '--string-in field foo'.split() +
@@ -251,15 +291,15 @@ def test_data_filter_string_in(invoke, assert_and_filters_equal):
251291

252292
expected_filt = {
253293
"type": "AndFilter",
254-
"config": [permission_filter, string_in_filter1, string_in_filter2]
294+
"config": default_filters + [string_in_filter1, string_in_filter2]
255295
}
256296

257297
assert_and_filters_equal(json.loads(result.output), expected_filt)
258298

259299

260300
@respx.mock
261301
@pytest.mark.asyncio
262-
def test_data_filter_update(invoke, assert_and_filters_equal):
302+
def test_data_filter_update(invoke, assert_and_filters_equal, default_filters):
263303
"""Check filter is created correctly and that multiple options results in
264304
multiple filters"""
265305
runner = CliRunner()
@@ -286,7 +326,7 @@ def test_data_filter_update(invoke, assert_and_filters_equal):
286326

287327
expected_filt = {
288328
"type": "AndFilter",
289-
"config": [permission_filter, update_filter1, update_filter2]
329+
"config": default_filters + [update_filter1, update_filter2]
290330
}
291331

292332
assert_and_filters_equal(json.loads(result.output), expected_filt)

tests/unit/test_data_filter.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,13 @@ def test_permission_filter():
215215
res = data_filter.permission_filter()
216216
expected = {'type': 'PermissionFilter', 'config': ['assets:download']}
217217
assert res == expected
218+
219+
220+
def test_std_quality_filter():
221+
res = data_filter.std_quality_filter()
222+
expected = {
223+
'type': 'StringInFilter',
224+
'field_name': 'quality_category',
225+
'config': ['standard']
226+
}
227+
assert res == expected

0 commit comments

Comments
 (0)