Skip to content

Commit bec5ae0

Browse files
committed
first draft
1 parent 05f30ca commit bec5ae0

3 files changed

Lines changed: 181 additions & 26 deletions

File tree

hapiclient/info.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def info(SERVER, DATASET, PARAMETERS, opts):
2121
meta.update({"x_dataset": DATASET})
2222

2323
if PARAMETERS is not None:
24-
return subset_meta(meta, PARAMETERS)
24+
subset_meta(meta, PARAMETERS)
25+
return meta
2526
else:
2627
return meta

hapiclient/util.py

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -364,46 +364,75 @@ def urlretrieve(url, fname):
364364
def subset_meta(meta, params):
365365
"""Extract subset of parameters from meta object returned by hapi().
366366
367-
``metar = subset_meta(meta, parameters)`` modifies ``meta["parameters"]`` array
368-
so that it only contains elements for the time variable and the parameters
369-
in the comma-separated string ``parameters``.
367+
``subset_meta(meta, parameters)`` modifies ``meta["parameters"]`` list
368+
in place so that it only contains elements for the time variable and the
369+
parameters in the comma-separated string ``parameters``.
370370
"""
371371

372+
# Note that tests for subset_meta() are in test_subset_meta.py, which also
373+
# has tests for error message strings. If error message strings change,
374+
# update tests in test_subset_meta.py.
375+
372376
if params == '':
373377
return meta
374378

375-
p = params.split(',')
376-
pm = [] # Parameter names in metadata
379+
pw = params.split(',') # Wanted parameters names as list
380+
381+
# Check for duplicate parameters in pw
382+
if len(pw) != len(set(pw)):
383+
# Print duplicate parameters
384+
duplicates = ','.join([x for x in pw if pw.count(x) > 1])
385+
error("Duplicate parameters in requested parameter list: '" + duplicates + "'")
386+
387+
# Check for errors in pw
388+
for p in pw:
389+
if p == '':
390+
error("Empty parameter name in requested parameter list: '" + params + "'")
391+
if p.startswith(' '):
392+
error("Leading space before parameter name '" + p + "'")
393+
if p.endswith(' '):
394+
error("Trailing space after parameter name '" + p + "'")
395+
396+
pa = [] # Available parameter names in metadata as list
377397
for i in range(0, len(meta['parameters'])):
378-
pm.append(meta['parameters'][i]['name'])
398+
pa.append(meta['parameters'][i]['name'])
399+
400+
# Check if meta has duplicate parameter names.
401+
if len(pa) != len(set(pa)):
402+
duplicates = ','.join([x for x in pa if pa.count(x) > 1])
403+
error('Duplicate parameter names in metadata returned by server: ' + duplicates)
379404

380-
# Check for parameters requested that are not in metadata
381-
for i in range(0, len(p)):
382-
if p[i] not in pm:
383-
error('Parameter %s is not in meta' % p[i] + '\n')
405+
# Check for parameters wanted that are not available
406+
for i in range(0, len(pw)):
407+
if pw[i] not in pa:
408+
error("Parameter '%s' is not in metadata from server" % pw[i])
384409
return
385410

386-
pa = [meta['parameters'][0]] # First parameter is always the time parameter
411+
# Keep first parameter, which is always the primary time parameter
412+
pa = [meta['parameters'][0]]
387413

388-
params_reordered = [] # Re-ordered params
389-
# If time parameter explicitly requested, put it first in params_reordered.
390-
if meta['parameters'][0]['name'] in p:
391-
params_reordered = [meta['parameters'][0]['name']]
414+
pw_reordered = [] # Re-ordered params
415+
# If time parameter explicitly requested, put it first in pw_reordered.
416+
if meta['parameters'][0]['name'] in pw:
417+
pw_reordered = [meta['parameters'][0]['name']]
392418

393419
# Create subset of parameter metadata
394-
for i in range(1, len(pm)):
395-
if pm[i] in p:
420+
for i in range(1, len(meta['parameters'])):
421+
if meta['parameters'][i]['name'] in pw:
396422
pa.append(meta['parameters'][i])
397-
params_reordered.append(pm[i])
398-
meta['parameters'] = pa
423+
pw_reordered.append(meta['parameters'][i]['name'])
424+
425+
pw_reordered_str = ','.join(pw_reordered)
399426

400-
params_reordered_str = ','.join(params_reordered)
427+
if not params == pw_reordered_str:
428+
msg = 'Order of requested parameters does not match order of '
429+
msg += 'parameters in server info metadata. '
430+
msg += "\n " + "Order requested: " + params
431+
msg += "\n " + "Order required: " + pw_reordered_str
432+
error(msg)
401433

