RDFProxy#

RDFProxy maps each SPARQL result onto a Pydantic model and lets FastAPI generate the OpenAPI description from it. A single adapter binds one endpoint, so it cannot combine the two sources. Its pagination is entity-aware: it rewrites the query to page over distinct entities instead of raw rows.

from helper import call

A simple request#

Looking up a DOI returns the article’s title from OpenCitations Meta, wrapped in a Page envelope.

call("http://localhost:8086/articles/10.1007/s11192-022-04367-w")
curl http://localhost:8086/articles/10.1007/s11192-022-04367-w 

# 200 OK

{
  "items": [
    {
      "doi": "10.1007/s11192-022-04367-w",
      "title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data",
      "br": "https://w3id.org/oc/meta/br/061202127149"
    }
  ],
  "page": 1,
  "size": 100,
  "total": 1,
  "pages": 1
}

The join#

No join. A single adapter binds one endpoint, so RDFProxy cannot reach OpenCitations Index to add the reference count.

Output#

JSON only, shaped by the Pydantic model and wrapped in a Page envelope.

Pagination#

Paging over distinct entities.

call("http://localhost:8086/articles/10.1007/s11192-022-04367-w/authors?page=2&size=2")
curl 'http://localhost:8086/articles/10.1007/s11192-022-04367-w/authors?page=2&size=2' 

# 200 OK

{
  "items": [
    {
      "author": "https://w3id.org/oc/meta/ra/061206532421",
      "family": [
        "Moretti"
      ],
      "given": [
        "Arianna"
      ]
    },
    {
      "author": "https://w3id.org/oc/meta/ra/0614010840729",
      "family": [
        "Peroni"
      ],
      "given": [
        "Silvio"
      ]
    }
  ],
  "page": 2,
  "size": 2,
  "total": 7,
  "pages": 4
}

Versioning#

Not supported.

API description#

OpenAPI 3.1. The Swagger UI and ReDoc render it at http://localhost:8086/docs and http://localhost:8086/redoc.

import requests

from helper import embed_swagger

spec = requests.get("http://localhost:8086/openapi.json", timeout=120).json()
embed_swagger(spec, base_url="http://localhost:8086/")

Consumer authentication#

Not supported by RDFProxy itself; FastAPI’s security utilities would have to be added by hand.

Endpoint authentication#

SPARQLModelAdapter hands aclient_config to the httpx.AsyncClient that sends the queries, so any credentials that httpx supports reach the endpoint, HTTP Basic and Digest included. The /basic route reads meta-basic with httpx.BasicAuth.

call("http://localhost:8086/basic/articles/10.1007/s11192-022-04367-w")
curl http://localhost:8086/basic/articles/10.1007/s11192-022-04367-w 

# 200 OK

{
  "items": [
    {
      "doi": "10.1007/s11192-022-04367-w",
      "title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data",
      "br": "https://w3id.org/oc/meta/br/061202127149"
    }
  ],
  "page": 1,
  "size": 100,
  "total": 1,
  "pages": 1
}

Operations#

GET only. The other methods are rejected.

call("http://localhost:8086/articles/10.1007/s11192-022-04367-w", method="POST", max_lines=0)
call("http://localhost:8086/articles/10.1007/s11192-022-04367-w", method="PUT", max_lines=0)
call("http://localhost:8086/articles/10.1007/s11192-022-04367-w", method="DELETE", max_lines=0)
curl -X POST http://localhost:8086/articles/10.1007/s11192-022-04367-w 

# 405 Method Not Allowed


... (3 more lines)
curl -X PUT http://localhost:8086/articles/10.1007/s11192-022-04367-w 

# 405 Method Not Allowed


... (3 more lines)
curl -X DELETE http://localhost:8086/articles/10.1007/s11192-022-04367-w 

# 405 Method Not Allowed


... (3 more lines)

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. Each call sends two requests because RDFProxy runs a count query beside the page query.

from helper import count_endpoint_requests

count_endpoint_requests("http://localhost:8086/articles/10.1007/s11192-022-04367-w")
First call: 200 OK, SPARQL requests that reached the endpoint: 2
Second call: 200 OK, SPARQL requests that reached the endpoint: 2