Skip to content

Commit

Permalink
improved deployment and UI
Browse files Browse the repository at this point in the history
  • Loading branch information
anbo-de committed Mar 23, 2024
1 parent 2057a01 commit 888d901
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 50 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ on: push
jobs:
build:
runs-on: ubuntu-latest

env:
CUSTOM_HEADER_LORIS: ${{ secrets.CUSTOM_HEADER_LORIS }}
steps:
- uses: actions/checkout@v4
- name: Save tag to file if release
if: startsWith(github.ref, 'refs/tags/')
run: echo ${{ github.ref_name }} > VERSION.txt
- name: prepare environment
run: bash -c ./service_config/prepare_env.sh
- name: Build the Docker image for temporary use only
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
run: docker build . --file Dockerfile --tag tmp:latest
Expand Down
30 changes: 24 additions & 6 deletions css/style_buttons.css
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
button[kind="primary"] {
#root>div:nth-child(1)>div>div>div>div>section.main>div.block-container>div>div>div>div>div>div>div>div>div>div>button {
background-color: #EEE;
border-color: #333399;
color: #000000;
}

.main div[data-testid="stHorizontalBlock"] button[kind="primary"] {
background-color: #33FF33;
border-color: #339933;
color: #000000;
}

button[kind="primary"]:hover {
.main div[data-testid="stHorizontalBlock"] button[kind="primary"]:hover {
background-color: #66FF66;
border-color: #336633;
color: #000000;
box-shadow: 0px 0px 1ex 0.5ex #CDC;
box-shadow: 0px 0px 1ex 0.5ex #CDC;
}

button[kind="secondary"] {
.main div[data-testid="stHorizontalBlock"] button[kind="secondary"] {
background-color: #FF3333;
border-color: #993333;
color: #000000;
}

button[kind="secondary"]:hover {
.main div[data-testid="stHorizontalBlock"] button[kind="secondary"]:hover {
background-color: #FF6666;
border-color: #663333;
color: #000000;
box-shadow: 0px 0px 1ex 0.5ex #DCC;
box-shadow: 0px 0px 1ex 0.5ex #DCC;
}

div[data-testid="stNotificationContentSuccess"] p {
font-size: 120% !important;
}

a.random_example {
padding-top: 2ex !important;
display: block;
float: right;
text-decoration-style: dotted;
text-decoration-skip-ink: auto;
}
122 changes: 81 additions & 41 deletions loris--llm-based-explanations-for-sparql-queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
from decouple import config
import os
import signal
import random

from util import include_css, replace_values_in_index_html
from util import include_css, replace_values_in_index_html, get_sparql_query_examples, get_random_element, feedback_messages, feedback_icons


BACKEND_URL = config('BACKEND_URL')
Expand All @@ -22,6 +23,11 @@
DESCRIPTION = config('DESCRIPTION').replace("\\n", "\n") % (
GITHUB_REPO, GITHUB_REPO + "/issues/new", GITHUB_REPO + "/issues/new")
META_DESCRIPTION = config('META_DESCRIPTION', default=None)
CUSTOM_HEADER = config('CUSTOM_HEADER', default=None)
FEEDBACK_ENDPOINT = config('FEEDBACK_ENDPOINT', default=None)

FEEDBACK_BEST = 5
FEEDBACK_WORST = 1

REPLACE_INDEX_HTML_CONTENT = config('REPLACE_INDEX_HTML_CONTENT', default=False, cast=bool)
CANONICAL_URL = config('CANONICAL_URL', default=None)
Expand Down Expand Up @@ -57,6 +63,7 @@
MISTRAL_MODEL_FINETUNED_ZERO_SHOT = MISTRAL_FINETUNED + SEPARATOR + ZEROSHOT
MISTRAL_MODEL_FINETUNED_ONE_SHOT = MISTRAL_FINETUNED + SEPARATOR + ONESHOT

explanation_last = { "explanation": "" }
explanation_models_dict = {
GPT3_5_ZERO_SHOT: {
MODEL_KEY: GPT3_5_MODEL,
Expand Down Expand Up @@ -110,19 +117,6 @@

explanation_languages = explanation_languages_dict.keys()

example_code = """PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT DISTINCT ?uri
WHERE {
?type wdt:P279* wd:Q4830453 .
?aerospace wdt:P279* wd:Q3477363 .
?healthcare wdt:P279* wd:Q15067276 .
?pharma wdt:P279* wd:Q507443 .
?uri wdt:P452 ?aerospace ;
wdt:P452 ?healthcare .
}
"""

agree_on_showing_additional_information = True

logging.basicConfig()
Expand All @@ -141,38 +135,66 @@
page_title=PAGE_TITLE,
page_icon=Image.open(PAGE_ICON)
)
include_css(st, ["css/style_github_ribbon.css", "css/style_menu_logo.css", "css/style_logo.css", "css/style_tabs.css", "css/style_buttons.css"])
include_css(st, ["css/style_github_ribbon.css", "css/style_menu_logo.css",
"css/style_logo.css", "css/style_tabs.css", "css/style_buttons.css"])

# if the dry run is enabled, we will stop the script
if config('DRY_RUN', default=False, cast=bool):
logging.info("dry run enabled, will stop script, now")
os.kill(os.getpid(), signal.SIGTERM)


@st.cache_data
def get_examples_from_qald9plus():
return get_sparql_query_examples()

example_codes = get_examples_from_qald9plus()

try:
example_id = int(st.query_params.get("example_id", -1))
if example_id == -1 or example_id is None or example_id > len(example_codes) - 1:
example_id = 0
except Exception as e:
logging.error("Error occurred: " + str(e))
example_id = 0

example_code = example_codes[example_id]

@st.cache_data
def get_explanation(sparql_query, model, lang):
model_name = model[MODEL_KEY]
shots = model[SHOTS_KEY]

query = urllib.parse.quote(sparql_query)
custom_url = f"{BACKEND_URL}/explanation?query_text={query}&language={lang}&shots={shots}&model={model_name}"
logging.info(f"Generating explanation for '{sparql_query}' using {model_name} via {custom_url}")

response = requests.get(custom_url)
headers = {}
if CUSTOM_HEADER is not None and CUSTOM_HEADER != "":
headers["X-Custom-Header"] = CUSTOM_HEADER
logging.info(f"Generating explanation for '{sparql_query}' using {model_name} via {custom_url} with headers {headers}" )

logging.info(response.status_code)
logging.info(response.json())
response = requests.get(custom_url, headers=headers)
logging.info("response.status_code: " + str(response.status_code))


if response.status_code == 200 and len(response.json()) > 0 and "explanation" in response.json()[0] and "message" not in response.json()[0] and "explanation" in response.json()[0]:
logging.info(response.json())
explanations = {
"subtitle": "Natural-language representation generated by *" + model_name + "*",
"subtitle": "Natural-language representation generated by ***" + model_name + "***",
"explanation": response.json()[0]["explanation"],
"ok": True
}
else:
try:
if len(response.json()) > 0 and "message" in response.json()[0]:
message = response.json()[0]["message"]
except Exception as e:
logging.error("Error occurred: " + str(e))
message = str(response.status_code) + " " + response.text

explanations = {
"subtitle": "Failed to generate the natural-language representation by *" + model_name + "*",
"explanation": response.json()[0]["message"],
"explanation": message if "message" in locals() else str(response.status_code) + " " + response.text,
"ok": False
}

Expand All @@ -189,11 +211,19 @@ def update_width_input():

with st.sidebar:
with open(PAGE_IMAGE, "rb") as f:
# Read the optional file VERSION.txt containing version number
version = ""
version_long = ""
if os.path.exists("VERSION.txt"):
with open("VERSION.txt", "r") as version_file:
version = version_file.read().strip()
version_long = ", current version " + version

image_data = base64.b64encode(f.read()).decode("utf-8")
st.sidebar.markdown(
f"""
<div style="display:table;margin-top:-10%;margin-bottom:15%;margin-left:auto;margin-right:auto;text-align:center">
<a href="{GITHUB_REPO}" title="go to GitHub repository"><img src="data:image/png;base64,{image_data}" class="app_logo"></a>
<a href="{GITHUB_REPO}" title="go to GitHub repository{version_long}"><img src="data:image/png;base64,{image_data}" class="app_logo"></a>
</div>
""",
unsafe_allow_html=True,
Expand Down Expand Up @@ -251,35 +281,41 @@ def update_width_input():
else:
include_css(st, ["css/remove_space_around_streamlit_body.css"])

st.subheader("Enter a SPARQL query")
header_column, button_column = st.columns([3, 1])
with header_column:
st.subheader("Enter a SPARQL query")
with button_column:
st.markdown(f"<a href='?example_id={random.randint(0, len(example_codes) - 1)}' class='random_example' target='_top'>Set a random SPARQL query</a>", unsafe_allow_html=True)

response_dict = code_editor(example_code, height=20, lang="sparql", theme=theme, shortcuts=shortcuts, options={"wrap": WRAP}, buttons=buttons)

logging.info(response_dict)

sparql_query = response_dict["text"]
def send_feedback(feedback_endpoint, sparql_query, model, language, textual_representation, feedback):
if feedback_endpoint is None:
logging.warning(f"No feedback endpoint is provided: {feedback_endpoint}.")
return

tab_data = []
for i, model in enumerate(explanation_models):
tab_data.append(
stx.TabBarItemData(
id=model,
title=model,
description="TODO"
)
)
response = requests.post(feedback_endpoint, json={
"sparql_query": sparql_query,
"model": model,
"language": language,
"textual_representation": textual_representation,
"feedback": feedback
})
logging.info("Feedback sent: " + str(response.status_code))

st.subheader(f"Natural-language representation ({language}) for the given SPARQL query")
if response_dict["type"] == "submit":
# chosen_id = stx.tab_bar(data=tab_data, key="tab_bar", default=default_model)
# logging.info("chosen_id: " + chosen_id)
# if chosen_id == None or chosen_id == "None":
# st.warning("Please select a model to generate the explanation.")
# else:
sparql_query = response_dict["text"]
logging.debug(selected_model)

with st.spinner("Generating natural-language representation of the SPARQL query..."):
explanation = get_explanation(sparql_query, selected_model, language)
st.toast(f"The representation has been generated successfully using *{selected_model[MODEL_KEY]}*.", icon="🎉")
if explanation_last["explanation"] == explanation["explanation"]:
st.toast(f"The representation has been generated successfully using *{selected_model[MODEL_KEY]}*.", icon="🎉")
else:
explanation_last = explanation

try:
subtitle = explanation["subtitle"]
Expand All @@ -301,9 +337,13 @@ def update_width_input():
st.warning("We think the generated natural-language representation is correct. Do you agree?")
placeholder, correct_column, incorrect_column = st.columns([2,2,3])
with correct_column:
st.button("✅ Yes", key="correct", type="primary")
if st.button("✅ Yes", key="correct", type="primary"):
send_feedback(FEEDBACK_ENDPOINT, sparql_query, selected_model, language, explanation_text, FEEDBACK_BEST)
st.toast(get_random_element(feedback_messages), icon=get_random_element(feedback_icons))
with incorrect_column:
st.button("❌ No", key="incorrect", type="secondary")
if st.button("⤬ No", key="incorrect", type="secondary"):
send_feedback(FEEDBACK_ENDPOINT, sparql_query, selected_model, language, explanation_text, FEEDBACK_WORST)
st.toast(get_random_element(feedback_messages), icon=get_random_element(feedback_icons))

else:
st.error("An error occurred: " + explanation_text, icon="⚠")
Expand Down
6 changes: 4 additions & 2 deletions service_config/files/env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
PAGE_ICON=images/loris-small.png
PAGE_IMAGE=images/loris.png
GITHUB_REPO=https://github.com/WSE-research/LLM-based-explanations-for-SPARQL-queries
DESCRIPTION=LoRiS translates your SPARQL query over the Wikidata and DBpedia knowledge graphs into a natural-language representation using multiple LLMs (Large Language Models), s.t., it becomes easier to understand [SPARQL queries](https://www.w3.org/TR/rdf-sparql-query/). For configuration, please see the sidebar. For more details, see our [GitHub repository](%s) where you can also [submit bug reports](%s) and [feature requests](%s).
META_DESCRIPTION=LoRiS -- LLM-based natural-language representations for SPARQL queries -- translates your SPARQL query over Wikidata or DBpedia using multiple LLMs, s.t., it becomes easier to understand SPARQL queries.
DESCRIPTION='LoRiS translates your SPARQL query over the Wikidata and DBpedia knowledge graphs into a natural-language representation using multiple LLMs (Large Language Models), s.t., it becomes easier to understand [SPARQL queries](https://www.w3.org/TR/rdf-sparql-query/). For configuration, please see the sidebar. For more details, see our [GitHub repository](%s) where you can also [submit bug reports](%s) and [feature requests](%s).'
META_DESCRIPTION='LoRiS -- LLM-based natural-language representations for SPARQL queries -- translates your SPARQL query over Wikidata or DBpedia using multiple LLMs, s.t., it becomes easier to understand SPARQL queries.'
REPLACE_INDEX_HTML_CONTENT=True
CANONICAL_URL=https://wse-research.org/LoriS--LLM-based-explanations-for-SPARQL-queries
BACKEND_URL=http://141.57.8.18:8099
CUSTOM_HEADER=CUSTOM_HEADER_LORIS
FEEDBACK_ENDPOINT=https://wse-research.org/api/sparql2nl-feedback
16 changes: 16 additions & 0 deletions service_config/prepare_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
if [ -z "CUSTOM_HEADER_LORIS" ]
then
echo "CUSTOM_HEADER_LORIS is not set. Exiting."
exit 2
else
sed -i "s/CUSTOM_HEADER_LORIS/${CUSTOM_HEADER_LORIS}/g" ./service_config/files/env
if [ `grep -c "CUSTOM_HEADER_LORIS" ./service_config/files/env` -ne 0 ]
then
echo "CUSTOM_HEADER_LORIS was not successfully replaced. Exiting."
exit 2
else
echo "CUSTOM_HEADER_LORIS was successfully replaced."
exit 0
fi
fi
Loading

0 comments on commit 888d901

Please sign in to comment.