hra-api
Version:
The Human Reference Atlas (HRA) API deployed to https://apps.humanatlas.io/api/
1,380 lines (1,359 loc) • 296 kB
JavaScript
#!/usr/bin/env node
// src/server/server.js
import { schedule } from "node-cron";
// src/library/shared/utils/add-to-endpoint.js
import toNT from "@rdfjs/to-ntriples";
import stream from "stream-browserify";
function toTripleString(quad) {
const subject = toNT(quad.subject).replace("_:_:", "_:");
const predicate = toNT(quad.predicate).replace("_:_:", "_:");
const object = toNT(quad.object).replace("_:_:", "_:");
return `${subject} ${predicate} ${object} .
`;
}
function* sparqlUpdateIterator(graph, quads) {
yield `
INSERT DATA {
GRAPH <${graph}> {
`;
for (const quad of quads) {
yield toTripleString(quad);
}
yield "}}\n";
}
async function addToEndpoint(graph, quads, endpoint) {
return fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/sparql-update"
},
body: stream.Readable.from(sparqlUpdateIterator(graph, quads))
});
}
// src/library/shared/utils/fetch-linked-data.js
import formats from "@rdfjs/formats-common";
import { isReadableStream } from "is-stream";
import jsonld from "jsonld";
import patchResponse from "nodeify-fetch/lib/patchResponse.browser.js";
var EXTENSION_MAPPING = {
"json-ld": "application/ld+json",
jsonld: "application/ld+json",
json: "application/ld+json",
nt: "application/n-triples",
nq: "application/n-quads",
n3: "text/n3",
owl: "application/rdf+xml",
rdf: "application/rdf+xml",
xml: "application/rdf+xml",
trig: "application/trig",
turtle: "text/turtle",
ttl: "text/turtle",
html: "text/html",
htm: "text/html"
};
async function getQuads(url, preferredFormat = "text/turtle") {
if (typeof url === "string" && url.startsWith("http")) {
const parsers = formats.parsers;
const otherFormats = Array.from(parsers.keys()).filter((k) => k !== preferredFormat).sort().reverse();
const res = await fetch(url, {
headers: new Headers({
accept: [preferredFormat, ...otherFormats].join(", ")
})
});
const type2 = res.headers.get("content-type").split(";")[0];
const extension = EXTENSION_MAPPING[url.split(".").slice(-1)[0]];
const guessedType = parsers.has(type2) ? type2 : parsers.has(extension) ? extension : void 0;
if (type2 === "application/json" || guessedType === "application/ld+json") {
const json = await res.json();
const quads = await jsonld.toRDF(json);
return quads;
} else if (guessedType) {
let body = res.body;
if (!isReadableStream(body)) {
body = patchResponse(res).body;
}
const stream2 = parsers.import(guessedType, body, { baseIRI: url });
const quads = [];
for await (const quad of stream2) {
quads.push(quad);
}
return quads;
} else {
try {
const json = JSON.parse(await res.text());
const quads = await jsonld.toRDF(json);
return quads;
} catch (err) {
console.log(err);
return Promise.reject(new Error(`unknown content type: ${type2}`));
}
}
} else {
try {
const json = typeof url === "string" ? JSON.parse(url) : url;
const quads = await jsonld.toRDF(json);
return quads;
} catch (err) {
return Promise.reject(new Error(`unknown content type: ${type}`));
}
}
}
// src/library/shared/utils/sparql.js
import jsonld2 from "jsonld";
import Papa from "papaparse";
jsonld2.documentLoader = async (documentUrl) => {
const document = await fetch(documentUrl).then((r) => r.json());
return {
contextUrl: null,
document,
documentUrl
};
};
function fetchSparql(query, endpoint, mimetype) {
const body = new URLSearchParams({ query });
return fetch(endpoint, {
method: "POST",
headers: {
Accept: mimetype,
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": body.toString().length.toString()
},
body
});
}
async function select(query, endpoint) {
const resp = await fetchSparql(query, endpoint, "text/csv");
const text = await resp.text();
const { data } = Papa.parse(text, { header: true, skipEmptyLines: true, dynamicTyping: true });
return data || [];
}
async function construct(query, endpoint, frame = void 0) {
const resp = await fetchSparql(query, endpoint, "application/ld+json");
const json = await resp.json();
if (frame) {
return await jsonld2.frame(json, frame);
} else {
return json;
}
}
async function update(updateQuery, endpoint) {
return fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/sparql-update"
},
body: updateQuery
});
}
async function deleteGraphs(graphs, endpoint) {
const updateQuery = graphs.map((graph) => `CLEAR GRAPH <${graph}>;`).join("\n");
return update(updateQuery, endpoint);
}
// src/library/shared/utils/named-graphs.js
var QUERY = "SELECT DISTINCT ?g WHERE { GRAPH ?g { ?s ?p ?o . } }";
async function namedGraphs(endpoint) {
const graphs = await select(QUERY, endpoint);
return new Set(graphs.map((graph) => graph.g));
}
// src/library/shared/utils/ensure-named-graphs.js
async function ensureNamedGraphs(graphsToCheck, endpoint) {
const graphs = new Set(await namedGraphs(endpoint));
let updateQuery = "";
for (const graphAndUrl of graphsToCheck) {
const graph = graphAndUrl.split("@@")[0];
const url = graphAndUrl.split("@@").slice(-1)[0];
if (!graphs.has(graph)) {
console.log((/* @__PURE__ */ new Date()).toISOString(), "Adding named graph:", graph);
updateQuery += `
CLEAR GRAPH <${graph}>;
LOAD <${url}> INTO GRAPH <${graph}>;
`;
graphs.add(graph);
}
}
await update(updateQuery, endpoint);
return graphs;
}
// src/library/v1/queries/ds-graph-enrichment.rq
var ds_graph_enrichment_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <http://www.w3\
.org/2000/01/rdf-schema#>\nPREFIX owl: <http://www.w3.org/2002/07/owl#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX HRA: <h\
ttps://purl.humanatlas.io/collection/hra-api>\nPREFIX DSGraphs: <https://purl.humanatlas.io/collection/ds-graphs>\nPREFIX \
DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>\nPREFIX has_characterizing_biomarker_set: <http:/\
/purl.obolibrary.org/obo/RO_0015004>\n\nINSERT {\n GRAPH DSGraphsExtra: {\n ?rui_location ccf:collides_with ?anatomical_\
structure ;\n ccf:collides_with ?as_parent ;\n ccf:collides_with_ct ?cell_type ;\n ccf:collides_with_bm ?bio\
marker .\n }\n}\nUSING HRA:\nUSING DSGraphs:\nUSING NAMED DSGraphsExtra:\nWHERE {\n {\n [] ccf:has_registration_location ?r\
ui_location .\n ?rui_location rdf:type ccf:SpatialEntity .\n\n FILTER NOT EXISTS {\n GRAPH DSGraphsExtra: {\n \
?rui_location ccf:collides_with [] .\n }\n }\n }\n\n {\n ?rui_location ccf:collides_with ?anatomical_structure\
.\n }\n UNION\n {\n [] rdf:type ccf:SpatialPlacement ;\n ccf:placement_relative_to ?refOrgan ;\n ccf:plac\
ement_for ?rui_location .\n\n {\n ?refOrgan ccf:representation_of ?anatomical_structure .\n }\n UNION\n {\n \
?refOrgan owl:sameAs [\n ccf:representation_of ?anatomical_structure ;\n ] .\n }\n }\n\n # Manually add pa\
ired organ parents\n OPTIONAL {\n VALUES (?as_parent ?anatomical_structure) {\n # Lymph Node\n (<http://purl.o\
bolibrary.org/obo/UBERON_0000029> <http://purl.obolibrary.org/obo/UBERON_0002509>)\n # Eye\n (<http://purl.oboli\
brary.org/obo/UBERON_0000970> <http://purl.obolibrary.org/obo/UBERON_0004548>)\n (<http://purl.obolibrary.org/obo/UB\
ERON_0000970> <http://purl.obolibrary.org/obo/UBERON_0004549>)\n # Fallopian Tube\n (<http://purl.obolibrary.org\
/obo/UBERON_0003889> <http://purl.obolibrary.org/obo/UBERON_0001303>)\n (<http://purl.obolibrary.org/obo/UBERON_0003\
889> <http://purl.obolibrary.org/obo/UBERON_0001302>)\n # Kidney\n (<http://purl.obolibrary.org/obo/UBERON_00021\
13> <http://purl.obolibrary.org/obo/UBERON_0004538>)\n (<http://purl.obolibrary.org/obo/UBERON_0002113> <http://purl\
.obolibrary.org/obo/UBERON_0004539>)\n # Knee\n (<http://purl.obolibrary.org/obo/UBERON_0001465> <http://purl.or\
g/sig/ont/fma/fma24978>)\n (<http://purl.obolibrary.org/obo/UBERON_0001465> <http://purl.org/sig/ont/fma/fma24977>)\n\
# Mammary Gland\n (<http://purl.obolibrary.org/obo/UBERON_0001911> <http://purl.org/sig/ont/fma/fma57991>)\n \
(<http://purl.obolibrary.org/obo/UBERON_0001911> <http://purl.org/sig/ont/fma/fma57987>)\n # Ovary\n (<http:/\
/purl.obolibrary.org/obo/UBERON_0000992> <http://purl.obolibrary.org/obo/UBERON_0002119>)\n (<http://purl.obolibrary\
.org/obo/UBERON_0000992> <http://purl.obolibrary.org/obo/UBERON_0002118>)\n # Palatine Tonsil\n (<http://purl.ob\
olibrary.org/obo/UBERON_0002373> <http://purl.org/sig/ont/fma/fma54974>)\n (<http://purl.obolibrary.org/obo/UBERON_0\
002373> <http://purl.org/sig/ont/fma/fma54973>)\n # Renal Pelvis\n (<http://purl.obolibrary.org/obo/UBERON_00012\
24> <http://purl.obolibrary.org/obo/UBERON_0018116>)\n (<http://purl.obolibrary.org/obo/UBERON_0001224> <http://purl\
.obolibrary.org/obo/UBERON_0018115>)\n # Ureter\n (<http://purl.obolibrary.org/obo/UBERON_0000056> <http://purl.\
obolibrary.org/obo/UBERON_0001223>)\n (<http://purl.obolibrary.org/obo/UBERON_0000056> <http://purl.obolibrary.org/o\
bo/UBERON_0001222>)\n # Lung (Edge case: we have reversed the relationship between lung and respiratory system for r\
easons)\n (<http://purl.obolibrary.org/obo/UBERON_0002048> <http://purl.obolibrary.org/obo/UBERON_0001004>)\n (<\
http://purl.obolibrary.org/obo/UBERON_0001004> <http://purl.obolibrary.org/obo/UBERON_0002048>)\n }\n \n OPTIONAL \
{\n ?parent_descriptor rdf:type ccf:CellMarkerDescriptor ;\n ccf:primary_anatomical_structure\
?as_parent ;\n ccf:primary_cell_type ?cell_type .\n OPTIONAL {\n ?parent_descriptor cc\
f:biomarker ?biomarker .\n }\n }\n }\n\n OPTIONAL {\n ?descriptor rdf:type ccf:CellMarkerDescriptor ;\n \
ccf:primary_anatomical_structure ?anatomical_structure ;\n ccf:primary_cell_type ?cell_type .\n OPT\
IONAL {\n ?descriptor ccf:biomarker ?biomarker .\n }\n }\n}\n";
// src/library/v1/queries/get-dataset-info.rq
var get_dataset_info_default = "PREFIX hraApi: <urn:hra-api#>\nPREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n\
PREFIX schema: <http://schema.org/>\nPREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\nPREFIX DSGraphs: <urn:hra-api:TOKEN:\
ds-info>\n\nSELECT ?status ?message ?checkback ?loadTime ?timestamp ?startTime\nFROM DSGraphs:\nWHERE {\n DSGraphs: a hraApi\
:Dataset ;\n hraApi:status ?status ;\n hraApi:message ?message ;\n hraApi:startTime ?startTime ;\n hraApi:update\
Time ?updateTime ;\n\n BIND(IF(?status = 'Ready' || ?status = 'Error', 60 * 60 * 1000, 2000) as ?checkback)\n BIND(STR(?u\
pdateTime) as ?timestamp)\n}\n";
// src/library/v1/queries/prunable-datasets.rq
var prunable_datasets_default = `PREFIX hraApi: <urn:hra-api#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT DISTINCT ?age ?maxAge ?dsInfo ?dsGraph ?status ?updateTime
WHERE {
GRAPH ?dsInfo {
?dsInfo a hraApi:Dataset ;
hraApi:namedGraph ?dsGraph ;
hraApi:status ?status ;
hraApi:updateTime ?updateTime .
# Max dataset age is currently set to 24 hours
BIND((xsd:dateTime("2001-01-02T00:00:00Z") - xsd:dateTime("2001-01-01T00:00:00Z")) as ?maxAge)
BIND(NOW() - ?updateTime as ?age)
FILTER((NOW() - ?updateTime) > ?maxAge || ?status = 'Error')
}
}
`;
// src/library/v1/queries/start-dataset-info.rq
var start_dataset_info_default = 'PREFIX hraApi: <urn:hra-api#>\nPREFIX schema: <http://schema.org/>\nPREFIX DSGraphInfo: \
<urn:hra-api:TOKEN:ds-info>\nPREFIX DSGraph: <urn:hra-api:TOKEN:ds-graph>\n\nWITH DSGraphInfo:\nDELETE {\n DSGraphInfo: a hr\
aApi:Dataset ;\n ?key ?value .\n}\nINSERT {\n DSGraphInfo: a hraApi:Dataset ;\n hraApi:status "Loading" ;\n hraApi:m\
essage "Job is queued to be run..." ;\n hraApi:namedGraph DSGraph: ;\n hraApi:startTime ?startTime ;\n hraApi:upda\
teTime ?startTime ;\n}\nWHERE {\n OPTIONAL {\n DSGraphInfo: a hraApi:Dataset ;\n ?key ?value .\n }\n BIND(NOW() as ?\
startTime)\n}\n';
// src/library/v1/queries/update-dataset-info.rq
var update_dataset_info_default = 'PREFIX hraApi: <urn:hra-api#>\nPREFIX schema: <http://schema.org/>\nPREFIX DSGraphs: <u\
rn:hra-api:TOKEN:ds-info>\n\nWITH DSGraphs:\nDELETE {\n DSGraphs: a hraApi:Dataset ;\n hraApi:status ?status ;\n hraApi\
:message ?message ;\n hraApi:updateTime ?updateTime .\n}\nINSERT {\n DSGraphs: a hraApi:Dataset ;\n hraApi:status ?new\
Status ;\n hraApi:message ?newMessage ;\n hraApi:updateTime ?newUpdateTime .\n}\nWHERE {\n OPTIONAL {\n DSGraphs: a \
hraApi:Dataset ;\n hraApi:status ?status ;\n hraApi:message ?message ;\n hraApi:updateTime ?updateTime .\n }\
\n\n BIND("{{STATUS}}" as ?newStatus)\n BIND("{{MESSAGE}}" as ?newMessage)\n BIND(NOW() as ?newUpdateTime)\n}\n';
// src/library/v1/utils/dataset-graph.js
var DEFAULT_GRAPHS = [
"https://purl.humanatlas.io/collection/hra-api@@https://cdn.humanatlas.io/digital-objects/collection/hra-api/latest/gr\
aph.ttl",
"https://purl.humanatlas.io/graph/hra-ccf-patches@@https://cdn.humanatlas.io/digital-objects/graph/hra-ccf-patches/lat\
est/graph.ttl",
"https://purl.humanatlas.io/graph/hra-pop@@https://cdn.humanatlas.io/digital-objects/graph/hra-pop/latest/graph.ttl",
"https://purl.humanatlas.io/collection/ds-graphs@@https://cdn.humanatlas.io/digital-objects/collection/ds-graphs/lates\
t/graph.ttl",
"https://purl.humanatlas.io/graph/ds-graphs-enrichments@@https://cdn.humanatlas.io/digital-objects/graph/ds-graphs-enr\
ichments/latest/graph.ttl"
];
async function initializeDatasetGraph(token, _request, endpoint) {
const updateQuery = start_dataset_info_default.replace("urn:hra-api:TOKEN:ds-info", `urn:hra-api:${token}:ds-info`).replace(
"urn:hra-api:TOKEN:ds-graph", `urn:hra-api:${token}:ds-graph`);
await update(updateQuery, endpoint);
}
async function updateDatasetInfo(status, message, token, endpoint) {
console.log((/* @__PURE__ */ new Date()).toISOString(), token, status, message);
const updateQuery = update_dataset_info_default.replace("urn:hra-api:TOKEN:ds-info", `urn:hra-api:${token}:ds-info`).replace(
"{{STATUS}}", status).replace("{{MESSAGE}}", message);
return update(updateQuery, endpoint);
}
async function getDatasetInfo(token, endpoint) {
const infoQuery = get_dataset_info_default.replace("urn:hra-api:TOKEN:ds-info", `urn:hra-api:${token}:ds-info`);
const status = await select(infoQuery, endpoint);
const results = status.length > 0 ? status[0] : {
status: "Error",
message: "Unknown error while loading database",
checkback: 36e5,
loadTime: 22594,
timestamp: (/* @__PURE__ */ new Date()).toISOString()
};
results.loadTime = results.loadTime || (results.status === "Loading" ? /* @__PURE__ */ new Date() : new Date(results.timestamp)) -
new Date(results.startTime);
return results;
}
async function createDatasetGraph(token, request, endpoint) {
try {
const graphs = await ensureNamedGraphs(DEFAULT_GRAPHS, endpoint);
const dsGraph = `urn:hra-api:${token}:ds-graph`;
const dsGraphEnrichments = `urn:hra-api:${token}:ds-graph-enrichments`;
if (!graphs.has(dsGraph)) {
for (const source of request.dataSources) {
await updateDatasetInfo("Loading", `Adding dataset`, token, endpoint);
const quads = await getQuads(source);
await addToEndpoint(dsGraph, quads, endpoint);
}
await updateDatasetInfo("Loading", `Enriching dataset`, token, endpoint);
await enrichDatasetGraph(dsGraph, dsGraphEnrichments, endpoint);
}
await updateDatasetInfo("Ready", `Dataset ready`, token, endpoint);
} catch (err) {
console.error("ERROR", token, request, endpoint, err);
await updateDatasetInfo("Error", `Error processing dataset`, token, endpoint);
}
}
async function enrichDatasetGraph(dsGraph, dsGraphEnrichments, endpoint) {
const updateQuery = ds_graph_enrichment_default.replace("PREFIX DSGraphs: <https://purl.humanatlas.io/collection/ds-gr\
aphs>", `PREFIX DSGraphs: <${dsGraph}>`).replace(
"PREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>",
`PREFIX DSGraphsExtra: <${dsGraphEnrichments}>`
);
const result = await update(updateQuery, endpoint);
if (!result.ok) {
console.log("error enriching", dsGraph, "code:", result.status);
console.error(await result.text());
}
return result;
}
async function pruneDatasetGraphs(endpoint) {
const datasets = await select(prunable_datasets_default, endpoint);
console.log(datasets.length, "datasets to prune");
if (datasets.length > 0) {
const graphs = datasets.reduce((acc, row) => acc.concat([row.dsInfo, row.dsGraph]), []);
console.log("deleting", graphs);
for (const graph of graphs) {
await deleteGraphs([graph], endpoint);
}
}
}
// src/server/app.js
import cors from "cors";
import express from "express";
import queue from "express-queue";
import helmet from "helmet";
import qs from "qs";
// src/server/cache-middleware.js
import { existsSync } from "fs";
import { resolve } from "path";
// src/server/environment.js
var DEFAULT_SPARQL_ENDPOINT = "https://lod.humanatlas.io/sparql";
function sparqlEndpoint() {
return process.env.SPARQL_ENDPOINT ?? DEFAULT_SPARQL_ENDPOINT;
}
function isWritable() {
return process.env.SPARQL_WRITABLE === "true";
}
function exposedSparqlEndpoint() {
return process.env.EXPOSED_SPARQL_ENDPOINT ?? (isWritable() ? DEFAULT_SPARQL_ENDPOINT : sparqlEndpoint());
}
function port() {
return process.env.PORT || 3e3;
}
function shortCacheTimeout() {
return process.env.CACHE_TIMEOUT || 3600;
}
function pruningSchedule() {
return process.env.PRUNING_SCHEDULE || "0 6 * * *";
}
function longCacheTimeout() {
return process.env.LONG_CACHE_TIMEOUT || shortCacheTimeout() * 24;
}
function activeQueryLimit() {
return process.env.ACTIVE_QUERIES || 4;
}
function cacheDir() {
return process.env.FILE_CACHE_DIR || "./file-cache";
}
// src/server/cache-middleware.js
function cache(ttl = shortCacheTimeout(), revalidateTtl = 600, errorTtl = 600) {
return (_req, res, next) => {
res.setHeader(
"Cache-Control",
`public, max-age=${ttl}, stale-while-revalidate=${revalidateTtl}, stale-if-error=${errorTtl}`
);
next();
};
}
var longCache = cache(longCacheTimeout());
var shortCache = cache(shortCacheTimeout());
function noCache(_req, res, next) {
res.setHeader("Cache-Control", "no-cache");
next();
}
function fileCache(filename) {
const filepath = resolve(cacheDir(), filename);
return async (_req, res, next) => {
if (existsSync(filepath)) {
res.sendFile(filepath, { cacheControl: false });
} else {
next();
}
};
}
// src/server/fetch-polyfill.js
import fetch2, { Headers as Headers2, Request, Response } from "node-fetch";
globalThis.fetch = fetch2;
globalThis.Headers = Headers2;
globalThis.Request = Request;
globalThis.Response = Response;
// src/server/routes/browser.js
import { Router } from "express";
// hra-api-spec.yaml
var hra_api_spec_default = `openapi: 3.0.3
info:
title: HRA-API
description: |
This API provides programmatic access to data registered to the Human Reference Atlas (HRA).
See the [HuBMAP HRA Portal](https://humanatlas.io/) for details.
version: 0.15.0
contact:
name: HuBMAP Help Desk
email: help@hubmapconsortium.org
license:
name: MIT License
url: https://spdx.org/licenses/MIT.html
servers:
- description: HRA-API Production
url: https://apps.humanatlas.io/api
- description: HRA-API Staging
url: https://apps.humanatlas.io/api--staging
- description: CCF-API (deprecated) Production
url: https://apps.humanatlas.io/hra-api
- description: Local Server
url: /
security: []
tags:
- name: v1
description: HRA-API v1 Routes
- name: ds-graph
description: Dataset Graph Routes
- name: hra-kg
description: HRA KG Routes
- name: hra-pop
description: HRApop Routes
externalDocs:
description: API Documentation
url: https://github.com/x-atlas-consortia/hra-api#readme
paths:
/v1/aggregate-results:
get:
summary: Get aggregate results / statistics
operationId: aggregate-results
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/AggregateResults'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/anatomical-systems-tree-model:
get:
summary: Get anatomical systems partonomy tree nodes
operationId: anatomical-systems-tree-model
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/OntologyTree'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/asctb-omap-sheet-config:
get:
summary: Get OMAP sheet config data for the ASCT+B Reporter
operationId: asctb-omap-sheet-config
tags:
- v1
responses:
'200':
$ref: '#/components/responses/AsctbReferenceData'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/asctb-sheet-config:
get:
summary: Get sheet config data for the ASCT+B Reporter
operationId: asctb-sheet-config
tags:
- v1
responses:
'200':
$ref: '#/components/responses/AsctbReferenceData'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/biomarker-term-occurences:
get:
summary: Get number of biomarker type term occurrences for a search
operationId: biomarker-term-occurences
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/TermOccurences'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/biomarker-tree-model:
get:
summary: Get biomarker tree nodes
operationId: biomarker-tree-model
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/OntologyTree'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/cell-type-term-occurences:
get:
summary: Get number of cell type term occurrences for a search
operationId: cell-type-term-occurences
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/TermOccurences'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/cell-type-tree-model:
get:
summary: Get cell type tree nodes
operationId: cell-type-tree-model
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/OntologyTree'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/collisions:
post:
summary: Given an extraction site, get mesh-based collisions with the reference organ.
operationId: collisions
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/ExtractionSite'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/v1/consortium-names:
get:
summary: Get consortium names (for filtering)
operationId: consortium-names
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/Strings'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/corridor:
post:
summary: Given an extraction site, generate a corridor with the reference organ.
operationId: corridor
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/ExtractionSite'
responses:
'200':
description: Successful operation
content:
model/gltf-binary:
schema:
type: string
format: binary
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/v1/db-status:
get:
summary: Get current status of database
operationId: db-status
tags:
- v1
parameters:
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/DatabaseStatus'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/ds-graph:
get:
summary: Get dataset graph
description: Get potentially filtered experimental data in dataset graph format (previously referred to as rui_loc\
ations.jsonld format)
operationId: ds-graph
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/extraction-site:
get:
summary: Lookup Extraction Site
operationId: extraction-site
tags:
- v1
parameters:
- $ref: '#/components/parameters/ExtractionSiteIri'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/ftu-illustrations:
get:
summary: Get 2D FTU Illustration data
operationId: ftu-illustrations
tags:
- v1
responses:
'200':
$ref: '#/components/responses/FtuIllustrations'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/get-spatial-placement:
post:
summary: Given a SpatialEntity already placed relative to a reference SpatialEntity, retrieve a new direct Spatial\
Placement to the given SpatialEntity IRI
operationId: get-spatial-placement
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/GetSpatialPlacement'
responses:
'200':
$ref: '#/components/responses/SpatialPlacement'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/v1/gtex/rui_locations.jsonld:
get:
summary: Get all GTEx rui locations (if enabled)
description: This option is only enabled if GTEX_ROUTES=true in the environment
operationId: gtex-rui-locations
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
description: Not found due to option being disabled
/v1/hubmap/rui_locations.jsonld:
get:
summary: Get all hubmap rui locations (if enabled)
description: This option is only enabled if XCONSORTIA_ROUTES=true in the environment
operationId: hubmap-rui-locations
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
description: Not found due to option being disabled
/v1/mesh-3d-cell-population:
post:
summary: Given a reference organ, 3d scene node, and cell population, generate cells in that distribution to fit \
in that 3d scene node.
operationId: mesh-3d-cell-population
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/Mesh3dCellPopulation'
responses:
'200':
description: Successful response with CSV file
content:
text/csv:
schema:
type: string
format: binary
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/v1/ontology-term-occurences:
get:
summary: Get number of ontology term occurrences for a search
operationId: ontology-term-occurences
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/TermOccurences'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/ontology-tree-model:
get:
summary: Get ontology term tree nodes
operationId: ontology-tree-model
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/OntologyTree'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/provider-names:
get:
summary: Get tissue provider names (for filtering)
operationId: provider-names
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/Strings'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/reference-organ-scene:
get:
summary: Get all nodes to form the 3D scene for an organ
operationId: reference-organ-scene
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/OrganIri'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/SpatialSceneNodes'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/reference-organs:
get:
summary: Get all reference organs
operationId: reference-organs
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/SpatialEntities'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/rui-reference-data:
get:
summary: Get reference data for the RUI tool
operationId: rui-reference-data
tags:
- v1
responses:
'200':
$ref: '#/components/responses/RuiReferenceData'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/scene:
get:
summary: Get all nodes to form the 3D scene of reference body, organs, and tissues
operationId: scene
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/SpatialSceneNodes'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/sennet/rui_locations.jsonld:
get:
summary: Get all sennet rui locations (if enabled)
description: This option is only enabled if XCONSORTIA_ROUTES=true in the environment
operationId: sennet-rui-locations
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
description: Not found due to option being disabled
/v1/session-token:
post:
summary: Get a session token
operationId: session-token
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/SessionToken'
responses:
'200':
$ref: '#/components/responses/SessionToken'
'404':
$ref: '#/components/responses/ErrorMessage'
'405':
$ref: '#/components/responses/ErrorMessage'
/v1/sparql:
get:
summary: Run a SPARQL query
operationId: sparql
tags:
- v1
parameters:
- $ref: '#/components/parameters/Query'
- $ref: '#/components/parameters/Token'
- $ref: '#/components/parameters/Format'
responses:
'200':
$ref: '#/components/responses/SparqlResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
post:
summary: Run a SPARQL query (POST)
operationId: sparql-post
tags:
- v1
requestBody:
$ref: '#/components/requestBodies/SparqlQuery'
parameters:
- $ref: '#/components/parameters/Token'
- $ref: '#/components/parameters/Format'
responses:
'200':
$ref: '#/components/responses/SparqlResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/technology-names:
get:
summary: Get technology names (for filtering)
operationId: technology-names
tags:
- v1
parameters:
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/Strings'
'404':
$ref: '#/components/responses/ErrorMessage'
/v1/tissue-blocks:
get:
summary: Get Tissue Block Results
operationId: tissue-blocks
tags:
- v1
parameters:
- $ref: '#/components/parameters/Age'
- $ref: '#/components/parameters/AgeRange'
- $ref: '#/components/parameters/Bmi'
- $ref: '#/components/parameters/BmiRange'
- $ref: '#/components/parameters/Cache'
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/Consortiums'
- $ref: '#/components/parameters/Providers'
- $ref: '#/components/parameters/Sex'
- $ref: '#/components/parameters/SpatialSearches'
- $ref: '#/components/parameters/Technologies'
- $ref: '#/components/parameters/Token'
responses:
'200':
$ref: '#/components/responses/TissueBlocks'
'404':
$ref: '#/components/responses/ErrorMessage'
/ds-graph/atlas-d2k:
get:
summary: Get Atlas D2K Dataset Graph
operationId: atlas-d2k
tags:
- ds-graph
parameters:
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/ds-graph/gtex:
get:
summary: Get GTEx Dataset Graph
operationId: gtex
tags:
- ds-graph
parameters:
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/ds-graph/hubmap:
get:
summary: Get HuBMAP Dataset Graph
operationId: hubmap
tags:
- ds-graph
parameters:
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/ds-graph/sennet:
get:
summary: Get SenNet Dataset Graph
operationId: sennet
tags:
- ds-graph
parameters:
- $ref: '#/components/parameters/Token'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
'404':
$ref: '#/components/responses/ErrorMessage'
/hra-pop/cell-summary-report:
post:
summary: Given a cell summary in csv format, retrieve a predicted cell summary report from HRApop showing relative\
anatomical structures, datasets, and rui locations.
operationId: cell-summary-report
tags:
- hra-pop
requestBody:
$ref: '#/components/requestBodies/GetCellSummaryReport'
responses:
'200':
$ref: '#/components/responses/CellSummaryReportResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/hra-pop/rui-location-cell-summary:
post:
summary: Given a SpatialEntity already placed relative to a reference SpatialEntity, retrieve a predicted cell sum\
mary from HRApop
operationId: rui-location-cell-summary
tags:
- hra-pop
requestBody:
$ref: '#/components/requestBodies/GetRuiLocationCellSummary'
responses:
'200':
$ref: '#/components/responses/RuiLocationCellSummaryResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/hra-pop/supported-organs:
get:
summary: Get all organs supported by HRApop
operationId: supported-organs
tags:
- hra-pop
responses:
'200':
$ref: '#/components/responses/IdLabelsResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/hra-pop/supported-reference-organs:
get:
summary: Get all reference organs supported by HRApop
operationId: supported-reference-organs
tags:
- hra-pop
responses:
'200':
$ref: '#/components/responses/IdLabelsResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/hra-pop/supported-tools:
get:
summary: Get all tools supported by HRApop
operationId: supported-tools
tags:
- hra-pop
responses:
'200':
$ref: '#/components/responses/IdLabelsResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/kg/asctb-term-occurences:
get:
summary: Get number of ASCT+B term occurrences for a search
operationId: asctb-term-occurences
tags:
- hra-kg
parameters:
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
responses:
'200':
$ref: '#/components/responses/TermOccurences'
'404':
$ref: '#/components/responses/ErrorMessage'
/kg/digital-objects:
get:
summary: List all digital objects in the HRA KG
operationId: digital-objects
tags:
- hra-kg
responses:
'200':
$ref: '#/components/responses/DigitalObjectsResponse'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
/kg/do-search:
get:
summary: Search for Digital Object PURLs
operationId: do-search
tags:
- hra-kg
parameters:
- $ref: '#/components/parameters/OntologyTerms'
- $ref: '#/components/parameters/CellTypeTerms'
- $ref: '#/components/parameters/BiomarkerTerms'
- $ref: '#/components/parameters/HraVersions'
responses:
'200':
$ref: '#/components/responses/Strings'
'404':
$ref: '#/components/responses/ErrorMessage'
'500':
$ref: '#/components/responses/ErrorMessage'
components:
schemas:
MinMax:
title: Number Range
description: |
Represents a range of numbers using a minimum and maximum.
Either end may be omitted to indicate an unlimited/infinite range in that direction.
\`min\` should be less than or equal to \`max\` but this is not strictly enforced.
type: object
properties:
min:
type: number
max:
type: number
SpatialSearch:
title: Probing Sphere
description: |
Specification for a Spatial Search via Probing Sphere
type: object
properties:
x:
title: X coordinate relative to target in millimeters
type: number
'y':
title: Y coordinate relative to target in millimeters
type: number
z:
title: Z coordinate relative to target in millimeters
type: number
radius:
title: Size of the probing sphere in millimeters
type: number
target:
title: The target spatial entity IRI
type: string
required:
- x
- 'y'
- z
- radius
- target
additionalProperties: false
AggregateCount:
title: Aggregated Count \\w Label
type: object
required:
- label
- count
properties:
label:
title: Aggregate Name/Field
type: string
count:
title: Aggregated Count
oneOf:
- type: number
nullable: false
- type: string
nullable: false
x-preprocessor-delete: oneOf
ErrorMessage:
title: Error Message
type: object
required:
- error
properties:
error:
title: Human readable description of the error
type: string
JsonLdObject:
title: JSON-LD Object
description: Base object for all json-ld objects.
type: object
required:
- '@id'
- '@type'
additionalProperties: true
properties:
'@id':
title: Unique Identifier
type: string
format: uri
example: http://purl.obolibrary.org/obo/UBERON_0013702
'@type':
title: Object Type
description: Contains the name of object class/interface
type: string
example: Sample
x-preprocessor-delete:
- properties/@id
- properties/@type
OntologyTreeNode:
title: Ontology Node
description: A node in the ontology tree.
type: object
allOf:
- $ref: '#/components/schemas/JsonLdObject'
required:
- '@type'
properties:
'@type':
type: string
enum:
- OntologyTreeNode
id:
title: Identifier
description: Unique identifier for the node.
type: string
format: uri
label:
title: Label
description: Main descriptive label for the node.
type: string
synonymLabels:
title: Synonym Labels
description: Additional label for the node.
type: array
items:
type: string
parent:
title: Parent Node Identifier
description: Reference to the parent node.
type: string
format: uri
children:
title: Child Node Identifiers
description: References to all child nodes.
type: array
items:
type: string
format: uri
x-preprocessor-delete:
- properties/@type
OntologyTree:
title: Ontology Tree
description: An ontology tree.
type: object
required:
- root
- nodes
properties:
root:
title: Root Node
description: Reference to the root node.
type: string
format: url
nodes:
title: All Nodes
description: A mapping of identifiers to each node object.
additionalProperties:
$ref: '#/components/schemas/OntologyTreeNode'
SpatialEntityCommon:
title: Spatial Entity C