Skip to content

Commit

Permalink
release: 🔖 version 0.4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
kikkomep committed Nov 6, 2024
2 parents dc16e15 + a4eb460 commit 9310f2c
Show file tree
Hide file tree
Showing 21 changed files with 703 additions and 39 deletions.
9 changes: 4 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "roc-validator"
version = "0.4.2"
version = "0.4.3"
description = "A Python package to validate RO-Crates"
authors = [
"Marco Enrico Piras <kikkomep@crs4.it>",
Expand Down Expand Up @@ -58,7 +58,7 @@ include = [
]

[tool.poetry.dependencies]
python = "^3.8.1"
python = "^3.9.20"
rdflib = "^7.0.0"
pyshacl = "^0.26.0"
click = "^8.1.7"
Expand Down
8 changes: 8 additions & 0 deletions rocrate_validator/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ def cli(ctx: click.Context, debug: bool, version: bool, disable_color: bool, no_
ctx.obj['interactive'] = interactive

try:
# Check the python version
# from rocrate_validator.utils import check_python_version, get_min_python_version
# if not check_python_version():
# console.print(
# "\n[bold][red]ERROR:[/red] A Python version "
# f"{'.'.join([str(_) for _ in get_min_python_version()])} or newer is required ! [/bold]")
# sys.exit(1)

# If the version flag is set, print the version and exit
if version:
console.print(
Expand Down
10 changes: 9 additions & 1 deletion rocrate_validator/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,14 @@ def __init__(self,
requirement: Requirement,
name: str,
level: Optional[RequirementLevel] = LevelCollection.REQUIRED,
description: Optional[str] = None):
description: Optional[str] = None,
hidden: Optional[bool] = None):
self._requirement: Requirement = requirement
self._order_number = 0
self._name = name
self._level = level
self._description = description
self._hidden = hidden

@property
def order_number(self) -> int:
Expand Down Expand Up @@ -912,6 +914,12 @@ def override(self) -> list[RequirementCheck]:
def overridden(self) -> bool:
return len(self.overridden_by) > 0

@property
def hidden(self) -> bool:
if self._hidden is not None:
return self._hidden
return self.requirement.hidden

@abstractmethod
def execute_check(self, context: ValidationContext) -> bool:
raise NotImplementedError()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,12 @@ ro-crate:RootDataEntityRequiredProperties
a sh:PropertyShape ;
sh:name "Root Data Entity: `datePublished` property" ;
sh:description """Check if the Root Data Entity includes a `datePublished` (as specified by schema.org)
to provide the date when the dataset was published. The datePublished MUST be a valid ISO 8601 date.
It SHOULD be specified to at least the day level, but MAY include a time component.""" ;
to provide the date when the dataset was published. The datePublished MUST be a valid ISO 8601 date.""" ;
sh:minCount 1 ;
sh:nodeKind sh:Literal ;
sh:path schema_org:datePublished ;
sh:pattern "^(\\d{4}-\\d{2}-\\d{2})(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?\\+\\d{2}:\\d{2})?$" ;
sh:message "The Root Data Entity MUST have a `datePublished` property (as specified by schema.org) with a valid ISO 8601 date and the precision of at least the day level" ;
sh:pattern "^([\\+-]?\\d{4})((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)?[0-5]\\d)?|24:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$" ;
sh:message "The Root Data Entity MUST have a `datePublished` property (as specified by schema.org) with a valid ISO 8601 date" ;
] .

ro-crate:RootDataEntityHasPartValueRestriction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,16 @@ ro-crate:RootDataEntityDirectRecommendedProperties a sh:NodeShape ;
sh:message "The `publisher` property of a `Root Data Entity` SHOULD be an `Organization`";
sh:nodeKind sh:IRI ;
sh:class schema_org:Organization ;
] ;
sh:property [
a sh:PropertyShape ;
sh:name "Root Data Entity: RECOMMENDED `datePublished` property" ;
sh:description """Check if the Root Data Entity includes a `datePublished` (as specified by schema.org)
to provide the date when the dataset was published. The datePublished MUST be a valid ISO 8601 date.
It SHOULD be specified to at least the day level, but MAY include a time component.""" ;
sh:minCount 1 ;
sh:nodeKind sh:Literal ;
sh:path schema_org:datePublished ;
sh:pattern "^([\\+-]?\\d{4})((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))|W([0-4]\\d|5[0-2])(-?[1-7])|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)?[0-5]\\d)?|24:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)$" ;
sh:message "The Root Data Entity MUST have a `datePublished` property (as specified by schema.org) with a valid ISO 8601 date and the precision of at least the day level" ;
] .
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ ro-crate:WebBasedDataEntityRequiredValueRestriction a sh:NodeShape ;
sh:name "Web-based Data Entity: `sdDatePublished` property" ;
sh:description """Check if the Web-based Data Entity has a `sdDatePublished` property""" ;
sh:path schema_org:sdDatePublished ;
# sh:datatype xsd:dateTime ;
sh:pattern "^(\\d{4}-\\d{2}-\\d{2})(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?\\+\\d{2}:\\d{2})?$" ;
sh:severity sh:Warning ;
sh:message """Web-based Data Entities SHOULD have a `sdDatePublished` property""" ;
sh:pattern "^([\\+-]?\\d{4})((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))|W([0-4]\\d|5[0-2])(-?[1-7])|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)?[0-5]\\d)?|24:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)$" ;
sh:message """Web-based Data Entities SHOULD have a `sdDatePublished` property to indicate when the absolute URL was accessed""" ;
] .
21 changes: 16 additions & 5 deletions rocrate_validator/requirements/shacl/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,23 @@ class SHACLCheck(RequirementCheck):

def __init__(self,
requirement: Requirement,
shape: Shape) -> None:
shape: Shape,
name: Optional[str] = None,
root: bool = False,
hidden: Optional[bool] = None,
level: Optional[bool] = None) -> None:
self._shape = shape
self._root = root
# init the check
super().__init__(requirement,
shape.name if shape and shape.name
name or shape.name if shape and shape.name
else shape.parent.name if shape.parent
else None,
shape.description if shape and shape.description
description=shape.description if shape and shape.description
else shape.parent.description if shape.parent
else None)
else None,
level=level,
hidden=hidden)
# store the instance
SHACLCheck.__add_instance__(shape, self)

Expand All @@ -66,12 +73,16 @@ def __init__(self,
"shape level %s does not match the level from the containing folder %s. "
"Consider moving the shape property or removing the severity property.",
self.name, shape.level, requirement_level_from_path)
self._level = None
self._level = level

@property
def shape(self) -> Shape:
return self._shape

@property
def root(self) -> bool:
return self._root

@property
def description(self) -> str:
return self._shape.description
Expand Down
20 changes: 15 additions & 5 deletions rocrate_validator/requirements/shacl/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,31 @@ def __init__(self,
# assign check IDs
self.__reorder_checks__()

def __reorder_checks__(self) -> None:
i = 0
for check in self._checks:
check.order_number = i
i += 1

def __init_checks__(self) -> list[RequirementCheck]:
# check if the shape is not None before creating checks
assert self.shape is not None, "The shape cannot be None"
assert self.shape.node is not None, "The shape node cannot be None"
# assign a check to each property of the shape
checks = []
# check if the shape has nested properties
has_properties = hasattr(self.shape, "properties") and len(self.shape.properties) > 0
# create a check for the shape itself, hidden if the shape has nested properties
checks.append(SHACLCheck(self, self.shape, name=f"Check {self.shape.name}" if has_properties else None,
hidden=has_properties, root=True))
# create a check for each property if the shape has nested properties
if hasattr(self.shape, "properties"):
if has_properties:
for prop in self.shape.properties:
logger.debug("Creating check for property %s %s", prop.name, prop.description)
property_check = SHACLCheck(self, prop)
logger.debug("Property check %s: %s", property_check.name, property_check.description)
checks.append(property_check)

# if no property checks, add a generic one
assert self.shape is not None, "The shape cannot be None"
if len(checks) == 0 and self.shape is not None and self.shape.node is not None:
checks.append(SHACLCheck(self, self.shape))
return checks

@property
Expand Down
23 changes: 23 additions & 0 deletions rocrate_validator/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,29 @@ def get_version() -> str:
return f"{version}-dirty" if dirty else version


def get_min_python_version() -> tuple[int, int, Optional[int]]:
"""
Get the minimum Python version required by the package
:return: The minimum Python version
"""
min_version_str = config["tool"]["poetry"]["dependencies"]["python"]
assert min_version_str, "The minimum Python version is required"
# remove any non-digit characters
min_version_str = re.sub(r'[^\d.]+', '', min_version_str)
# convert the version string to a tuple
min_version = tuple(map(int, min_version_str.split(".")))
logger.debug(f"Minimum Python version: {min_version}")
return min_version


def check_python_version() -> bool:
"""
Check if the current Python version meets the minimum requirements
"""
return sys.version_info >= get_min_python_version()


def get_config(property: Optional[str] = None) -> dict:
"""
Get the configuration for the package or a specific property
Expand Down
36 changes: 36 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,39 @@ def ro_crate_profile_should_path(ro_crate_profile_path):
@fixture
def ro_crate_profile_may_path(ro_crate_profile_path):
return os.path.join(ro_crate_profile_path, "may")


@fixture(params=[
"2024 01 01",
"2024 Jan 01",
"2021-13-01",
"2021-00-10",
"2021-01-32",
"2021-01-01T25:00",
"2021-01-01T23:60",
"2021-01-01T23:59:60",
"T23:59:59",
])
def invalid_datetime(request):
return request.param


@fixture(params=[
"2024",
"2024-01",
"202401",
"2024-01-01",
"20240101",
"2024-001",
"2024-W01",
"2024-W01-1",
"2024-01-01T00:00",
"2024-01-01T00:00:00",
"2024-01-01T00:00:00Z",
"2024-01-01T00:00:00+00:00",
"2024-01-01T00:00:00.000",
"2024-01-01T00:00:00.000Z",
"2024-01-01T00:00:00.000+00:00",
])
def valid_datetime(request):
return request.param
Loading

0 comments on commit 9310f2c

Please # to comment.