From 76f6e5e916f1c1d400e51e8704a09a2fbfa294e1 Mon Sep 17 00:00:00 2001 From: Hannah Bast Date: Sun, 1 Dec 2024 09:24:15 +0100 Subject: [PATCH] Now also get the example queries as YAML Via the command line: `python manage.py examples --format `. Via API call: `.../examples/?format=`. The only supported formats are `tsv` and `yaml`. The default is `tsv`. --- backend/management/commands/examples.py | 58 ++++++++++++++++--------- backend/views.py | 12 +++-- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/backend/management/commands/examples.py b/backend/management/commands/examples.py index 435880a..b280397 100644 --- a/backend/management/commands/examples.py +++ b/backend/management/commands/examples.py @@ -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 querySPARQL query in one line without newlines # # TODO: Provide option to return result as JSON. @@ -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=""): @@ -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): @@ -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() diff --git a/backend/views.py b/backend/views.py index 4897a9d..0870dbd 100644 --- a/backend/views.py +++ b/backend/views.py @@ -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