Skip to content

Commit 1393a45

Browse files
authored
Merge pull request #47 from yucongalicechen/keyvalue2
closes #26: loading user-specified key-value pairs
2 parents cbf7a46 + 22706cb commit 1393a45

File tree

3 files changed

+120
-4
lines changed

3 files changed

+120
-4
lines changed

src/diffpy/labpdfproc/labpdfprocapp.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
from pathlib import Path
44

55
from diffpy.labpdfproc.functions import apply_corr, compute_cve
6-
from diffpy.labpdfproc.tools import known_sources, set_output_directory, set_wavelength
6+
from diffpy.labpdfproc.tools import known_sources, load_user_metadata, set_output_directory, set_wavelength
77
from diffpy.utils.parsers.loaddata import loadData
88
from diffpy.utils.scattering_objects.diffraction_objects import XQUANTITIES, Diffraction_object
99

1010

11-
def get_args():
11+
def get_args(override_cli_inputs=None):
1212
p = ArgumentParser()
1313
p.add_argument("mud", help="Value of mu*D for your " "sample. Required.", type=float)
1414
p.add_argument("-i", "--input-file", help="The filename of the " "datafile to load.")
@@ -58,12 +58,25 @@ def get_args():
5858
action="store_true",
5959
help="Outputs will not overwrite existing file unless --force is specified.",
6060
)
61-
args = p.parse_args()
61+
p.add_argument(
62+
"-u",
63+
"--user-metadata",
64+
metavar="KEY=VALUE",
65+
nargs="+",
66+
help="Specify key-value pairs to be loaded into metadata using the format key=value. "
67+
"Separate pairs with whitespace, and ensure no whitespaces before or after the = sign. "
68+
"Avoid using = in keys. If multiple = signs are present, only the first separates the key and value. "
69+
"If a key or value contains whitespace, enclose it in quotes. "
70+
"For example, facility='NSLS II', 'facility=NSLS II', beamline=28ID-2, "
71+
"'beamline'='28ID-2', 'favorite color'=blue, are all valid key=value items. ",
72+
)
73+
args = p.parse_args(override_cli_inputs)
6274
return args
6375

6476

6577
def main():
6678
args = get_args()
79+
args = load_user_metadata(args)
6780
args.output_directory = set_output_directory(args)
6881
args.wavelength = set_wavelength(args)
6982

src/diffpy/labpdfproc/tests/test_tools.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
import pytest
77

8-
from diffpy.labpdfproc.tools import known_sources, set_output_directory, set_wavelength
8+
from diffpy.labpdfproc.labpdfprocapp import get_args
9+
from diffpy.labpdfproc.tools import known_sources, load_user_metadata, set_output_directory, set_wavelength
910

1011
params1 = [
1112
([None], ["."]),
@@ -76,3 +77,63 @@ def test_set_wavelength_bad(inputs, msg):
7677
actual_args = argparse.Namespace(wavelength=inputs[0], anode_type=inputs[1])
7778
with pytest.raises(ValueError, match=re.escape(msg[0])):
7879
actual_args.wavelength = set_wavelength(actual_args)
80+
81+
82+
params5 = [
83+
([], []),
84+
(
85+
["--user-metadata", "facility=NSLS II", "beamline=28ID-2", "favorite color=blue"],
86+
[["facility", "NSLS II"], ["beamline", "28ID-2"], ["favorite color", "blue"]],
87+
),
88+
(["--user-metadata", "x=y=z"], [["x", "y=z"]]),
89+
]
90+
91+
92+
@pytest.mark.parametrize("inputs, expected", params5)
93+
def test_load_user_metadata(inputs, expected):
94+
expected_args = get_args(["2.5"])
95+
for expected_pair in expected:
96+
setattr(expected_args, expected_pair[0], expected_pair[1])
97+
delattr(expected_args, "user_metadata")
98+
99+
cli_inputs = ["2.5"] + inputs
100+
actual_args = get_args(cli_inputs)
101+
actual_args = load_user_metadata(actual_args)
102+
assert actual_args == expected_args
103+
104+
105+
params6 = [
106+
(
107+
["--user-metadata", "facility=", "NSLS II"],
108+
[
109+
"Please provide key-value pairs in the format key=value. "
110+
"For more information, use `labpdfproc --help.`"
111+
],
112+
),
113+
(
114+
["--user-metadata", "favorite", "color=blue"],
115+
"Please provide key-value pairs in the format key=value. "
116+
"For more information, use `labpdfproc --help.`",
117+
),
118+
(
119+
["--user-metadata", "beamline", "=", "28ID-2"],
120+
"Please provide key-value pairs in the format key=value. "
121+
"For more information, use `labpdfproc --help.`",
122+
),
123+
(
124+
["--user-metadata", "facility=NSLS II", "facility=NSLS III"],
125+
"Please do not specify repeated keys: facility. ",
126+
),
127+
(
128+
["--user-metadata", "wavelength=2"],
129+
"wavelength is a reserved name. Please rerun using a different key name. ",
130+
),
131+
]
132+
133+
134+
@pytest.mark.parametrize("inputs, msg", params6)
135+
def test_load_user_metadata_bad(inputs, msg):
136+
cli_inputs = ["2.5"] + inputs
137+
actual_args = get_args(cli_inputs)
138+
with pytest.raises(ValueError, match=msg[0]):
139+
actual_args = load_user_metadata(actual_args)

src/diffpy/labpdfproc/tools.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,45 @@ def set_wavelength(args):
6060
return WAVELENGTHS[args.anode_type]
6161
else:
6262
return WAVELENGTHS["Mo"]
63+
64+
65+
def _load_key_value_pair(s):
66+
items = s.split("=")
67+
key = items[0].strip()
68+
if len(items) > 1:
69+
value = "=".join(items[1:])
70+
return (key, value)
71+
72+
73+
def load_user_metadata(args):
74+
"""
75+
Load user metadata into the provided argparse Namespace, raise ValueError if in incorrect format
76+
77+
Parameters
78+
----------
79+
args argparse.Namespace
80+
the arguments from the parser
81+
82+
Returns
83+
-------
84+
the updated argparse Namespace with user metadata inserted as key-value pairs
85+
86+
"""
87+
88+
reserved_keys = vars(args).keys()
89+
90+
if args.user_metadata:
91+
for item in args.user_metadata:
92+
if "=" not in item:
93+
raise ValueError(
94+
"Please provide key-value pairs in the format key=value. "
95+
"For more information, use `labpdfproc --help.`"
96+
)
97+
key, value = _load_key_value_pair(item)
98+
if key in reserved_keys:
99+
raise ValueError(f"{key} is a reserved name. Please rerun using a different key name. ")
100+
if hasattr(args, key):
101+
raise ValueError(f"Please do not specify repeated keys: {key}. ")
102+
setattr(args, key, value)
103+
delattr(args, "user_metadata")
104+
return args

0 commit comments

Comments
 (0)