Commit 0fc2acf1 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Added catalog endpoint to dcat.

parent 4644356a
......@@ -21,3 +21,4 @@ from flask_restplus import Api
from .api import blueprint, api
from .datasets import Dataset
from .catalog import Catalog
# Copyright 2018 Markus Scheidgen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an"AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from flask_restplus import Resource, reqparse, fields
from flask import Response
from elasticsearch_dsl import Q
from nomad import search
from .api import api
from .mapping import Mapping
ns = api.namespace('catalog', description='The API for DCAT catalog.')
iso8601 = fields.DateTime(dt_format='iso8601')
arg_parser = reqparse.RequestParser()
arg_parser.add_argument('format', type=str, choices=[
'xml',
'n3',
'turtle',
'nt',
'pretty-xml',
'trig'])
arg_parser.add_argument('after', type=str)
arg_parser.add_argument(
'modified_since', type=lambda x: iso8601.parse(x),
help='A yyyy-MM-ddTHH:mm:ss (RFC3339) maximum entry time (e.g. upload time)')
@ns.route('/')
class Catalog(Resource):
@api.doc('get_dcat_datasets')
@api.expect(arg_parser)
@api.produces(['application/xml'])
@api.response(404, 'There is no entry with the given id.')
@api.response(401, 'This entry is not publically accessible.')
@api.response(200, 'Data send', headers={'Content-Type': 'application/xml'})
def get(self):
''' Returns a page of DCAT datasets. '''
args = arg_parser.parse_args()
format_ = args.get('format')
if format_ is None:
format_ = 'xml'
modified_since = args.get('modified_since', None)
modified_since = iso8601.parse(modified_since) if modified_since is not None else None
after = args.get('after', None)
search_request = search.SearchRequest().owner('public')
if modified_since is not None:
modified_clause = Q('range', upload_time=dict(gte=modified_since))
modified_clause |= Q('range', last_edit=dict(gte=modified_since))
modified_clause |= Q('range', last_processing=dict(gte=modified_since))
search_request.q &= modified_clause
es_search = search_request._search.query(search_request.q)
if after is not None:
es_search = es_search.extra(search_after=[after], sort='calc_id')
es_response = es_search.execute()
mapping = Mapping()
mapping.map_catalog(es_response.hits)
return Response(
mapping.g.serialize(format=format_).decode('utf-8'), 200,
{'Content-Type': 'application/xml'})
......@@ -36,6 +36,12 @@ class Mapping():
self.persons = {}
def map_catalog(self, entries):
catalog = URIRef(url('catalog'))
self.g.add((catalog, RDF.type, DCAT.Catalog))
for entry in entries:
self.g.add((catalog, DCT.dataset, self.map_entry(entry)))
def map_entry(self, entry: EntryMetadata):
dataset = URIRef(url('datasets', entry.calc_id))
......
......@@ -15,6 +15,7 @@
import pytest
from datetime import datetime
from nomad import infrastructure, config
from nomad.datamodel import EntryMetadata
from nomad.app.dcat.mapping import Mapping
......@@ -59,3 +60,20 @@ def test_get_dataset(elastic_infra, api, example_entry):
assert rv.status_code == 200
clear_elastic(elastic_infra)
def test_get_catalog(elastic_infra, api, example_entry):
clear_elastic(elastic_infra)
for i in range(1, 11):
example_entry.calc_id = 'test-id-%d' % i
example_entry.upload_time = datetime(2000, 1, 1)
example_entry.last_processing = datetime(2020, 1, i)
example_entry.a_elastic.index()
infrastructure.elastic_client.indices.refresh(index=config.elastic.index_name)
rv = api.get('/catalog/?after=test-id-3&modified_since=2020-01-07&format=nt')
assert rv.status_code == 200
clear_elastic(elastic_infra)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment