Reputation: 1546
i am using yaml to store my config data. once i load the file. i want to check if certain Key and Values exist.
yaml content:
sftp:
host: server
username: user
password: pass
path: /mnt/Storage/Folder/
filename: blah
so i need to know if these key values exists in the yaml file. since these are required in order to work properly. what is the best way to do this? i can use this method below, it i would have to manually check on by one. The required key values are going to grow, this is just the minimum.
if (key in data):
return True
Upvotes: 0
Views: 3352
Reputation: 1255
There are a couple of approaches. Since your input is more complex than, say, a dict with two keys, I'd go with number four, a library for path expressions, like jsonpath.
Completely manual
You navigate thru the object tree, raise an exception if something is unexpected.
Pro/con: Maximal control, also over error messages, but minimum descriptiveness.
Manual path evaluation
You define the expected “paths” and then have a (possibly nested) loop to go thru each, and evaluate if the input object matches the path. Philips answer falls into that category.
Questions like this one about xpath for dicts might point you a favorable direction, implementation-wise.
Pro/con: Can be descriptive, but might be non-trivial to get the evaluation right for all corner cases.
Builtin evaluation
You define a set of functions that must evaluate to a non-None value. Python does the evaluation for you. Something along these lines:
must_evaluate = {
lambda o: o["sftp"]["host"],
lambda o: o["sftp"]["username"],
lambda o: o["sftp"]["passowrd"],
lambda o: o["sftp"]["path"],
lambda o: o["filename"],
}
def check_with_builtin_resolution(obj):
def check_lambda_on_obj(l):
try:
if l(obj) is not None:
return True
except AttributeError:
pass
except KeyError:
pass
return False
for l in must_evaluate:
if not check_lambda_on_obj(l):
return False
return True
Pro/con: Quite descriptive, though not as nice as paths in 2 or 4 might be. Biggest con: No trivial way to describe, which expectation failed, since lambdas don't print well.
Library for path expressions
Use a library for path expressions, like jsonpath. Iterate over each expression and raise an exception, when it does not evaluate to what you want.
Pro/con: Legible, and good support for decent error messages.
Library for object tree checking
Maybe some other poster is aware of existing, mature work. I myself being bothered by this problem have started to fiddle with parseobj, but can't recommend that for real usage just yet.
Upvotes: 1
Reputation: 1429
So in order to make sure every key you need exists, you are going to have to check for each one explicitly somehow. However, if the keys are unique, then you could use sets to make it a bit cleaner, e.g.,
needed = set(["host", "username", "password"]) #etc.
then to detect / read in the YAML file:
seen = set()
for key, value in data.iteritems():
seen.add(key)
return needed.issubset(seen)
Upvotes: 0