Lookup basic phone number information or send SMS messages

def CLI(ctx, config, list_lookups):
    """Lookup basic phone number information or send SMS messages"""
    loglevel = 'info'
    verbosity = getattr(logging, loglevel.upper(), 'INFO')
    #verbosity = logging.DEBUG
    ctx.obj = {
        'verbosity': verbosity,
        'logfile': None,
        'config': {'lookups': {}},
    }
    #logfmt = '%(levelname)-8s | %(message)s'
    logfmt = '%(message)s'
    logging.basicConfig(format=logfmt, level=verbosity)
    debug('CLI >  CWD="{0}"'.format(os.getcwd()))
    with open(CONFIG_FILE, 'ab+') as phonedb:
        phonedb.seek(0)
        rawdata = phonedb.read()
        if rawdata:
            data = json.loads(rawdata, object_pairs_hook=OrderedDict)
            debug(data)
            ctx.obj['config'] = data
            if 'lookups' not in ctx.obj['config']:
                ctx.obj['config']['lookups'] = {}

    if 'sms_gateways' not in ctx.obj['config']:
        """
        gwsorted = sorted(ctx.obj['config']['sms_gateways'].items())
        gwordered = OrderedDict()
        for (k, v) in gwsorted:
            gwordered[k] = v
        ctx.obj['config']['sms_gateways'] = gwordered
        """
        info('loading SMS gateways...')
        sms_gateways = {}
        with open('carrier-gateways', 'rb') as gateways:
            gwdata = gateways.read()
            import re
            re_carrier = r'(?P<carrier>\w+[\w\&\(\)\-\'\s]*[\w\)\(]+)\s+'
            re_gateway = r'10digitphonenumber(?P<gateway>\@\w[\w\.]*\w)\s+'
            gwre = re.compile(re_carrier + re_gateway)
            gws = gwre.findall(gwdata)
            for gw in gwre.finditer(gwdata):
                gwinfo = gw.groupdict()
                debug(gw.groupdict())
                sms_gateways[gwinfo['carrier']] = gwinfo['gateway']
            num_lines = len([l for l in gwdata.split('\n') if len(l)])
            debug('lines={0} ({1} / 2)'.format(num_lines/2, num_lines))
            debug('matches={0}'.format(len(data)))
        ctx.obj['config']['sms_gateways'] = sms_gateways
        with open(CONFIG_FILE, 'wb') as cfg:
            cfg.write(json.dumps(ctx.obj['config'], indent=2))
        info('SMS gateways written to config')

    if list_lookups:
        sms_updated = False
        from fuzzywuzzy import fuzz
        from fuzzywuzzy import process
        lookups = ctx.obj['config']['lookups']
        info('cached lookups:')
        for number, pinfo in lookups.iteritems():
            owner = pinfo['comment']
            common = pinfo['body']['national_format']
            carrier = pinfo['body']['carrier']['name']
            pntype = pinfo['body']['carrier']['type']
            info('  {0}: {1}'.format(owner, common))
            info('    - carrier: {0}'.format(carrier))
            info('    - type: {0}'.format(pntype))
            debug('    - unformatted: {0}'.format(number))
            if 'sms' not in lookups[number]:
                carriers = ctx.obj['config']['sms_gateways'].keys()
                fuzzy = process.extract(carrier, carriers)
                fuzz_max = 0
                result = []
                gateway_key = None
                for f in fuzzy:
                    if f[1] >= fuzz_max:
                        fuzz_max = f[1]
                        result.append(f[0])
                debug(result)
                if len(result) > 1:
                    if len(sorted(result)[0]) <= len(carrier):
                        gateway_key = sorted(result)[0]
                    else:
                        gateway_key = result[0]
                else:
                    gateway_key = result[0]
                gw_suffix = ctx.obj['config']['sms_gateways'][gateway_key]
                ctx.obj['config']['lookups'][number]['sms'] = '{0}{1}'.format(
                    number, gw_suffix)
                sms_updated = True
            info('    - SMS gateway: {0}'.format(
                ctx.obj['config']['lookups'][number]['sms']))
        if sms_updated:
            with open(CONFIG_FILE, 'wb') as cfg:
                cfg.write(json.dumps(ctx.obj['config'], indent=2))
        ctx.exit()