Exemplo n.º 1
0
def transform_for_linked_data(edge):
    """
    Modify an edge (assertion) in place to contain values that are appropriate
    for a Linked Data API.

    Although this code isn't actually responsible for what an API returns
    (see the conceptnet-web repository for that), it helps to deal with what
    edge dictionaries should contain here.

    The relevant changes are:

    - Remove the 'features' list
    - Rename 'uri' to '@id'
    - Make 'start', 'end', and 'rel' into dictionaries with an '@id' and
      'label', removing the separate 'surfaceStart' and 'surfaceEnd'
      attributes
    - All dictionaries should have an '@id'. For the edge itself, it's the
      URI. Without this, we get RDF blank nodes, which are awful.
    - Set '@type' on objects representing edges and sources. (Nodes get their
      @type from the `ld_node` function.)
    """
    if 'features' in edge:
        del edge['features']
    for source in edge['sources']:
        conj = conjunction_uri(*sorted(source.values()))
        source['@id'] = conj
        source['@type'] = 'Source'
    edge['@id'] = edge['uri']
    del edge['uri']
    edge['@type'] = 'Edge'

    start_uri = edge['start']
    end_uri = edge['end']
    rel_uri = edge['rel']
    start_label = edge.get('surfaceStart')
    end_label = edge.get('surfaceEnd')
    del edge['surfaceStart']
    del edge['surfaceEnd']
    edge['start'] = ld_node(start_uri, start_label)
    edge['end'] = ld_node(end_uri, end_label)
    edge['rel'] = ld_node(rel_uri, None)
    if 'other' in edge:
        # TODO: Find out when we use this, or remove it if we don't use it
        if edge['other'] == start_uri:
            edge['other'] = edge['start']
        elif edge['other'] == end_uri:
            edge['other'] = edge['end']
        else:
            edge['rel'] = ld_node(rel_uri, None)

    return edge
Exemplo n.º 2
0
def transform_for_linked_data(edge):
    """
    Modify an edge (assertion) in place to contain values that are appropriate
    for a Linked Data API.

    Although this code isn't actually responsible for what an API returns
    (see the conceptnet-web repository for that), it helps to deal with what
    edge dictionaries should contain here.

    The relevant changes are:

    - Remove the 'features' list
    - Rename 'uri' to '@id'
    - Make 'start', 'end', and 'rel' into dictionaries with an '@id' and
      'label', removing the separate 'surfaceStart' and 'surfaceEnd'
      attributes
    - All dictionaries should have an '@id'. For the edge itself, it's the
      URI. Without this, we get RDF blank nodes, which are awful.
    - Set '@type' on objects representing edges and sources. (Nodes get their
      @type from the `ld_node` function.)
    """
    if 'features' in edge:
        del edge['features']
    for source in edge['sources']:
        conj = conjunction_uri(*sorted(source.values()))
        source['@id'] = conj
        source['@type'] = 'Source'
    edge['@id'] = edge['uri']
    del edge['uri']
    edge['@type'] = 'Edge'

    start_uri = edge['start']
    end_uri = edge['end']
    rel_uri = edge['rel']
    start_label = edge.get('surfaceStart')
    end_label = edge.get('surfaceEnd')
    del edge['surfaceStart']
    del edge['surfaceEnd']
    edge['start'] = ld_node(start_uri, start_label)
    edge['end'] = ld_node(end_uri, end_label)
    edge['rel'] = ld_node(rel_uri, None)
    if 'other' in edge:
        # TODO: Find out when we use this, or remove it if we don't use it
        if edge['other'] == start_uri:
            edge['other'] = edge['start']
        elif edge['other'] == end_uri:
            edge['other'] = edge['end']
        else:
            edge['rel'] = ld_node(rel_uri, None)

    return edge
Exemplo n.º 3
0
def lookup_grouped_by_feature(term,
                              filters=None,
                              scan_limit=1000,
                              group_limit=10):
    """
    Given a query for a concept, return assertions about that concept grouped by
    their features (for example, "A dog wants to ..." could be a group).

    It will scan up to `scan_limit` assertions to find out which features exist,
    then retrieve `group_limit` assertions for each feature if possible.
    """
    if not term.startswith('/c/'):
        return error(
            {}, 400,
            'Only concept nodes (starting with /c/) can be grouped by feature.'
        )

    found = FINDER.lookup_grouped_by_feature(term)
    grouped = []
    for groupkey, assertions in found.items():
        direction, rel = groupkey
        base_url = '/query'
        feature_pairs = groupkey_to_pairs(groupkey, term)
        url = make_query_url(base_url, feature_pairs)
        symmetric = direction == 0
        group = {
            '@id': url,
            'weight': sum(assertion['weight'] for assertion in assertions),
            'feature': dict(feature_pairs),
            'edges': assertions[:MAX_GROUP_SIZE],
            'symmetric': symmetric
        }
        if len(assertions) > MAX_GROUP_SIZE:
            view = make_paginated_view(base_url,
                                       feature_pairs,
                                       0,
                                       group_limit,
                                       more=True)
            group['view'] = view

        grouped.append(group)

    grouped.sort(key=lambda g: -g['weight'])
    for group in grouped:
        del group['weight']

    response = ld_node(term)
    if not grouped and filters is None:
        return error(response, 404, '%r is not a node in ConceptNet.' % term)
    else:
        response['features'] = grouped
        return success(response)
