LinkML的SPARQL模板
项目描述
sparqlfun
基于LinkML的SPARQL模板库和执行引擎
- SPARQL模板的模块化核心库SPARQL模板
- 使用通用词汇(rdf、owl、skos等)的通用模板
- OBO和生物特定,例如Ubergraph
- 即将推出:uniprot、wikidata等
- 模板的完全FAIR描述
- 每个模板都有一个URI(例如:https://linkml.io/sparqlfun/PairwiseCommonDescendant)
- 每个模板参数都有一个URI(例如:https://linkml.io/sparqlfun/subject)
- 包括每个描述的完整元数据
- 在YAML、RDF、SHACL、ShEx等中描述模板
- 用于建模模板的丰富表达语言
- 使用LinkML作为基础语言
- 可选的python绑定/对象模型使用LinkML
- 支持SELECT和CONSTRUCT
- 可选导出到TSV、JSON、YAML、RDF
- 广泛的端点元数据
这是当前alpha软件,接口和组织可能会改变
浏览默认模板
注意:当前yaml中的所有元数据均未显示在生成的文档中
命令行
使用sparqlfun:PairwiseCommonSubClassAncestor模板
sparqlfun query -e ubergraph -T PairwiseCommonSubClassAncestor node1=GO:0046220 node2=GO:0008295
结果
results:
- node1: GO:0046220
node2: GO:0008295
predicate1: rdfs:subClassOf
predicate2: rdfs:subClassOf
ancestor: GO:0009987
- node1: GO:0046220
node2: GO:0008295
predicate1: rdfs:subClassOf
predicate2: rdfs:subClassOf
ancestor: GO:0044237
- node1: GO:0046220
node2: GO:0008295
predicate1: rdfs:subClassOf
predicate2: rdfs:subClassOf
ancestor: GO:0044271
...
本地RDF文件
如果您指定了-f
/ --format
选项,则假定-e
是一个磁盘上文件的路径
sparqlfun query -e go.owl.ttl -f ttl -T PairwiseCommonSubClassAncestor node1=GO:0046220 node2=GO:0008295
列出所有模板
sparqlfun endpoints
Python
from sparqlfun import SparqlEngine
from sparqlfun.model import PairwiseCommonSubClassAncestor
se = SparqlEngine(endpoint='ubergraph')
se.bind_prefixes(GO='http://purl.obolibrary.org/obo/GO_')
for apair in se.query(PairwiseCommonSubClassAncestor(node1='GO:0046220', node2='GO:0008295')).results:
print(f'ROW={apair.node1} <-> {apair.node2} ANCESTOR = {apair.ancestor}')
更多示例,请参阅GitHub中的[tests/]目录
浏览模板
- 源文件位于sparqlfun/schema
- 在此处添加新模板
- 在网站上浏览生成的Markdown
- Markdown是从yaml模式自动创建的
您也可以在此处列出模板
sparqlfun templates
或详细查看
sparqlfun templates --detail
工作原理
基础
模板定义为遵循LinkML模式的YAML文件。
一个包含单个模板的yaml文件可能看起来像这样
schema:
id: http://example.org/my-vocab/templates
prefixes:
my: http://example.org/my-vocab/
classes:
my template:
slots:
- my_var1
- my_var2
annotations:
sparql.select: |-
SELECT * WHERE { ... ?my_var1 ... ?my_var2}
slots:
my_var1:
description: about my var 1
my_var2:
description: about my var 2
这定义了一个名为MyTemplate
的模板,具有两个插槽/参数,以及一个任意复杂的SPARQL select查询。
YAML文件被拆分为包含至少3个部分的块
- 模式元数据,包括前缀声明
- 您的模板,位于
classes
部分 - 您的参数/变量,位于
slots
部分
请注意,插槽的定义位于类/模板之外的不同部分。鼓励跨模板“重用”插槽。但是,如果您不想重用,可以使用属性声明作为快捷方式。
以上内容可用于查询
sparqlfun -e ubergraph -T MyTemplate my_var2=MY_VAL
您可以在命令行上指定任何或所有变量(如果您指定了所有变量,那么您的SELECT实际上是一个ASK查询)。
然而,这些功能超越了其他模板系统,并利用了LinkML是一个完整的丰富建模语言,与JSON-Schema、SHACL、ShEx等有绑定的事实。
例如,您将获得描述您的模板的Markdown文档。如果您的模式带有诸如描述之类的元数据,这些Markdown文档将更加丰富。
- 描述
- 插槽的范围
- 模板和插槽的映射和URI
这带来了一系列实际的好处
- 您的模板可以有强类型
- 模板可以编译成多种其他形式
- 模板被转换为Python数据类,提供了可选的ORM-like层、IDE支持等
- 未来的应用程序将能够使用模板元数据
- 每个插槽的文档
- 为日期、枚举等字段提供拾取器
- 例如,如果模板插槽的范围是类MyClass,则应用程序可以提供自动完成功能
模板继承
模板可以继承,从而促进重用和组合模式
为了说明,考虑一个简单的“基础”模板来查询三元组
classes:
triple:
aliases:
- statement
description: >-
Represents an RDF triple
slots:
- subject
- predicate
- object
class_uri: rdf:Statement
in_subset:
- base table
annotations:
sparql.select: SELECT * WHERE { ?subject ?predicate ?object}
这个模板单独看可能不是特别有用的模板 - 您可以直接使用sparql查询(尽管即使是这种简单的模式,模板也可能有用,例如用于生成API等)
新模板可以使用这个作为基类,并从中继承,这意味着插槽将被继承,从而消除了部分样板代码和重新定义它们的需求
classes:
quad:
is_a: triple
slots:
- graph ## s/p/o slots inherited from triple
annotations:
sparql.select: SELECT * WHERE {GRAPH ?graph { ?subject ?predicate ?object}}
继承允许使用LinkML classification_rules
构造提供更强大的功能。假设我们想将类型三元组表示为通用三元组的子代
rdf type triple:
is_a: triple
description: >-
A triple that indicates the asserted type of the subject entity
slot_usage:
object:
description: >-
The entity type
range: class node
classification_rules:
- is_a: triple
slot_conditions:
predicate:
equals_string: rdf:type
注意我们不需要在此处指定SPARQL模板 - 模板将自动从分类规则生成。
继承的使用是可选的。您可能会发现,在相似的模板中有一定程度的冗余和重复信息会更简单。请注意,您仍然可以通过插槽的共同词汇表获得相当数量的重用
SPARQL CONSTRUCT和嵌套/内联对象
示例CONSTRUCT查询
obo class:
is_a: class node
class_uri: owl:Class
slots:
- definition
- exact_synonyms
annotations:
sparql.construct: |-
CONSTRUCT {
?id a owl:Class ;
IAO:0000115 ?definition ;
oboInOwl:hasExactSynonym ?exact_snonyms
}
WHERE {
?id a owl:Class .
OPTIONAL { ?id IAO:0000115 ?definition } .
OPTIONAL { ?id oboInOwl:hasExactSynonym ?exact_snonyms } .
}
...
slots:
definition:
slot_uri: IAO:0000115
exact_synonyms:
slot_uri: oboInOwl:hasExactSynonym
multivalued: true
然后我们可以按以下方式查询
sparqlfun -e ontobee -T OboClass id=GO:0000023
结果将根据LinkML规范对模型进行嵌套
{
"results": [
{
"id": "GO:0000023",
"definition": "The chemical reactions and pathways involving the disaccharide maltose (4-O-alpha-D-glucopyranosyl-D-glucopyranose), an intermediate in the catabolism of glycogen and starch.",
"exact_synonyms": [
"malt sugar metabolic process",
"malt sugar metabolism",
"maltose metabolism"
]
}
],
"@type": "ResultSet"
}
(注意:模板还编译成JSON-Schema,可用于额外的验证)
您也可以使用-f ttl
获取三元存储返回的turtle
@prefix ns1: <http://www.geneontology.org/formats/oboInOwl#> .
@prefix ns2: <http://purl.obolibrary.org/obo/> .
@prefix ns3: <https://w3id.org/sparqlfun/> .
ns2:GO_0000023 a <http://www.w3.org/2002/07/owl#Class> ;
ns2:IAO_0000115 "The chemical reactions and pathways involving the disaccharide maltose (4-O-alpha-D-glucopyranosyl-D-glucopyranose), an intermediate in the catabolism of glycogen and starch." ;
ns1:hasExactSynonym "malt sugar metabolic process",
"malt sugar metabolism",
"maltose metabolism" .
[] a ns3:ResultSet ;
ns3:results ns2:GO_0000023 .
使用-t tsv
选项,LinkML CSV 导出器将尽可能地将嵌套结构扁平化到 TSV 格式,例如使用管道作为多值之间的内部分隔符。
多个值
参数可以作为列表传递,这将转换为VALUES
语句。
sparqlfun -e ontobee -T OboClass id=GO:0000023,GO:0000024
模块化
LinkML 允许导入,因此可以使用导入来模块化模板。
注意将来,此存储库可能被分割,其中 bio/obo 特定功能将迁移到新的存储库。
Jinja 命令的使用
您可以通过 Jinja2 模板指令来整合额外的逻辑。
obo class filtered:
is_a: class node
class_uri: owl:Class
slots:
- definition
- exact_synonyms
annotations:
sparql.construct: |-
CONSTRUCT {
?id a owl:Class ;
IAO:0000115 ?definition ;
oboInOwl:hasExactSynonym ?exact_snonyms
}
WHERE {
?id a owl:Class .
OPTIONAL { ?id IAO:0000115 ?definition } .
OPTIONAL { ?id oboInOwl:hasExactSynonym ?exact_snonyms } .
{% if query_has_subclass_ancestor %}
?id rdfs:subClassOf ?query_has_subclass_ancestor
{% endif %}
}
slots:
query_has_subclass_ancestor:
range: class node
description: transitive is_a parent
in_subset:
- ubergraph ## requires relation-graph closure
支持的端点
此框架可以与任何 SPARQL 端点一起使用。然而,当前预定义的模板主要针对 OBO 风格本体和用于 ubergraph 和 ontobee 等三元组存储的存储模式组合。
特别是,ubergraph 使用 relation-graph 推理工具预先计算从 TBox 存在性公理推导出的直接三元组,从而允许对推导本体进行简单而强大的查询。
有关所有预定义端点的列表,请参阅 sparqlfun/config 中的配置文件。
示例
endpoints:
ubergraph:
url: https://stars-app.renci.org/ubergraph/sparql
example_queries:
- query_template: PairwiseCommonSubClassAncestor
bindings:
node1: GO:0046220
node2: GO:0008295
有关端点模式,请参阅 config_schema.yaml。
注意,有一个丰富的元数据模型,旨在促进应用程序和自动化测试。应该能够根据提供的元数据自动确定哪些模板与哪些端点兼容。
添加您自己的模板
目前,如果您正在使用现有的预定义模板,则此库最容易使用(欢迎提供 PR)。
但是,您可以使用框架与您自己的模板来处理您的三元组数据。这尚不支持。需要几个步骤,将来这将更容易。
首先,您需要创建自己的 YAML 文件。这需要符合 LinkML 元模型 - 我们建议复制现有的模板来完成此操作。这些内容可能在此阶段看起来像是多余的样板,但稍后会很有用。
接下来,您需要编译模板
gen-python my_template.yaml > my_template.py
这需要 linkml(此库将 linkml 作为开发依赖项使用)。
您需要将这两个作为参数传递给 sparqlfun(-m
和 -S
)。
待办事项
- 将依赖项添加到完整的 LinkML 框架
- 允许动态编译模板
另请参阅
这受到了强大的但晦涩的 sparqlprog 系统的启发,并设计为该系统的替代品。
待办事项:列出其他 SPARQL 模板框架
待办事项
- 更好的文档
- 框架
- 模板
- 使用 Python、SHACL 等的如何使用指南
- 示例笔记本
- 与 semantic-sql 中的 SQL/rdftab 功能统一
- Cypher 绑定
- 拆分为特定于生物学的
- 展示更多 ubergraph 的强大功能
- 快速 API/无服务器端点
- 展示更多验证
- 集成可视化/obographviz
- 编译到其他框架,例如 grlc
- 链式操作
- 将一个输出注入到另一个中并合并结果,例如获取标签
- 类似于 Wikidata 服务
- UI/yasgui 集成
- 从 dosdp 生成(使用 dosdp-query 算法)
- 模板
- uniprot
- gocams
- wikidata
项目详情
下载文件
下载您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。