Only Persephone, daughter of Zeus and wife of Hades, could travel between the Underworld and the world of the living. Project Persephone is the liaison between our physical world and the world of the Semantic Web.
A Clojure library for validating xAPI Statements against xAPI Profiles, featuring interactive CLI and webserver applications.
- Library: How to use the library/API functions
- CLI: How to run the
validate
andmatch
commands - Webserver: How to start up and run a webserver
Add the following to the :deps
map in your deps.edn
file:
com.yetanalytics/project-persephone {:mvn/version "0.9.1"}
Alternatively, to run the CLI or server as an application, you can pull a Docker image from DockerHub:
docker pull yetanalytics/persephone:latest
Persephone performs two main tasks on xAPI Statements: Statement Template validation and Pattern matching. The former checks if a Statement follows the specifications of one or more Statement Templates in xAPI Profiles, while the latter performs regex-like matching against Profile Patterns. Persephone does so following the validation and matching guidelines of the xAPI Profile specification.
For example, suppose that you have the following Statement:
{
"id": "00000000-4000-8000-0000-000000000000",
"timestamp": "2022-06-27T10:10:10.000Z",
"actor": {
"name": "My Name",
"mbox": "mailto:foo@example.org",
"objectType": "Agent"
},
"verb": {
"id": "https://xapinet.org/xapi/yet/calibration/v1/concepts#did",
"display": {"en-US": "Did"}
},
"object": {
"id": "https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-1",
"objectType": "Activity",
"definition": {
"name": {"en-US": "Activity 1"},
"description": {"en-US": "The first Activity"}
}
},
"context": {
"contextActivities": {
"category": [
{
"id": "https://xapinet.org/xapi/yet/calibration/v1",
"objectType": "Activity"
}
]
}
}
}
The Statement will match against the following Statement Template:
{
"id" : "https://xapinet.org/xapi/yet/calibration/v1/templates#activity-1",
"inScheme" : "https://xapinet.org/xapi/yet/calibration/v1",
"prefLabel" : {
"en" : "Activity Template 1"
},
"definition" : {
"en" : "The statement template and rules associated with Activity 1 getting done."
},
"type" : "StatementTemplate",
"verb" : "https://xapinet.org/xapi/yet/calibration/v1/concepts#did",
"rules" : [
{
"location" : "$.id",
"presence" : "included"
},
{
"location" : "$.timestamp",
"presence" : "included"
},
{
"any" : ["https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-1"],
"location" : "$.object.id",
"presence" : "included"
},
{
"any" : ["Activity 1"],
"location" : "$.object.definition.name.en-US",
"presence" : "included"
},
{
"any" : ["The first Activity"],
"location" : "$.object.definition.description.en-US",
"presence" : "included"
},
{
"any" : ["https://xapinet.org/xapi/yet/calibration/v1"],
"location" : "$.context.contextActivities.category[0].id",
"presence" : "included"
}
]
}
because the verb
in the Statement is the same as the verb
in the Statement Template, and because the Statement's id
, name
, description
, and category.id
property values are included in the values specified by the Template's rules, which are matched using the location
JSONPath strings.
Now suppose that the Statement is the first in a sequence of Statements. This Statement will match against the following Patterns:
{
"definition" : {
"en" : "Pattern 1"
},
"primary" : true,
"prefLabel" : {
"en" : "Learning Pattern 1"
},
"type" : "Pattern",
"inScheme" : "https://xapinet.org/xapi/yet/calibration/v1",
"id" : "https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-1",
"sequence" : [
"https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-2",
"https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-3"
]
},
{
"definition" : {
"en" : "Pattern 2"
},
"primary" : false,
"prefLabel" : {
"en" : "Learning Pattern 2"
},
"type" : "Pattern",
"inScheme" : "https://xapinet.org/xapi/yet/calibration/v1",
"id" : "https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-2",
"optional" : "https://xapinet.org/xapi/yet/calibration/v1/templates#activity-1"
}
since Pattern 1 (which is a primary Pattern, indicating that it is the starting point for Pattern matching) specifies a sequence of Patterns 2 and 3, and Pattern 2 indicates that the Statement can optionally match against the aforementioned Statement Template, which the Statement indeed does.
Copyright © 2019-2024 Yet Analytics, Inc.
Distributed under the Apache License version 2.0.
The Persephone logo is based off of Proserpine by Hiram Powers.