BASIL#
BASIL stores its SPARQL queries in its own triplestore and renders the results itself, so its output formats are fixed and do not use endpoint negotiation. It binds a single endpoint, so it answers from Meta only.
from pathlib import Path
from helper import call
BASIL_ID = Path("basil/state/api-id").read_text().strip()
BASIL_RDF_ID = Path("basil/state/api-id-rdf").read_text().strip()
A simple request#
Looking up a DOI returns the article’s title from OpenCitations Meta.
call(f"http://localhost:8080/basil/{BASIL_ID}/api.json?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8080/basil/ts57gntldzz7/api.json?doi=10.1007/s11192-022-04367-w'
# 200 OK
{
"vars": [
"br",
"title"
],
"items": [
{
"br": "https://w3id.org/oc/meta/br/061202127149",
"title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data"
}
]
}
The join#
No join. BASIL binds a single endpoint, so it cannot reach OpenCitations Index to add the reference count.
Output#
SELECT results as JSON or CSV; a CONSTRUCT query as RDF.
call(f"http://localhost:8080/basil/{BASIL_ID}/api.csv?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8080/basil/ts57gntldzz7/api.csv?doi=10.1007/s11192-022-04367-w'
# 200 OK
br,title
https://w3id.org/oc/meta/br/061202127149,Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data
call(f"http://localhost:8080/basil/{BASIL_RDF_ID}/api.ttl?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8080/basil/vb928kwrq7n9/api.ttl?doi=10.1007/s11192-022-04367-w'
# 200 OK
BASE <file:///basil/>
PREFIX datacite: <http://purl.org/spar/datacite/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX literal: <http://www.essepuntato.it/2010/06/literalreification/>
<https://w3id.org/oc/meta/br/061202127149>
dcterms:title "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data";
datacite:hasIdentifier <https://w3id.org/oc/meta/id/061202156316> .
Pagination#
Not supported.
Versioning#
Not supported.
API description#
Swagger 1.2.
call(f"http://localhost:8080/basil/{BASIL_ID}/api-docs")
curl http://localhost:8080/basil/ts57gntldzz7/api-docs
# 200 OK
{"swaggerVersion":"1.2","basePath":"http://localhost:8080/basil","resourcePath":"ts57gntldzz7","apis":[{"path":"/ts57gntldzz7/api","resourcePath":"/ts57gntldzz7/api","operations":[{"method":"GET","nickname":"API","summary":"","type":"void","produces":["text/x-nquads","application/sparql-results+json","application/n-triples","text/csv","application/ld+json","text/turtle","text/plain","application/sparql-results+xml","application/rdf+xml","application/xml","text/tsv","application/json","application/rdf+json"],"parameters":[{"name":"doi","description":"","required":true,"type":"string","paramType":"query"}]}]},{"path":"/ts57gntldzz7/api{ext}","resourcePath":"/ts57gntldzz7/api","operations":[{"method":"GET","nickname":"APIext","summary":"","type":"void","produces":["text/x-nquads","application/sparql-results+json","application/n-triples","text/csv","application/ld+json","text/turtle","text/plain","application/sparql-results+xml","application/rdf+xml","application/xml","text/tsv","application/json","application/rdf+json"],"parameters":[{"name":"doi","description":"","required":true,"type":"string","paramType":"query"},{"name":"ext","description":"Extension of the output data format (e.g., .json, .xml)","required":"false","type":"string","paramType":"path","allowMultiple":"false"}]}]}]}
Consumer authentication#
Not supported for consumers: HTTP Basic guards the routes that create or change an API, while the routes that run it have no check.
call(f"http://localhost:8080/basil/{BASIL_ID}/docs", method="DELETE")
curl -X DELETE http://localhost:8080/basil/ts57gntldzz7/docs
# 403 Forbidden
{"error":"Not authenticated"}
With the owner’s credentials the same request succeeds.
call(f"http://localhost:8080/basil/{BASIL_ID}/docs", method="DELETE", basic_auth=("demo", "demo"))
curl -X DELETE -u demo:demo http://localhost:8080/basil/ts57gntldzz7/docs
# 204 No Content
Running the API needs no credentials, and BASIL has no setting to require them.
call(f"http://localhost:8080/basil/{BASIL_ID}/api.json?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8080/basil/ts57gntldzz7/api.json?doi=10.1007/s11192-022-04367-w'
# 200 OK
{
"vars": [
"br",
"title"
],
"items": [
{
"br": "https://w3id.org/oc/meta/br/061202127149",
"title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data"
}
]
}
Endpoint authentication#
HTTP Basic.
BASIL_BASIC_ID = Path("basil/state/api-id-basic").read_text().strip()
call(f"http://localhost:8080/basil/{BASIL_BASIC_ID}/api.json?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8080/basil/r1fle1ohgj1h/api.json?doi=10.1007/s11192-022-04367-w'
# 200 OK
{
"vars": [
"br",
"title"
],
"items": [
{
"br": "https://w3id.org/oc/meta/br/061202127149",
"title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data"
}
]
}
Operations#
GET and POST, both running the same read query, with the POST parameters sent as a form. The other methods are rejected.
call(f"http://localhost:8080/basil/{BASIL_ID}/api.json", method="POST", form={"doi": "10.1007/s11192-022-04367-w"})
curl -X POST --data-urlencode doi=10.1007/s11192-022-04367-w http://localhost:8080/basil/ts57gntldzz7/api.json
# 200 OK
{
"vars": [
"br",
"title"
],
"items": [
{
"br": "https://w3id.org/oc/meta/br/061202127149",
"title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data"
}
]
}
call(f"http://localhost:8080/basil/{BASIL_ID}/api.json?doi=10.1007/s11192-022-04367-w", method="PUT", max_lines=0)
call(f"http://localhost:8080/basil/{BASIL_ID}/api.json?doi=10.1007/s11192-022-04367-w", method="DELETE", max_lines=0)
curl -X PUT 'http://localhost:8080/basil/ts57gntldzz7/api.json?doi=10.1007/s11192-022-04367-w'
# 405 Method Not Allowed
curl -X DELETE 'http://localhost:8080/basil/ts57gntldzz7/api.json?doi=10.1007/s11192-022-04367-w'
# 405 Method Not Allowed
Caching#
Not supported. The tool reaches OpenCitations Meta through a proxy that records every request it forwards, and two identical calls send the same SPARQL requests twice.
from helper import count_endpoint_requests
count_endpoint_requests(f"http://localhost:8080/basil/{BASIL_ID}/api.json?doi=10.1007/s11192-022-04367-w")
First call: 200 OK, SPARQL requests that reached the endpoint: 1
Second call: 200 OK, SPARQL requests that reached the endpoint: 1
Control over JSON#
Not supported. The JSON of a SELECT query always has the vars and items frame seen in the first request, with one flat record per result row, and the API definition has no field to change it.