Exemplo n.º 4
0
def lookup_grouped_by_feature(term, filters=None, feature_limit=10):
    """
    Given a query for a concept, return assertions about that concept grouped by
    their features (for example, "A dog wants to ..." could be a group).
    """
    if not term.startswith('/c/'):
        return error(
            {}, 400,
            'Only concept nodes (starting with /c/) can be grouped by feature.'
        )

    found = FINDER.lookup_grouped_by_feature(term, limit=(feature_limit + 1))
    grouped = []
    for groupkey, assertions in found.items():
        direction, rel = groupkey
        base_url = '/query'
        feature_pairs = groupkey_to_pairs(groupkey, term)
        url = make_query_url(base_url, feature_pairs)
        symmetric = direction == 0
        group = {
            '@id': url,
            'weight': sum(assertion['weight'] for assertion in assertions),
            'feature': dict(feature_pairs),
            'edges': assertions[:feature_limit],
            'symmetric': symmetric,
        }
        if len(assertions) > feature_limit:
            view = make_paginated_view(base_url,
                                       feature_pairs,
                                       0,
                                       feature_limit,
                                       more=True)
            group['view'] = view

        grouped.append(group)

    grouped.sort(key=lambda g: -g['weight'])
    for group in grouped:
        del group['weight']

    response = ld_node(term)
    if not grouped and not filters:
        return error(response, 404,
                     '%r is not a node in ConceptNet.' % response['label'])
    else:
        response['features'] = grouped
        return success(response)
Exemplo n.º 5
0
def lookup_grouped_by_feature(term, filters=None, feature_limit=10):
    """
    Given a query for a concept, return assertions about that concept grouped by
    their features (for example, "A dog wants to ..." could be a group).
    """
    if not term.startswith('/c/'):
        return error(
            {}, 400, 'Only concept nodes (starting with /c/) can be grouped by feature.'
        )

    found = FINDER.lookup_grouped_by_feature(term, limit=(feature_limit + 1))
    grouped = []
    for groupkey, assertions in found.items():
        direction, rel = groupkey
        base_url = '/query'
        feature_pairs = groupkey_to_pairs(groupkey, term)
        url = make_query_url(base_url, feature_pairs)
        symmetric = direction == 0
        group = {
            '@id': url,
            'weight': sum(assertion['weight'] for assertion in assertions),
            'feature': dict(feature_pairs),
            'edges': assertions[:feature_limit],
            'symmetric': symmetric,
        }
        if len(assertions) > feature_limit:
            view = make_paginated_view(
                base_url, feature_pairs, 0, feature_limit, more=True
            )
            group['view'] = view

        grouped.append(group)

    grouped.sort(key=lambda g: -g['weight'])
    for group in grouped:
        del group['weight']

    response = ld_node(term)
    if not grouped and not filters:
        return error(
            response, 404, '%r is not a node in ConceptNet.' % response['label']
        )
    else:
        response['features'] = grouped
        return success(response)
Exemplo n.º 6
0
def lookup_grouped_by_feature(term, filters=None, scan_limit=1000, group_limit=10):
    """
    Given a query for a concept, return assertions about that concept grouped by
    their features (for example, "A dog wants to ..." could be a group).

    It will scan up to `scan_limit` assertions to find out which features exist,
    then retrieve `group_limit` assertions for each feature if possible.
    """
    if not term.startswith('/c/'):
        return error(
            {}, 400,
            'Only concept nodes (starting with /c/) can be grouped by feature.'
        )

    found = FINDER.lookup_grouped_by_feature(term)
    grouped = []
    for groupkey, assertions in found.items():
        direction, rel = groupkey
        base_url = '/query'
        feature_pairs = groupkey_to_pairs(groupkey, term)
        url = make_query_url(base_url, feature_pairs)
        symmetric = direction == 0
        group = {
            '@id': url,
            'weight': sum(assertion['weight'] for assertion in assertions),
            'feature': dict(feature_pairs),
            'edges': assertions[:MAX_GROUP_SIZE],
            'symmetric': symmetric
        }
        if len(assertions) > MAX_GROUP_SIZE:
            view = make_paginated_view(base_url, feature_pairs, 0, group_limit, more=True)
            group['view'] = view

        grouped.append(group)

    grouped.sort(key=lambda g: -g['weight'])
    for group in grouped:
        del group['weight']

    response = ld_node(term)
    if not grouped and filters is None:
        return error(response, 404, '%r is not a node in ConceptNet.' % term)
    else:
        response['features'] = grouped
        return success(response)