Skip to content

Commit

Permalink
simplified DTR taxonomy retrival, DTR UI recursion breaks for unknown…
Browse files Browse the repository at this point in the history
… reason, push for alpha deployment
  • Loading branch information
MichalGawor committed Dec 2, 2024
1 parent 87f8152 commit 0d6f174
Show file tree
Hide file tree
Showing 21 changed files with 152 additions and 129 deletions.
17 changes: 8 additions & 9 deletions dogconfig/dogproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]



DTR_ENABLED = True
VERIFY_SSL = False

# Application definition
INSTALLED_APPS = [
Expand All @@ -86,11 +87,10 @@
# local
'dogapi',
'dogui'

]

DTR_ENABLED = False

if DTR_ENABLED:
INSTALLED_APPS += ['dogdtr']

REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
Expand All @@ -100,14 +100,10 @@
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

VERIFY_SSL = False



SPECTACULAR_SETTINGS = {
'TITLE': 'Digital Object Gate',
'DESCRIPTION': 'DOG API resolving referenced resources in the metadata',
'VERSION': '1.0.3',
'VERSION': VERSION,
'SERVE_INCLUDE_SCHEMA': False,
# OTHER SETTINGS
}
Expand Down Expand Up @@ -143,6 +139,9 @@
},
]

if DTR_ENABLED:
TEMPLATES[0]['DIRS'] += [join(BASE_DIR, './../dogdtr/dogdtr/templates')]

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
Expand Down
10 changes: 5 additions & 5 deletions dogconfig/dogproject/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from dogapi.views_api import (fetch, identify, sniff, is_pid, get_all_repositories,
get_repositories_status)
from dogdtr.views_api import expand_datatype
from dogdtr.views_api import expand_datatype_view

from dogdtr.views_ui import dtr
from dogui.views_ui import about, contact, home
Expand All @@ -24,13 +24,13 @@
path('api/v1/ispid/', is_pid, name='is pid'),

path('__debug__/', include('debug_toolbar.urls')),
path('api/v1/expanddatatype/', expand_datatype, name='expand data type'),
path('api/v1/expanddatatype/', expand_datatype_view, name='expand data type'),
path('api/v1/allregrepo/', get_all_repositories, name='get all repositories'),
path('api/v1/repostatus/', get_repositories_status, name='get repositories status'),

# UI
path('', home, name='main'),
path('about', about, name='about'),
path('contact', contact, name='contact'),
path('dtr', dtr, name='contact')
path('about/', about, name='about'),
path('contact/', contact, name='contact'),
path('dtr/', dtr, name='dtr'),
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
94 changes: 45 additions & 49 deletions dogdtr/dogdtr/dtr.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@

import json
import urllib

from requests import RequestException
from requests import get
from typing import List, Tuple, Union


from .utils import MIMEType


class DataTypeNotFoundException(Exception):
def __init__(self, message):
self.message = message


def expand_datatype(data_type: str) -> dict:
def expand_datatype(data_type: Union[str, List[str]]) -> List[dict]:
"""
Wrapper for DTR datatype taxonomy discovery
"""
return get_dtr_taxonomy_by_type(data_type)
if isinstance(data_type, str):
return [get_dtr_taxonomy_by_type(data_type)]
elif isinstance(data_type, list):
return [get_dtr_taxonomy_by_type(dt) for dt in data_type]


def get_dtr_taxonomy_by_type(data_type: str) -> dict:
Expand All @@ -24,61 +31,50 @@ def get_dtr_taxonomy_by_type(data_type: str) -> dict:
:param data_type: str, MIME type, e.g. 'text/xml'
:return: dict, a dictionary representation of the type's taxonomy
"""
dtr_type_search_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/search?query={data_type}&name={data_type}"
dtr_taxonomy_search_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/search?query={data_type}&name={data_type}"
data_type = urllib.parse.quote(data_type, safe='')

try:
url, dtr_taxonomy_search_response, header = get(dtr_type_search_endpoint)
dtr_taxonomy_search_response = get(dtr_taxonomy_search_endpoint)
except RequestException as error:
raise DataTypeNotFoundException(f"DataType <{data_type}> doesn't exist in the DTR taxonomy") from error
raise DataTypeNotFoundException(f"Failed to reach DTR to query for taxonomy") from error
except ValueError as error:
raise DataTypeNotFoundException(f"Failed to unpack DTR response. Most probably {data_type} is not registered") from error

dtr_taxonomy_json = json.loads(dtr_taxonomy_search_response)
print("get_dtr_taxonomy_by_type: TAXONOMY")
print(dtr_taxonomy_json)
try:
dtr_type_id = dtr_taxonomy_json[0]["id"]
except (IndexError, KeyError) as error:
raise DataTypeNotFoundException(f"DataType <{data_type}> doesn't exist in the DTR taxonomy") from error
parents = dtr_taxonomy_json[0]["parents"]
if parents:
for parent_id, parent_name in parents.items():
dtr_type_id = get_taxonomy_root_node_by_id(parent_id)
return get_taxonomy_subtree_from_root_id(dtr_type_id)
dtr_taxonomy_search_json = dtr_taxonomy_search_response.json()
type_taxonomy_id = dtr_taxonomy_search_json[0]["id"]
except IndexError as error:
raise DataTypeNotFoundException(f"Failed to resolve {data_type} taxonomy. Most probably it doesn't exist.")


def get_taxonomy_root_node_by_id(data_type_id: str) -> str:
"""
Returns an ID of the root type of the taxonomy for the given data_type_id
root_taxonomy_id = retrieve_root(type_taxonomy_id)
taxonomy_tree = retrieve_taxonomy_tree(root_taxonomy_id)
return taxonomy_tree

