Skip to content

Commit

Permalink
Merge pull request #16 from dbpedia/feature/14
Browse files Browse the repository at this point in the history
new Dialogflow scenario for explainability
  • Loading branch information
muskan-k authored Aug 27, 2023
2 parents cb67ae4 + b0411af commit e2065e9
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 21 deletions.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8"
},
"python.formatting.provider": "none"
}
2 changes: 1 addition & 1 deletion Webhook/config.env → Webhook/.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ RDF_VIZ_HOST_URL=http://141.57.8.18:40193/visualize/
SPARQL_URL=${QANARY_HOST_URL}/sparql
DBPEDIA_SPARQL_URL=https://dbpedia.org/sparql
QANARY_PIPELINE_URL=${QANARY_HOST_URL}/startquestionansweringwithtextquestion
COMPONENT_URL=${QANARY_HOST_URL}/components
COMPONENT_URL=${QANARY_HOST_URL}/components
2 changes: 1 addition & 1 deletion Webhook/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM python:3.7

WORKDIR /app
COPY . /app
COPY ./config.env /app/.env
COPY ./.env /app/.env

RUN pip install virtualenv
RUN virtualenv venv && . venv/bin/activate
Expand Down
10 changes: 8 additions & 2 deletions Webhook/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,28 @@
qanaryComponents = None
qanaryComponentNames = None


def getComponents():
global qanaryComponents
global qanaryComponentNames
response = urllib.request.urlopen(os.getenv('COMPONENT_URL')).read().decode()
print("component url" + str(os.getenv('COMPONENT_URL')))
response = urllib.request.urlopen(
os.getenv('COMPONENT_URL')).read().decode()
body = ast.literal_eval(response)
qanaryComponents = fuzzyset.FuzzySet()
qanaryComponents = fuzzyset.FuzzySet()
qanaryComponentNames = set()
for i in range(len(body)):
qanaryComponents.add(body[i]['name'])
# TODO
qanaryComponentNames.add(body[i]['name'])


def getQanaryComponentNames():
global qanaryComponentNames
getComponents()
return qanaryComponentNames


def getQanaryComponents():
global qanaryComponents
getComponents()
Expand Down
1 change: 1 addition & 0 deletions Webhook/fulfillment/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class FulfillmentMessages(BaseModel):
intentMap['qanary-CreateProfile'] = intents.createProfileIntent
intentMap['qanary-DeactivateComponent'] = intents.deactivateComponentIntent
intentMap['qanary-EmptyComponents'] = intents.emptyComponentsIntent
intentMap['qanary-GetExplanationOfPrevAnswer'] = intents.getExplanationOfPrevAnswerIntent
intentMap['qanary-RemoveComponentFromProfile'] = intents.removeComponentFromProfileIntent
intentMap['qanary-ResetComponents'] = intents.resetComponentsIntent
intentMap['qanary-ShowActiveComponents'] = intents.showActiveComponentsIntent
Expand Down
168 changes: 159 additions & 9 deletions Webhook/helpers/intents.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
import requests
import sys
import os
import re
from dotenv import load_dotenv

load_dotenv()
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

profileComponents = []
sessionIdManagement = {}
lastKbquestion = {}
lastGraphId = {}
lastKbAnswer = {}
profiles = {}
profileComponents = []
DEFAULT_COMPONENTS = ["NED-DBpediaSpotlight", "SparqlExecuter",
"OpenTapiocaNED", "BirthDataQueryBuilder", "WikidataQueryExecuter"]
"OpenTapiocaNED", "BirthDataQueryBuilder", "WikidataQueryExecuter"]


def activateComponentIntent(agent):
Expand Down Expand Up @@ -54,14 +56,63 @@ def activeQanaryComponentsIntent(agent):
return output


def getAnswerFromDbpedia(query):
endpointUrl = os.getenv('DBDBPEDIA_SPARQL_URL')
sparql = SPARQLWrapper(endpointUrl)
def getAnswerFromBackend(query, URL):
# endpointUrl = os.getenv('DBPEDIA_SPARQL_URL')
print(str(query))
sparql = SPARQLWrapper(URL)
sparql.setQuery(query)
sparql.setReturnFormat(JSON)
sparql.setMethod(POST)
result = sparql.queryAndConvert()
return result['results']['bindings'][0]['answer']['value']
print(result)
entityURI = result['results']['bindings'][0]['uri']['value']
getLabelQuery = """
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label WHERE {
<"""+entityURI+"""> rdfs:label ?label
FILTER(LANG(?label)="en")
}
"""
sparql = SPARQLWrapper(URL)
sparql.setQuery(getLabelQuery)
sparql.setReturnFormat(JSON)
sparql.setMethod(POST)
label = sparql.queryAndConvert()
label = label['results']['bindings'][0]['label']['value']
return "Thank you for trying the Qanary question-answering system! Here's the answer that Qanary retrived for you: " + str(label)


