views:

145

answers:

1

Hi!

I'm using YAML as a configuration file format for a Python project.

Recently I found Rx to be the only schema validator available for Python and YAML. :-/ Kwalify works with YAML, but it's only for Ruby and Java. :(

I've been reading their lacking documentation all day and just can't seem to write a valid schema to represent my file structure. Help?

I have the following YAML config file:

cmd:
  exec: mycmd
  aliases: [my, cmd]
  filter:
    sms: 'regex .*'

load:
  exec: load
  filter:
    sms: 'load: .*$'

echo:
  exec: echo %

I'm failing at representing a nested structure. What I want is for the outer-most item (cmd, load and echo, in this case) to be an arbitrary string that in turn contains other items. 'exec' is a fixed string and required item; 'aliases' and 'filter' are also fixed, but should be optional. Filter in turn has another set of required and optional items. How should I represent this with Rx?

So far I have the following schema (in YAML), which Rx fails to compile:

type: //rec
required:
  type: //rec
  required:
    exec: //str
  optional:
    aliases:
      type: //arr
      contents: //str
      length: {min: 1, max: 10}
    filter:
      type: //rec
      optional:
        sms: //str
        email: //str
        all: //str

Testing this in IPython gives me this:

/Rx.py in make_schema(self, schema)
     68       raise Error('invalid schema argument to make_schema')
     69
---> 70     uri = self.expand_uri(schema["type"])
     71
     72     if not self.type_registry.get(uri): raise "unknown type %s" % uri

KeyError: 'type'

Which leads me to believe I'm not specifying "type" somewhere. :-S

Any ideas?

I'm pretty tired fighting with this thing... Is there some other way I can write a schema and use it to validate my configuration files?

Thanks in advance,

Ivan

+2  A: 

Try this:

type: //map
values:
  type: //rec
  required:
    exec: //str
  optional:
    aliases:
      type: //arr
      contents: //str
      length: {min: 1, max: 10}
    filter:
      type: //rec
      optional:
        sms: //str
        email: //str
        all: //str

A map can contain any string as a key, whereas a rec can only contain the keys specified in 'required' and 'optional'.

Daniel Lucraft
Yup, that works! I never thought about using //map this way; was too focused on the //rec type.The author of Rx, Ricardo Signes, has kindly sent me a helpful response as well, which I thought I'd share a snipper of with anyone who might have a similar problem in the future: http://pastebin.com/f13421133. I hope he doesn't mind me doing so.Thanks for your answer, Daniel! You saved my day! :D
imiric