[{"data":1,"prerenderedAt":1005},["ShallowReactive",2],{"prezapi-search":3,"/prezapi/fuseki-fts":592,"prezapi-navigation":966},[4,10,16,22,27,32,37,42,47,52,56,61,66,71,76,81,86,91,96,101,106,111,116,121,126,131,136,141,146,151,156,161,165,170,175,180,185,190,195,200,205,210,214,219,224,230,235,239,244,249,254,259,264,269,274,279,284,289,294,299,304,309,314,319,324,329,334,338,343,348,353,358,363,368,373,378,383,388,393,398,403,408,413,418,423,428,433,438,442,447,452,457,462,467,471,476,481,486,491,496,501,506,511,516,521,526,530,533,538,543,548,553,558,563,567,572,577,582,587],{"id":5,"title":6,"titles":7,"content":8,"level":9},"/prezapi","PrezAPI",[],"The API for Prez Prez is a data-configurable Linked Data API framework that delivers profiles of Knowledge Graph data according to the Content Negotiation by Profile standard. Where's the UI?Prez delivers data only - usually RDF but could be GeoJSON, XML etc. - and it delivers a special form of RDF which includes labels for all objects and predicates Prez can find in its database.If you want a UI that can render Prez' labelled RDF as HTML and other fancy graphical widgets, see the PrezUI.",1,{"id":11,"title":12,"titles":13,"content":14,"level":15},"/prezapi#data-validation","Data Validation",[6],"For Prez to deliver data via its various subsystems, the data needs to conform to some minimum requirements: you can't, for instance, run VocPrez without any SKOS ConceptSchemes defined!",2,{"id":17,"title":18,"titles":19,"content":20,"level":21},"/prezapi#validation","Validation",[6,12],"All the profiles listed above provide validators that can be used with RDF data to test to see if it's valid. If it is, Prez will be just fine with it. The profiles' validators are all available from the profiles themselves (navigate to the listings of other profile resources via the specification links above) and they are also loaded into the KurrawongAI SHACL Validator online tool which you can use without downloading or installing anything: https://tools.kurrawong.ai/validate Look for the VocPrez Compounded and similar validators. The 'compounded' bit means that validator will validate data against all VocPrez and inherited requirements.",3,{"id":23,"title":24,"titles":25,"content":26,"level":15},"/prezapi#contact","Contact",[6],"NOTE: This open source tool is actively developed and supported by KurrawongAI, a small Australian Knowledge Graph company, developers at the University of Melbourne and by open source contributors too.To flag problems or raise questions, please create issues in the Issue Tracker or you can contact developers using their details below. Here are the lead developers: KurrawongAIhttps://kurrawong.ai David Habgooddavid@kurrawong.ai Nicholas Carnick@kurrawong.ai Edmond Chucedmond@kurrawong.ai University of Melbourne - PrezUI mainlyJamie Feissjamie.feiss@unimelb.edu.au",{"id":28,"title":29,"titles":30,"content":31,"level":15},"/prezapi#contributing","Contributing",[6],"We love contributions to this tool and encourage you to create Issues in this repository's Issue Tracker or to submit a Pull Requests!",{"id":33,"title":34,"titles":35,"content":36,"level":15},"/prezapi#license","License",[6],"This version of Prez and the contents of this repository are also available under the BSD-3-Clause License.",{"id":38,"title":39,"titles":40,"content":41,"level":9},"/prezapi/quickstart","Quickstart",[],"",{"id":43,"title":44,"titles":45,"content":46,"level":15},"/prezapi/quickstart#installation","Installation",[39],"To get a copy of Prez on your computer, run: git clone https://github.com/RDFLib/prez Prez is developed with Poetry, a Python packaging and dependency tool.\nPoetry presents all of Prez's dependencies (other Python packages) in the pyproject.toml file located in the project root directory. To install the Python dependencies run: poetry install Note: Poetry must be installed on the system. To check if you have Poetry installed run poetry --version. For tips on installing and managing specific dependency groups check the documentation.",{"id":48,"title":49,"titles":50,"content":51,"level":15},"/prezapi/quickstart#running-a-demonstration-instance","Running a demonstration instance",[39],"Docker Compose can be used to run a demonstration instance. The compose files comprises three services: Prez (PrezAPI), PrezUI, and Fuseki. To run the stack, change directory into the demo directory and run: docker compose up. The Fuseki instance is empty, but can have data added to it, such as the test data under test_data. html pre.shiki code .sCaUI, html code.shiki .sCaUI{--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .sXNWB, html code.shiki .sXNWB{--shiki-default:#A31515;--shiki-dark:#CE9178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":53,"title":54,"titles":55,"content":41,"level":9},"/prezapi/features","Features",[],{"id":57,"title":58,"titles":59,"content":60,"level":15},"/prezapi/features#redirect-service","Redirect Service",[54],"As a Linked Data server, Prez provides a redirect service at /identifier/redirect that accepts a query parameter iri, looks up the iri in the database for a foaf:homepage predicate with a value, and if it exists, return a redirect response to the value. This functionality is useful for institutions who issue their own persistent identifiers under a domain name that they control. The mapping from the persistent identifier to the target web resource is stored in the backend SPARQL store. This is an alternative solution to persistent identifier services such as the w3id.org. In some cases, it can be used together with such persistent identifier services to avoid the need to provide the redirect mapping in webserver config (NGINX, Apache HTTP, etc.) and instead, define the config as RDF data.",{"id":62,"title":63,"titles":64,"content":65,"level":9},"/prezapi/configuration/env","Environment Variables",[],"Configuring the API with environment variables The following Environment Variables can be used to configure Prez:\nIn most cases all that is required is the SPARQL_ENDPOINT variable. These can be set in a '.env' file which will get read in via python-dotenv.\nAlternatively, set them directly in the environment from which Prez is run. An example .env file with the minimum required variables is in the repo as .env-required-template, and an example .env file with all possible configuration variables, showing defaults, is in the repo as .env-full-template.",{"id":67,"title":68,"titles":69,"content":70,"level":15},"/prezapi/configuration/env#sparql-endpoint-configuration","SPARQL Endpoint Configuration",[63],"SPARQL_ENDPOINT: Read-only SPARQL endpoint for Prez. Default is None.SPARQL_USERNAME: A username for the Prez SPARQL endpoint, if required by the RDF DB. Default is None.SPARQL_PASSWORD: A password for the Prez SPARQL endpoint, if required by the RDF DB. Default is None.ENABLE_SPARQL_ENDPOINT: Whether to enable the SPARQL endpoint. I.e. whether prez exposes the remote repository's SPARQL endpoint (typically a triplestore). Default is False. NB the SPARQL endpoint when enabled supports POST requests. Prez itself does not make any updates to the remote repository (e.g. the remote Triplestore), however, if the remote SPARQL endpoint is enabled it is then possible that users can make updates to the remote repository using the SPARQL endpoint.",{"id":72,"title":73,"titles":74,"content":75,"level":15},"/prezapi/configuration/env#network-configuration","Network Configuration",[63],"PROTOCOL: The protocol used to deliver Prez. Default is \"http\".HOST: Prez's host domain name. Default is \"localhost\".PORT: The port Prez is made accessible on. Default is 8000.",{"id":77,"title":78,"titles":79,"content":80,"level":15},"/prezapi/configuration/env#system-uri","System URI",[63],"SYSTEM_URI: The URL where prez is deployed. This is utilised only by the OGC Features API to generate links. Non OGC Features endpoints provided by prez provide prez:link relative links and so do not use this SYSTEM_URI. Default is f\"{protocol}://{host}:{port}\".",{"id":82,"title":83,"titles":84,"content":85,"level":15},"/prezapi/configuration/env#logging-configuration","Logging Configuration",[63],"LOG_LEVEL: Logging level. Default is \"INFO\".LOG_OUTPUT: Logging output destination. Default is \"stdout\".",{"id":87,"title":88,"titles":89,"content":90,"level":15},"/prezapi/configuration/env#prez-metadata","Prez Metadata",[63],"PREZ_TITLE: Title for the Prez instance. Default is \"Prez\".PREZ_DESC: Description of the Prez instance. Default is a description of the Prez web framework API.PREZ_VERSION: Version of the Prez instance. Default is None.",{"id":92,"title":93,"titles":94,"content":95,"level":15},"/prezapi/configuration/env#curie-separator","CURIE Separator",[63],"CURIE_SEPARATOR: Separator used in CURIEs. Default is \":\". This separator appears in links generated by Prez, and in turn in URL paths.",{"id":97,"title":98,"titles":99,"content":100,"level":15},"/prezapi/configuration/env#predicate-configuration","Predicate Configuration",[63],"Used for displaying RDF with human readable labels. LABEL_PREDICATES: List of predicates used for labels. Default includes:\nskos:prefLabeldcterms:titlerdfs:labelsdo:name When an annotated (+anot) mediatype is used, Prez includes triples for every URI in the initial response which has one of the above properties. These annotation triples are then cached. The annotations are used for display purposes, for example HTML pages.",{"id":102,"title":103,"titles":104,"content":105,"level":21},"/prezapi/configuration/env#description-predicates","Description Predicates",[63,98],"Similar to label predicates above. DESCRIPTION_PREDICATES: List of predicates used for descriptions. Default includes:\nskos:definitiondcterms:descriptionsdo:description",{"id":107,"title":108,"titles":109,"content":110,"level":21},"/prezapi/configuration/env#provenance-predicates","Provenance Predicates",[63,98],"Similar to provenance predicates above. PROVENANCE_PREDICATES: List of predicates used for provenance. Default includes:\ndcterms:provenance",{"id":112,"title":113,"titles":114,"content":115,"level":21},"/prezapi/configuration/env#other-predicates","Other Predicates",[63,98],"The annotation mechanism can further be used to generally return certain properties wherever present. OTHER_PREDICATES: List of other predicates. Default includes:\nsdo:colorreg:statusskos:narrowerskos:broader",{"id":117,"title":118,"titles":119,"content":120,"level":15},"/prezapi/configuration/env#sparql-repository-configuration","SPARQL Repository Configuration",[63],"SPARQL_REPO_TYPE: Type of SPARQL repository. Default is \"remote\". Options are \"remote\", \"pyoxigraph\", and \"oxrdflib\"SPARQL_TIMEOUT: Timeout for SPARQL queries. Default is 30.",{"id":122,"title":123,"titles":124,"content":125,"level":15},"/prezapi/configuration/env#contact-information","Contact Information",[63],"PREZ_CONTACT: Contact information for Prez. Default is None.",{"id":127,"title":128,"titles":129,"content":130,"level":15},"/prezapi/configuration/env#prefix-generation","Prefix Generation",[63],"DISABLE_PREFIX_GENERATION: Whether to disable prefix generation. It is recommended to disable prefix generation for large data repositories, further, it is recommended to always specify prefixes in the prez/reference_data/prefixes/ directory. Default is False.",{"id":132,"title":133,"titles":134,"content":135,"level":15},"/prezapi/configuration/env#language-and-search-configuration","Language and Search Configuration",[63],"DEFAULT_LANGUAGE: Default language for Prez. Default is \"en\".DEFAULT_SEARCH_PREDICATES: Default search predicates. Default includes:\nrdfs:labelskos:prefLabelsdo:namedcterms:title",{"id":137,"title":138,"titles":139,"content":140,"level":15},"/prezapi/configuration/env#local-rdf-directory","Local RDF Directory",[63],"Used in conjunction with the Pyoxigraph repo. Specifies a directory (from the repository root) to load into the Pyoxigraph in memory data graph. Not used for other repository types. LOCAL_RDF_DIR: Directory for local RDF files. Default is \"rdf\".",{"id":142,"title":143,"titles":144,"content":145,"level":15},"/prezapi/configuration/env#endpoint-structure","Endpoint Structure",[63],"ENDPOINT_STRUCTURE: Default structure of the endpoints, used to generate links. Default is (\"catalogs\", \"collections\", \"items\").",{"id":147,"title":148,"titles":149,"content":150,"level":15},"/prezapi/configuration/env#system-endpoints","System Endpoints",[63],"SYSTEM_ENDPOINTS: List of system endpoints. Default includes:\nep:system/profile-listingep:system/profile-object",{"id":152,"title":153,"titles":154,"content":155,"level":15},"/prezapi/configuration/env#listing-and-search-configuration","Listing and Search Configuration",[63],"LISTING_COUNT_LIMIT: The maximum number of items to count for a listing endpoint. Counts greater than this limit will be returned as \">N\" where N is the limit. Default is 100.SEARCH_COUNT_LIMIT: The maximum number of items to return in a search result. Default is 10.",{"id":157,"title":158,"titles":159,"content":160,"level":15},"/prezapi/configuration/env#temporal-configuration","Temporal Configuration",[63],"TEMPORAL_PREDICATE: The predicate used for temporal properties. Default is sdo:temporal.",{"id":162,"title":163,"titles":164,"content":41,"level":9},"/prezapi/configuration/cql","CQL",[],{"id":166,"title":167,"titles":168,"content":169,"level":9},"/prezapi/configuration/endpoints","Custom Endpoints",[],"Prez allows the configuration of custom endpoints. That is, you can specify the route structure e.g. /catalogs/{catalogId}/products/{productId} And then specify which classes these endpoints deliver, and what the RDF relations between those classes are.",{"id":171,"title":172,"titles":173,"content":174,"level":15},"/prezapi/configuration/endpoints#examples","Examples",[167],"For a fully worked example of a custom endpoint definition see the examples and\nof course the default endpoint definitions",{"id":176,"title":177,"titles":178,"content":179,"level":15},"/prezapi/configuration/endpoints#creating-custom-endpoint-definitions","Creating custom endpoint definitions",[167],"Firstly, refer to the examples above, to get an idea of what an endpoint definition file\nlooks like. In particular this one The definitions are just RDF so can be stored in any RDF serialisation format.\nThey can be written by hand, and there is also a UI to create them via a form. The form is sufficient for the simple case, but for more advanced definitions you may\nprefer to write them by hand. To access the form: Set the CONFIGURATION_MODE environment variable to \"true\"Start PrezGo to the /configure-endpoints page and complete the formSave your workturn off CONFIGURATION_MODE Once you have a custom endpoint definition file refer to the next section to see how to\ntell Prez to use it.",{"id":181,"title":182,"titles":183,"content":184,"level":15},"/prezapi/configuration/endpoints#using-custom-endpoint-definitions","using Custom Endpoint definitions",[167],"Custom endpoints are defined in RDF. Prez detects them in a specific location in the codebase (useful for development, where the Prez git repo has been cloned), or can retrieve them from a remote repository (useful for production, or when using the docker image). To set up Prez to read custom endpoints using the first method, where the Prez repo has been cloned: Set the CUSTOM_ENDPOINTS environment variable to \"true\"Copy your endpoint definition file to prez/reference_data/endpoints/custom_endpoints/Start / restart Prez. You should see the dynamic endpoints being created in the logs. To set up Prez to read custom endpoints from a repository (typically a SPARQL endpoint, but can also be Pyoxigraph reading from a local directory): Set the CUSTOM_ENDPOINTS environment variable to \"true\"upload your endpoint definition file to the triplestore into the \u003Chttps://prez.dev/SystemGraph> named graph. The endpoints must be of type https://prez.dev/ont/OGCFeaturesEndpoint or ont:DynamicEndpoint, AND also a https://prez.dev/ont/ListingEndpoint or https://prez.dev/ont/ObjectEndpoint.Start / restart Prez. You should see the dynamic endpoints being created in the logs.",{"id":186,"title":187,"titles":188,"content":189,"level":15},"/prezapi/configuration/endpoints#limitations","Limitations",[167],"The following limitations apply at present: The endpoint structure must be specified in the config to match what is input through the form.\nrelated to this:Only one route can be specified (though multiple class hierarchies which use that one route can be specified)\ni.e. you can specify\n/catalogs/{catalogId}/products/{productId}\nbut not\n/catalogs/{catalogId}/products/{productId}\nand\n`/datasets/{datasetId}/items/{itemsId}\non the one prez instance.This limitation is only due to link generation, which looks up the (currently) single endpoint structure variable in the config file.This should be resolvable with a small amount of work. At link generation time, an endpoint nodeshape is in context, and endpoint nodeshapes are mapped to a route structure.The number of hierarchy levels within a route must be two or three (i.e. 2 or 3 levels of classes = 4-6 listing/object endpoints)The lower limit of two is because prez uses the relationships between classes to identify which objects to list. A single level of hierarchy has no reference to another level. A small amount of dev work would resolve this. The endpoint nodeshapes can be specified in the case of N=1 to not look for relationships to other classes.The higher limit of three is because the SHACL parsing is not completely recursive. It could be manually extended to N levels, however it would be better to write a general SHACL parsing library.",{"id":191,"title":192,"titles":193,"content":194,"level":9},"/prezapi/configuration/facets","Faceted Search",[],"Prez supports faceted search on all listing and object endpoints: Listing endpoints:/cql/search\nall endpoints declared a prez:ListingEndpoint. With default settings this includes /catalogs /catalogs/{catalogId}/collections etc. Object endpoints:\nFaceted search can also be performed on all object endpoints (prez:ObjectEndpoint) by providing the focus node IRI directly. In this case, no subselect is performed and faceting works the same way for the properties of the single object. Note: At this point faceting is only supported for categorical properties (though faceting will correctly produce / execute queries on properties with continuous values the output is probably not desirable). Faceting profiles use a subset of predicates as regular prez profiles, as such, regular prez profiles can be reused for faceting. It is recommended not to do this, but instead define separate faceting profiles which only define the properties to be faceted on, and make the profiles easier to read by not including the properties not needed for faceting. The following must be included in the faceting profile: A property path on a sh:NodeShape which includes a sh:union clause with one or more properties to facet on.\nThe properties must be either:\nSHACL predicate paths (i.e. direct properties, not sequence, inverse paths etc.); orComplex property paths (sequence, inverse etc.) can utilise shext:pathAlias. Note to use path aliases in general you must set the USE_PATH_ALIASES environment variable to true;The properties must currently be nested under a sh:union clause.The profile must be declared both a prof:Profile and prez:ListingProfileIt must declare a dcterms:title, dcterms:identifier and dcterms:description. Faceted search is an opt in feature that is only run when the facet_profile query string argument is supplied. The facet profile URI, curie, or DCTERMS identifier of the profile (with or without datatype xsd:token) can be supplied to identify the facet profile to use. A minimal facet profile demonstrating both a direct property to facet on and one with a path alias is shown below: \u003Chttps://prez.dev/profile/facet-by-type>\n    a prof:Profile , prez:ListingProfile ;\n    dcterms:identifier \"facet-type\"^^xsd:token ;\n    dcterms:title \"Facet things by type and material\" ;\n    dcterms:description \"Allows faceting by rdf:type and sdo:material\" ;\n    sh:property [ \n        sh:path [ \n            sh:union (\n                         rdf:type \n                         \u003Chttps://schema.org/material>\n                     )\n                ]\n                ] . The generated facet queries are of the form: CONSTRUCT {\n  [\n      \u003Chttps://prez.dev/facetName> ?facetName;\n      \u003Chttps://prez.dev/facetValue> ?facetValue;\n      \u003Chttps://prez.dev/facetCount> ?facetCount\n  ] \n}\nWHERE {\n  SELECT ?facetName ?facetValue (COUNT(?focus_node) AS ?facetCount)\n  WHERE {\n    {\n        # for listing, CQL, and search, a subselect is included\n      SELECT DISTINCT ?focus_node\n      WHERE {\n        ?focus_node \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type> \u003Chttps://linked.data.gov.au/def/borehole/Borehole> .\n        ?focus_node \u003Chttp://www.w3.org/ns/dcat#resource>|^\u003Chttp://www.w3.org/ns/sosa/isSampleOf> ?path_node_1 .\n        ?path_node_1 \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?path_node_classes_1\n        VALUES ?path_node_classes_1{ \u003Chttps://schema.org/Report> \u003Chttp://www.w3.org/ns/sosa/Sample> \u003Chttps://www.gswa.com/WellLog> \u003Chttps://www.gswa.com/Observation> \u003Chttps://schema.org/ImageObject> \u003Chttps://www.gswa.com/LoggingRun>  }\n      }\n    }\n    {\n      ?focus_node \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?prof_1_node_1\n      BIND(\u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type> AS ?facetName)\n      BIND(?prof_1_node_1 AS ?facetValue)\n    }\n    UNION\n    {\n      ?focus_node \u003Chttps://schema.org/material> ?prof_1_node_2\n      BIND(\u003Chttps://schema.org/material> AS ?facetName)\n      BIND(?prof_1_node_2 AS ?facetValue)\n    }\n  }GROUP BY ?facetName ?facetValue\n}",{"id":196,"title":197,"titles":198,"content":199,"level":15},"/prezapi/configuration/facets#open-faceting","Open Faceting",[192],"Open faceting is allowed, meaning you can perform faceted search without providing a search term by using only the facet_profile parameter: /search?facet_profile=xyz When no search term is provided, Prez automatically injects a ?focus_node a ?type triple in the subselect query. This ensures that only instances of classes are faceted on, rather than attempting to facet across all nodes in the dataset. Performance Considerations: Open faceting works well for smaller datasets, but performance can become an issue with larger datasets since it needs to process all class instances without any filtering constraints. For larger datasets, it is recommended to: Perform a search first to narrow the result setAdd additional filters or search terms to reduce the scope (using parameters: filter, bbox, datetime, q)Use a separate full text search/faceting implementation designed for large-scale operations such as open search or lucene html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":201,"title":202,"titles":203,"content":204,"level":9},"/prezapi/configuration/profiles","Custom Profiles",[],"How to define and use your own profiles",{"id":206,"title":207,"titles":208,"content":209,"level":9},"/prezapi/configuration/queryables","Custom Queryables",[],"How to define and use your own queryables",{"id":211,"title":212,"titles":213,"content":41,"level":9},"/prezapi/deployment","Deployment",[],{"id":215,"title":216,"titles":217,"content":218,"level":15},"/prezapi/deployment#running","Running",[212],"This section is for developing Prez locally. See the Running options below for running Prez in production. To run the development server (with auto-reload on code changes): poetry run python main.py",{"id":220,"title":221,"titles":222,"content":223,"level":21},"/prezapi/deployment#running-in-a-container","Running in a Container",[212,216],"Prez container images are built using a GitHub Action and are available here. The Dockerfile in the repository can also be used to build a Docker image.",{"id":225,"title":226,"titles":227,"content":228,"level":229},"/prezapi/deployment#image-variants","Image variants",[212,216,221],"The image name is ghcr.io/rdflib/prez. The latest tag points to the latest stable release of Prez. All latest stable releases have a major, major.minor, and major.minor.patch tag pointing to it. For example, for a release with a git tag of 3.2.4, the following tags will be on the container image: 33.23.2.4latest The full version is automatically created/incremented using the Semantic Release GitHub Action, which automatically increments the version based on commits to the main\nbranch. html pre.shiki code .sCaUI, html code.shiki .sCaUI{--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .sXNWB, html code.shiki .sXNWB{--shiki-default:#A31515;--shiki-dark:#CE9178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",4,{"id":231,"title":232,"titles":233,"content":234,"level":9},"/prezapi/development","Development",[],"This documentation is to assist developers of Prez, not users or installers.",{"id":236,"title":29,"titles":237,"content":238,"level":15},"/prezapi/development#contributing",[232],"Prez is open source software, and contributions are welcome.",{"id":240,"title":241,"titles":242,"content":243,"level":21},"/prezapi/development#testing","Testing",[232,29],"Prez uses PyTest and Coverage for testing and test coverage reports. To run all available tests: poetry run pytest tests To run all available tests for coverage analysis: poetry run coverage run -m pytest tests To generate a coverage report: poetry run coverage report",{"id":245,"title":246,"titles":247,"content":248,"level":21},"/prezapi/development#pre-commit-hooks","Pre-Commit Hooks",[232,29],"To ensure that the below commit messaging and linting rules are enforced, you need to\ninstall pre-commit and then install the hooks for this repository pre-commit install --hook-type pre-commit\npre-commit install --hook-type commit-msg",{"id":250,"title":251,"titles":252,"content":253,"level":21},"/prezapi/development#commit-messaging-and-semantic-versioning","Commit Messaging and Semantic Versioning",[232,29],"Use of Conventional Commits is enforced via\npre-commit hooks. This helps the maintainers\nto keep the commit hisotry clean and to automate the release of new versions. In short: fix: and perf: commits will automatically trigger a new patch version i.e. 0.0.1 --> 0.0.2feat: commits will automatically trigger a new minor version i.e. 0.0.1 --> 0.1.0, andcommits with a BREAKING CHANGE: message will cause a new major version i.e. 0.0.1 --> 1.0.0 These rules are as per the default settings for python semantic release.",{"id":255,"title":256,"titles":257,"content":258,"level":21},"/prezapi/development#formatting-and-linting","Formatting and Linting",[232,29],"To keep the codebase consistent, pre-commit hooks are used to enforce formatting and\nlinting standards. The following tools are run before a commit: tooldescriptionruffcheck for syntax and logical errorsblackapply consistent formattingisortimport sorting",{"id":260,"title":261,"titles":262,"content":263,"level":15},"/prezapi/development#profiles","Profiles",[232],"SHACL NodeShapes and PropertyShapes are utilised to determine which properties of Focus Nodes should be rendered.",{"id":265,"title":266,"titles":267,"content":268,"level":21},"/prezapi/development#general-profile-specification","General profile specification",[232,261],"Each Profile must have the following properties: A prof:Profile typeA type of either prez:ObjectProfile (for rendering objects) or prez:ListingProfile (for rendering lists of objects), or both.A title, identifier (with datatype xsd:token), and description, using the DCTERMS namespace.",{"id":270,"title":271,"titles":272,"content":273,"level":21},"/prezapi/development#specification-of-mediatypes-and-resource-formats","Specification of Mediatypes and Resource Formats",[232,261],"Extensions to SHACL are used to specify the mediatypes and resource formats available for a given profile. These are specified as follows. The namespace used is http://www.w3.org/ns/dx/connegp/altr-ext#, and the prefix used for this namespace is altr-ext.",{"id":275,"title":276,"titles":277,"content":278,"level":229},"/prezapi/development#resource-formats","Resource formats",[232,261,271],"The default resource format for a profile can be set with altr-ext:hasDefaultResourceFormat.\nFor example: prez:OGCSchemesObjectProfile\n    a prof:Profile , prez:ObjectProfile , sh:NodeShape ;\n    altr-ext:hasDefaultResourceFormat \"text/turtle\" ;\n. The available resource formats for a profile can be set with altr-ext:hasResourceFormat.\nFor example: prez:OGCSchemesObjectProfile\n    a prof:Profile , prez:ObjectProfile , sh:NodeShape ;\n    altr-ext:hasResourceFormat \"text/turtle\" , \"application/ld+json\" ;",{"id":280,"title":281,"titles":282,"content":283,"level":229},"/prezapi/development#classes-for-a-profile","Classes for a Profile",[232,261,271],"The classes of object which a profile constrains can be specified with altr-ext:constrainsClass.\nPrez utilises this information when determining whether a requested profile can be used; and the alternate profiles that are available to render a resource. An example is given below: prez:OGCSchemesObjectProfile\n    a prof:Profile , prez:ObjectProfile , sh:NodeShape ;\n    altr-ext:constrainsClass dcat:Catalog ;\n.",{"id":285,"title":286,"titles":287,"content":288,"level":21},"/prezapi/development#default-profiles","Default profiles",[232,261],"A default profile can be specified using the altr-ext:hasNodeShape and altr-ext:hasDefaultProfile predicates. This is typically done on an \"umbrella\" profile which indicates default profiles for all classes the API can render. An example is given below: prez:OGCRecordsProfile\n    a prof:Profile ;\n    dcterms:identifier \"ogc\"^^xsd:token ;\n    dcterms:description \"A system profile for OGC Records conformant API\" ;\n    dcterms:title \"OGC Profile\" ;\n    altr-ext:constrainsClass prez:CatPrez ;\n    altr-ext:hasDefaultResourceFormat \"text/anot+turtle\" ;\n    altr-ext:hasNodeShape [\n        a sh:NodeShape ;\n        sh:targetClass prof:Profile , dcat:Catalog , dcat:Resource , skos:Concept , geo:Feature , geo:FeatureCollection\n                               , skos:Collection , rdf:Resource , prez:SearchResult , prez:CQLFilterResult ;\n        altr-ext:hasDefaultProfile prez:OGCListingProfile\n    ] , [\n        a sh:NodeShape ;\n        sh:targetClass skos:ConceptScheme ;\n        altr-ext:hasDefaultProfile prez:OGCSchemesListProfile\n    ] , [\n        a sh:NodeShape ;\n        sh:targetClass skos:ConceptScheme ;\n        altr-ext:hasDefaultProfile prez:OGCSchemesObjectProfile\n    ] , [\n        a sh:NodeShape ;\n        sh:targetClass prof:Profile , dcat:Catalog , dcat:Resource , skos:Concept , geo:Feature , geo:FeatureCollection\n                               , skos:Collection , rdf:Resource ;\n        altr-ext:hasDefaultProfile prez:OGCItemProfile\n    ]\n    . Note the target classes are shared across both listings of items, and items themselves; the API determines whether a listing or object profile is appropriate based on the endpoint a request is received at.",{"id":290,"title":291,"titles":292,"content":293,"level":229},"/prezapi/development#direct-paths","Direct Paths",[232,261,286],"Direct properties of a focus node are specified via sh:path.\nExample: sh:property [\n    sh:path prov:qualifiedDerivation\n    ] A convenience predicate is provided to specify the inclusion of all predicates, shext:allPredicateValues.\nExample: sh:property [\n    sh:path shext:allPredicateValues ;\n    ]",{"id":295,"title":296,"titles":297,"content":298,"level":229},"/prezapi/development#sequence-paths","Sequence Paths",[232,261,286],"Sequence paths are specified as property shapes with a path representing the linked list of properties from a focus node. sh:property [\n    sh:path ( prov:qualifiedDerivation prov:hadRole )\n    ]",{"id":300,"title":301,"titles":302,"content":303,"level":229},"/prezapi/development#inverse-paths","Inverse Paths",[232,261,286],"Inverse paths are specified on a nested blank node where the first property is sh:inversePath. sh:property [\n    sh:path [ sh:inversePath dcterms:hasPart ] ;\n    ]",{"id":305,"title":306,"titles":307,"content":308,"level":229},"/prezapi/development#combinations-of-paths","Combinations of paths",[232,261,286],"Multiple paths can be specified at once using sh:union. sh:property [\n    sh:path (\n        sh:union (\n          dcterms:publisher\n          reg:status\n          ( prov:qualifiedDerivation prov:hadRole )\n          ( prov:qualifiedDerivation prov:entity )\n        )\n      )\n    ]",{"id":310,"title":311,"titles":312,"content":313,"level":21},"/prezapi/development#excluded-and-optional-paths","Excluded and Optional paths.",[232,261],"The above property paths when specified without a min or max count must be present for a focus node to be returned. That is, by default, specified paths must be present for the focus node and properties to be returned.\nThe following constructs can be used to specify excluded or optional properties.",{"id":315,"title":316,"titles":317,"content":318,"level":229},"/prezapi/development#exclude","Exclude",[232,261,311],"Specification: sh:maxCount 0\nInterpretation: do not include these paths from the focus node, even if they exist in the data.\nExample: sh:property [\n    sh:maxCount 0 ;\n    sh:path dcterms:hasPart\n    ]",{"id":320,"title":321,"titles":322,"content":323,"level":229},"/prezapi/development#optional","Optional",[232,261,311],"Specification: sh:minCount 0\nInterpretation: include these paths from the focus node if they exist.\nExample: sh:property [\n    sh:minCount 0 ;\n    sh:path dcterms:hasPart\n    ]",{"id":325,"title":326,"titles":327,"content":328,"level":21},"/prezapi/development#blank-nodes","Blank Nodes",[232,261],"A convenience predicate is provided to specify the inclusion of blank nodes to a given depth, shext:bnode-depth. Note this is specified directly on the profile and not on a property shape as it does not relate to any particular property shape.\nSpecification: shext:bnode-depth\nExample: prez:OGCSchemesObjectProfile\n    a prof:Profile , prez:ObjectProfile , sh:NodeShape ;\n    shext:bnode-depth 2 ;",{"id":330,"title":331,"titles":332,"content":333,"level":21},"/prezapi/development#profile-and-mediatype-selection-logic","Profile and mediatype selection logic",[232,261],"The following logic is used to determine the profile and mediatype to be returned: If a profile and mediatype are requested, they are returned if a matching profile which has the requested mediatype is found, otherwise the default profile for the most specific class is returned, with its default mediatype.If a profile only is requested, if it can be found it is returned, otherwise the default profile for the most specific class is returned. In both cases the default mediatype is returned.If a mediatype only is requested, the default profile for the most specific class is returned, and if the requested mediatype is available for that profile, it is returned, otherwise the default mediatype for that profile is returned.If neither a profile nor mediatype is requested, the default profile for the most specific class is returned, with the default mediatype for that profile.",{"id":335,"title":336,"titles":337,"content":41,"level":15},"/prezapi/development#focus-node-selection","Focus Node Selection",[232],{"id":339,"title":340,"titles":341,"content":342,"level":21},"/prezapi/development#high-level-summary","High level summary",[232,336],"For object endpoints, the (single) focus node is specified at runtime, either as a URL path parameter or query string argument. For listing endpoints, the following inputs are used to determine which nodes to select: Endpoint - an endpoint is mapped to one or more endpoint SHACL NodeShapes.CQL JSON - only used as filter, i.e. filters on specified predicates.Search term - filters the label properties of focus nodes to a given search term. Currently a REGEX search is supported. All listing endpoints support these inputs. The inputs are transformed into the SPARQL Grammar, merged together, and combined with SPARQL Grammar for profiles to create a single query. Profiles specify the inclusion/exclusion of properties on focus nodes, and are detailed in \"Profile Design\".",{"id":344,"title":345,"titles":346,"content":347,"level":21},"/prezapi/development#detail","Detail",[232,336],"Determine which nodes to select.\nThis forms the inner select part of the SPARQL query. The inputs are one or more of: the URL path a query is sent to; a CQL filter expression; and a search term. The outputs are three sets of SPARQL Grammar objects TriplesSameSubject, TriplesSameSubjectPath, and GraphPatternNotTriples. The TriplesSameSubject are used to form the ConstructTriples part of the query; the TriplesSameSubjectPath, and GraphPatternNotTriples form the WhereClause.",{"id":349,"title":350,"titles":351,"content":352,"level":229},"/prezapi/development#_1-endpoint-nodeshapes","1. Endpoint Nodeshapes:",[232,336,345],"Considerations: Class of objects to list (e.g. for /catalogs, list all items of class dcat:Catalog)Relationship to parent objects (e.g. for /catalogs/{parent_catalog_curie}/collections/, list all items that have the relationship dcterms:hasPart from the parent catalog curie)\nImplementation:\nSHACL shapes are used to represent the how URL path parameters are translated into a SPARQL query.\nOne endpoint maps to one or more endpoint NodeShapes. For example the items endpoint can render resources of type skos:Concept and geo:Feature. An example of an endpoint definition is: ogce:item-object\n    a ont:ObjectEndpoint ;\n    ont:relevantShapes ex:Feature , ex:ConceptSchemeConcept , ex:CollectionConcept , ex:Resource ;\n. To determine which NodeShape (under ont:relevantShapes) should be used to render resources, the class of parents in the URL path is first determined. The logic for this is: 1. Get the classes of all parents in the URL path. Prez caches this class information. 2. Match these to sh:class statements on the PropertyShapes for the NodeShape. sh:class is used on nested PropertyShapes to specify a constraint on the class of related nodes, that is, nodes related via the property shape. (e.g. \"the class of the first parent is dcat:Resource, the class of the second parent is dcat:Catalog, therefore the applicable NodeShape for the listing is the ex:Resource NodeShape.)\nThe NodeShape information, once determined, is used for: 1. Query generation - which class of nodes to list (e.g. rdf:Resource below) 2. Link generation - to determine which endpoints can render a resource of a given class, and, how to find the parents of a given object in order to generate a link (e.g. the parents are all related via dcterms:hasPart in the example below.)\nAn example NodeShapes for describing an endpoint is: ex:Resource\n    a sh:NodeShape ;\n    ont:hierarchyLevel 3 ;\n    sh:targetClass rdf:Resource ;\n    sh:property [\n        sh:path [ sh:inversePath dcterms:hasPart ] ;\n        sh:class dcat:Resource ;\n    ] , [\n        sh:path ( [ sh:inversePath dcterms:hasPart ] [ sh:inversePath dcterms:hasPart ] );\n        sh:class dcat:Catalog ;\n    ] . The hierarchyLevel is used to filter the set of potentially relevant NodeShapes - when a request comes from an endpoint, that endpoint has a corresponding hierarchy level. A further example for the collections endpoint is provided: ex:Collections\n    a sh:NodeShape ;\n    ont:hierarchyLevel 2 ;\n    sh:targetClass geo:FeatureCollection , skos:ConceptScheme , skos:Collection , dcat:Resource ;\n    sh:property [\n        sh:path [ sh:inversePath dcterms:hasPart ] ;\n        sh:class dcat:Catalog ;\n    ] . This means to select the nodes of class dcat:Resource, geo:FeatureCollection, skos:ConceptScheme, or skos:Collection, which are related to a parent node of class dcat:Catalog, by the relationship dcterms:hasPart.",{"id":354,"title":355,"titles":356,"content":357,"level":229},"/prezapi/development#_2-cql","2. CQL",[232,336,345],"Considerations: Mapping of JSON values to URIs.Filtering of properties vs. graph pattern matching; the latter supports more complex operations (sequence, inverse paths etc.).\nImplementation:\nCQL JSON expressions are translated to JSON LD to allow easy mapping to URIs.\nExamples are provided in the API docs using test data. A demo instance is available here.\nCQL JSON documentation is available here: Properties are assumed to be URIs.\nValues for properties can be specified as URIs using a JSON LD like \"@id\", for example: {\n  \"op\": \"=\",\n  \"args\": [\n    {\n      \"property\": \"http://www.w3.org/2000/01/rdf-schema#member\"\n    },\n    { \"@id\": \"http://example.com/datasets/sandgate/facilities\" }\n  ]\n} The following context is \"inserted\" into CQL JSON to create \"CQL JSON-LD\". {\n  \"@version\": 1.1,\n  \"@base\": \"http://example.com/\",\n  \"@vocab\": \"http://example.com/vocab/\",\n  \"cql\": \"http://www.opengis.net/doc/IS/cql2/1.0/\",\n  \"sf\": \"http://www.opengis.net/ont/sf#\",\n  \"geo\": \"http://www.opengis.net/ont/geosparql#\",\n  \"landsat\": \"http://example.com/landsat/\",\n  \"ro\": \"http://example.com/ro/\",\n  \"args\": {\n    \"@container\": \"@set\",\n    \"@id\": \"cql:args\"\n  },\n  \"property\": {\n    \"@type\": \"@id\",\n    \"@id\": \"cql:property\"\n  },\n  \"op\": {\n    \"@id\": \"cql:operator\"\n  },\n  \"type\": {\n    \"@id\": \"sf:type\"\n  }\n} The following has been implemented: Spatial functionsString pattern matchingProperty filtering The following has not yet been implemented: Time filtering",{"id":359,"title":360,"titles":361,"content":362,"level":229},"/prezapi/development#_3-search-query","3. Search query.",[232,336,345],"Implementation:\nThe search term is inserted into three different regex expressions which match the search term in different ways, and weights the results. A full search query is generated, and then relevant parts are extracted (TriplesSameSubject etc. as listed above), to generate a final query. Prez utilises the sparql-grammar-pydantic library to generate SPARQL queries.",{"id":364,"title":365,"titles":366,"content":367,"level":15},"/prezapi/development#content-delivered-by-prez","Content delivered by Prez",[232],"Prez returns: RDF data for specified objectsRDF data for lists of objectsAnnotated RDF* for specified objectsAnnotated RDF* for lists of objectsAvailable ProfilesAn alternates profile for every object or listing, listing all available profiles and mediatypesOpenAPI documentation for the API * Annotated RDF is RDF which includes labels, descriptions, explanatory, and other properties for all RDF terms. The predicates Prez looks for are rdfs:label, dcterms:description, and dcterms:provenance. The list of predicates Prez looks for can be extended in the profiles.",{"id":369,"title":370,"titles":371,"content":372,"level":15},"/prezapi/development#internal-links","Internal links",[232],"The objects Prez delivers RDF for have URIs that uniquely identify them. Prez delivers RDF for these objects at URLs on the web. These URLs and URIs are not required to be the same, and frequently are not. For objects that Prez holds information for, it is helpful if Prez tells users the URL of these when they are referenced elsewhere in the API. This is in two places: Listings of objects, for example dcat:Catalog at the /catalogs endpoint; andLinks to related objects, where the API holds information on the related object.\nIn these cases, in the annotated RDF mediatype (text/anot+turtle) URL paths are provided which link to the related object. For cases where URIs and URLs for a given object differ, URL redirection can be used to send users to the Prez URL instance which displays information for the object.",{"id":374,"title":375,"titles":376,"content":377,"level":21},"/prezapi/development#link-generation","Link generation",[232,370],"Internal links use CURIEs. Prez uses the default RDFLib prefixes, covering common namespaces.\nAdditional prefixes can be specified using the Vann ontology property \"vann:preferredNamespacePrefix\". These can be added to turtle files in the prez/reference_data/prefixes directory.\nAny turtle files in this directory will be loaded on startup. When Prez encounters a URI which is required for an internal link but is not in the current known prefixes, it will generate a prefix using the following logic: Get the \"second to last part\" of the URI; either the part before a fragment if it exists, or the second to last path segment otherwise.If this second to last part is less than six characters, use it as is, else:Remove vowels from the second to last part and use this as the prefix.If this prefix fails to bind for any reason, use RDFLib's default \"ns1\", \"ns2\" etc. prefixes. To get \"sensible\" or \"nice\" prefixes, it is recommended to add all prefixes which will be required to turtle files in prez/reference_data/prefixes.\nA future change could allow the prefixes to be specified alongside data in the backend, as profiles currently can be.",{"id":379,"title":380,"titles":381,"content":382,"level":15},"/prezapi/development#generating-prefixes","Generating Prefixes",[232],"The following SPARQL query can be used as a starting point to check if a namespace prefix is defined for instances of\nthe main classes prez delivers. NB this query should NOT be run against SPARQL endpoints for large datasets; offline\noptions should instead be used.\nNB. for \"short\" URIs, i.e. a hostname with no fragments and a \"no\" path, this query will (correctly, but uselessly)\nreturn \"http://\" or \"https://\". You will need to otherwise identify what these URIs are and provide prefixes for them\nshould you wish. PREFIX skos: \u003Chttp://www.w3.org/2004/02/skos/core#>\nPREFIX vann: \u003Chttp://purl.org/vocab/vann/>\nPREFIX dcat: \u003Chttp://www.w3.org/ns/dcat#>\nPREFIX geo: \u003Chttp://www.opengis.net/ont/geosparql#>\n\nSELECT DISTINCT ?namespace\n{?uri a ?type\n  BIND (REPLACE(STR(?uri), \"(.*[/#])[^#/]*$\", \"$1\") AS ?namespace)\n  VALUES ?type { skos:Collection skos:ConceptScheme skos:Concept dcat:Dataset geo:FeatureCollection geo:Feature dcat:Resource dcat:Catalog }\n  MINUS {?namespace vann:preferredPrefix ?prefix .}\n} LIMIT 100",{"id":384,"title":385,"titles":386,"content":387,"level":15},"/prezapi/development#annotation-properties","Annotation properties",[232],"Prez recognises the following kinds of annotation properties, and can return RDF, either via SPARQL queries, or the\nendpoints as annotated RDF. When an annotated mediatype is requested (e.g. text/anot+turtle), Prez will look for the following predicates for\nevery RDF term in the (initial) response returned by the triplestore. That is it will expand the response to include\nthe annotations and return the RDF merge of the original response and the annotations. Additional predicates can be added to the list of predicates Prez looks for in the profiles by adding these predicates to the configuration.",{"id":389,"title":390,"titles":391,"content":392,"level":15},"/prezapi/development#how-to-add-an-endpoint","How to add an endpoint",[232],"New endpoints can be added to Prez by adding RDF, and minimal addition of FastAPI decorators. Add FastAPI decorator,\nFor Listing endpoints, add these to the listings function in prez/routers/ogc_router. An example is: @router.get(\n    \"/catalogs\",\n    summary=\"Catalog Listing\",\n    name=OGCE[\"catalog-listing\"],\n    responses=responses\n) See the references in the code for what should be provided for responses and openapi_extra; these fields are optional but useful for documentation.\nThe name is required, and should be a URI. 2. An endpoint definition. 1. The endpoint URI must match the name uri in the decorator. 2. The endpoint must be declared a ont:ListingEndpoint or ont:ObjectEndpopint, as Prez uses different application code to render results for these two types of endpoint.\nThese are in prez/reference_data/endpoints/endpoint_metadata.ttl. An example is: ogce:catalog-listing\n    a ont:ListingEndpoint ;\n    ont:relevantShapes ex:Catalogs ;\n. A NodeShape for the endpoint. This describes how nodes should be selected at the given endpoint. An example is: ex:Catalogs\n    a sh:NodeShape ;\n    ont:hierarchyLevel 1 ;\n    sh:targetClass dcat:Catalog ;\n    sh:property [\n        sh:path dcterms:hasPart ;\n        sh:or (\n            [ sh:class dcat:Resource ]\n            [ sh:class geo:FeatureCollection ]\n            [ sh:class skos:ConceptScheme ]\n            [ sh:class skos:Collection ]\n        ) ;\n    ] . This specifies the selection of focus nodes of class dcat:Catalog which have the relationship dcterms:hasPart to one or more of the listed classes.",{"id":394,"title":395,"titles":396,"content":397,"level":15},"/prezapi/development#query-generation","Query Generation",[232],"Prez utilises the sparql-grammar-pydantic library to generate SPARQL queries.",{"id":399,"title":400,"titles":401,"content":402,"level":21},"/prezapi/development#focus-nodes","Focus nodes",[232,395],"For objects, the focus node is specified in a query path as a curie, or in the case of the /object endpoint, as query parameter with the key \"uri\".\nFor lists of objects, the focus node is a variable, fixed within prez to ?focus_node.\nUsage: The focus node is substituted into the main query.",{"id":404,"title":405,"titles":406,"content":407,"level":21},"/prezapi/development#main-query-generation","Main Query Generation",[232,395],"Prez creates a single main query to describe an object or listing of objects. The structure of the query is as follows: CONSTRUCT {\n    \u003Cconstruct_triples + construct_tss_list>\n}\nWHERE {\n    # for listing queries only:\n    {\n        SELECT ?focus_node \u003Cinnser_select_vars>\n        WHERE {\n            \u003Cinner_select_tssp_list>\n            \u003Cinner_select_gpnt>\n            }\n        ORDER BY \u003Corder_by_direction>(\u003Corder_by>)\n        LIMIT \u003Climit>\n        OFFSET \u003Coffset>\n    }\n    # for all queries:\n    \u003Cprofile_triples>\n    \u003Cprofile_gpnt>\n}",{"id":409,"title":410,"titles":411,"content":412,"level":229},"/prezapi/development#construct_triples-and-construct_tss_list","construct_triples and construct_tss_list",[232,395,405],"The triples to construct. This is taken from the union of: Profile_Triples (directly) - i.e. any triple specified in the where clause will be constructedAny triples within the Profile_GPNTs object. Prez utilises a convenience function provided by the SPARQL Grammar library which recursively extracts all triples within a given SPARQL Grammar object.Additional_Construct_Triples (directly) - these may come from a search query, such as the query result weights, etc.",{"id":414,"title":415,"titles":416,"content":417,"level":229},"/prezapi/development#profile_triples-and-profile_gpnts","profile_triples and profile_GPNTs",[232,395,405],"There is one source of profile triples and profile GPNTs - these are derived from SHACL node and property shapes associated with the selected profile (returned by ConnegP). At a conceptual level these profile shapes represent the \"properties\" or \"attributes\" to be returned for each focus node. At present the following SHACL expressions are covered: minCount = 0 (optional property)maxCount = 0 (exclude property)pathsequence pathinverse pathclassblank nodes to a specified depth\nHow to specify these is detailed in the Profile Design section.",{"id":419,"title":420,"titles":421,"content":422,"level":229},"/prezapi/development#inner_select_triples-and-inner_select_gpnts","Inner_Select_Triples and Inner_Select_GPNTs",[232,395,405],"Inner Select Triples and Inner Select GPNTs are taken from the union of: CQLSearch queriesEndpoint Nodeshapes\nThese are detailed in the Focus Node Selection section.",{"id":424,"title":425,"titles":426,"content":427,"level":21},"/prezapi/development#annotations","Annotations",[232,395],"Where an annotated mediatype is requested, Prez returns any annotations it can find from all available repositories (data, systems, and annotations reposoitory).These annotations are then cached against the URI they are for.The caching utilises aiocache.\naiocache is currently set up with in memory caches. It could be extended to utilise Redis. A sequence diagram is shown for annotation retrieval: sequenceDiagram\n    Client ->> FastAPI: Request for data with annotated mediatype\n    FastAPI ->> Repo: send_queries(object/list query)\n    Repo -->> FastAPI: initial response graph\n    FastAPI ->> FastAPI: get URIs in initial response\n    FastAPI ->> Cache: check cache for annotations\n    Cache -->> FastAPI: return cached annotations (if any)\n    FastAPI ->> FastAPI: determine cached and uncached URIs\n    FastAPI ->> Repo: query for uncached annotations\n    Repo -->> FastAPI: return cached annotations (if any)\n    FastAPI ->> Cache: cache previously uncached annotations\n    FastAPI ->> Client: return initial response graph + annotations Annotations are returned with one of the following mapped prez namespaced URIs. prez🏷 skos:prefLabel, dcterms:title, rdfs:label, sdo:name\nprez:description: skos:definition, dcterms:description, sdo:description\nprez:provenance: dcterms:provenance",{"id":429,"title":430,"titles":431,"content":432,"level":21},"/prezapi/development#repositories","Repositories",[232,395],"An abstraction over data providers is provided with \"Repositories\". Three types are supported; Pyoxigraph (in memory), Oxrdflib, and RemoteSparql. Data repository - one of Pyoxigraph, Oxrdflib, or RemoteSparqlSystem repository - PyoxigraphAnnotations repository - Pyoxygraph",{"id":434,"title":435,"titles":436,"content":437,"level":15},"/prezapi/development#startup-routine","Startup Routine",[232],"Check the SPARQL endpoints can be reached. A blank query (ASK {}) is used to test this. The SPARQL endpoints are not health checked post startup.Create in memory profile, prefix, and endpoint graphs, containing all profiles in the prez/profiles directory, and any additional profiles available in the triplestore (declared as a http://www.w3.org/ns/dx/prof/Profile)Look for predefined object counts in the triplestore.",{"id":439,"title":440,"titles":441,"content":41,"level":15},"/prezapi/development#high-level-sequence-object-endpoint","High Level Sequence /object endpoint",[232],{"id":443,"title":444,"titles":445,"content":446,"level":21},"/prezapi/development#prezui-or-similar-human-actionable-client","PrezUI or similar human-actionable client",[232,440],"Prez provides a /object endpoint as an endpoint that supplies any information known about a given URI. If an annotated\nmediatype is requested, prez will additionally provide all system links for endpoints which can render the object. The\nhigh level sequence for this endpoint is as follows: Get the URI for the object from the query stringGet the class(es) of the object from the triplestoreUse prez's reference data for endpoints to determine which endpoints can render this object, and, a template for\nthese endpoints, specifying any variables that need to be substituted (such as parent URIs).Get the object information from the triplestore, using an open profile, and in parallel any system information needed\nto construct the system links.Return the response",{"id":448,"title":449,"titles":450,"content":451,"level":15},"/prezapi/development#specification-of-remote-sparql-templates-for-object-endpoints","Specification of remote SPARQL templates for Object endpoints",[232],"The OGC Features endpoints can utilise custom SPARQL templates.\nAt present the queries must be of the form: PREFIX geo: \u003Chttp://www.opengis.net/ont/geosparql#>\nPREFIX rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX sosa: \u003Chttp://www.w3.org/ns/sosa/>\nCONSTRUCT {\n ...\n}\nWHERE {\n    VALUES ?focusNode { UNDEF }\n...\n} At present the queries are ONLY substituted with the focus node URI, and only for OGC Features endpoints. It is intended that this functionality will provide the basis for a more general templating system across all OBJECT endpoints in the future.\nThese templates should be declared in the remote repo in this format: PREFIX prez: \u003Chttps://prez.dev/ont/>\nPREFIX rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#>\nINSERT DATA { GRAPH \u003Chttps://prez/system> {\n    [ a prez:TemplateQuery ;\n        rdf:value \"\"\"\u003Ctemplate_queries>\n\"\"\" ;\n        prez:forEndpoint \"http://www.opengis.net/ogcapi-features-1/1.0/feature\" ;\n    ]\n    }} Prez will detect these template queries and when a request comes in on the endpoint with the relevant URI, utilise the template query. Templates can also be specified in prez/reference_data/xxx.rq, and mapped to an endpoint using the endpoint_to_template_query_filename setting (can be set as an environment variable), where xxx.rq is the filename of the template query. For example: export ENDPOINT_TO_TEMPLATE_QUERY_FILENAME='{\"http://www.opengis.net/ogcapi-features-1/1.0/feature\": \"xxx.rq\"}'",{"id":453,"title":454,"titles":455,"content":456,"level":15},"/prezapi/development#high-level-sequence-listing-and-individual-object-endpoints","High Level Sequence listing and individual object endpoints",[232],"Prez follows the following logic to determine what information to return, based on a profile, and in what mediatype to return it. Determine the URI for an object or listing of objects: For objects:\nDirectly supplied through the /object?uri= query string argumentFrom the URL path the object is requested from, for example /catalogs/. abc is a curie, which is expanded to a URI. Get all classes for the object or object listingDetermine the profile and mediatype to use for the object. This is implemented as a SPARQL query and takes into account:\nThe classes of the objectAvailable profiles and mediatypesRequested profiles and mediatypesDefault profiles and mediatypes\nThe logic used to determine the profile and mediatype is detailed in section x.Build a SPARQL query.Execute the SPARQL query.If the mediatype requested is NOT annotated RDF (text/anot+turtle), return the results of 5, else retrieve the annotations:\nCheck Prez cache for annotationsFor terms without annotations in the cache, query the triplestore for annotationsCache any annotations returned from the triplestoreReturn the annotations merged with the results of the SPARQL query in step 5.",{"id":458,"title":459,"titles":460,"content":461,"level":15},"/prezapi/development#caching","Caching",[232],"Prez caches the following things using aiocache: ClassesAnnotations - those predicates listed under label_predicates, description_predicates, and provenance_predicates in the settings.Internal links generated for itemsFeature Collection information at the feature listing endpoint only. These are cached for 10 minutes only.\nThere is no other caching of \"instance\" data in Prez.",{"id":463,"title":464,"titles":465,"content":466,"level":15},"/prezapi/development#release-process","Release Process",[232],"Semantic Release has been set up to automate the release process for this repository, based on Conventional Commits. Conventional Commit messages should preferably be used for all commits, and MUST be used for PR titles (which become commit headers). PR Titles are validated using commitlint, and if failing, will prevent a merge of the PR to main. The release rules, i.e. how Semantic Release increments the version based on the commit messages, are as follows: - type: \"feat\"\n  release: \"minor\"\n- type: \"fix\"\n  release: \"patch\"\n- type: \"perf\"\n  release: \"patch\"\n- type: \"docs\"\n  release: \"patch\"\n- type: \"revert\"\n  release: \"patch\"\n- breaking: true\n  release: \"major\" html pre.shiki code .sCaUI, html code.shiki .sCaUI{--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .sXNWB, html code.shiki .sXNWB{--shiki-default:#A31515;--shiki-dark:#CE9178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .si2PQ, html code.shiki .si2PQ{--shiki-default:#0000FF;--shiki-dark:#569CD6}html pre.shiki code .s6-IL, html code.shiki .s6-IL{--shiki-default:#001080;--shiki-dark:#9CDCFE}html pre.shiki code .sK6Qu, html code.shiki .sK6Qu{--shiki-default:#000000;--shiki-dark:#D4D4D4}html pre.shiki code .s6mp_, html code.shiki .s6mp_{--shiki-default:#800000;--shiki-dark:#569CD6}",{"id":468,"title":469,"titles":470,"content":41,"level":9},"/prezapi/endpoints","API Endpoints",[],{"id":472,"title":473,"titles":474,"content":475,"level":15},"/prezapi/endpoints#endpoints","Endpoints",[469],"Prez delivers the following endpoints:",{"id":477,"title":478,"titles":479,"content":480,"level":21},"/prezapi/endpoints#core-endpoints","Core Endpoints",[469,473],"EndpointDefault MT/text/anot+turtle/docstext/html/catalogs/{catalogId}text/anot+turtle/catalogs/{catalogId}/collectionstext/anot+turtle/catalogs/{catalogId}/collections/{recordsCollectionId}text/anot+turtle/catalogs/{catalogId}/collections/{recordsCollectionId}/itemstext/anot+turtle/catalogs/{catalogId}/collections/{recordsCollectionId}/items/{itemId}text/anot+turtle/purge-tbox-cacheapplication/json/tbox-cacheapplication/json/healthapplication/json/prefixestext/anot+turtle/concept-hierarchy/{parent_curie}/narrowerstext/anot+turtle/concept-hierarchy/{parent_curie}/top-conceptstext/anot+turtle/cqltext/anot+turtle/profilestext/anot+turtle/searchtext/anot+turtle/profiles/{profile_curie}text/anot+turtle/objecttext/anot+turtle/identifier/redirectN/A/identifier/curie/{iri}text/plain/identifier/iri/{curie}text/plai",{"id":482,"title":483,"titles":484,"content":485,"level":21},"/prezapi/endpoints#ogc-features-api-endpoints","OGC Features API Endpoints",[469,473],"The OGC Features API Endpoints are based at the ROOT /catalogs/{catalogId}/collections/{recordsCollectionId}/ EndpointDefault MT{ROOT}/featuresapplication/json{ROOT}/features/docstext/html{ROOT}/features/conformanceapplication/json{ROOT}/features/collectionsapplication/json{ROOT}/features/collections/{collectionId}application/json{ROOT}/features/collections/{collectionId}/itemsapplication/geo+json{ROOT}/features/collections/{collectionId}/items/{featureId}application/geo+jso",{"id":487,"title":488,"titles":489,"content":490,"level":9},"/prezapi/fuseki-fts","Fuseki Full Text Search",[],"Fuseki FTS (Full-Text Search) Integration Prez integrates with Apache Jena Fuseki's full-text search capabilities to enable efficient text search across RDF data.",{"id":492,"title":493,"titles":494,"content":495,"level":15},"/prezapi/fuseki-fts#basic-usage","Basic Usage",[488],"Use the predicates URL query parameter to specify which indexed properties or property shapes to search: /search?q=geological&predicates=http://www.w3.org/2000/01/rdf-schema#label,http://www.w3.org/2004/02/skos/core#definition,ocr",{"id":497,"title":498,"titles":499,"content":500,"level":15},"/prezapi/fuseki-fts#property-shapes-for-complex-paths","Property Shapes for Complex Paths",[488],"If you don't want the search result IRI to be immediately on the search term triple, you can use an FTS property shape. This allows searching through complex property paths.",{"id":502,"title":503,"titles":504,"content":505,"level":21},"/prezapi/fuseki-fts#example-property-shape","Example Property Shape",[488,498],"@prefix rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n@prefix ont: \u003Chttps://prez.dev/ont/> .\n@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n@prefix ex: \u003Chttp://example.com/> .\n@prefix po: \u003Chttp://www.essepuntato.it/2008/12/pattern#> .\n@prefix sh: \u003Chttp://www.w3.org/ns/shacl#> .\n\nex:OCR\n    a sh:PropertyShape ;\n    a ont:JenaFTSPropertyShape ;\n    sh:path ( po:contains po:contains ) ;\n    sh:name \"Returns document focus nodes for full text search\" ;\n    dcterms:identifier \"ocr\" ;\n    ont:searchPredicate rdf:value ;\n.",{"id":507,"title":508,"titles":509,"content":510,"level":21},"/prezapi/fuseki-fts#using-property-shapes","Using Property Shapes",[488,498],"Reference the property shape using its dcterms:identifier in the predicates parameter: /search?q=geology&predicates=ocr This will search for \"geology\" in rdf:value literals, but return search result IRIs that are connected through the po:contains / po:contains path.",{"id":512,"title":513,"titles":514,"content":515,"level":15},"/prezapi/fuseki-fts#predicates-parameter-values","Predicates Parameter Values",[488],"The predicates parameter accepts: RDF predicate IRIs - Direct references to Lucene indexed properties (e.g., http://www.w3.org/2000/01/rdf-schema#label, http://www.w3.org/2004/02/skos/core#definition)Property shape identifiers - The dcterms:identifier value of FTS property shapes (e.g., ocr)PropList IRIs - References to Fuseki text index property lists, as IRIs (e.g., http://example.com/label in the example below)",{"id":517,"title":518,"titles":519,"content":520,"level":15},"/prezapi/fuseki-fts#fuseki-configuration-example","Fuseki Configuration Example",[488],"@prefix sdo: \u003Chttps://schema.org/> .\n@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n@prefix rdfs: \u003Chttp://www.w3.org/2000/01/rdf-schema#> .\n@prefix skos: \u003Chttp://www.w3.org/2004/02/skos/core#> .\n\u003C#indexLucene> a text:TextIndexLucene ;\n    text:directory \"/fuseki/databases/ds/lucene\" ;\n    text:entityMap \u003C#entMap> ;\n    text:propLists\n        (\n            [\n                text:propListProp ex:label ;\n                text:props ( rdfs:label sdo:name skos:prefLabel dcterms:title ) ;\n            ]\n        ) .\n\n\u003C#entMap> a text:EntityMap ;\n    text:map (\n         [ text:field \"label\" ; text:predicate rdfs:label ]\n         [ text:field \"name\" ; text:predicate sdo:name ]\n         [ text:field \"preflabel\" ; text:predicate skos:prefLabel ]\n         [ text:field \"title\" ; text:predicate dcterms:title ]\n         # ... other mappings\n    ) . With this configuration, you can use http://example.com/label or http://www.w3.org/1999/02/22-rdf-syntax-ns#value in the predicates parameter to search across multiple related properties. html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":522,"title":523,"titles":524,"content":525,"level":9},"/prezapi/ogc-features","OGC Features API",[],"Prez provides an OGC Features compliant API The API is mounted as a sub application at \"/catalogs/{catalogId}/collections/{recordsCollectionId}/features\" by default.\nIt can be mounted at a different path by setting the configuration setting ogc_features_mount_path (or corresponding upper cased environment variable). Queryables are a part of the OGC Features specifications which provide a listing of which parameters can be queried.\nThe queryables are a flat set of properties on features. Because Prez consumes an RDF Knowledge Graph, it is desirable to query more than top level properties.\nTo achieve this, Prez provides a mechanism to declare paths through the graph as queryables.\nTo declare these paths, you can use SHACL. An example is provided below: @prefix cql: \u003Chttp://www.opengis.net/doc/IS/cql2/1.0/> .\n@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n@prefix dwc: \u003Chttp://rs.tdwg.org/dwc/terms/> .\n@prefix ex: \u003Chttp://example.com/> .\n@prefix sh: \u003Chttp://www.w3.org/ns/shacl#> .\n@prefix sname: \u003Chttps://fake-scientific-name-id.com/name/afd/> .\n@prefix sosa: \u003Chttp://www.w3.org/ns/sosa/> .\n@prefix xsd: \u003Chttp://www.w3.org/2001/XMLSchema#> .\n\nex:BDRScientificNameQueryableShape\n  a sh:PropertyShape ;\n  a cql:Queryable ;\n  sh:path (\n      [ sh:inversePath sosa:hasFeatureOfInterest ]\n      sosa:hasMember\n      sosa:hasResult\n      dwc:scientificNameID\n      ) ;\n  sh:name \"Scientific Name\" ;\n  dcterms:identifier \"scientificname\" ;\n  sh:datatype xsd:string ;\n  sh:in (\n      sname:001\n      sname:002\n) ;\n. It is recommended that templated SPARQL queries are used to periodically update the sh:in values, which correspond to enumerations. When Prez starts, it will query the remote repository (typically a triplestore) for all Queryables.\nIt queries for them using a CONSTRUCT query, serializes this as JSON-LD, and does a minimal transformation to produce the OGC Features compliant response.\nThe query is: \"\"\"\n    PREFIX cql: \u003Chttp://www.opengis.net/doc/IS/cql2/1.0/>\n    PREFIX dcterms: \u003Chttp://purl.org/dc/terms/>\n    PREFIX sh: \u003Chttp://www.w3.org/ns/shacl#>\n    PREFIX rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#>\n    CONSTRUCT {\n    ?queryable cql:id ?id ;\n        cql:name ?title ;\n        cql:datatype ?type ;\n        cql:enum ?enums .\n    }\n    WHERE {?queryable a cql:Queryable ;\n        dcterms:identifier ?id ;\n        sh:name ?title ;\n        sh:datatype ?type ;\n        sh:in/rdf:rest*/rdf:first ?enums ;\n    }\n    \"\"\" And the output after transformation is of the form (which is the format required for OGC Features): {\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"http://localhost:8000/catalogs/dtst:bdr/collections/syn:68a782a8-d7fe-4b3e-8377-c76c9cc245cc/features/queryables\",\n  \"type\": \"object\",\n  \"title\": \"Global Queryables\",\n  \"description\": \"Global queryable properties for all collections in the OGC Features API.\",\n  \"properties\": {\n    \"scientificname\": {\n      \"title\": \"Scientific Name\",\n      \"type\": \"string\",\n      \"enum\": [\n        \"https://fake-scientific-name-id.com/name/afd/001\",\n        \"https://fake-scientific-name-id.com/name/afd/002\",\n      ]\n    }\n  }\n} Separately, Prez internally translates the declared SHACL Property Path expression into SPARQL and injects this into queries when the queryable, e.g. scientificname, in the example above, is requested.",{"id":527,"title":528,"titles":529,"content":41,"level":9},"/prezapi/path-aliases","Path Aliases",[],{"id":531,"title":528,"titles":532,"content":41,"level":9},"/prezapi/path-aliases#path-aliases",[],{"id":534,"title":535,"titles":536,"content":537,"level":15},"/prezapi/path-aliases#introduction","Introduction",[528],"Prez utilizes SHACL shapes to define how data should be selected and structured for API responses. SHACL property paths (sh:path) can become complex, involving sequences, alternatives, or inverse paths. The Path Alias feature allows you to define a simple, custom URI (an \"alias\") to represent these potentially complex paths in the output RDF graph.",{"id":539,"title":540,"titles":541,"content":542,"level":15},"/prezapi/path-aliases#motivation","Motivation",[528],"Simplified Output: Instead of returning data structured according to a complex, nested property path, using an alias presents the data as if it were connected to the main resource via a single, direct predicate (the alias). This can significantly simplify the RDF graph returned by the API.Client Compatibility: Some client applications may have difficulty parsing or interpreting complex SPARQL property paths. Aliases provide a simpler, predicate-object structure that is easier to consume.Stable Predicates: While the underlying data structure or the SHACL path to reach it might evolve, an alias can provide a stable predicate URI in the API response, decoupling the client from the intricacies of the data model's path structure.",{"id":544,"title":545,"titles":546,"content":547,"level":15},"/prezapi/path-aliases#syntax","Syntax",[528],"Path aliases are defined using the shext:pathAlias predicate (you'll need to define a suitable prefix like shext: for a namespace like http://example.com/shacl-extension# or your own). There are two main ways to apply an alias: On the Property Shape BNode:\nDefine shext:pathAlias directly within the sh:property blank node. This alias applies to the sh:path defined in the same blank node.PREFIX sh: \u003Chttp://www.w3.org/ns/shacl#>\nPREFIX dcterms: \u003Chttp://purl.org/dc/terms/>\nPREFIX prov: \u003Chttp://www.w3.org/ns/prov#>\nPREFIX shext: \u003Chttp://example.com/shacl-extension#>\n\n\u003Chttp://example-profile> a sh:NodeShape ;\nsh:property\n    [\n        sh:union\n            (\n                [\n                # Simple Path Example\n                    sh:path dcterms:title ;\n                    shext:pathAlias \u003Chttps://alias/title> ;\n                ]\n                [\n                # Sequence Path Example\n                    sh:path ( prov:qualifiedDerivation prov:hadRole ) ;\n                    shext:pathAlias \u003Chttps://alias/derivation-role> ;\n                ]\n            )\n    ] ;\n.\nAdjacent to Nested sh:path (within sh:union, sh:alternativePath, etc.):\nWhen using constructs like sh:union or sh:alternativePath that contain lists of paths, you can define an alias specifically for one or more of those nested paths. The alias is placed within the blank node that also contains the nested sh:path.PREFIX sh: \u003Chttp://www.w3.org/ns/shacl#>\nPREFIX skos: \u003Chttp://www.w3.org/2004/02/skos/core#>\nPREFIX prov: \u003Chttp://www.w3.org/ns/prov#>\nPREFIX shext: \u003Chttp://example.com/shacl-extension#>\n\n\u003Chttp://example-profile>\n    a sh:NodeShape ;\n    sh:property [\n        sh:path [\n            sh:union (\n                # Path 1: No alias\n                skos:prefLabel\n\n                # Path 2: Has an alias defined adjacent to its sh:path\n                [\n                    sh:path ( prov:qualifiedDerivation prov:hadRole ) ;\n                    shext:pathAlias \u003Chttps://alias/derivation-role> ;\n                ]\n            )\n        ]\n    ] .",{"id":549,"title":550,"titles":551,"content":552,"level":15},"/prezapi/path-aliases#behavior-construct-vs-where","Behavior: CONSTRUCT vs WHERE",[528],"The key aspect of path aliasing is how it affects the generated SPARQL query: WHERE Clause: The original, potentially complex sh:path (e.g., dcterms:title, ( prov:qualifiedDerivation prov:hadRole ), skos:prefLabel|rdfs:label) is always used in the WHERE clause to locate and filter the data in the underlying triplestore.CONSTRUCT Clause:If use_path_aliases is True (see Configuration below) and a shext:pathAlias is defined for a path, the alias URI is used as the predicate in the CONSTRUCT clause.If use_path_aliases is False, or if no alias is defined for a path, the original path structure is replicated in the CONSTRUCT clause. Example: Given this shape with an alias: [\n    sh:path dcterms:title ;\n    shext:pathAlias \u003Chttps://alias/title> ;\n] WHERE clause will contain: ?focus_node dcterms:title ?value .CONSTRUCT clause (if use_path_aliases = True) will contain: ?focus_node \u003Chttps://alias/title> ?value .CONSTRUCT clause (if use_path_aliases = False) will contain: ?focus_node dcterms:title ?value . For a sequence path like ( prov:qualifiedDerivation prov:hadRole ) aliased to \u003Chttps://alias/derivation-role>: WHERE clause will contain: ?focus_node prov:qualifiedDerivation ?intermediate . ?intermediate prov:hadRole ?value .CONSTRUCT clause (if use_path_aliases = True) will contain: ?focus_node \u003Chttps://alias/derivation-role> ?value .CONSTRUCT clause (if use_path_aliases = False) will contain: ?focus_node prov:qualifiedDerivation ?intermediate . ?intermediate prov:hadRole ?value .",{"id":554,"title":555,"titles":556,"content":557,"level":15},"/prezapi/path-aliases#configuration","Configuration",[528],"The use of path aliases in the CONSTRUCT clause is controlled by a setting, typically found in prez.config.settings: use_path_aliases = True: Enables the use of defined aliases in the CONSTRUCT clause.use_path_aliases = False: Disables aliases; the original paths are used in the CONSTRUCT clause. This allows users to choose whether they want the simplified output structure provided by aliases or the structure that directly mirrors the SHACL paths. html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":559,"title":560,"titles":561,"content":562,"level":9},"/prezapi/result-counting","Result Counting",[],"Results are counted in the following way: Scenario:\nThere are 132 total items. LISTING_COUNT_LIMIT = 100",{"id":564,"title":565,"titles":566,"content":41,"level":15},"/prezapi/result-counting#configuration-options","Configuration Options",[560],{"id":568,"title":569,"titles":570,"content":571,"level":21},"/prezapi/result-counting#listing_count_on_demand","LISTING_COUNT_ON_DEMAND",[560,565],"Controls when count queries are executed for listing endpoints. This provides performance optimization by allowing clients to explicitly request counts only when needed. Default: false (for backwards compatibility)Future versions: May default to true When LISTING_COUNT_ON_DEMAND=false (default): Counts are automatically included in RDF listing responses (up to LISTING_COUNT_LIMIT)This is the current/legacy behaviour When LISTING_COUNT_ON_DEMAND=true: Counts are NOT included in regular RDF listing responsesTo get the count, clients must pass ?resultType=hitsWhen resultType=hits is passed, ONLY the count is returned (no items/data)This matches the behaviour already implemented for OGC Features endpointsProvides finer control for frontends over when expensive count queries are performed Note: GeoJSON responses always follow the hits-only pattern (counts only with ?resultType=hits) regardless of this setting.",{"id":573,"title":574,"titles":575,"content":576,"level":21},"/prezapi/result-counting#behaviour-matrix","Behaviour Matrix",[560,565],"MediaTypeLISTING_COUNT_ON_DEMANDRequest TypeResponse ContainsAnnotated RDF (e.g., text/anot+turtle)false (default)Normal listingItems + CountNon-annotated RDF (e.g., text/turtle)false (default)Normal listingItems only (no count*)RDF (annotated or non-annotated)false (default)?resultType=hitsCount only (no items)RDF (annotated or non-annotated)trueNormal listingItems only (no count)RDF (annotated or non-annotated)true?resultType=hitsCount only (no items)GeoJSONfalse or trueNormal listingFeatures only (no numberMatched**)GeoJSONfalse or true?resultType=hitsnumberMatched only (no features) *Counts are annotations, so non-annotated mediatypes never include counts in normal listings (only with ?resultType=hits). **numberMatched may be inferred on the first page if the number of features returned is less than the page limit, but no count query is executed. Future Changes: In a future major release, the LISTING_COUNT_ON_DEMAND setting will be removed and the behaviour will default to the current LISTING_COUNT_ON_DEMAND=true behaviour (counts only returned when explicitly requested via ?resultType=hits).",{"id":578,"title":579,"titles":580,"content":581,"level":15},"/prezapi/result-counting#listing-endpoints-non-search","Listing Endpoints (Non-Search)",[560],"PagePage SizeStart ItemEnd ItemTotal Count Displayed120120>1002202140>10052081100>100620101120>120720121132132",{"id":583,"title":584,"titles":585,"content":586,"level":15},"/prezapi/result-counting#search-endpoints-search_uses_listing_count_limit-false","Search Endpoints (SEARCH_USES_LISTING_COUNT_LIMIT = false)",[560],"Count query not run — uses page size + 1 fetch logic to determine if more results exist. PagePage SizeStart ItemEnd ItemTotal Count Displayed125126>252252651>50525101126>125625126132132",{"id":588,"title":589,"titles":590,"content":591,"level":15},"/prezapi/result-counting#search-endpoints-search_uses_listing_count_limit-true","Search Endpoints (SEARCH_USES_LISTING_COUNT_LIMIT = true)",[560],"Count query is run. The same LISTING_COUNT_LIMIT is enforced. PagePage SizeStart ItemEnd ItemTotal Count Displayed120121>1003204161>10052081101>100620101121>120720121132132",{"id":593,"title":488,"body":594,"code":959,"date":959,"description":960,"editorContent":959,"extension":961,"icon":959,"meta":962,"navigation":677,"path":487,"seo":963,"source":959,"stem":964,"tags":959,"__hash__":965},"prezapi/prezapi/fuseki-fts.md",{"type":595,"value":596,"toc":950},"minimark",[597,601,605,613,622,625,627,631,727,730,740,746,757,760,766,807,810,936,946],[598,599,600],"p",{},"Prez integrates with Apache Jena Fuseki's full-text search capabilities to enable efficient text search across RDF data.",[602,603,493],"h2",{"id":604},"basic-usage",[598,606,607,608,612],{},"Use the ",[609,610,611],"code",{},"predicates"," URL query parameter to specify which indexed properties or property shapes to search:",[614,615,620],"pre",{"className":616,"code":618,"language":619},[617],"language-text","/search?q=geological&predicates=http://www.w3.org/2000/01/rdf-schema#label,http://www.w3.org/2004/02/skos/core#definition,ocr\n","text",[609,621,618],{"__ignoreMap":41},[602,623,498],{"id":624},"property-shapes-for-complex-paths",[598,626,500],{},[628,629,503],"h3",{"id":630},"example-property-shape",[614,632,636],{"className":633,"code":634,"language":635,"meta":41,"style":41},"language-turtle shiki shiki-themes light-plus dark-plus","@prefix rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n@prefix ont: \u003Chttps://prez.dev/ont/> .\n@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n@prefix ex: \u003Chttp://example.com/> .\n@prefix po: \u003Chttp://www.essepuntato.it/2008/12/pattern#> .\n@prefix sh: \u003Chttp://www.w3.org/ns/shacl#> .\n\nex:OCR\n    a sh:PropertyShape ;\n    a ont:JenaFTSPropertyShape ;\n    sh:path ( po:contains po:contains ) ;\n    sh:name \"Returns document focus nodes for full text search\" ;\n    dcterms:identifier \"ocr\" ;\n    ont:searchPredicate rdf:value ;\n.\n","turtle",[609,637,638,645,650,655,660,666,672,679,685,691,697,703,709,715,721],{"__ignoreMap":41},[639,640,642],"span",{"class":641,"line":9},"line",[639,643,644],{},"@prefix rdf: \u003Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n",[639,646,647],{"class":641,"line":15},[639,648,649],{},"@prefix ont: \u003Chttps://prez.dev/ont/> .\n",[639,651,652],{"class":641,"line":21},[639,653,654],{},"@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n",[639,656,657],{"class":641,"line":229},[639,658,659],{},"@prefix ex: \u003Chttp://example.com/> .\n",[639,661,663],{"class":641,"line":662},5,[639,664,665],{},"@prefix po: \u003Chttp://www.essepuntato.it/2008/12/pattern#> .\n",[639,667,669],{"class":641,"line":668},6,[639,670,671],{},"@prefix sh: \u003Chttp://www.w3.org/ns/shacl#> .\n",[639,673,675],{"class":641,"line":674},7,[639,676,678],{"emptyLinePlaceholder":677},true,"\n",[639,680,682],{"class":641,"line":681},8,[639,683,684],{},"ex:OCR\n",[639,686,688],{"class":641,"line":687},9,[639,689,690],{},"    a sh:PropertyShape ;\n",[639,692,694],{"class":641,"line":693},10,[639,695,696],{},"    a ont:JenaFTSPropertyShape ;\n",[639,698,700],{"class":641,"line":699},11,[639,701,702],{},"    sh:path ( po:contains po:contains ) ;\n",[639,704,706],{"class":641,"line":705},12,[639,707,708],{},"    sh:name \"Returns document focus nodes for full text search\" ;\n",[639,710,712],{"class":641,"line":711},13,[639,713,714],{},"    dcterms:identifier \"ocr\" ;\n",[639,716,718],{"class":641,"line":717},14,[639,719,720],{},"    ont:searchPredicate rdf:value ;\n",[639,722,724],{"class":641,"line":723},15,[639,725,726],{},".\n",[628,728,508],{"id":729},"using-property-shapes",[598,731,732,733,736,737,739],{},"Reference the property shape using its ",[609,734,735],{},"dcterms:identifier"," in the ",[609,738,611],{}," parameter:",[614,741,744],{"className":742,"code":743,"language":619},[617],"/search?q=geology&predicates=ocr\n",[609,745,743],{"__ignoreMap":41},[598,747,748,749,752,753,756],{},"This will search for \"geology\" in ",[609,750,751],{},"rdf:value"," literals, but return search result IRIs that are connected through the ",[609,754,755],{},"po:contains / po:contains"," path.",[602,758,513],{"id":759},"predicates-parameter-values",[598,761,762,763,765],{},"The ",[609,764,611],{}," parameter accepts:",[767,768,769,785,797],"ol",{},[770,771,772,776,777,780,781,784],"li",{},[773,774,775],"strong",{},"RDF predicate IRIs"," - Direct references to Lucene indexed properties (e.g., ",[609,778,779],{},"http://www.w3.org/2000/01/rdf-schema#label",", ",[609,782,783],{},"http://www.w3.org/2004/02/skos/core#definition",")",[770,786,787,790,791,793,794,784],{},[773,788,789],{},"Property shape identifiers"," - The ",[609,792,735],{}," value of FTS property shapes (e.g., ",[609,795,796],{},"ocr",[770,798,799,802,803,806],{},[773,800,801],{},"PropList IRIs"," - References to Fuseki text index property lists, as IRIs (e.g., ",[609,804,805],{},"http://example.com/label"," in the example below)",[602,808,518],{"id":809},"fuseki-configuration-example",[614,811,813],{"className":633,"code":812,"language":635,"meta":41,"style":41},"@prefix sdo: \u003Chttps://schema.org/> .\n@prefix dcterms: \u003Chttp://purl.org/dc/terms/> .\n@prefix rdfs: \u003Chttp://www.w3.org/2000/01/rdf-schema#> .\n@prefix skos: \u003Chttp://www.w3.org/2004/02/skos/core#> .\n\u003C#indexLucene> a text:TextIndexLucene ;\n    text:directory \"/fuseki/databases/ds/lucene\" ;\n    text:entityMap \u003C#entMap> ;\n    text:propLists\n        (\n            [\n                text:propListProp ex:label ;\n                text:props ( rdfs:label sdo:name skos:prefLabel dcterms:title ) ;\n            ]\n        ) .\n\n\u003C#entMap> a text:EntityMap ;\n    text:map (\n         [ text:field \"label\" ; text:predicate rdfs:label ]\n         [ text:field \"name\" ; text:predicate sdo:name ]\n         [ text:field \"preflabel\" ; text:predicate skos:prefLabel ]\n         [ text:field \"title\" ; text:predicate dcterms:title ]\n         # ... other mappings\n    ) .\n",[609,814,815,820,824,829,834,839,844,849,854,859,864,869,874,879,884,888,894,900,906,912,918,924,930],{"__ignoreMap":41},[639,816,817],{"class":641,"line":9},[639,818,819],{},"@prefix sdo: \u003Chttps://schema.org/> .\n",[639,821,822],{"class":641,"line":15},[639,823,654],{},[639,825,826],{"class":641,"line":21},[639,827,828],{},"@prefix rdfs: \u003Chttp://www.w3.org/2000/01/rdf-schema#> .\n",[639,830,831],{"class":641,"line":229},[639,832,833],{},"@prefix skos: \u003Chttp://www.w3.org/2004/02/skos/core#> .\n",[639,835,836],{"class":641,"line":662},[639,837,838],{},"\u003C#indexLucene> a text:TextIndexLucene ;\n",[639,840,841],{"class":641,"line":668},[639,842,843],{},"    text:directory \"/fuseki/databases/ds/lucene\" ;\n",[639,845,846],{"class":641,"line":674},[639,847,848],{},"    text:entityMap \u003C#entMap> ;\n",[639,850,851],{"class":641,"line":681},[639,852,853],{},"    text:propLists\n",[639,855,856],{"class":641,"line":687},[639,857,858],{},"        (\n",[639,860,861],{"class":641,"line":693},[639,862,863],{},"            [\n",[639,865,866],{"class":641,"line":699},[639,867,868],{},"                text:propListProp ex:label ;\n",[639,870,871],{"class":641,"line":705},[639,872,873],{},"                text:props ( rdfs:label sdo:name skos:prefLabel dcterms:title ) ;\n",[639,875,876],{"class":641,"line":711},[639,877,878],{},"            ]\n",[639,880,881],{"class":641,"line":717},[639,882,883],{},"        ) .\n",[639,885,886],{"class":641,"line":723},[639,887,678],{"emptyLinePlaceholder":677},[639,889,891],{"class":641,"line":890},16,[639,892,893],{},"\u003C#entMap> a text:EntityMap ;\n",[639,895,897],{"class":641,"line":896},17,[639,898,899],{},"    text:map (\n",[639,901,903],{"class":641,"line":902},18,[639,904,905],{},"         [ text:field \"label\" ; text:predicate rdfs:label ]\n",[639,907,909],{"class":641,"line":908},19,[639,910,911],{},"         [ text:field \"name\" ; text:predicate sdo:name ]\n",[639,913,915],{"class":641,"line":914},20,[639,916,917],{},"         [ text:field \"preflabel\" ; text:predicate skos:prefLabel ]\n",[639,919,921],{"class":641,"line":920},21,[639,922,923],{},"         [ text:field \"title\" ; text:predicate dcterms:title ]\n",[639,925,927],{"class":641,"line":926},22,[639,928,929],{},"         # ... other mappings\n",[639,931,933],{"class":641,"line":932},23,[639,934,935],{},"    ) .\n",[598,937,938,939,941,942,945],{},"With this configuration, you can use ",[609,940,805],{}," or ",[609,943,944],{},"http://www.w3.org/1999/02/22-rdf-syntax-ns#value"," in the predicates parameter to search across multiple related properties.",[947,948,949],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":41,"searchDepth":15,"depth":15,"links":951},[952,953,957,958],{"id":604,"depth":15,"text":493},{"id":624,"depth":15,"text":498,"children":954},[955,956],{"id":630,"depth":21,"text":503},{"id":729,"depth":21,"text":508},{"id":759,"depth":15,"text":513},{"id":809,"depth":15,"text":518},null,"Fuseki FTS (Full-Text Search) Integration","md",{},{"title":488,"description":960},"prezapi/fuseki-fts","sTji3CySjAlYG7ykdpNWzRFXTBtpeKo5daa_A2WVk6s",[967],{"title":6,"path":5,"stem":968,"children":969,"tags":959},"prezapi/1.index",[970,971,973,975,992,994,996,998,999,1001,1003],{"title":6,"path":5,"stem":968,"tags":959},{"title":39,"path":38,"stem":972,"tags":959},"prezapi/2.quickstart",{"title":54,"path":53,"stem":974,"tags":959},"prezapi/3.features",{"title":555,"path":976,"stem":977,"children":978,"page":991},"/prezapi/configuration","prezapi/4.configuration",[979,981,983,985,987,989],{"title":63,"path":62,"stem":980,"tags":959},"prezapi/4.configuration/1.env",{"title":163,"path":162,"stem":982,"tags":959},"prezapi/4.configuration/cql",{"title":167,"path":166,"stem":984,"tags":959},"prezapi/4.configuration/endpoints",{"title":192,"path":191,"stem":986,"tags":959},"prezapi/4.configuration/facets",{"title":202,"path":201,"stem":988,"tags":959},"prezapi/4.configuration/profiles",{"title":207,"path":206,"stem":990,"tags":959},"prezapi/4.configuration/queryables",false,{"title":212,"path":211,"stem":993,"tags":959},"prezapi/deployment",{"title":232,"path":231,"stem":995,"tags":959},"prezapi/development",{"title":469,"path":468,"stem":997,"tags":959},"prezapi/endpoints",{"title":488,"path":487,"stem":964,"tags":959},{"title":523,"path":522,"stem":1000,"tags":959},"prezapi/ogc-features",{"title":528,"path":527,"stem":1002,"tags":959},"prezapi/path-aliases",{"title":560,"path":559,"stem":1004,"tags":959},"prezapi/result-counting",1774621042888]