def obtainPrefixedQueryData(query):
dataset_prefixes = {
"wd": {
"prefix": "wd",
"url": "http://www.wikidata.org/entity/",
"sparql_url": "https://query.wikidata.org/bigdata/namespace/wdq/sparql"
},
"wdt": {
"prefix": "wdt",
"url": "http://www.wikidata.org/prop/direct/",
"sparql_url": "https://query.wikidata.org/bigdata/namespace/wdq/sparql"
},
"dbp": {
"prefix": "dbp",
"url": "http://dbpedia.org/resource/",
"sparql_url": "https://dbpedia.org/sparql"
}
}

dataset = None
prefix_matches = re.findall(r'\b(wd|wdt|dbpedia):', query)
if prefix_matches:
prefixes = set(prefix_matches)
for prefix in prefixes:
if prefix in dataset_prefixes:
dataset = prefix if prefix != "dbpedia" else "dbpedia"
query = f"PREFIX {prefix}: <{dataset_prefixes[dataset]['url']}>\n" + query

sparql_url = dataset_prefixes.get(dataset, {}).get('sparql_url', None)

return query, sparql_url


def getAnswerFromQanary(graphId):
Expand All @@ -83,8 +134,10 @@ def getAnswerFromQanary(graphId):
sparql.setReturnFormat(JSON)
sparql.setMethod(POST)
result = sparql.queryAndConvert()
dbpediaQuery = result['results']['bindings'][0]['resultAsSparqlQuery']['value']
result = getAnswerFromDbpedia(dbpediaQuery)
print(result)
SparqlQuery = result['results']['bindings'][0]['resultAsSparqlQuery']['value']
finalSPARQLquery, queryURL = obtainPrefixedQueryData(SparqlQuery)
result = getAnswerFromBackend(finalSPARQLquery, queryURL)
if result is not None:
output = result
return output
Expand All @@ -93,20 +146,116 @@ def getAnswerFromQanary(graphId):
def askQanaryIntent(agent):
sessionId = agent['session'].split('/')[4]
lastKbquestion[sessionId] = agent['queryResult']['queryText']
print(sessionIdManagement)
getComponent = sessionIdManagement[sessionId]

show = getComponent['components']
print(show)
print(str(lastKbquestion[sessionId]))
params = {
"question": lastKbquestion[sessionId],
"componentlist[]": show
}
print("URL: " + str(os.getenv('QANARY_PIPELINE_URL')))
response = requests.post(os.getenv('QANARY_PIPELINE_URL'), params)
responseDict = ast.literal_eval(response.text)
print("response dict: " + str(responseDict))
currentGraphId = responseDict['inGraph']
lastGraphId[sessionId] = currentGraphId
output = getAnswerFromQanary(currentGraphId)
lastKbAnswer[sessionId] = output
return output


def getAnnotationsOfComponentAction(annotationType, graphURI):
endpointUrl = os.getenv('SPARQL_URL')
if "AnnotationOfInstance" in annotationType:
queryAnnotationsOfComponent = """PREFIX qa: <http://www.wdaqua.eu/qa#>
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
SELECT
?annotation
?question
?startPosition
?endPosition
?resource
?annotationCreator
?annotationDate
?annotationConfidence
FROM <"""+graphURI+""">
WHERE {
?annotation a qa:AnnotationOfInstance .
?annotation oa:hasTarget [
a oa:SpecificResource;
oa:hasSource ?question ;
oa:hasSelector [
a oa:TextPositionSelector ;
oa:start ?startPosition ;
oa:end ?endPosition
]
] .
?annotation oa:hasBody ?resource ;
oa:annotatedBy ?annotationCreator ;
oa:annotatedAt ?annotationDate ;
qa:score ?annotationConfidence .
}"""
sparql = SPARQLWrapper(endpointUrl)
sparql.setQuery(queryAnnotationsOfComponent)
sparql.setReturnFormat(JSON)
sparql.setMethod(POST)
print(str(queryAnnotationsOfComponent))
resultFromAnnotation = sparql.queryAndConvert()
print(str(resultFromAnnotation))
return resultFromAnnotation


