diff --git a/rocrate_validator/profiles/five-safes-crate/may/8_disclosure_phase.ttl b/rocrate_validator/profiles/five-safes-crate/may/8_disclosure_phase.ttl
index 2ad58813..46943191 100644
--- a/rocrate_validator/profiles/five-safes-crate/may/8_disclosure_phase.ttl
+++ b/rocrate_validator/profiles/five-safes-crate/may/8_disclosure_phase.ttl
@@ -52,8 +52,7 @@ five-safes-crate:DisclosureObjectHasStartTimeIfBegun
sh:path schema:startTime ;
sh:minCount 1 ;
sh:maxCount 1 ;
- sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ;
sh:severity sh:Info ;
- sh:description "Disclosure object MAY have startTime property with RFC 3339 full datetime string if action began." ;
- sh:message "Disclosure object MAY have startTime property with RFC 3339 full datetime string if action began." ;
+ sh:description "`DisclosureCheck` MAY have the `startTime` property if `actionStatus` is either ActiveActionStatus, CompletedActionStatus or FailedActionStatus." ;
+ sh:message "`DisclosureCheck` MAY have the `startTime` property if `actionStatus` is either ActiveActionStatus, CompletedActionStatus or FailedActionStatus." ;
] .
\ No newline at end of file
diff --git a/rocrate_validator/profiles/five-safes-crate/must/8_disclosure_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/8_disclosure_phase.ttl
index e371203d..d46e38ca 100644
--- a/rocrate_validator/profiles/five-safes-crate/must/8_disclosure_phase.ttl
+++ b/rocrate_validator/profiles/five-safes-crate/must/8_disclosure_phase.ttl
@@ -44,30 +44,31 @@ five-safes-crate:DisclosureObjectHasDescriptiveNameAndIsAssessAction
sh:property [
a sh:PropertyShape ;
sh:name "AssessAction" ;
- sh:description "DisclosureCheck MUST be a `schema:AssessAction`." ;
+ sh:description "`DisclosureCheck` MUST be a `schema:AssessAction`." ;
sh:path rdf:type ;
sh:minCount 1 ;
sh:hasValue schema:AssessAction;
sh:severity sh:Violation ;
- sh:message "DisclosureCheck MUST be a `schema:AssessAction`." ;
+ sh:message "`DisclosureCheck` MUST be a `schema:AssessAction`." ;
] ;
sh:property [
a sh:PropertyShape ;
sh:name "name" ;
- sh:description "DisclosureCheck MUST have a name string of at least 20 characters." ;
+ sh:description "`DisclosureCheck` MUST have a name string of at least 10 characters." ;
+ sh:minCount 1 ;
sh:path schema:name ;
sh:datatype xsd:string ;
- sh:minLength 20 ;
+ sh:minLength 10 ;
sh:severity sh:Violation ;
- sh:message "DisclosureCheck MUST have a name string of at least 20 characters." ;
+ sh:message "`DisclosureCheck` MUST have a name string of at least 10 characters." ;
] .
-five-safes-crate:DisclosureObjectHasActionStatus
+five-safes-crate:DisclosureObjectHasActionStatusWithAcceptedValue
a sh:NodeShape ;
sh:name "DisclosureCheck" ;
- sh:description "DisclosureCheck" ;
+ sh:description "`DisclosureCheck` MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ;
sh:target [
a sh:SPARQLTarget ;
@@ -86,7 +87,7 @@ five-safes-crate:DisclosureObjectHasActionStatus
sh:property [
a sh:PropertyShape ;
sh:name "actionStatus" ;
- sh:description "The value of actionStatus MUST be one of the allowed values." ;
+ sh:description "`DisclosureCheck` MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ;
sh:path schema:actionStatus ;
sh:in (
"http://schema.org/PotentialActionStatus"
@@ -95,5 +96,63 @@ five-safes-crate:DisclosureObjectHasActionStatus
"http://schema.org/FailedActionStatus"
) ;
sh:severity sh:Violation ;
- sh:message "The value of actionStatus MUST be one of the allowed values." ;
+ sh:message "`DisclosureCheck` MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ;
+ ] .
+
+
+five-safes-crate:DisclosureObjectHasCompliantStartTimeFormat
+ a sh:NodeShape ;
+ sh:name "DisclosureCheck" ;
+ sh:description "`DisclosureCheck` --> `startTime` MUST follow the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ;
+ sh:target [
+ a sh:SPARQLTarget ;
+ sh:select """
+ PREFIX schema:
+ PREFIX shp:
+
+ SELECT ?this
+ WHERE {
+ ?this schema:additionalType shp:DisclosureCheck ;
+ schema:startTime ?o
+ }
+ """ ;
+ ] ;
+
+ sh:property [
+ a sh:PropertyShape ;
+ sh:name "StartTime" ;
+ sh:path schema:startTime ;
+ sh:minCount 0 ;
+ sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ;
+ sh:severity sh:Violation ;
+ sh:message "`DisclosureCheck` --> `startTime` MUST follow the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ;
+ ] .
+
+
+five-safes-crate:DisclosureObjectHasCompliantEndTimeFormat
+ a sh:NodeShape ;
+ sh:name "DisclosureCheck" ;
+ sh:description "`DisclosureCheck` --> `endTime` MUST follow the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ;
+ sh:target [
+ a sh:SPARQLTarget ;
+ sh:select """
+ PREFIX schema:
+ PREFIX shp:
+
+ SELECT ?this
+ WHERE {
+ ?this schema:additionalType shp:DisclosureCheck ;
+ schema:endTime ?o
+ }
+ """ ;
+ ] ;
+
+ sh:property [
+ a sh:PropertyShape ;
+ sh:name "EndTime" ;
+ sh:path schema:endTime ;
+ sh:minCount 0 ;
+ sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ;
+ sh:severity sh:Violation ;
+ sh:message "`DisclosureCheck` --> `endTime` MUST follow the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ;
] .
diff --git a/rocrate_validator/profiles/five-safes-crate/should/8_disclosure_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/8_disclosure_phase.ttl
index a070de95..1d466251 100644
--- a/rocrate_validator/profiles/five-safes-crate/should/8_disclosure_phase.ttl
+++ b/rocrate_validator/profiles/five-safes-crate/should/8_disclosure_phase.ttl
@@ -32,7 +32,7 @@ five-safes-crate:RootDataEntityShouldMentionDisclosureObject
sh:sparql [
a sh:SPARQLConstraint ;
sh:name "mentions" ;
- sh:description "RootDataEntity SHOULD mention a disclosure object." ;
+ sh:description "`RootDataEntity` SHOULD mention a disclosure object." ;
sh:select """
PREFIX schema:
PREFIX shp:
@@ -46,14 +46,14 @@ five-safes-crate:RootDataEntityShouldMentionDisclosureObject
}
""" ;
sh:severity sh:Warning ;
- sh:message "RootDataEntity SHOULD mention a disclosure object." ;
+ sh:message "`RootDataEntity` SHOULD mention a disclosure object." ;
] .
five-safes-crate:DisclosureObjectHasActionStatus
a sh:NodeShape ;
sh:name "DisclosureCheck" ;
- sh:description "DisclosureCheck" ;
+ sh:description "The `DisclosureCheck` SHOULD have `actionStatus` property." ;
sh:target [
a sh:SPARQLTarget ;
@@ -71,11 +71,11 @@ five-safes-crate:DisclosureObjectHasActionStatus
sh:property [
a sh:PropertyShape ;
sh:name "ActionStatus" ;
- sh:description "The DisclosureCheck SHOULD have actionStatus property." ;
+ sh:description "The `DisclosureCheck` SHOULD have `actionStatus` property." ;
sh:path schema:actionStatus ;
sh:minCount 1 ;
sh:severity sh:Warning ;
- sh:message "The DisclosureCheck SHOULD have actionStatus property." ;
+ sh:message "The `DisclosureCheck` SHOULD have `actionStatus` property." ;
] .
@@ -108,8 +108,7 @@ five-safes-crate:DisclosureObjectHasEndTimeIfcompletedOrFailed
sh:path schema:endTime ;
sh:minCount 1 ;
sh:maxCount 1 ;
- sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ;
sh:severity sh:Warning ;
- sh:description "Disclosure object SHOULD have endTime property with a valid datetetime if action completed of failed." ;
- sh:message "Disclosure object SHOULD have endTime property with a valid datetime if action completed of failed." ;
+ sh:description "`DisclosureCheck` SHOULD have the `endTime` property if `actionStatus` is either CompletedActionStatus or FailedActionStatus." ;
+ sh:message "`DisclosureCheck` SHOULD have the `endTime` property if `actionStatus` is either CompletedActionStatus or FailedActionStatus." ;
] .
\ No newline at end of file
diff --git a/tests/integration/profiles/five-safes-crate/test_5src_8_disclosure_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_8_disclosure_phase.py
index 07fecf21..1d3310c8 100644
--- a/tests/integration/profiles/five-safes-crate/test_5src_8_disclosure_phase.py
+++ b/tests/integration/profiles/five-safes-crate/test_5src_8_disclosure_phase.py
@@ -16,7 +16,7 @@
from rocrate_validator.models import Severity
from tests.ro_crates import ValidROC
-from tests.shared import do_entity_test
+from tests.shared import do_entity_test, SPARQL_PREFIXES
# set up logging
logger = logging.getLogger(__name__)
@@ -26,10 +26,9 @@
def test_5src_disclosure_object_with_no_name():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
?this schema:name ?name .
}
@@ -39,23 +38,25 @@ def test_5src_disclosure_object_with_no_name():
<./> schema:mentions ?this .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ "`DisclosureCheck` MUST have a name string of at least 10 characters."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
def test_5src_disclosure_object_with_name_not_string():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
?this schema:name ?name .
}
@@ -68,28 +69,30 @@ def test_5src_disclosure_object_with_name_not_string():
<./> schema:mentions ?this .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ "`DisclosureCheck` MUST have a name string of at least 10 characters."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
def test_5src_disclosure_object_with_not_long_enough_name():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
?this schema:name ?name .
}
INSERT {
- ?this schema:name "Too short" .
+ ?this schema:name "Short" .
}
WHERE {
?this schema:additionalType shp:DisclosureCheck ;
@@ -97,26 +100,27 @@ def test_5src_disclosure_object_with_not_long_enough_name():
<./> schema:mentions ?this .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ "`DisclosureCheck` MUST have a name string of at least 10 characters."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
def test_5src_disclosure_object_not_an_assess_action():
- sparql = """
- PREFIX schema:
- PREFIX shp:
- PREFIX rdf:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- ?this rdf:type ?o .
+ ?this rdf:type schema:AssessAction .
}
INSERT {
?this rdf:type "Not an AssessAction type" .
@@ -126,173 +130,186 @@ def test_5src_disclosure_object_not_an_assess_action():
schema:additionalType shp:DisclosureCheck .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ "`DisclosureCheck` MUST be a `schema:AssessAction`."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
def test_5src_disclosure_object_with_no_proper_action_status():
- sparql = """
- PREFIX schema:
- PREFIX shp:
- PREFIX rdf:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- ?this schema:actionStatus ?o .
+ ?s schema:actionStatus ?o .
}
INSERT {
- ?this schema:actionStatus "This is not a proper actionStatus" .
+ ?s schema:actionStatus "This is not a proper actionStatus" .
}
WHERE {
- ?this schema:actionStatus ?o ;
- schema:additionalType shp:DisclosureCheck .
+ ?s schema:actionStatus ?o ;
+ schema:additionalType shp:DisclosureCheck .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ (
+ "`DisclosureCheck` MUST have an actionStatus with an allowed value "
+ "(see https://schema.org/ActionStatusType)."
+ )
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
-# ----- SHOULD fails tests
-
-
-def test_5src_disclosure_object_not_mentioned_by_root_data_entity():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+def test_5src_disclosure_object_has_no_properly_formatted_start_time():
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- <./> schema:mentions ?o .
+ ?s schema:startTime ?time .
+ }
+ INSERT {
+ ?s schema:startTime "1st Dec '25 @ 10:00:00" .
}
WHERE {
- ?o schema:additionalType shp:DisclosureCheck .
+ ?s schema:additionalType shp:DisclosureCheck ;
+ schema:startTime ?time .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
- requirement_severity=Severity.RECOMMENDED,
+ rocrate_path=ValidROC().five_safes_crate_result,
+ requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ (
+ "`DisclosureCheck` --> `startTime` MUST follow the RFC 3339 standard "
+ "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))."
+ )
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
-def test_5src_disclosure_object_with_no_action_status():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+def test_5src_disclosure_object_has_no_properly_formatted_end_time():
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- ?s schema:actionStatus ?o .
+ ?s schema:endTime ?time .
+ }
+ INSERT {
+ ?s schema:endTime "1st Dec '25 @ 10:00:00" .
}
WHERE {
- ?s schema:additionalType shp:DisclosureCheck .
+ ?s schema:additionalType shp:DisclosureCheck ;
+ schema:endTime ?time .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
- requirement_severity=Severity.RECOMMENDED,
+ rocrate_path=ValidROC().five_safes_crate_result,
+ requirement_severity=Severity.REQUIRED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ (
+ "`DisclosureCheck` --> `endTime` MUST follow the RFC 3339 standard "
+ "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))."
+ )
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
-def test_5src_disclosure_object_has_no_properly_formatted_start_time_if_begun():
- sparql = """
- PREFIX schema:
- PREFIX shp:
+# ----- SHOULD fails tests
+
+def test_5src_disclosure_object_not_mentioned_by_root_data_entity():
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- ?s schema:startTime ?o .
- }
- INSERT {
- ?s schema:startTime "1st Dec '25 @ 10:00:00" .
+ <./> schema:mentions ?o .
}
WHERE {
- ?s schema:additionalType shp:DisclosureCheck ;
- schema:actionStatus ?status .
- FILTER(?status IN (
- "http://schema.org/CompletedActionStatus",
- "http://schema.org/FailedActionStatus",
- "http://schema.org/ActiveActionStatus"
- ))
+ ?o schema:additionalType shp:DisclosureCheck .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.RECOMMENDED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["RootDataEntity"],
+ expected_triggered_issues=[
+ "`RootDataEntity` SHOULD mention a disclosure object."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
-def test_5src_disclosure_object_has_no_end_time_if_ended():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+def test_5src_disclosure_object_with_no_action_status():
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
- ?s schema:endTime ?o .
+ ?s schema:actionStatus ?o .
}
WHERE {
?s schema:additionalType shp:DisclosureCheck ;
- schema:actionStatus ?status .
- FILTER(?status IN (
- "http://schema.org/CompletedActionStatus",
- "http://schema.org/FailedActionStatus"
- ))
+ schema:actionStatus ?o .
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.RECOMMENDED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ "The `DisclosureCheck` SHOULD have `actionStatus` property."
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
-def test_5src_disclosure_object_has_no_properly_formatted_end_time_if_ended():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+def test_5src_disclosure_object_has_no_end_time_if_ended():
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
?s schema:endTime ?o .
}
- INSERT {
- ?s schema:endTime "1st Dec '25 @ 10:00:00" .
- }
WHERE {
?s schema:additionalType shp:DisclosureCheck ;
+ schema:endTime ?o ;
schema:actionStatus ?status .
FILTER(?status IN (
"http://schema.org/CompletedActionStatus",
@@ -300,13 +317,19 @@ def test_5src_disclosure_object_has_no_properly_formatted_end_time_if_ended():
))
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.RECOMMENDED,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ (
+ "`DisclosureCheck` SHOULD have the `endTime` property if `actionStatus` "
+ "is either CompletedActionStatus or FailedActionStatus."
+ )
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)
@@ -316,15 +339,15 @@ def test_5src_disclosure_object_has_no_properly_formatted_end_time_if_ended():
def test_5src_disclosure_object_has_no_start_time_if_begun():
- sparql = """
- PREFIX schema:
- PREFIX shp:
-
+ sparql = (
+ SPARQL_PREFIXES
+ + """
DELETE {
?s schema:startTime ?o .
}
WHERE {
?s schema:additionalType shp:DisclosureCheck ;
+ schema:startTime ?o ;
schema:actionStatus ?status .
FILTER(?status IN (
"http://schema.org/CompletedActionStatus",
@@ -333,13 +356,19 @@ def test_5src_disclosure_object_has_no_start_time_if_begun():
))
}
"""
+ )
do_entity_test(
- rocrate_path=ValidROC().five_safes_crate_request,
+ rocrate_path=ValidROC().five_safes_crate_result,
requirement_severity=Severity.OPTIONAL,
expected_validation_result=False,
- expected_triggered_requirements=None,
- expected_triggered_issues=None,
+ expected_triggered_requirements=["DisclosureCheck"],
+ expected_triggered_issues=[
+ (
+ "`DisclosureCheck` MAY have the `startTime` property if `actionStatus` "
+ "is either ActiveActionStatus, CompletedActionStatus or FailedActionStatus."
+ )
+ ],
profile_identifier="five-safes-crate",
rocrate_entity_mod_sparql=sparql,
)