Skip to content

Commit 39be954

Browse files
committed
cli - implement filter combining
when the filter-json flag is present, AND the filter with whatever other filters are specified if the filter-json content is an object with a filter property, use this value also test addition + minor doc tweaks this resolves #128 and adds some nice convenience
1 parent 49da66f commit 39be954

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

planet/scripts/util.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,23 @@ def check_writable(dirpath):
7979

8080

8181
def filter_from_opts(**kw):
82-
'''Build a AND filter from the provided filter_in OR kwargs defaulting to an
83-
empty 'and' filter (@todo: API workaround).
82+
'''Build a AND filter from the provided kwargs defaulting to an
83+
empty 'and' filter (@todo: API workaround) if nothing is provided.
84+
85+
If the 'filter_json' argument is provided, this will be assumed to contain
86+
a filter specification and will be anded with other filters. If the
87+
'filter_json' is a search, the search filter value will be used.
88+
8489
All kw values should be tuple or list
8590
'''
8691
filter_in = kw.pop('filter_json', None)
8792
active = and_filter_from_opts(kw)
88-
no_filters = len(active['config']) == 0
89-
if no_filters and not filter_in:
90-
return filters.and_filter()
91-
if not no_filters and filter_in:
92-
raise click.ClickException(
93-
'Specify filter options or provide using --filter-json, not both')
9493
if filter_in:
95-
active = filter_in
94+
filter_in = filter_in.get('filter', filter_in)
95+
if len(active['config']) > 0:
96+
active = filters.and_filter(active, filter_in)
97+
else:
98+
active = filter_in
9699
return active
97100

98101

tests/test_v1_cli.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,47 @@ def test_filter(runner):
5555
def filt(*opts):
5656
return runner.invoke(main, ['data', 'filter'] + list(opts))
5757
assert_success(filt(), {
58-
"type": "AndFilter",
59-
"config": []
58+
'type': 'AndFilter',
59+
'config': []
6060
})
6161
assert_success(filt('--string-in', 'eff', 'a b c'), {
62-
"type": "AndFilter",
63-
"config": [
62+
'type': 'AndFilter',
63+
'config': [
6464
{'config': ['a', 'b', 'c'], 'field_name': 'eff',
6565
'type': 'StringInFilter'}
6666
]
6767
})
68+
filter_spec = {
69+
'type': 'StringInFilter',
70+
'config': ['a'],
71+
'field_name': 'eff'
72+
}
73+
# if no other options, filter-json is used as is
74+
assert_success(filt('--filter-json', json.dumps(filter_spec)), filter_spec)
75+
# verify we extract the filter property of a search
76+
assert_success(filt('--filter-json', json.dumps({
77+
"filter": filter_spec
78+
})), filter_spec)
79+
# filters are combined - the --string-in option results in a single AND
80+
# filter and this is combined with the provided filter_spec in a top-level
81+
# AND filter
82+
assert_success(filt('--filter-json', json.dumps(filter_spec),
83+
'--string-in', 'eff', 'b'), {
84+
'config': [
85+
{
86+
'type': 'AndFilter',
87+
'config': [
88+
{
89+
'type': 'StringInFilter',
90+
'config': ['b'],
91+
'field_name': 'eff'
92+
}
93+
]
94+
},
95+
filter_spec
96+
],
97+
'type': 'AndFilter'
98+
})
6899
# @todo more cases that are easier to write/maintain
69100

70101

0 commit comments

Comments
 (0)