0

Howdo people,

I'm to put together a limited Q&A program that will allow the user to query Wikidata using SPARQL with very specific/limited query structures.

I've got the program going, but I'm running into issues when entering queries that are formulated differently.

def sparql_query(line):
    m = re.search('What is the (.*) of (.*)?', line)
    relation = m.group(1)
    entity = m.group(2)
    wdparams['search'] = entity
    json = requests.get(wdapi, wdparams).json()
    for result in json['search']:
        entity_id = result['id']
        wdparams['search'] = relation
        wdparams['type'] = 'property'
        json = requests.get(wdapi, wdparams).json()
        for result in json['search']:
            relation_id = result['id']
            fire_sparql(entity_id, relation_id)
    return fire_sparql

As you can see, this only works with queries following that specific structure, for example "What is the color of night?" Queries along the lines of 'What are the ingredients of pizza?' simply would cause the program to crash because it doesn't follow the 'correct' structure as set in the code. As such, I would like it to be able to differentiate between different types of query structures ("What is.." and "What are.." for example) and still collect the needed information (relation/property and entity).

This setup is required, insofar as I can determine, seeing as the property and entity need to be extracted from the query in order to get the proper results from Wikidata. This is unfortunately also what I'm running into problems with; I can't seem to use 'if' or 'while-or' statements without the code returning all sorts of issues.

So the question being: How can I make the code accept differently formulated queries whilst still retrieving the needed information from them?

Many thanks in advance.

The entirety of the code in case required:

#!/usr/bin/python3
import sys
import requests
import re


def main():
    example_queries()
    for line in sys.stdin:
        line = line.rstrip()
        answer = sparql_query(line)
        print(answer)


def example_queries():
    print("Example query?\n\n Ask your question.\n")


wdapi = 'https://www.wikidata.org/w/api.php'
wdparams = {'action': 'wbsearchentities', 'language': 'en', 'format': 'json'}


def sparql_query(line):
    m = re.search('What is the (.*) of (.*)', line)
    relation = m.group(1)
    entity = m.group(2)
    wdparams['search'] = entity
    json = requests.get(wdapi, wdparams).json()
    for result in json['search']:
        entity_id = result['id']
        wdparams['search'] = relation
        wdparams['type'] = 'property'
        json = requests.get(wdapi, wdparams).json()
        for result in json['search']:
            relation_id = result['id']
            fire_sparql(entity_id, relation_id)
    return fire_sparql


url = 'https://query.wikidata.org/sparql'


def fire_sparql(ent, rel):
    query = 'SELECT * WHERE { wd:' + ent + ' wdt:' + rel + ' ?answer.}'
    print(query)
    data = requests.get(url, params={'query': query, 'format': 'json'}).json()
    for item in data['results']['bindings']:
        for key in item:
            if item[key]['type'] == 'literal':
                print('{} {}'.format(key, item[key]['value']))
            else:
                print('{} {}'.format(key, item[key]))


if __name__ == "__main__":
    main()
Fillask
  • 23
  • 3
  • I do not understand. What works and what does not work? – UninformedUser May 08 '17 at 14:39
  • Apologies for the confusion. Essentially the code itself works, it produces the desired results, but the possible queries that can be entered are currently limited to those that follow this exact structure: "What is ** of **", a 'What are', or 'Where is' function simply doesn't work right now and I don't know to make it so that they do. I would like to allow multiple possible query structures, but it is unclear to me how I can make the code differentiate between the type of query structure provided by the user and still collect the correct information (relation/property and entity). – Fillask May 08 '17 at 16:26

0 Answers0