Skip to content

Commit

Permalink
Now also get the example queries as YAML
Browse files Browse the repository at this point in the history
Via the command line: `python manage.py examples <backend> --format
<format>`.

Via API call: `.../examples/<backend>?format=<format>`.

The only supported formats are `tsv` and `yaml`. The default is `tsv`.
  • Loading branch information
Hannah Bast committed Dec 1, 2024
1 parent d4e356a commit 76f6e5e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
58 changes: 37 additions & 21 deletions backend/management/commands/examples.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
from django.core.management.base import BaseCommand, CommandError
from django.db.models import TextChoices
from django.core.management.base import BaseCommand
from backend.models import Backend
from backend.models import Link
from backend.models import Example
from pprint import pprint
import requests
import sys
import re


# Command to get the example queries from the particular backend, with one line
# per query, in the format:
#
#
# name of query<TAB>SPARQL query in one line without newlines
#
# TODO: Provide option to return result as JSON.
Expand All @@ -19,7 +15,7 @@ class Command(BaseCommand):

# Copied from warmup.py, is this really needed?
def __init__(self, *args, **kwargs):
super().__init__( *args, **kwargs)
super().__init__(*args, **kwargs)

# Custom log function.
def log(self, msg=""):
Expand All @@ -28,6 +24,12 @@ def log(self, msg=""):
# Command line arguments.
def add_arguments(self, parser):
parser.add_argument("slug", nargs=1, help="Slug of the backend")
parser.add_argument(
"--output-format",
choices=["tsv", "yaml"],
default="tsv",
help="Output format (default: tsv)",
)

# This defines the actual behavior.
def handle(self, *args, returnLog=False, **options):
Expand All @@ -41,33 +43,47 @@ def handle(self, *args, returnLog=False, **options):
try:
backend = Backend.objects.filter(slug=slug).get()
except Exception as e:
self.log(f"Error finding config with slug \"{slug}\": {e}")
self.log(f'Error finding config with slug "{slug}": {e}')
return
# self.log()
# self.log(f"ID of backend \"{slug}\" is: {backend.pk}")
# self.log()
# self.log(f"Keys of Example table: {Example._meta.fields}")
result = []
for example in Example.objects.filter(backend=backend).order_by("sortKey"):
query_name = example.name
query_string = self.normalize_query(example.query)
result.append(f"{query_name}\t{query_string}")
self.log(f"Returning {len(result)} example queries for backend \"{slug}\"")
return "\n".join(result) + "\n"
output_format = options.get("output_format", "tsv")
if output_format == "tsv":
result = []
for example in Example.objects.filter(backend=backend).order_by("sortKey"):
query_name = example.name
query_string = self.normalize_query(example.query)
result.append(f"{query_name}\t{query_string}")
self.log(f'Returning {len(result)} example queries for backend "{slug}"')
return "\n".join(result) + "\n"
else:
result = [f"kb: {backend.slug}", "queries:"]
for example in Example.objects.filter(backend=backend).order_by("sortKey"):
query_name = example.name
# Indent each line by four spaces.
query_string = re.sub(r"^", " ", example.query, flags=re.MULTILINE)
result.append(f"- name: {query_name}\n"
f" query: |\n"
f"{query_string}")
return "\n".join(result) + "\n"



# Helper function for normalizing a query (translated from
# static/js/helper.js).
def normalize_query(self, query):
# Replace # in IRIs by %23.
query = re.sub(r'(<[^>]+)#', r'\1%23', query)
query = re.sub(r"(<[^>]+)#", r"\1%23", query)
# Remove comments.
query = re.sub(r'#.*\n', ' ', query, flags=re.MULTILINE)
query = re.sub(r"#.*\n", " ", query, flags=re.MULTILINE)
# Re-replace %23 in IRIs by #.
query = re.sub(r'(<[^>]+)%23', r'\1#', query)
query = re.sub(r"(<[^>]+)%23", r"\1#", query)
# Replace all sequences of whitespace by a single space.
query = re.sub(r'\s+', ' ', query)
query = re.sub(r"\s+", " ", query)
# Remove . before }.
query = re.sub(r'\s*\.\s*}', ' }', query)
query = re.sub(r"\s*\.\s*}", " }", query)
# Remove any trailing whitespace.
query = query.strip()

Expand Down
12 changes: 9 additions & 3 deletions backend/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,19 @@ def warmup(request, backend, target):

# Handle API request like https://qlever.cs.uni-freiburg.de/api/examples/wikidata
def examples(request, backend):
print_to_log(f'Call of "examples" in views.py with backend = "{backend}"')
output_format = request.GET.get("format", "tsv")
print_to_log(f"Call of `examples` in `views.py` with backend={backend}"
f" and output_format={output_format}")
command = ExamplesCommand()
try:
examples_tsv = command.handle(returnLog=True, slug=[backend])
examples_tsv = command.handle(returnLog=True, slug=[backend],
output_format=output_format)
except Exception as e:
return HttpResponse("Error: " + str(e), status=500)
return HttpResponse(examples_tsv, content_type="text/tab-separated-values")
if output_format == "yaml":
return HttpResponse(examples_tsv, content_type="text/yaml")
else:
return HttpResponse(examples_tsv, content_type="text/tab-separated-values")


# Handle API request like https://qlever.cs.uni-freiburg.de/api/prefixes/wikidata
Expand Down

0 comments on commit 76f6e5e

Please sign in to comment.