Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion hapiclient/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def info(SERVER, DATASET, PARAMETERS, opts):
meta.update({"x_dataset": DATASET})

if PARAMETERS is not None:
return subset_meta(meta, PARAMETERS)
subset_meta(meta, PARAMETERS)
return meta
else:
return meta
79 changes: 54 additions & 25 deletions hapiclient/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,46 +364,75 @@ def urlretrieve(url, fname):
def subset_meta(meta, params):
"""Extract subset of parameters from meta object returned by hapi().

``metar = subset_meta(meta, parameters)`` modifies ``meta["parameters"]`` array
so that it only contains elements for the time variable and the parameters
in the comma-separated string ``parameters``.
``subset_meta(meta, parameters)`` modifies ``meta["parameters"]`` list
in place so that it only contains elements for the time variable and the
parameters in the comma-separated string ``parameters``.
"""

# Note that tests for subset_meta() are in test_subset_meta.py, which also
# has tests for error message strings. If error message strings change,
# update tests in test_subset_meta.py.

if params == '':
return meta

p = params.split(',')
pm = [] # Parameter names in metadata
pw = params.split(',') # Wanted parameters names as list

# Check for duplicate parameters in pw
if len(pw) != len(set(pw)):
# Print duplicate parameters
duplicates = ','.join([x for x in pw if pw.count(x) > 1])
error("Duplicate parameters in requested parameter list: '" + duplicates + "'")

# Check for errors in pw
for p in pw:
if p == '':
error("Empty parameter name in requested parameter list: '" + params + "'")
if p.startswith(' '):
error("Leading space before parameter name '" + p + "'")
if p.endswith(' '):
error("Trailing space after parameter name '" + p + "'")

pa = [] # Available parameter names in metadata as list
for i in range(0, len(meta['parameters'])):
pm.append(meta['parameters'][i]['name'])
pa.append(meta['parameters'][i]['name'])

# Check if meta has duplicate parameter names.
if len(pa) != len(set(pa)):
duplicates = ','.join([x for x in pa if pa.count(x) > 1])
error('Duplicate parameter names in metadata returned by server: ' + duplicates)

# Check for parameters requested that are not in metadata
for i in range(0, len(p)):
if p[i] not in pm:
error('Parameter %s is not in meta' % p[i] + '\n')
# Check for parameters wanted that are not available
for i in range(0, len(pw)):
if pw[i] not in pa:
error("Parameter '%s' is not in metadata from server" % pw[i])
return

pa = [meta['parameters'][0]] # First parameter is always the time parameter
# Keep first parameter, which is always the primary time parameter
pa = [meta['parameters'][0]]

params_reordered = [] # Re-ordered params
# If time parameter explicitly requested, put it first in params_reordered.
if meta['parameters'][0]['name'] in p:
params_reordered = [meta['parameters'][0]['name']]
pw_reordered = [] # Re-ordered params
# If time parameter explicitly requested, put it first in pw_reordered.
if meta['parameters'][0]['name'] in pw:
pw_reordered = [meta['parameters'][0]['name']]

# Create subset of parameter metadata
for i in range(1, len(pm)):
if pm[i] in p:
for i in range(1, len(meta['parameters'])):
if meta['parameters'][i]['name'] in pw:
pa.append(meta['parameters'][i])
params_reordered.append(pm[i])
meta['parameters'] = pa
pw_reordered.append(meta['parameters'][i]['name'])

pw_reordered_str = ','.join(pw_reordered)

params_reordered_str = ','.join(params_reordered)
if not params == pw_reordered_str:
msg = 'Order of requested parameters does not match order of '
msg += 'parameters in server info metadata. '
msg += "\n " + "Order requested: " + params
msg += "\n " + "Order required: " + pw_reordered_str
error(msg)

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

return meta

Expand Down
125 changes: 125 additions & 0 deletions test/test_subset_meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from hapiclient.util import HAPIError, subset_meta

meta = {
"parameters": [
{"name": "Time"},
{"name": "Parameter1"},
{"name": "Parameter2"},
{"name": "Parameter3"}
]
}

msg_o = "Exception not raised by subset_meta() with "

def test_simple():
params = 'Parameter1,Parameter2'
subset_meta(meta, params)
assert len(meta['parameters']) == 3
assert meta['parameters'][0]['name'] == 'Time'
assert meta['parameters'][1]['name'] == 'Parameter1'
assert meta['parameters'][2]['name'] == 'Parameter2'


def test_params_wrong_order():
params = 'Parameter2,Parameter1'
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Order of requested parameters does not match')
else:
assert False, msg_o + "parameters in wrong order."


def test_params_duplicate_name():
params = 'Parameter1,Parameter1'
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Duplicate parameters in requested parameter list')
else:
assert False, msg_o + "duplicate parameter names."


def test_params_invalid_name():
params = 'Parameter1,ParameterX'
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith("Parameter 'ParameterX' is not in metadata from server")
else:
assert False, msg_o + "invalid parameter name."


def test_params_empty_value():
params = 'Parameter2,'
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Empty parameter name')
else:
assert False, msg_o + "empty parameter name."


def test_params_leading_space():
params = ' Parameter1,Parameter2'
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Leading space')
else:
assert False, msg_o + "leading space in parameter name."


def test_params_trailing_space():
params = 'Parameter1,Parameter2 '
try:
subset_meta(meta, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Trailing space')
else:
assert False, msg_o + "trailing space in parameter name."


def test_params_time_given():
params = 'Time,Parameter1'
subset_meta(meta, params)
assert len(meta['parameters']) == 2
assert meta['parameters'][0]['name'] == 'Time'
assert meta['parameters'][1]['name'] == 'Parameter1'


def test_meta_duplicate_names():
meta_dup = {
"parameters": [
{"name": "Time"},
{"name": "Parameter1"},
{"name": "Parameter1"},
{"name": "Parameter3"}
]
}
params = 'Parameter1'
try:
subset_meta(meta_dup, params)
except Exception as e:
assert isinstance(e, HAPIError)
assert str(e).startswith('Duplicate parameter names in metadata returned by server')
else:
assert False, msg_o + "duplicate parameter names in metadata returned by server."


if __name__ == "__main__":
test_simple()
test_params_wrong_order()
test_params_duplicate_name()
test_params_invalid_name()
test_params_empty_value()
test_params_leading_space()
test_params_trailing_space()
test_params_time_given()
test_meta_duplicate_names()
Loading