def getExplanationOfPrevAnswerIntent(agent):
sessionId = agent['session'].split('/')[4]
print("session id: " + sessionId)
try:
lastGraphIdOfSession = lastGraphId[sessionId]
except:
lastGraphIdOfSession = None
explanation = "Sorry, there was no previously asked question in this session."
if lastGraphIdOfSession is not None:
endpointUrl = os.getenv('SPARQL_URL')
componentName = agent['queryResult']['parameters']['componentname']
print("component name: " + componentName)
queryAnnotationsOfPrevQuestion = """PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
PREFIX qa: <http://www.wdaqua.eu/qa#>
SELECT *
FROM <"""+lastGraphIdOfSession+""">
WHERE {
?annotationId rdf:type ?type.
?annotationId oa:hasBody ?body.
?annotationId oa:hasTarget ?target.
?annotationId oa:annotatedBy ?componentname.
FILTER REGEX (STR(?componentname), ".*:"""+componentName+"""$") .
}"""
sparql = SPARQLWrapper(endpointUrl)
sparql.setQuery(queryAnnotationsOfPrevQuestion)
sparql.setReturnFormat(JSON)
sparql.setMethod(POST)
result = sparql.queryAndConvert()
annotationType = result['results']['bindings'][0]['type']['value']
print(str(annotationType))
resultFromAnnotation = getAnnotationsOfComponentAction(
annotationType, lastGraphIdOfSession)
print(str(resultFromAnnotation))
annotationCreater = resultFromAnnotation['results']['bindings'][0]['annotationCreator']['value']
resource = resultFromAnnotation['results']['bindings'][0]['resource']['value']
startPos = resultFromAnnotation['results']['bindings'][0]['startPosition']['value']
endPos = resultFromAnnotation['results']['bindings'][0]['endPosition']['value']
confidence = resultFromAnnotation['results']['bindings'][0]['annotationConfidence']['value']
annotationDate = resultFromAnnotation['results']['bindings'][0]['annotationDate']['value']
explanationFromQanary = "In the previous question, the component " + annotationCreater +\
" has found the resource "+resource+" from position "+startPos+" to position "+endPos+". " +\
"The component claims a confidence of "+confidence + \
" for this result. The result was created at "+annotationDate+"."
return explanationFromQanary if not None else explanation


def activateProfileIntent(agent):
profileName = agent['queryResult']['parameters']['profilename']
defaultcomponent = fuzzyset.FuzzySet()
Expand Down Expand Up @@ -135,6 +284,7 @@ def activateProfileIntent(agent):
def addComponentToProfileIntent(agent):
profileName = agent['queryResult']['parameters']['profilename']
sessionId = sessionId = agent['session'].split('/')[4]
print(sessionId)
if sessionId+profileName in profiles:
componentName = agent['queryResult']['parameters']['componentname']
qanaryComponentList = components.getQanaryComponents()
Expand Down Expand Up @@ -190,7 +340,7 @@ def createProfileIntent(agent):
if sessionId+profileName in profiles:
output = 'Profile \'' + profileName + '\' already exists.'
else:

profiles[sessionId +
profileName] = {'components': profileComponents.copy()}
output = ' Profile \'' + profileName + '\' added successfully. Now to use this profile you can say \'start ' + \
Expand Down
8 changes: 4 additions & 4 deletions Webhook/requests/activateComponent.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"responseId": "6ea20321-43c4-4daf-a96e-7b209bc9de47-97a30490",
"queryResult": {
"queryText": "add ldshuyo",
"queryText": "activate component",
"parameters": {
"activatecomponent": [
"ldshuyo"
"QB-Python-DeepPavlov"
]
},
"allRequiredParamsPresent": true,
Expand All @@ -24,10 +24,10 @@
"no-input": 0,
"no-match": 0,
"activatecomponent": [
"ldshuyo"
"QB-Python-DeepPavlov"
],
"activatecomponent.original": [
"ldshuyo"
"QB-Python-DeepPavlov"
]
}
}
Expand Down
8 changes: 4 additions & 4 deletions Webhook/requests/addComponentToProfile.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"responseId": "f735da0b-93ee-4f48-b815-f584a400669e-97a30490",
"queryResult": {
"queryText": "to profile Sam add ldshuyo",
"queryText": "to profile Sam add NED-DBpediaSpotlight",
"parameters": {
"componentname": "ldshuyo",
"componentname": "QB-Python-DeepPavlov",
"profilename": "Sam"
},
"allRequiredParamsPresent": true,
Expand All @@ -22,8 +22,8 @@
"parameters": {
"no-input": 0,
"no-match": 0,
"componentname": "ldshuyo",
"componentname.original": "ldshuyo",
"componentname": "QB-Python-DeepPavlov",
"componentname.original": "QB-Python-DeepPavlov",
"profilename": "Sam",
"profilename.original": "Sam"
}
Expand Down
38 changes: 38 additions & 0 deletions Webhook/requests/askqanaryIntent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"responseId": "349e65c0-4680-4d5e-af5e-04f51c5812b5-1b0ea404",
"queryResult": {
"queryText": "real name of superhero captain America",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentText": "No answer available.",
"fulfillmentMessages": [
{
"text": {
"text": [
"No answer available."
]
}
}
],
"outputContexts": [
{
"name": "projects/fabled-alchemy-379117/agent/sessions/c9edd005-b579-95b3-1762-39677eccf5c2/contexts/__system_counters__",
"parameters": {
"no-input": 0,
"no-match": 0
}
}
],
"intent": {
"name": "projects/fabled-alchemy-379117/agent/intents/031bc0e9-26dd-4585-b933-14fa56a01a5a",
"displayName": "qanary-AskQanary"
},
"intentDetectionConfidence": 0.7662884,
"languageCode": "en"
},
"originalDetectIntentRequest": {
"source": "DIALOGFLOW_CONSOLE",
"payload": {}
},
"session": "projects/dbpedia-chatbot-v1-kaab/agent/sessions/18191cd9-d123-f842-fdef-48df376ca011"
}
Loading

0 comments on commit e2065e9

Please sign in to comment.