Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c92d88c
feat(utils): :sparkles: add offline mode and cache management to Http…
kikkomep Apr 23, 2026
7c9e825
feat(utils): :sparkles: add helpers to configure the cache path
kikkomep Apr 23, 2026
57eceb5
feat(core): :sparkles: support offline mode when downloading remote R…
kikkomep Apr 23, 2026
6974912
test(utils): :white_check_mark: add unit tests for HttpRequester offl…
kikkomep Apr 23, 2026
949ec6f
feat(utils): :sparkles: add HTTP cache warm-up from profile artifacts
kikkomep Apr 23, 2026
eedabf1
feat(utils): :sparkles: add cache-aware JSON-LD document loader
kikkomep Apr 23, 2026
9ef1ff5
feat(models): :sparkles: add offline and no-cache options to Validati…
kikkomep Apr 23, 2026
f8b99bc
feat(cli): :sparkles: add `--offline` flag and refine `--no-cache` he…
kikkomep Apr 23, 2026
e296f10
feat(cli): :sparkles: add `cache` subcommand to manage the HTTP cache
kikkomep Apr 23, 2026
9b3eba6
test(utils): :white_check_mark: add unit tests for profile URL discov…
kikkomep Apr 23, 2026
72e2909
test(utils): :white_check_mark: add unit tests for the JSON-LD docume…
kikkomep Apr 23, 2026
ed6e58e
test(integration): :white_check_mark: add integration tests for offli…
kikkomep Apr 23, 2026
463b316
fix(utils): :loud_sound: fix log level message
kikkomep Apr 23, 2026
7a56e54
style(tests): :rotating_light: fix linter warning F401
kikkomep Apr 23, 2026
0ee0abb
test(conftest): :wrench: update test configuration
kikkomep Apr 23, 2026
4c5497c
chore: :loud_sound: adjust cache outcome log level
kikkomep Apr 23, 2026
7b3e8bc
fix(models): :bug: forward `extra_profiles_path` when computing
kikkomep Apr 27, 2026
f3a7e6d
test(models): :white_check_mark: cover profile resoution from
kikkomep Apr 27, 2026
5044814
fix(shacl): :bug: derive NodeShape level from nested PropertyShapes
kikkomep Apr 28, 2026
a306f7f
fix(core): :bug: filter failed requirements/checks by configured seve…
kikkomep Apr 28, 2026
bb514b3
test(shacl): :white_check_mark: cover NodeShape level derivation from…
kikkomep Apr 28, 2026
254fb88
fix(shacl): :bug: drop sub-threshold pyshacl violations at the source
kikkomep Apr 28, 2026
9f48674
feat(model): :sparkles: feat(core): :sparkles: add SourceSnippet clas…
kikkomep Apr 29, 2026
fe740e4
feat(Python): :sparkles: implement the `get_source_snippet` method fo…
kikkomep Apr 29, 2026
25bc7b4
feat(SHACL): :sparkles: implement the `get_source_snippet` method for…
kikkomep Apr 29, 2026
23164b7
refactor(SHACL): :recycle: rewrite `build_node_subgraph` as an iterat…
kikkomep Apr 29, 2026
f3fb7f3
feat(cli): extend CLI command to describe requirement checks
kikkomep Apr 29, 2026
887e2a8
test(cli): :white_check_mark: add unit tests for the `describe profil…
kikkomep Apr 30, 2026
9bc3063
Merge pull request #166 from kikkomep/fix/issue-143
kikkomep May 6, 2026
f1c0cfd
fix(shacl): :bug: build property shape subgraph by reachability
kikkomep May 6, 2026
4f7ec5a
test(utils): :white_check_mark: add unit tests for the `get_shape_pro…
kikkomep May 6, 2026
e43364b
refactor(models): :recycle: introduce pre/post internal validation ho…
kikkomep May 6, 2026
439c68f
test(model): :white_check_mark: add unit tests for the pre/post inter…
kikkomep May 6, 2026
bcb5cac
fix(shacl): :bug: evaluate inherited shapes for zero-shape target pro…
kikkomep May 6, 2026
93e2b0b
test(shacl): :white_check_mark: regression test for zero-shape target…
kikkomep May 6, 2026
04d0552
fix(model): :rotating_light: add missing methods and reformat code
kikkomep May 6, 2026
4c2fbbd
fix: :rotating_light: reformat code to fix linter warnings
kikkomep May 6, 2026
03a32fc
fix error message for bad position in HowToStep
simleo May 7, 2026
a9783ce
feat(model): :sparkles: extend Profile model to compute descendants
kikkomep May 8, 2026
dd84c32
feat(checks): :sparkles: support `deactivated` flag on RequirementChe…
kikkomep May 8, 2026
4196f0e
feat(model): :sparkles: skip deactivated Python checks
kikkomep May 8, 2026
71540b1
chore(model): :art: reformat code
kikkomep May 8, 2026
1acd74d
test(checks): :white_check_mark: cover `deactivated` flag on Requirem…
kikkomep May 8, 2026
0b6bff7
docs(profiles): :sparkles: document check override-by-name and deacti…
kikkomep May 8, 2026
a710ab0
Merge pull request #170 from kikkomep/fix/shacl-issues
kikkomep May 8, 2026
d1eabba
started working on ISA process fix
floWetzels May 11, 2026
c3e2d5f
Process class for all process checks
floWetzels May 11, 2026
c5e29e4
fixed non-determinism with manual assay/study definition in process
floWetzels May 12, 2026
9a3047a
Merge pull request #171 from simleo/fix_position_msg
simleo May 13, 2026
e3fda59
added classes for most ISA types
floWetzels May 13, 2026
3ff4245
finalized rdf classes for ISA types
floWetzels May 13, 2026
b3bfa0b
Merge pull request #168 from kikkomep/fix/requirement-severity
kikkomep May 13, 2026
fd39545
Merge pull request #172 from kikkomep/feat/disabling-check
kikkomep May 13, 2026
8da4b60
fix(shacl): :bug: reference `owner.graph` in `get_source_snippet`
kikkomep May 13, 2026
419fece
feat(constants): :wrench: default HTTP cache to never expire
kikkomep May 13, 2026
757b86a
fix(validation): :mute: report offline cache misses once per URL
kikkomep May 15, 2026
7926832
fix(cli/cache): :sparkles: resolve profile tokens in `cache warm`
kikkomep May 15, 2026
6925d55
feat(cli/cache): :sparkles: allow caching of explicit URLs via 'cache…
kikkomep May 15, 2026
f9b43ae
feat(cli/cache): :sparkles: add `cache list` (alias `ls`)
kikkomep May 15, 2026
c0bea7f
test(conftest): :wrench: force wide terminal for Rich-based CLI asser…
kikkomep May 15, 2026
0419466
test(validation): :white_check_mark: cover offline cache-miss warning…
kikkomep May 15, 2026
b6873fa
test(cli/cache): :white_check_mark: add CLI tests for 'cache warm --u…
kikkomep May 15, 2026
392df1a
refactor(cli/cache): :art: drop Status column from `cache list` table
kikkomep May 15, 2026
1568ef6
Added tests for objects with ISA types that are not connected to ISA …
floWetzels May 18, 2026
1f5439a
Fixed some comments and descriptions in ISA profile
floWetzels May 18, 2026
31caaa4
minor formatting fixes
floWetzels May 18, 2026
dd538b9
Merge pull request #175 from nfdi4plants/process-fix
simleo May 18, 2026
0b8289b
refactor(errors): :recycle: accept str, Path or URI in ROCrateInvalid…
kikkomep May 19, 2026
62f89c0
feat(uri): :sparkles: add `is_external_reference()` scheme detector
kikkomep May 19, 2026
469bbe5
feat(uri): :sparkles: classify remote schemes and report granular ava…
kikkomep May 19, 2026
76e92a4
feat(rocrate): :sparkles: add check_availability() with AvailabilityS…
kikkomep May 19, 2026
75d0442
refactor(checks): :recycle: document web-data-entity exclusion
kikkomep May 19, 2026
0196dc9
feat(checks): :sparkles: handle UNAUTHORIZED/UNCHECKABLE web data ent…
kikkomep May 19, 2026
f5d0d8f
test(uri): :white_check_mark: add tests for scheme classification and…
kikkomep May 19, 2026
e8c170f
test(rocrate): :white_check_mark: test data entities with external re…
kikkomep May 19, 2026
2762f4b
test(checks): :white_check_mark: test external-reference data entitie…
kikkomep May 19, 2026
2fe0374
Merge pull request #169 from kikkomep/feat/describe-req-check
kikkomep May 21, 2026
63acb6a
fix(uri): :bug: treat file:// URIs with non-local authority as remote
kikkomep May 29, 2026
379d297
test(cli): :wrench: fix config to support small terminals windows
kikkomep May 29, 2026
45b2f49
test(uri): :white_check_mark: add tests for file:// URIs with non-loc…
kikkomep May 29, 2026
33012b6
fix(cli/cache): :bug: avoid stream=True when fetching remote crates
kikkomep Jun 1, 2026
64cc050
test(cli/cache): :white_check_mark: add regression test for 'cache wa…
kikkomep Jun 1, 2026
6f850d0
Merge pull request #165 from kikkomep/feat/offline-mode
kikkomep Jun 1, 2026
1abd2a1
Merge pull request #177 from kikkomep/fix/issue-176
kikkomep Jun 1, 2026
39414e0
chore(release): :arrow_up: update dependencies in `poetry.lock` file
kikkomep Jun 1, 2026
7569fff
chore(release): :bookmark: bump version to 0.10.0
kikkomep Jun 1, 2026
e10c3b5
docs: :memo: add documentation for cache and offline mode features
kikkomep Jun 1, 2026
c5bf1f5
docs: :books: update copyright years and refactor acknowledgements se…
kikkomep Jun 1, 2026
15f2259
chore(docs): update configuration to suppress warnings
kikkomep Jun 1, 2026
af0fe9b
chore: :bookmark: update changelog (v0.10.0)
kikkomep Jun 1, 2026
46b74d7
chore(typos): :wrench: exclude hexadecimal identifiers from spell che…
kikkomep Jun 1, 2026
fad2dfa
prepare-release-0.10.0
kikkomep Jun 1, 2026
5847d4a
chore(release): :arrow_up: update dependencies in `poetry.lock` file
kikkomep Jun 1, 2026
ded0279
chore: 🔧 update obsolete GitHub actions
kikkomep Jun 1, 2026
9a82482
refactor(http): extract session teardown into _close_session helper
kikkomep Jun 9, 2026
80b15c9
feat(http): reconfigure existing HttpRequester singleton instead of r…
kikkomep Jun 9, 2026
c9b4cc2
fix(http): resolve session method lazily in HTTP wrapper
kikkomep Jun 9, 2026
38482fc
fix(models): reconfigure HTTP requester in place instead of resetting it
kikkomep Jun 9, 2026
877ea8d
test(http): add unit tests
kikkomep Jun 9, 2026
3252731
Merge pull request #178 from kikkomep/fix/http-requester-handling
kikkomep Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
- name: 🏗️ Build a binary wheel and a source tarball
run: poetry build
- name: 📦 Store the distribution packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: python-package-distributions
path: |
Expand All @@ -111,7 +111,7 @@ jobs:
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- name: ⬇️ Download all the distribution packages
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: python-package-distributions
path: dist/
Expand All @@ -132,7 +132,7 @@ jobs:
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- name: ⬇️ Download all the dists
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: python-package-distributions
path: dist/
Expand All @@ -151,18 +151,18 @@ jobs:

