Django (Python) 中 SPARQL 的 REST API?

Dan*_*iel 5 python sparql rdflib django-rest-framework reactjs

介绍

我今天给您带来的挑战是:实现Real Rime REST APIGETPOSTPUTDELETE等),以使用前端应用程序的Django REST Framework (我正在使用React )来查询更新任何SPARQL端点,以请求和使用REST API提供的序列化数据。

请注意,我使用 Django 是因为我想在将来实现Web移动应用程序,但现在我只会在React Web应用程序上实现它。

规格

REST API应该能够:

  • 通过HTTP请求对SPARQL端点执行(读取或更新)查询。
  • 根据HTTP响应,将响应序列化为JSON RDF 标准化表或RDF 图表
  • 将序列化响应存储在Python对象中。
  • 向端点提供对前端应用程序(例如 React)的序列化响应。
  • 处理来自前端应用程序的传入请求,“翻译”并作为SPARQL查询执行。
  • 发回对前端应用程序请求的响应。

所有这一切都是在实时执行所有查询和更新的同时进行的。

我所说的实时 API是什么意思:

  1. SPARQL查询是通过HTTP请求从REST APISPARQL端点执行的。
  2. REST API读取从请求生成的HTTP响应。
  3. REST API将响应序列化为相应的格式。
  4. 此序列化响应本地存储在Python对象中以供将来使用。

(注意:查询中来自SPARQL端点的所有三元组现在都存在于SPARQL端点以及Python对象中,并且在本地和远程都是一致的。)

  1. 然后(假设)修改或更新三元组(本地或远程)。
  2. 现在本地三元组与远程三元组不同步
  3. REST API现在意识到了此更新(也许通过监听器/观察者对象?)。
  4. 然后,REST API通过更新查询请求(如果在本地进行更改)或通过使用查询请求的响应更新Python对象(如果在远程进行更新)来自动同步三元组。
  5. 最后,两者(SPARQL端点和Python对象)应该共享最新更新的三元组,因此保持同步

之前的尝试

我目前已经能够使用包(用于执行查询)查询SPARQL端点,以及用于从响应中序列化和实例化Python对象的和包,如下所示:SPARQLWrapperRDFLibJSON

import json

from rdflib import RDFS, Graph

from SPARQLWrapper import GET, JSON, JSONLD, POST, TURTLE, SPARQLWrapper


class Store(object):
    def __init__(self, query_endpoint, update_endpoint=None):
        self.query_endpoint = query_endpoint
        self.update_endpoint = update_endpoint
        self.sparql = SPARQLWrapper(query_endpoint, update_endpoint)

    def graph_query(self, query: str, format=JSONLD, only_conneg=True):
        results = self.query(query, format, only_conneg) 
        results_bytes = results.serialize(format=format)
        results_json = results_bytes.decode('utf8').replace("'", '"')
        data = json.loads(results_json)
        return data

    def query(self, query: str, format=JSON, only_conneg=True):
        self.sparql.resetQuery()
        self.sparql.setMethod(GET)
        self.sparql.setOnlyConneg(only_conneg)
        self.sparql.setQuery(query)
        self.sparql.setReturnFormat(format)
        return self.sparql.queryAndConvert()

    def update_query(self, query: str, only_conneg=True):
        self.sparql.resetQuery()
        self.sparql.setMethod(POST)
        self.sparql.setOnlyConneg(only_conneg)
        self.sparql.setQuery(query)
        self.sparql.query()


store = Store('http://www.example.com/sparql/Example')
print(store.query("""SELECT ?s WHERE {?s ?p ?o} LIMIT 1"""))
print(store.graph_query("""DESCRIBE <http://www.example.com/sparql/Example/>"""))
Run Code Online (Sandbox Code Playgroud)

挑战

前面的代码已经可以解决:

  • 通过 HTTP 请求对 SPARQL 端点执行(读取或更新)查询
  • 根据 HTTP 响应,将响应序列化为 JSON RDF 标准化表或 RDF 图表
  • 将序列化响应存储在 Python 对象中。

但仍然未能实现这些其他方面:

  • 向端点提供对前端应用程序(例如 React)的序列化响应。处理来自前端应用程序的传入请求,“翻译”并作为 SPARQL 查询执行。**
  • 发回对前端应用程序请求的响应。

最后但并非最不重要的一点是,它完全无法实现这一挑战的实时方面。

问题:

  • 你会如何实施这个?
  • 这真的是最好的方法吗?
  • 可以优化已经运行的代码吗?
  • 有什么东西已经做到了这一点吗?

太感谢了!

小智 1

抱歉,我对 Django 不太了解,所以无法在这里回答 Django 的具体情况。

但是,我可以这样说:SPARQL 有一个 HTTP 交互规范(https://www.w3.org/TR/sparql11-protocol/),它告诉您使用sparql?query=...& sparql?update...style URI 来查询存储,那么为什么要定义一个用store.query&等做事的新方法store.graph_query

有 Django 特定的原因吗?

您现在就可以使用 React 或任何您想要的方式向 SPARQL 端点提出问题。

您说缺少的是“提供带有序列化响应的端点”,但 SPARQL 响应就是这样!SPARQL 查询响应格式在规范中定义(例如 JSON:https: //www.w3.org/TR/sparql11-results-json/),并且 SPARQLWrapper 知道如何将它们解析为 Python 对象。其他语言库,例如 JavaScript 中的 rdflib.js 也知道。

有关独立 JS SPARQL 客户端,请参阅 YASGUI ( https://triply.cc/docs/yasgui )。