Skip to content

Latest commit

 

History

History
271 lines (228 loc) · 12.6 KB

cli.md

File metadata and controls

271 lines (228 loc) · 12.6 KB

Command Line Interface

Persephone supports the persephone CLI command with two subcommands: validate and match, which performs Statement Template validation and Pattern matching, respectively.

To use the CLI, first run make bundle, then cd to target/bundle. You will then be able to run /bin/persephone.sh, which will accept a subcommand followed by arguments for Profiles, Statements, and so on. You can also provide the command with a --help or -h flag and it will list its subcommands.

Note that Profile and Statement arguments accept URIs, e.g. filepaths, not the JSON data itself. In addition, some arguments (e.g. --profile) may be repeated to allow the CLI to accept multiple arguments.

The validate subcommand validates a single Statement against Statement Templates in one or more Profiles. The following table shows its arguments:

Subcommand Argument Description
-p, --profile URI Profile URI filepath/location; must specify one or more.
-i, --template-id IRI IDs of Statement Templates to validate against; can specify zero or more. Filters out all Templates that are not included.
-s, --statement URI Statement filepath/location; must specify one.
-e, --extra-statements URI Extra Statement batch filepath/location; can specify zero or more. If specified, activates Statement Ref property validation, where the referred object/context Statement exists in this batch and its Template exists in a provided Profile.
-a, --all-valid If set, the Statement is not considered valid unless it is valid against ALL Templates. Otherwise, it only needs to be valid against at least one Template.
-c, --short-circuit If set, then print on only the first Template the Statement fails validation against.Otherwise, print for all Templates the Statement fails against.
-h, --help Display the help menu.

The match subcommand matches a Statement batch against Patterns in one or more Profiles. The following table shows its arguments:

Subcommand Argument Description
-p, --profile URI Profile filepath/location; must specify one or more.
-i, --pattern-id IRI IDs of primary Patterns to match against; can specify zero or more. Filters out all Patterns that are not included.
-s, --statement URI Statement filepath/location; must specify one or more.
-n, --compile-nfa If set, compiles the Patterns into a non-deterministic finite automaton (NFA) instead of a deterministic one, allowing for more detailed error traces at the cost of decreased performance.
-h, --help Display the help menu.

persephone validate examples

In the examples in this and the next section, assume that the test-resources/sample_profiles and test-resources/sample_statements directories were copied into target/bundle, i.e. the location where we run ./bin/persephone.

For our first example, we can validate the calibration_1.json Statement against the Statement Templates in the calibration.jsonld Profile:

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json

This will run, print nothing, and exit with code 0, indicating successful validation.

We can also add additional Profiles as so:

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --profile sample_profiles/catch.json \
  --statement sample_statements/calibration_1.json

and it will output the same result, as the Statement will still match against the calibration.jsonld Profile, even though it will fail validation against all Templates in the catch.json profile.

However, if we try to duplicate Templates, e.g. by putting in the same Profile twice:

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json

you will receive the following error:

ID error: Profile IDs are not unique

You would also receive a similar error if Template IDs are not unique.

To see an example of failed validation, set the --all-valid flag so that the Statement has to be valid against all Templates:

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --all-valid

This will run and print the following message to stdout before exiting with code 1:

----- Statement Validation Failure -----
Template ID:  https://xapinet.org/xapi/yet/calibration/v1/templates#activity-2
Statement ID: 00000000-4000-8000-0000-000000000000

Template Verb property was not matched.
 template Verb:
   https://xapinet.org/xapi/yet/calibration/v1/concepts#didnt
 statement Verb:
   https://xapinet.org/xapi/yet/calibration/v1/concepts#did