402-
if not params == params_reordered_str:
403-
msg = "\n " + "Order requested: " + params
404-
msg = msg + "\n " + "Order required: " + params_reordered_str
405-
error('Order of requested parameters does not match order of ' \
406-
'parameters in server info metadata.' + msg + '\n')
434+
# Modify meta to only include time parameter and parameters in pw.
435+
meta['parameters'] = pa
407436

408437
return meta
409438

test/test_subset_meta.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
from hapiclient.util import HAPIError, subset_meta
2+
3+
meta = {
4+
"parameters": [
5+
{"name": "Time"},
6+
{"name": "Parameter1"},
7+
{"name": "Parameter2"},
8+
{"name": "Parameter3"}
9+
]
10+
}
11+
12+
msg_o = "Exception not raised by subset_meta() with "
13+
14+
def test_simple():
15+
params = 'Parameter1,Parameter2'
16+
subset_meta(meta, params)
17+
assert len(meta['parameters']) == 3
18+
assert meta['parameters'][0]['name'] == 'Time'
19+
assert meta['parameters'][1]['name'] == 'Parameter1'
20+
assert meta['parameters'][2]['name'] == 'Parameter2'
21+
22+
23+
def test_params_wrong_order():
24+
params = 'Parameter2,Parameter1'
25+
try:
26+
subset_meta(meta, params)
27+
except Exception as e:
28+
assert isinstance(e, HAPIError)
29+
assert str(e).startswith('Order of requested parameters does not match')
30+
else:
31+
assert False, msg_o + "parameters in wrong order."
32+
33+
34+
def test_params_duplicate_name():
35+
params = 'Parameter1,Parameter1'
36+
try:
37+
subset_meta(meta, params)
38+
except Exception as e:
39+
assert isinstance(e, HAPIError)
40+
assert str(e).startswith('Duplicate parameters in requested parameter list')
41+
else:
42+
assert False, msg_o + "duplicate parameter names."
43+
44+
45+
def test_params_invalid_name():
46+
params = 'Parameter1,ParameterX'
47+
try:
48+
subset_meta(meta, params)
49+
except Exception as e:
50+
assert isinstance(e, HAPIError)
51+
assert str(e).startswith("Parameter 'ParameterX' is not in metadata from server")
52+
else:
53+
assert False, msg_o + "invalid parameter name."
54+
55+
56+
def test_params_empty_value():
57+
params = 'Parameter2,'
58+
try:
59+
subset_meta(meta, params)
60+
except Exception as e:
61+
assert isinstance(e, HAPIError)
62+
assert str(e).startswith('Empty parameter name')
63+
else:
64+
assert False, msg_o + "empty parameter name."
65+
66+
67+
def test_params_leading_space():
68+
params = ' Parameter1,Parameter2'
69+
try:
70+
subset_meta(meta, params)
71+
except Exception as e:
72+
assert isinstance(e, HAPIError)
73+
assert str(e).startswith('Leading space')
74+
else:
75+
assert False, msg_o + "leading space in parameter name."
76+
77+
78+
def test_params_trailing_space():
79+
params = 'Parameter1,Parameter2 '
80+
try:
81+
subset_meta(meta, params)
82+
except Exception as e:
83+
assert isinstance(e, HAPIError)
84+
assert str(e).startswith('Trailing space')
85+
else:
86+
assert False, msg_o + "trailing space in parameter name."
87+
88+
89+
def test_params_time_given():
90+
params = 'Time,Parameter1'
91+
subset_meta(meta, params)
92+
assert len(meta['parameters']) == 2
93+
assert meta['parameters'][0]['name'] == 'Time'
94+
assert meta['parameters'][1]['name'] == 'Parameter1'
95+
96+
97+
def test_meta_duplicate_names():
98+
meta_dup = {
99+
"parameters": [
100+
{"name": "Time"},
101+
{"name": "Parameter1"},
102+
{"name": "Parameter1"},
103+
{"name": "Parameter3"}
104+
]
105+
}
106+
params = 'Parameter1'
107+
try:
108+
subset_meta(meta_dup, params)
109+
except Exception as e:
110+
assert isinstance(e, HAPIError)
111+
assert str(e).startswith('Duplicate parameter names in metadata returned by server')
112+
else:
113+
assert False, msg_o + "duplicate parameter names in metadata returned by server."
114+
115+
116+
if __name__ == "__main__":
117+
test_simple()
118+
test_params_wrong_order()
119+
test_params_duplicate_name()
120+
test_params_invalid_name()
121+
test_params_empty_value()
122+
test_params_leading_space()
123+
test_params_trailing_space()
124+
test_params_time_given()
125+
test_meta_duplicate_names()

0 commit comments

Comments
 (0)