:param data_type_id: str, DTR MIME type PID, e.g. 21.T11969/f33c32fa8246e2ca6d5c
:return: dict, a dictionary representation of the type's taxonomy
"""
dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{data_type_id}"
url, dtr_taxonomy_node_response, header = get(dtr_taxonomy_endpoint)
dtr_taxonomy_json = json.loads(dtr_taxonomy_node_response)
try:
dtr_type_id = dtr_taxonomy_json["id"]
except (IndexError, KeyError) as error:
raise DataTypeNotFoundException(f"DataType with id <{data_type_id}> doesn't exist in the DTR taxonomy") from error
parents = dtr_taxonomy_json["parents"]
# Assumption of single parent
taxonomy_root_id = dtr_type_id
if parents:
for parent_id, parent_name in parents.items():
taxonomy_root_id = get_taxonomy_root_node_by_id(parent_id)
return taxonomy_root_id


def get_taxonomy_subtree_from_root_id(root_id: str) -> dict:
"""
Get a subtree from the root ID
def retrieve_root(taxonomy_id: str) -> Tuple[str, str]:
dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{taxonomy_id}"
taxonomy_response = get(dtr_taxonomy_endpoint)
taxonomy_json = taxonomy_response.json()

:param root_id: str, the root node ID
:return: dict, MIME type taxonomy
"""
dtr_taxonomy_subtree_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{root_id}/subtree"
url, dtr_taxonomy_subtree_response, header = get(dtr_taxonomy_subtree_endpoint)
dtr_taxonomy_subtree_json = json.loads(dtr_taxonomy_subtree_response)
return dtr_taxonomy_subtree_json
# Recurse until no parent under "parents" key
for parent_id, parent_name in taxonomy_json["parents"].items():
return retrieve_root(parent_id)
taxonomy_id = taxonomy_json["id"]
return taxonomy_id


def retrieve_taxonomy_tree(taxonomy_id: str):
dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{taxonomy_id}"
dtr_taxonomy_response = get(dtr_taxonomy_endpoint)
dtr_taxonomy_json = dtr_taxonomy_response.json()

taxonomy_name = dtr_taxonomy_json["name"]

children = []
for child_id, child_name in dtr_taxonomy_json["children"].items():
children.append(retrieve_taxonomy_tree(child_id))
return {taxonomy_name: {"id": taxonomy_id, "children": children}}


"""
Expand Down
7 changes: 4 additions & 3 deletions dogdtr/dogdtr/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ class MIMETypeForm(forms.Form):
"""
Input form for inserting MIMEtype
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["mimetype"].label = ""

mimetype_field: MIMETypeField = MIMETypeField(required=True,
widget=forms.TextInput(attrs={'required': 'True'}))

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["mimetype_field"].label = ""
18 changes: 16 additions & 2 deletions dogdtr/dogdtr/templates/UI/_dtr.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
{% extends 'UI/_.html' %}
{% block content %}
<h2> PLACEHOLDER </h2>
<h3> PLUGGABLE DTR UI TBD Q4 2024 </h3>
<div id="content">
<h2> DOG Data Type Registry plugin</h2>
<h3> DOG subservice allowing MIMEtype taxonomy expansion based on <a href="">Data Type Registry</a></h3>

Type a MIMEtype (e.g. `application/json`) into the box

{% block mimetype %}
{% if mimetype_form %}
{% include 'UI/_form_mimetype.html' with form=mimetype_form %}
{% endif %}
{% endblock mimetype %}

{% block result %}
{% endblock result %}
</div>
{% endblock content %}
19 changes: 11 additions & 8 deletions dogdtr/dogdtr/templates/UI/_expanddatatype.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{% extends 'UI/_content.html' %}
{% load dogui_extras %}
{% extends 'UI/_dtr.html' %}
{{ taxonomies }}
{% block result %}
<ul>
{% with node=taxonomy_tree.node template_name="UI/tree/_tree_node_view.html" %}
{% include "UI/tree/_tree_node_view.html" %}
{% endwith %}
</ul>
{% endblock result %}
{% for input_type, taxonomy in taxonomies.items %}
<ul>
{{ taxonomy }}
{% if taxonomy %}
{% include 'UI/tree/_tree_node_view.html' with node=taxonomy %}
{% endif %}
</ul>
{% endfor %}
{% endblock result %}
2 changes: 1 addition & 1 deletion dogdtr/dogdtr/templates/UI/_form_mimetype.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div id="input_text">
<form method="GET" id="mimetype_form" action="/">
<form method="GET" id="mimetype_form" action="/dtr/">
<label for="mimetype_candidate">MIMEtype</label>
{{ form }}
<button type="submit">Go!</button>
Expand Down
12 changes: 0 additions & 12 deletions dogdtr/dogdtr/templates/UI/_tree_node_view.html

This file was deleted.

16 changes: 16 additions & 0 deletions dogdtr/dogdtr/templates/UI/tree/_tree_node_view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'UI/_expanddatatype.html' %}
{% block node %}
{% for input_type_name, data in node.items %}
{% if data.children %}
{% for child in data.children %}

<li>
{% with node=child template_name="UI/tree/_tree_node_view.html" %}
{% include template_name %}
{% endwith %}
</li>

{% endfor %}
{% endif %}
{% endfor %}
{% endblock node %}
10 changes: 10 additions & 0 deletions dogdtr/dogdtr/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from dogapi.utils import parse_queryparam


from typing import List



class MIMEType:
name: str
id: str
children: List


class TaxonomyTree:
def __init__(self, taxonomy_dict: dict):
self.name = next(iter(taxonomy_dict.keys()))
Expand Down
8 changes: 4 additions & 4 deletions dogdtr/dogdtr/views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
)
@permission_classes([AllowAny])
@api_view(['GET'])
def expand_datatype(request: Request) -> Response:
data_types = parse_queryparam(request, 'data_type')
def expand_datatype_view(request: Request) -> Response:
mime_types = parse_queryparam(request, 'mimetype')
expanded_datatypes: dict = {}
for data_type in data_types:
for data_type in mime_types:
expanded_datatypes[data_type] = expand_datatype(data_type)
if expanded_datatypes:
return Response(expanded_datatypes, status=200)
else:
return Response(f"MIME data type(s) {data_types} is either not correct or has been not recognised",
return Response(f"MIME data type(s) {mime_types} is either not correct or has been not recognised",
status=400)
26 changes: 17 additions & 9 deletions dogdtr/dogdtr/views_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import logging.config


import requests

from .utils import TaxonomyTree
from .forms import MIMETypeForm

Expand All @@ -17,17 +19,23 @@

def dtr(request: HttpRequest) -> HttpResponse:
context: RequestContext = RequestContext(request)
mimetype_form: MIMETypeForm = MIMETypeForm(request.GET)
mimetype_form: MIMETypeForm = MIMETypeForm(request.GET, use_required_attribute=False)

if pid_form.is_valid():
context.push({"view": "dtr"})
context.push({"DTR_ENABLED": DTR_ENABLED})

if mimetype_form.is_valid():
context.push({"mimetype_form": mimetype_form})
pids = mimetype_form.cleaned_data['mimetype_field']
api_url = API_NETLOC + f'/expanddatatype/?data_type={",".join(pids)}'
mimetypes = mimetype_form.cleaned_data['mimetype_field']

api_response = requests.get(api_url, verify=VERIFY_SSL)
api_url = API_NETLOC + f'/expanddatatype/?mimetype={",".join(mimetypes)}'

api_response = requests.get(api_url, verify=VERIFY_SSL)

context: RequestContext = RequestContext(request)
context.push({"view": "dtr"})
context.push({"DTR_ENABLED": DTR_ENABLED})
return render(request, "UI/_dtr.html", context.flatten())
print(api_response.json())
context.push({f"taxonomies": api_response.json()})
return render(request, f"UI/_expanddatatype.html", context.flatten())
else:
context.push({"mimetype_form": mimetype_form})
context.push({"view": "dtr"})
return render(request, "UI/_dtr.html", context.flatten())
10 changes: 9 additions & 1 deletion dogui/dogui/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from django.conf import settings


import re

def version(request):
# pylint: disable=unused-argument
return {'VERSION': settings.VERSION}
version = settings.VERSION
alpha_regex = re.compile(r"[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+")
beta_regex = re.compile(r"[0-9]+\.[0-9]+\.[0-9]+")
if alpha_regex.match(version):
return {"VERSION": version, "INSTANCE": "ALPHA"}
elif beta_regex.match(version):
return {'VERSION': version, "INSTANCE": "BETA"}
Loading

0 comments on commit 0d6f174

Please sign in to comment.