steps:
- name: ⬇️ Download all the distribution packages
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: python-package-distributions
path: dist/
- name: 🖊️ Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.0.0
uses: sigstore/gh-action-sigstore-python@v3.3.0
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: 📦 Store the signed distribution packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: python-package-signatures
path: dist/*.json
Expand All @@ -177,12 +177,12 @@ jobs:
id-token: write # IMPORTANT: mandatory for sigstore
steps:
- name: ⬇️ Download all the distribution packages
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: python-package-distributions
path: dist/
- name: ⬇️ Download all the distribution signatures
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: python-package-signatures
path: dist/
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: ⌛ Lint Python code
run: flake8 -v rocrate_validator tests
- name: ⌛ Spell check code and profiles (covers Python and SHACL)
uses: crate-ci/typos@v1.41.0
uses: crate-ci/typos@v1.47.0

# Runs the tests
test:
Expand Down
79 changes: 79 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,85 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.10.0] - 2026-06-01

Full changelog: https://github.com/crs4/rocrate-validator/compare/0.9.0...0.10.0

### ✨ Added

- feat(cli): add offline mode with an `--offline` flag and an HTTP `cache` subcommand to validate RO-Crates without network access ([e296f10](https://github.com/crs4/rocrate-validator/commit/e296f10), [f8b99bc](https://github.com/crs4/rocrate-validator/commit/f8b99bc))
- feat(utils): add a cache-aware JSON-LD document loader and HTTP cache warm-up from profile artifacts ([eedabf1](https://github.com/crs4/rocrate-validator/commit/eedabf1), [949ec6f](https://github.com/crs4/rocrate-validator/commit/949ec6f))
- feat(utils): add offline mode and cache management to `HttpRequester`, with configurable cache path ([c92d88c](https://github.com/crs4/rocrate-validator/commit/c92d88c), [7c9e825](https://github.com/crs4/rocrate-validator/commit/7c9e825))
- feat(core): support offline mode when downloading remote RO-Crates ([57eceb5](https://github.com/crs4/rocrate-validator/commit/57eceb5))
- feat(cli/cache): add `cache list` (alias `ls`) and allow caching of explicit URLs via `cache warm` ([f9b43ae](https://github.com/crs4/rocrate-validator/commit/f9b43ae), [6925d55](https://github.com/crs4/rocrate-validator/commit/6925d55))
- feat(cli): extend the `describe` command to describe individual requirement checks ([f3fb7f3](https://github.com/crs4/rocrate-validator/commit/f3fb7f3))
- feat(model): add a `SourceSnippet` class and `RequirementCheck.get_source_snippet`, implemented for both SHACL and Python checks ([9f48674](https://github.com/crs4/rocrate-validator/commit/9f48674), [25bc7b4](https://github.com/crs4/rocrate-validator/commit/25bc7b4), [fe740e4](https://github.com/crs4/rocrate-validator/commit/fe740e4))
- feat(checks): support a `deactivated` flag on `RequirementCheck` to override/deactivate checks by name for Python and SHACL ([dd84c32](https://github.com/crs4/rocrate-validator/commit/dd84c32), [4196f0e](https://github.com/crs4/rocrate-validator/commit/4196f0e))
- feat(rocrate): add `check_availability()` with `AvailabilityStatus` on entities and granular remote-scheme classification ([76e92a4](https://github.com/crs4/rocrate-validator/commit/76e92a4), [469bbe5](https://github.com/crs4/rocrate-validator/commit/469bbe5))
- feat(checks): handle `UNAUTHORIZED`/`UNCHECKABLE` web data entities as warnings ([0196dc9](https://github.com/crs4/rocrate-validator/commit/0196dc9))
- feat(uri): add an `is_external_reference()` scheme detector ([62f89c0](https://github.com/crs4/rocrate-validator/commit/62f89c0))
- feat(model): extend the `Profile` model to compute descendants ([a9783ce](https://github.com/crs4/rocrate-validator/commit/a9783ce))
- ISA profile: add RDF classes for ISA types and a dedicated `Process` class for process checks ([3ff4245](https://github.com/crs4/rocrate-validator/commit/3ff4245), [e3fda59](https://github.com/crs4/rocrate-validator/commit/e3fda59), [c3e2d5f](https://github.com/crs4/rocrate-validator/commit/c3e2d5f))

### 🔧 Changed

- refactor(models): introduce pre/post internal validation hooks on `Validator` ([e43364b](https://github.com/crs4/rocrate-validator/commit/e43364b))
- refactor(SHACL): rewrite `build_node_subgraph` as an iterative BNode traversal ([23164b7](https://github.com/crs4/rocrate-validator/commit/23164b7))
- refactor(errors): accept `str`, `Path` or `URI` in `ROCrateInvalidURIError` ([0b8289b](https://github.com/crs4/rocrate-validator/commit/0b8289b))
- refactor(cli/cache): drop the `Status` column from the `cache list` table ([392df1a](https://github.com/crs4/rocrate-validator/commit/392df1a))
- feat(constants): default the HTTP cache to never expire ([419fece](https://github.com/crs4/rocrate-validator/commit/419fece))

### 🐛 Fixed

- fix(shacl): build property shape subgraphs by reachability and derive `NodeShape` level from nested `PropertyShape`s ([f1c0cfd](https://github.com/crs4/rocrate-validator/commit/f1c0cfd), [50448145](https://github.com/crs4/rocrate-validator/commit/5044814))
- fix(shacl): evaluate inherited shapes for zero-shape target profiles ([bcb5cac](https://github.com/crs4/rocrate-validator/commit/bcb5cac))
- fix(shacl): drop sub-threshold PySHACL violations at the source ([254fb88](https://github.com/crs4/rocrate-validator/commit/254fb88))
- fix(core): filter failed requirements/checks by the configured severity ([a306f7f](https://github.com/crs4/rocrate-validator/commit/a306f7f))
- fix(models): forward `extra_profiles_path` when computing validation statistics ([7b3e8bc](https://github.com/crs4/rocrate-validator/commit/7b3e8bc))
- fix(uri): treat `file://` URIs with a non-local authority as remote ([63acb6a](https://github.com/crs4/rocrate-validator/commit/63acb6a))
- fix(cli/cache): resolve profile tokens in `cache warm` and avoid `stream=True` when fetching remote crates ([7926832](https://github.com/crs4/rocrate-validator/commit/7926832), [33012b6](https://github.com/crs4/rocrate-validator/commit/33012b6))
- fix(validation): report offline cache misses once per URL ([757b86a](https://github.com/crs4/rocrate-validator/commit/757b86a))
- fix(ISA): correct the error message for a bad position in `HowToStep` ([03a32fc](https://github.com/crs4/rocrate-validator/commit/03a32fc))

### 📚 Documentation

- docs: add a dedicated documentation page for the cache and offline mode features ([e10c3b5](https://github.com/crs4/rocrate-validator/commit/e10c3b5))
- docs(profiles): document check override-by-name and deactivation ([0b6bff7](https://github.com/crs4/rocrate-validator/commit/0b6bff7))

## [0.9.0] - 2026-04-20

Full changelog: https://github.com/crs4/rocrate-validator/compare/0.8.1...0.9.0

### ✨ Added

- feat(profiles/isa): add the ISA RO-Crate profile, with checks and tests for Investigation, Study, Assay, Process, Protocol, Sample, Data, Person and PropertyValue entities ([852fb23](https://github.com/crs4/rocrate-validator/commit/852fb23), [d62e214](https://github.com/crs4/rocrate-validator/commit/d62e214), [727b6f0](https://github.com/crs4/rocrate-validator/commit/727b6f0))
- feat(cli): add CLI options to configure the HTTP cache (`--cache-path`, `--cache-max-age`) ([564230f](https://github.com/crs4/rocrate-validator/commit/564230f))
- feat(model): enable cache configuration in `ValidationSettings` ([b2b47ba](https://github.com/crs4/rocrate-validator/commit/b2b47ba))
- feat(utils): extend the `HttpRequester` constructor to support cache configuration parameters ([2f2a873](https://github.com/crs4/rocrate-validator/commit/2f2a873))
- feat(ro-crate): refine the constraint enforcing metadata descriptor existence ([2c6ea76](https://github.com/crs4/rocrate-validator/commit/2c6ea76))
- feat(file-descriptor): add an internal remote-context retrieval method supporting the alternate `Link` header ([f8b0e55](https://github.com/crs4/rocrate-validator/commit/f8b0e55))

### 🔧 Changed

- refactor(ro-crate): relax the `ROCrateMetadataFileDescriptor` class definition ([61ddbb5](https://github.com/crs4/rocrate-validator/commit/61ddbb5))
- refactor(file-descriptor): route checks through the new remote-context retrieval method ([0ce2619](https://github.com/crs4/rocrate-validator/commit/0ce2619))
- chore(utils): increase the session cache max age to 300 seconds ([36ca0ac](https://github.com/crs4/rocrate-validator/commit/36ca0ac))
- ci(gh-actions): update outdated GitHub Actions ([d565c5d](https://github.com/crs4/rocrate-validator/commit/d565c5d))

### 🐛 Fixed

- fix(ro-crate): target metadata descriptor shapes by class and select the candidate descriptor via SPARQL ([8219f27](https://github.com/crs4/rocrate-validator/commit/8219f27), [39bd761](https://github.com/crs4/rocrate-validator/commit/39bd761), [1a91aa4](https://github.com/crs4/rocrate-validator/commit/1a91aa4))
- fix(shacl): extract `@base` from the JSON-LD document for ontology parsing ([57f5c54](https://github.com/crs4/rocrate-validator/commit/57f5c54))
- fix(SHACL-core): improve SHACL violation parsing with better error handling ([90a9f06](https://github.com/crs4/rocrate-validator/commit/90a9f06))
- fix(file-descriptor): accept `application/json` and treat the `Link` header case-insensitively for remote context retrieval ([fe5ba1c](https://github.com/crs4/rocrate-validator/commit/fe5ba1c))
- fix(file-descriptor): refine the compacted JSON-LD key validation logic ([45a7017](https://github.com/crs4/rocrate-validator/commit/45a7017))
- fix(core): allow terms defined by context prefixes ([5fe8171](https://github.com/crs4/rocrate-validator/commit/5fe8171))
- fix(core): fix output formatting ([523fbf4](https://github.com/crs4/rocrate-validator/commit/523fbf4))

### 📚 Documentation

- docs(cli): document the `-1` value for no cache expiration in the `--cache-max-age` help ([c5848bc](https://github.com/crs4/rocrate-validator/commit/c5848bc))

## [0.8.1] - 2026-02-18

Full changelog: https://github.com/crs4/rocrate-validator/compare/0.8.0...0.8.1
Expand Down
9 changes: 8 additions & 1 deletion docs/0_toc.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
..
Copyright (c) 2024 CRS4
Copyright (c) 2024-2026 CRS4

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
2_usage_cli
3_usage_api
4_how_it_works
5_offline_mode

.. toctree::
:maxdepth: 5
Expand All @@ -30,3 +31,9 @@
11_writing_a_profile
10_api
genindex

.. toctree::
:maxdepth: 1
:caption: About

ack
4 changes: 2 additions & 2 deletions docs/10_api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
..
Copyright (c) 2024 CRS4
Copyright (c) 2024-2026 CRS4

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -135,7 +135,7 @@ Python Check API
======================

Requirement Class
----------
-----------------
.. autoclass:: rocrate_validator.requirements.python.PyRequirement
:members:

Expand Down
148 changes: 148 additions & 0 deletions docs/11_writing_a_profile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,154 @@ These instructions assume you are familiar with code development using Python an
#. When your profile & tests are written, open a pull request to contribute
it back to the repository!

Overriding inherited checks
---------------------------

When a profile inherits from another profile (via ``prof:isProfileOf`` /
``prof:isTransitiveProfileOf``), it automatically receives every check
declared by its ancestors. The validator additionally supports
**override-by-name**: a child profile can replace an inherited check by
declaring a new check with the **same name**.

This allows an extension profile to *redefine* the content of an inherited
check — for example, to make a constraint stricter or looser, change its
severity, or, as described in the next section, fully deactivate it.

Override-by-name is enabled by default. It can be disabled via the
``allow_requirement_check_override`` validation setting (CLI / API), which
will raise an error on duplicate check names instead.

SHACL checks
^^^^^^^^^^^^

Each SHACL ``NodeShape`` / ``PropertyShape`` becomes a check whose name is
its ``sh:name``. To override an inherited check, declare a shape in the
extension profile with the **same** ``sh:name`` as the inherited one:

.. code-block:: turtle

# Parent profile
ro:ShapeC
a sh:NodeShape ;
sh:name "The Shape C" ;
sh:targetNode ro:ro-crate-metadata.json ;
sh:property [
a sh:PropertyShape ;
sh:name "Check Metadata File Descriptor entity existence" ;
sh:path rdf:type ;
sh:minCount 1 ;
sh:message "Missing entity" ;
] .

.. code-block:: turtle

# Extension profile — overrides the inherited PropertyShape by sh:name
ro:ShapeC
a sh:NodeShape ;
sh:name "The Shape C" ;
sh:targetNode ro:ro-crate-metadata.json ;
sh:property [
a sh:PropertyShape ;
sh:name "Check Metadata File Descriptor entity existence" ;
sh:path rdf:type ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:message "Stricter override from extension profile" ;
] .

Both top-level shapes and ``PropertyShape`` entries nested inside a parent
``NodeShape`` (i.e., declared inline, without an absolute IRI) can be
overridden this way.

Python checks
^^^^^^^^^^^^^

Python checks declared via the ``@check`` decorator are matched by their
``name`` argument. To override an inherited Python check, declare a new
function with the same ``name`` in the extension profile:

.. code-block:: python

# In the extension profile's checks module
from rocrate_validator.requirements.python import check

@check(name="Check Metadata File Descriptor entity existence")
def overridden_check(self, ctx):
# New implementation that replaces the inherited one
...

Deactivating inherited checks
-----------------------------

A child profile can also **fully deactivate** a check inherited from one of
its ancestors. A deactivated check is skipped during validation and
reported as such in the validation result. This is useful when an extension
profile relaxes the parent's expectations, or replaces a coarse-grained
check with a more specific one declared elsewhere in the same profile.

SHACL checks
^^^^^^^^^^^^

Two complementary mechanisms are supported, depending on whether the shape
to disable has an absolute IRI of its own.

**Shape with an absolute IRI** (e.g. a top-level ``NodeShape`` or a named
``PropertyShape``): reference the shape by IRI from the extension profile
and mark it as deactivated, without redeclaring it.

.. code-block:: turtle

# Extension profile
<https://parent-profile/ShapeC> sh:deactivated true .

**Nested ``PropertyShape`` without an absolute IRI** (a property declared
inline inside a parent ``NodeShape``): use the override-by-name mechanism
described in the previous section. Declare a new ``PropertyShape`` in the
extension profile with the same ``sh:name`` as the one to disable, and set
``sh:deactivated true`` on it. This overrides the parent's
``PropertyShape``, and the validator reports the resulting check as
deactivated.

.. code-block:: turtle

# Extension profile — disables the inherited PropertyShape by sh:name
ro:ShapeC
a sh:NodeShape ;
sh:name "The Shape C" ;
sh:targetNode ro:ro-crate-metadata.json ;
sh:property [
a sh:PropertyShape ;
sh:name "Check Metadata File Descriptor entity existence" ;
sh:path rdf:type ;
sh:deactivated true ;
] .

.. note::

Cross-profile deactivation is scoped to the shape's transitive
descendants: a ``sh:deactivated true`` triple declared by a profile
that does not inherit (directly or transitively) from the shape's
owning profile is ignored. This prevents unrelated profiles loaded in
the same process from interfering with one another.

Python checks
^^^^^^^^^^^^^

The ``@check`` decorator accepts a ``deactivated`` flag, mirroring SHACL's
``sh:deactivated``. Combined with override-by-name, an extension profile
can disable an inherited Python check by redeclaring it with
``deactivated=True``:

.. code-block:: python

from rocrate_validator.requirements.python import check

@check(name="Check Metadata File Descriptor entity existence",
deactivated=True)
def disabled(self, ctx):
# Body is irrelevant — the check is skipped during validation.
return True

Running validator & tests during profile development
----------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/1_installation.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
..
Copyright (c) 2024 CRS4
Copyright (c) 2024-2026 CRS4

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
8 changes: 7 additions & 1 deletion docs/2_usage_cli.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
..
Copyright (c) 2024 CRS4
Copyright (c) 2024-2026 CRS4

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,3 +31,9 @@ CLI Validation
:parser: myst_parser.sphinx_
:start-line: 93
:end-line: 120

.. seealso::

To validate without network access and manage the HTTP cache from the
command line (the ``--offline`` and ``--no-cache`` flags and the ``cache``
subcommand), see :ref:`offline_mode`.
8 changes: 7 additions & 1 deletion docs/3_usage_api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
..
Copyright (c) 2024 CRS4
Copyright (c) 2024-2026 CRS4

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,6 +30,12 @@ Programmatic Validation
:start-line: 121
:end-line: 162

.. seealso::

To resolve resources from a local cache or run validation without network
access (the ``offline`` / ``no_cache`` settings of ``ValidationSettings``),
see :ref:`offline_mode`.


Metadata-only Validation
------------------------
Expand Down
Loading