diff options
-rw-r--r-- | gn3/api/metadata.py | 90 | ||||
-rw-r--r-- | gn3/db/rdf.py | 47 |
2 files changed, 80 insertions, 57 deletions
diff --git a/gn3/api/metadata.py b/gn3/api/metadata.py index ef6cffe..f023e17 100644 --- a/gn3/api/metadata.py +++ b/gn3/api/metadata.py @@ -12,7 +12,6 @@ from flask import current_app from pyld import jsonld from SPARQLWrapper import JSON, JSONLD, SPARQLWrapper -from gn3.db.rdf import get_phenotype_metadata from gn3.db.rdf import sparql_query from gn3.db.rdf import RDF_PREFIXES, PREFIXES @@ -309,17 +308,88 @@ CONSTRUCT { except (RemoteDisconnected, URLError): return jsonify({}) -@metadata.route("/phenotype/<name>", methods=["GET"]) -def phenotype(name): +@metadata.route("/phenotypes/<name>", methods=["GET"]) +def phenotypes(name): """Fetch a phenotype's metadata given it's name""" try: - return jsonify( - get_phenotype_metadata( - SPARQLWrapper(current_app.config.get("SPARQL_ENDPOINT")), - name, - ).data - ) - # The virtuoso server is misconfigured or it isn't running at all + args = request.args + dataset = args.get("dataset", "") + sparql = SPARQLWrapper(current_app.config.get("SPARQL_ENDPOINT")) + sparql.setQuery(Template(""" +$prefix + +CONSTRUCT { + ?phenotype ?predicate ?object ; + ?pubPredicate ?pubObject ; + ex:species ?speciesName ; + ex:inbredSet ?inbredSetName ; + ex:dataset ?datasetName . +} WHERE { + ?phenotype skos:altLabel "$name" ; + xkos:classifiedUnder ?inbredSet ; + ?predicate ?object . + ?inbredSet ^xkos:classifiedUnder ?phenotype ; + rdfs:label ?inbredSetName ; + xkos:generalizes ?species . + ?species skos:prefLabel ?speciesName . + FILTER (!regex(str(?predicate), '(classifiedUnder)', 'i')) . + OPTIONAL { + ?publication ^dct:isReferencedBy ?phenotype ; + rdf:type fabio:ResearchPaper ; + ?pubPredicate ?pubObject . + FILTER (!regex(str(?pubPredicate), '(hasPubMedId|type)', 'i')) . + } . + OPTIONAL { + ?dataset rdf:type dcat:Dataset ; + xkos:classifiedUnder ?type; + rdfs:label "$dataset" ; + skos:prefLabel ?datasetName . + ?type ^skos:member gnc:DatasetType . + FILTER(?type = gnc:Phenotype) . + } +} +""").substitute(prefix=RDF_PREFIXES, name=name, + dataset=dataset)) + results = json.loads(sparql.queryAndConvert().serialize(format="json-ld")) + if not results: + return jsonify({}) + frame = { + "@context": PREFIXES | { + "data": "@graph", + "type": "@type", + "id": "@id", + "traitName": "skos:altLabel", + "trait": "rdfs:label", + "altName": "rdfs:altLabel", + "description": "dct:description", + "abbreviation": "dct:abbreviation", + "labCode": "gnt:labCode", + "submitter": "gnt:submitter", + "contributor": "dct:contributor", + "mean": "gnt:mean", + "locus": "gnt:locus", + "LRS": "gnt:LRS", + "references": "dct:isReferencedBy", + "additive": "gnt:additive", + "sequence": "gnt:sequence", + "title": "dct:title", + "journal": "fabio:Journal", + "volume": "prism:volume", + "page": "fabio:page", + "creator": "dct:creator", + "abstract": "dct:abstract", + "year": { + "@id": "fabio:hasPublicationYear", + "@type": "xsd:gYear", + }, + "month": { + "@id": "prism:publicationDate", + "@type": "xsd:gMonth" + }, + }, + "type": "gnc:Phenotype", + } + return jsonld.compact(jsonld.frame(results, frame), frame) except (RemoteDisconnected, URLError): return jsonify({}) diff --git a/gn3/db/rdf.py b/gn3/db/rdf.py index ae0ec29..c8a5017 100644 --- a/gn3/db/rdf.py +++ b/gn3/db/rdf.py @@ -85,50 +85,3 @@ def get_url_local_name(string: str) -> str: url = urlparse(string) return unquote(url.path).rpartition("/")[-1] return string - - -def get_phenotype_metadata( - sparql_conn: SPARQLWrapper, name: str -): - """Return info about a phenotype with a given NAME""" - __metadata_query = """ -$prefix - -CONSTRUCT { - ?phenotype ?pPredicate ?pValue . - ?phenotype ?publicationTerm ?publicationValue . - ?phenotype gn:speciesName ?speciesName . - ?phenotype gn:inbredSetName ?inbredSetBinomialName . - ?phenotype gn:datasetName ?datasetFullName . -} WHERE { - ?phenotype ?pPredicate ?pValue . - OPTIONAL { - ?phenotype gn:phenotypeOfPublication ?publication . - ?publication ?publicationTerm ?publicationValue . - } . - OPTIONAL { - ?phenotype gn:phenotypeOfDataset ?dataset . - ?dataset gn:name ?datasetFullName . - ?dataset gn:datasetOfInbredSet ?inbredSet . - ?inbredSet gn:binomialName ?inbredSetBinomialName . - ?inbredSet gn:inbredSetOfSpecies ?species . - ?species gn:displayName ?speciesName . - } . - FILTER( ?phenotype = phenotype:$name ) . - MINUS { - ?phenotype rdf:type ?pValue . - } - MINUS { - ?publication rdf:type ?publicationValue . - } -} -""" - result: MonadicDict = MonadicDict() - for key, value in sparql_query( - sparql_conn, - Template(__metadata_query) - .substitute(name=name, - prefix=RDF_PREFIXES) - )[0].items(): - result[key] = value - return result |