Skip to content

Commit

Permalink
New command and view examples for getting example queries
Browse files Browse the repository at this point in the history
There is now a new command and view that can be used to retrieve all
example queries for a given backend as TSV. Here is an example call:

`docker exec -it qlever-ui bash -c "python manage.py examples wikidata"`

To obtain the same result via an API call (no special permissions
required):

`curl -s https://qlever.cs.uni-freiburg.de/api/examples/wikidata`
  • Loading branch information
Hannah Bast committed Jul 9, 2023
1 parent 5931611 commit d3620a1
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
77 changes: 77 additions & 0 deletions backend/management/commands/examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from django.core.management.base import BaseCommand, CommandError
from django.db.models import TextChoices
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.
class Command(BaseCommand):
help = "Usage: python manage.py examples <argument string>"

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

# Custom log function.
def log(self, msg=""):
print(msg)

# Command line arguments.
def add_arguments(self, parser):
parser.add_argument("slug", nargs=1, help="Slug of the backend")

# This defines the actual behavior.
def handle(self, *args, returnLog=False, **options):
try:
slug = options["slug"][0]
except Exception as e:
self.log(f"Error parsing command line arguments: {e}")
self.log()
self.print_help("manage.py", "examples")
return
try:
backend = Backend.objects.filter(slug=slug).get()
except Exception as 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.all():
if example.backend.pk == backend.pk:
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"

# 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)
# Remove comments.
query = re.sub(r'#.*\n', ' ', query, flags=re.MULTILINE)
# Re-replace %23 in IRIs by #.
query = re.sub(r'(<[^>]+)%23', r'\1#', query)
# Replace all sequences of whitespace by a single space.
query = re.sub(r'\s+', ' ', query)
# Remove . before }.
query = re.sub(r'\s*\.\s*}', ' }', query)
# Remove any trailing whitespace.
query = query.strip()

return query


1 change: 1 addition & 0 deletions backend/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
name='index'),
re_path(r'^api/share$', views.shareLink, name='shareLink'),
re_path(r'^api/warmup/(?P<backend>[^/]+)/(?P<target>[a-zA-Z0-9_-]+)$', views.warmup, name='warmup'),
re_path(r'^api/examples/(?P<backend>[^/]+)$', views.examples, name='examples'),
]
18 changes: 16 additions & 2 deletions backend/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from .models import *
from backend.management.commands.warmup import Command as WarmupCommand
from backend.management.commands.examples import Command as ExamplesCommand

import json
import urllib
Expand Down Expand Up @@ -122,6 +123,7 @@ def shareLink(request):
return redirect('/')


# Handle "warmup" request.
def warmup(request, backend, target):
token = request.GET.get("token")
backends = Backend.objects.filter(slug=backend)
Expand All @@ -143,12 +145,24 @@ def warmup(request, backend, target):
except Exception as e:
return JsonResponse({"status":"error", "message": str(e)})
return JsonResponse({"status":"ok", "log": log})

# Handle "examples" request, for example:
#
# Helpers
# With the URL https://qlever.cs.uni-freiburg.de/api/examples/wikidata
#
# this function is called with backend = "wikidata".
def examples(request, backend):
print_to_log(f"Call of \"examples\" in views.py with backend = \"{backend}\"")
command = ExamplesCommand()
try:
tsv = command.handle(returnLog=True, slug=[backend])
except Exception as e:
return HttpResponse("Error: " + str(e), status=500)
return HttpResponse(tsv, content_type="text/tab-separated-values")


def log(msg, output=print):
# Helpers
def print_to_log(msg, output=print):
"""
Helper to log things that happen during the process
"""
Expand Down

0 comments on commit d3620a1

Please sign in to comment.