Skip to content

Commit

Permalink
wip: stateless pls_format_metadata api
Browse files Browse the repository at this point in the history
  • Loading branch information
aaxelb committed Dec 17, 2021
1 parent 59c8a14 commit 636f760
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 4 deletions.
8 changes: 8 additions & 0 deletions api/pls_format_metadata/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path

from . import views


urlpatterns = [
path('pls-format-metadata', views.pls_format_metadata),
]
43 changes: 43 additions & 0 deletions api/pls_format_metadata/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json

from django.http import HttpResponse

from share.util.extensions import Extensions
from share.regulate import Regulator


def pls_format_metadata(request):
if request.method != 'POST':
return HttpResponse(
status=405,
headers={'Allow': 'POST'},
content='only POST!'
)

transformer_key = request.GET.get('transformer', 'v2_push')
normal_graph = pls_normalize(request.body, transformer_key)
requested_formats = request.GET.getlist('formats')
formatted_records = [
pls_format(normal_graph, format_key)
for format_key in requested_formats
]
return HttpResponse(
content=json.dumps(formatted_records),
)


def pls_normalize(raw_datum, transformer_key):
transformer = Extensions.get('share.transformers', transformer_key)()
graph = transformer.transform(raw_datum)
Regulator().regulate(graph) # in-place


def pls_format(graph, record_formats):
formatters = [
Extensions.get('share.metadata_formats', record_format)()
for record_format in record_formats
]
return [
formatter.format_from_graph(graph)
for formatter in formatters
]
2 changes: 2 additions & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
url('^', include('api.suids.urls')),
url('^', include('api.users.urls')),

url('^', include('api.pls_format_metadata.urls')),

url('^schemas?/', include('api.schemas.urls'), name='schema'),
url('^search/', include('api.search.urls'), name='search'),

Expand Down
9 changes: 8 additions & 1 deletion share/metadata_formats/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@

from share.models.core import NormalizedData
from share.models.ingest import SourceUniqueIdentifier
from share.util.graph import MutableGraph


class MetadataFormatter(ABC):
@abstractmethod
def format(self, normalized_data: NormalizedData) -> Optional[str]:
"""return a string representation of the given metadata in the formatter's format
"""
mgraph = MutableGraph.from_jsonld(normalized_data.data)
return self.format_from_graph(mgraph)

@abstractmethod
def format_from_graph(self, normalized_data: NormalizedData) -> Optional[str]:
"""return a string representation of the given metadata in the formatter's format
"""
raise NotImplementedError
Expand Down
3 changes: 3 additions & 0 deletions share/metadata_formats/oai_dc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class OaiDcFormatter(MetadataFormatter):

def format(self, normalized_datum):
mgraph = MutableGraph.from_jsonld(normalized_datum.data)
return self.format_from_graph(mgraph)

def format_from_graph(self, mgraph):
central_work = mgraph.get_central_node(guess=True)

if (
Expand Down
4 changes: 4 additions & 0 deletions share/metadata_formats/sharev2_elastic.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def format_as_deleted(self, suid):
'is_deleted': True,
})

def format_from_graph(self, mgraph):
# HACK because sharev2_elastic is dumb
raise NotImplementedError('sharev2_elastic formatter depends on a NormalizedData')

def format(self, normalized_datum):
mgraph = MutableGraph.from_jsonld(normalized_datum.data)
central_work = mgraph.get_central_node(guess=True)
Expand Down
2 changes: 1 addition & 1 deletion share/transform/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class BaseTransformer(metaclass=abc.ABCMeta):

def __init__(self, source_config):
def __init__(self, source_config=None):
self.config = source_config

@abc.abstractmethod
Expand Down
2 changes: 1 addition & 1 deletion share/transform/chain/links.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ def execute(self, obj):
break

if not final[0]:
if self._urn_fallback:
if self._urn_fallback and getattr(Context(), '_config', None):
urn = self.FALLBACK_FORMAT.format(source=Context()._config.label, id=urllib.parse.quote(obj))
return URNLink().execute(urn)
else:
Expand Down
1 change: 0 additions & 1 deletion share/transformers/oai.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ class RootParser(OAICreativeWork):
type_map = root_type_map

if property_list:
logger.debug('Attaching addition properties %s to transformer for %s', property_list, self.config.label)
for prop in property_list:
if prop in RootParser._extra:
logger.warning('Skipping property %s, it already exists', prop)
Expand Down
26 changes: 26 additions & 0 deletions tests/api/test_pls_format_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from tests.share.metadata_formats.base import FORMATTER_TEST_INPUTS
from tests.share.metadata_formats.test_oai_dc_formatter import TestOaiDcFormatter as oaidc_test_cases


class TestPlsFormatMetadata:
def _get_test_keys(self):
return FORMATTER_TEST_INPUTS.keys()

def _get_input(self, test_key):
return FORMATTER_TEST_INPUTS[test_key]['normalized_datum_kwargs']['data']

def _get_expected_output(self, test_key):
return oaidc_test_cases.expected_outputs[test_key]

def test_works(self, client):
for test_key in self._get_test_keys():
try:
resp = client.post(
'/api/v2/pls-format-metadata',
self._get_input(test_key),
)
assert resp.status_code == 200
assert resp.json() == self._get_expected_output(test_key)
print(f'success! ({test_key})')
except Exception as e:
print(f'fail! ({test_key}, {e})')

0 comments on commit 636f760

Please sign in to comment.