Source code for modelr.web.urlargparse

'''
====================
modelr.web.urlparse
====================

.. seealso:: http://docs.python.org/dev/library/argparse.html
'''
import sys
from urlparse import urlparse, parse_qs
from argparse import Namespace
import json
from modelr.constants import WAVELETS
from modelr.constants import REFLECTION_MODELS

def rock_properties_type(str_input):
    from modelr.rock_properties import RockProperties
    args = str_input.split(',')
    assert ((len(args) == 3) or (len(args)==6))

    if (len(args) == 3 ):
        return RockProperties(float(args[0]),
                              float(args[1]), float(args[2]))
    return RockProperties(float(args[0]),
                          float(args[1]), float(args[2]),
                          float(args[3]), float(args[4]),
                          float(args[5]))


          
[docs]def wavelet_type(str_input): ''' To be used as the 'type' value in an Argument. Takes a string as input and returns an arbitrary value. Example:: parser.add_argument('wavelet', type=wavelet_type, help='... ', default='ricker', choices=WAVELETS.keys()) ''' return WAVELETS[str_input]
[docs]def reflectivity_type(str_input): ''' To be used as the 'type' value in an Argument. Takes a string as input and returns an arbitrary value. Example:: parser.add_argument('reflectivity_model', type=reflectivity_type, help='... ', default='zoeppritz', choices=MODELS.keys()) ''' return REFLECTION_MODELS[str_input]
[docs]class Argument(object): ''' A place holder for a url argument. ''' def __init__(self, name, required=False, default=None, type=str, action='store', help='', choices=None): self.name = name self.required = required self.default = default self.type = type self.action = action self.help = help self.choices = choices def parse_arg(self, args): if not args or not args[0] or args[0] == 'null': if self.required: raise ArgumentError("missing argument %r" % (self.name,)) else: return self.default arg = args[0] if self.action != 'list': if self.choices is not None and arg not in self.choices: raise ArgumentError("argument %s is invalid:" + " must be one of %r (got %r)" % (self.name, self.choices, arg)) try: arg = self.type(arg) except: raise ArgumentError("argument %s: invalid %s" + " value: %r" % (self.name, self.type.__name__, arg)) return arg else: new_args = [] for arg in arg.split(','): try: value = self.type(arg) except: raise ArgumentError("argument %s: invalid %s"+ " value: %r" % (self.name, self.type.__name__, arg)) new_args.append(value) return new_args @property def json_dict(self): return { 'name':self.name, 'required': self.required, 'default': self.default, 'type':self.type.__name__, 'action':self.action, 'help': self.help, 'choices': self.choices, } @property def html_help(self): return '<li><b>%s</b>: %s</li>\n' % (self.name, self.help)
[docs]class ArgumentError(Exception): ''' Exception to be called when arguments are not as expected by the parser. '''
[docs]class SendHelp(Exception): ''' Exception to be called when the help argument is found. ''' def __init__(self, html): Exception.__init__(self, html) self.html = html
[docs]class URLArgumentParser(object): ''' Parse a key=value arguments in a url string. Modeled after http://docs.python.org/dev/library/argparse.html ''' def __init__(self, description): ''' Constructor ''' self.description = description # self.arguments = {'help': Argument('help')} self.arguments = {}
[docs] def add_argument(self, name, required=False, default=None, type=str, action='store', help='', choices=None): ''' add an argument ''' arg = Argument(name, required, default, type, action, help, choices) self.arguments[name] = arg
[docs] def parse_params(self, params): ''' parse the arguments gotten by urlparse.parse_qs ''' result = dict() if 'help' in params: params.pop('help') self.raise_help() for key in self.arguments: arg = params.pop(key, None) value = self.arguments[key].parse_arg(arg) result[key] = value if params: key, value = params.popitem() raise ArgumentError("got unexpected argument %r" % (key,)) return Namespace(**result)
[docs] def parse_ulr(self, path): ''' parse a url into its argument. ''' uri = urlparse(path) params = parse_qs(uri.query) return self.parse_params(params)
@property def json_data(self): obj = {'description': self.description, 'arguments': {k:v.json_dict for (k, v) in self.arguments.items()}} return json.dumps(obj) @property def help_html(self): arguments = '\n'.join(arg.html_help for arg in self.arguments.values()) return '<p>%s</p><ul>\n%s</ul>' % (self.description, arguments) def raise_help(self): raise SendHelp(self.help_html)
def main(): path = sys.argv[1] parser = URLArgumentParser('description') parser.add_argument('script', required=True, type=str) if __name__ == '__main__': main()