Get the record for a name or a subdomain.  Optionally include its history, and optionally return an expired name or a name in its grace period.
    Return the blockchain-extracted information on success.
    Return {'error': ...} on error
        In particular, return {'error': 'Not found.'} if the name isn't registered

    If include_expired is True, then a name record will be returned even if it expired
    If include_expired is False, but include_grace is True, then the name record will be returned even if it is expired and in the grace period

def get_name_record(name, include_history=False, include_expired=False, include_grace=True, proxy=None, hostport=None,
                    history_page=None):
    """
    Get the record for a name or a subdomain.  Optionally include its history, and optionally return an expired name or a name in its grace period.
    Return the blockchain-extracted information on success.
    Return {'error': ...} on error
        In particular, return {'error': 'Not found.'} if the name isn't registered

    If include_expired is True, then a name record will be returned even if it expired
    If include_expired is False, but include_grace is True, then the name record will be returned even if it is expired and in the grace period
    """
    if isinstance(name, (str,unicode)):
        # coerce string
        name = str(name)

    assert proxy or hostport, 'Need either proxy handle or hostport string'
    if proxy is None:
        proxy = connect_hostport(hostport)
    
    # what do we expect?
    required = None
    is_blockstack_id = False
    is_blockstack_subdomain = False

    if is_name_valid(name):
        # full name
        required = NAMEOP_SCHEMA_REQUIRED[:]
        is_blockstack_id = True

    elif is_subdomain(name):
        # subdomain 
        required = SUBDOMAIN_SCHEMA_REQUIRED[:]
        is_blockstack_subdomain = True

    else:
        # invalid
        raise ValueError("Not a valid name or subdomain: {}".format(name))
        
    if include_history:
        required += ['history']

    nameop_schema = {
        'type': 'object',
        'properties': NAMEOP_SCHEMA_PROPERTIES,
        'required': required
    }

    rec_schema = {
        'type': 'object',
        'properties': {
            'record': nameop_schema,
        },
        'required': [
            'record'
        ],
    }

    resp_schema = json_response_schema(rec_schema)

    resp = {}
    lastblock = None
    try:
        if include_history:
            resp = get_name_and_history(name, proxy=proxy, history_page=history_page)
            if 'error' in resp:
                # fall back to legacy path
                log.debug(resp)
                resp = proxy.get_name_blockchain_record(name)
        else:
            resp = proxy.get_name_record(name)

        resp = json_validate(resp_schema, resp)
        if json_is_error(resp):
            if resp['error'] == 'Not found.':
                return {'error': 'Not found.', 'http_status': resp.get('http_status', 404)}

            return resp

        lastblock = resp['lastblock']

    except socket.timeout:
        log.error("Connection timed out")
        resp = {'error': 'Connection to remote host timed out.', 'http_status': 503}
        return resp

    except socket.error as se:
        log.error("Connection error {}".format(se.errno))
        resp = {'error': 'Connection to remote host failed.', 'http_status': 502}
        return resp

    except ValidationError as e:
        if BLOCKSTACK_DEBUG:
            log.exception(e)

        resp = {'error': 'Server response did not match expected schema.  You are likely communicating with an out-of-date Blockstack node.', 'http_status': 502}
        return resp
    
    except Exception as ee:
        if BLOCKSTACK_DEBUG:
            log.exception(ee)

        log.error("Caught exception while connecting to Blockstack node: {}".format(ee))
        resp = {'error': 'Failed to contact Blockstack node.  Try again with `--debug`.', 'http_status': 500}
        return resp

    if not include_expired and is_blockstack_id:
        # check expired
        if lastblock is None:
            return {'error': 'No lastblock given from server', 'http_status': 503}

        if include_grace:
            # only care if the name is beyond the grace period
            if lastblock >= int(resp['record']['renewal_deadline']) and int(resp['record']['renewal_deadline']) > 0:
                return {'error': 'Name expired', 'http_status': 404}

            elif int(resp['record']['renewal_deadline']) > 0 and lastblock >= int(resp['record']['expire_block']) and lastblock < int(resp['record']['renewal_deadline']):
                resp['record']['grace_period'] = True

            else:
                resp['record']['grace_period'] = False

        else:
            # only care about expired, even if it's in the grace period
            if lastblock > int(resp['record']['expire_block']) and int(resp['record']['expire_block']) > 0:
                return {'error': 'Name expired', 'http_status': 404}

    return resp['record']