Template rule was not followed:
  {:any [\"https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-2\"],
   :location \"$.object.id\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-1

Template rule was not followed:
  {:any [\"Activity 2\"],
   :location \"$.object.definition.name.en-US\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   Activity 1

Template rule was not followed:
  {:any [\"The second Activity\"],
   :location \"$.object.definition.description.en-US\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   The first Activity

----- Statement Validation Failure -----
Template ID:  https://xapinet.org/xapi/yet/calibration/v1/templates#activity-3
Statement ID: 00000000-4000-8000-0000-000000000000

Template rule was not followed:
  {:any [\"https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-3\"],
   :location \"$.object.id\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   https://xapinet.org/xapi/yet/calibration/v1/concepts#activity-1

Template rule was not followed:
  {:any [\"Activity 3\"],
   :location \"$.object.definition.name.en-US\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   Activity 1

Template rule was not followed:
  {:any [\"The third Activity\"],
   :location \"$.object.definition.description.en-US\",
   :presence \"included\"}
 failed 'any' property: evaluated values must include some values given by 'any'
 statement values:
   The first Activity

-----------------------------
Total errors found: 7

If we set the --short-circuit flag along with --all-valid:

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --short-circuit --all-valid

then only validation failures for the first failing Template will appear.

We can use the --template-id argument to select which Templates the Statement is validated against.

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --template-id https://xapinet.org/xapi/yet/calibration/v1/templates#activity-2 \
  --template-id https://xapinet.org/xapi/yet/calibration/v1/templates#activity-3

This way, we pass to the CLI the two Templates the Statement is invalid against, so running this will result in the same validation failure output as in the previous example.

Note that if we set --template-id to the ID of a non-existent Template, such that no Templates would be validated against, e.g.

% ./bin/persephone.sh validate \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --template-id http://random-template.org

we get the following error message:

Compilation error: no Statement Templates to validate against

persephone match examples

We can match the Statement batch consisting of calibration_1.json and calibration_2.json against the Patterns in the calibration.jsonld Profile as so:

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --statement sample_statements/calibration_2.json

This will run, print nothing, and exit with code 0, indicating match success.

The --statement argument can also accept a Statement array file; in this example, calibration_coll.json is an array of the Statements in calibration_1.json and calibration_2.json, in that order.

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_coll.json

Individual Statements and Statement arrays can be mixed and matched when using --statement multiple times.

Note that the --profile flag can also be called multiple times to match against Patterns from multiple Profiles (this is important if Patterns in one Profile reference Patterns in another). Be mindful that if you have duplicate Profile or Pattern IDs you will receive an error.

However, if we were to match a Statement that was not intended to be matched with the Profile, for example:

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/adl_3.json

the CLI will print an error message to stdout indicating that the Statement does not refer to the profile version in its category context activity IDs:

----- Pattern Match Error -----
Error Description:  Missing Profile version in context category activity IDs
Statement ID:       6690e6c9-3ef0-4ed3-8b37-7f3964730bee

Category contextActivity IDs:
http://www.example.com/meetings/categories/teammeeting

Errors would also appear if the Statement included a sub-registration without a registration, or if the sub-registration did not conform to spec.

The order in which the Statements are passed to the match subcommand matters greatly. If we switch the order of our Statements from the first example, Pattern matching fails:

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_2.json \
  --statement sample_statements/calibration_1.json

and this message will be printed to stdout:

----- Pattern Match Failure -----
Primary Pattern ID: https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-1
Statement ID:       00000000-4000-8000-0000-000000000000

Pattern matching has failed.

If we set the --compile-nfa flag, then we can get a detailed trace of the Pattern matching path:

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_2.json \
  --statement sample_statements/calibration_1.json \
  --compile-nfa
----- Pattern Match Failure -----
Primary Pattern ID: https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-1
Statement ID:       00000000-4000-8000-0000-000000000000

Statement Templates visited:
  https://xapinet.org/xapi/yet/calibration/v1/templates#activity-2
Pattern path:
  https://xapinet.org/xapi/yet/calibration/v1/templates#activity-2
  https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-3
  https://xapinet.org/xapi/yet/calibration/v1/patterns#pattern-1

Note that similar to --template-id, we can use --pattern-id to filter out Patterns (note that these must be primary Patterns). If we set --pattern-id to a non-existent Pattern so that no Patterns are available to be matched:

% ./bin/persephone.sh match \
  --profile sample_profiles/calibration.jsonld \
  --statement sample_statements/calibration_1.json \
  --statement sample_statements/calibration_2.json \
  --pattern-id http://random-pattern.org

we will receive the following error message

Compilation error: no Patterns to match against, or one or more Profiles lacks Patterns

Docker

To use with Docker, pull the image yetanalytics/persephone:[tag] and execute the following:

docker run -v [filepath]:/persephone/[filepath] -it yetanalytics/persephone:docker /persephone/bin/persephone.sh <subcommand> <args>

The container will run and exit once the command completes. The -v command can be use to map filepaths for resources (e.g. Profiles and Statements) to the Docker working directory /persephone.

Note that if /persephone/bin/persephone.sh validate <args> is not provided, then the container will run persephone.sh --help by default.